From 5b58c57426b19b5a1d09353272529d516efad761 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Fri, 21 Oct 2011 03:48:04 +0200
Subject: [PATCH] kernel: Move GPL kernel sources under sys/gnu to have them
 all in one place.

This affects files in sys/dev/sound/pci/gnu and sys/vfs/gnu/ext2fs.

sys/gnu is analogous to the gnu directory for userland, i.e. below it, we
follow the same hierarchy as in /usr/src/sys.

This commit changes the location of the ext2fs headers, which are public,
so I've bumped __DragonFly_version in order to have something to patch
against, in case this causes breakage in /usr/pkgsrc.
---
 Makefile_upgrade.inc                   |    1 +
 etc/mtree/BSD.include.dist             |   10 +-
 include/Makefile                       |    3 +-
 lib/libfsid/ext2.c                     |    4 +-
 sys/Makefile.modules                   |    2 +-
 sys/conf/files                         |   30 +-
 sys/dev/sound/driver/emu10k1/Makefile  |    3 +-
 sys/dev/sound/pci/csa.c                |    2 +-
 sys/dev/sound/pci/emu10k1.c            |    2 +-
 sys/dev/sound/pci/gnu/csaimg.h         |  342 ------
 sys/dev/sound/pci/gnu/emu10k1-ac97.h   |  294 -----
 sys/dev/sound/pci/gnu/emu10k1-alsa.h   | 1375 ---------------------
 sys/dev/sound/pci/gnu/emu10k1.h        |  741 -----------
 sys/dev/sound/pci/gnu/maestro3_dsp.h   |  215 ----
 sys/dev/sound/pci/gnu/maestro3_reg.h   |  693 -----------
 sys/dev/sound/pci/maestro3.c           |    4 +-
 sys/gnu/Makefile                       |    3 +
 sys/gnu/dev/sound/pci/csaimg.h         |  341 +++++
 sys/gnu/dev/sound/pci/emu10k1-ac97.h   |  293 +++++
 sys/gnu/dev/sound/pci/emu10k1-alsa.h   | 1374 +++++++++++++++++++++
 sys/gnu/dev/sound/pci/emu10k1.h        |  740 +++++++++++
 sys/gnu/dev/sound/pci/maestro3_dsp.h   |  214 ++++
 sys/gnu/dev/sound/pci/maestro3_reg.h   |  692 +++++++++++
 sys/gnu/vfs/Makefile                   |    3 +
 sys/gnu/vfs/ext2fs/COPYRIGHT.INFO      |   55 +
 sys/gnu/vfs/ext2fs/Makefile            |   10 +
 sys/gnu/vfs/ext2fs/dinode.h            |  132 ++
 sys/gnu/vfs/ext2fs/dir.h               |  159 +++
 sys/gnu/vfs/ext2fs/ext2_alloc.c        |  537 ++++++++
 sys/gnu/vfs/ext2fs/ext2_balloc.c       |  313 +++++
 sys/gnu/vfs/ext2fs/ext2_bitops.h       |  114 ++
 sys/gnu/vfs/ext2fs/ext2_bmap.c         |  343 ++++++
 sys/gnu/vfs/ext2fs/ext2_extern.h       |  120 ++
 sys/gnu/vfs/ext2fs/ext2_fs.h           |  566 +++++++++
 sys/gnu/vfs/ext2fs/ext2_fs_sb.h        |   85 ++
 sys/gnu/vfs/ext2fs/ext2_ihash.c        |  214 ++++
 sys/gnu/vfs/ext2fs/ext2_inode.c        |  575 +++++++++
 sys/gnu/vfs/ext2fs/ext2_inode_cnv.c    |  137 ++
 sys/gnu/vfs/ext2fs/ext2_linux_balloc.c |  621 ++++++++++
 sys/gnu/vfs/ext2fs/ext2_linux_ialloc.c |  516 ++++++++
 sys/gnu/vfs/ext2fs/ext2_lookup.c       | 1042 ++++++++++++++++
 sys/gnu/vfs/ext2fs/ext2_quota.c        |  923 ++++++++++++++
 sys/gnu/vfs/ext2fs/ext2_readwrite.c    |  298 +++++
 sys/gnu/vfs/ext2fs/ext2_subr.c         |   87 ++
 sys/gnu/vfs/ext2fs/ext2_vfsops.c       | 1354 ++++++++++++++++++++
 sys/gnu/vfs/ext2fs/ext2_vnops.c        | 2113 +++++++++++++++++++++++++++++++
 sys/gnu/vfs/ext2fs/ext2mount.h         |  124 ++
 sys/gnu/vfs/ext2fs/fs.h                |  195 +++
 sys/gnu/vfs/ext2fs/i386-bitops.h       |  172 +++
 sys/gnu/vfs/ext2fs/inode.h             |  173 +++
 sys/gnu/vfs/ext2fs/quota.h             |  204 +++
 sys/sys/param.h                        |    4 +-
 sys/vfs/Makefile                       |    3 +-
 sys/vfs/gnu/Makefile                   |    6 -
 sys/vfs/gnu/ext2fs/COPYRIGHT.INFO      |   57 -
 sys/vfs/gnu/ext2fs/Makefile            |   10 -
 sys/vfs/gnu/ext2fs/dinode.h            |  133 --
 sys/vfs/gnu/ext2fs/dir.h               |  160 ---
 sys/vfs/gnu/ext2fs/ext2_alloc.c        |  538 --------
 sys/vfs/gnu/ext2fs/ext2_balloc.c       |  314 -----
 sys/vfs/gnu/ext2fs/ext2_bitops.h       |  115 --
 sys/vfs/gnu/ext2fs/ext2_bmap.c         |  344 ------
 sys/vfs/gnu/ext2fs/ext2_extern.h       |  121 --
 sys/vfs/gnu/ext2fs/ext2_fs.h           |  567 ---------
 sys/vfs/gnu/ext2fs/ext2_fs_sb.h        |   85 --
 sys/vfs/gnu/ext2fs/ext2_ihash.c        |  216 ----
 sys/vfs/gnu/ext2fs/ext2_inode.c        |  576 ---------
 sys/vfs/gnu/ext2fs/ext2_inode_cnv.c    |  138 ---
 sys/vfs/gnu/ext2fs/ext2_linux_balloc.c |  622 ----------
 sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c |  517 --------
 sys/vfs/gnu/ext2fs/ext2_lookup.c       | 1042 ----------------
 sys/vfs/gnu/ext2fs/ext2_quota.c        |  924 --------------
 sys/vfs/gnu/ext2fs/ext2_readwrite.c    |  299 -----
 sys/vfs/gnu/ext2fs/ext2_subr.c         |   89 --
 sys/vfs/gnu/ext2fs/ext2_vfsops.c       | 1355 --------------------
 sys/vfs/gnu/ext2fs/ext2_vnops.c        | 2115 --------------------------------
 sys/vfs/gnu/ext2fs/ext2mount.h         |  125 --
 sys/vfs/gnu/ext2fs/fs.h                |  196 ---
 sys/vfs/gnu/ext2fs/i386-bitops.h       |  173 ---
 sys/vfs/gnu/ext2fs/inode.h             |  174 ---
 sys/vfs/gnu/ext2fs/quota.h             |  205 ---
 81 files changed, 14877 insertions(+), 14909 deletions(-)
 delete mode 100644 sys/dev/sound/pci/gnu/csaimg.h
 delete mode 100644 sys/dev/sound/pci/gnu/emu10k1-ac97.h
 delete mode 100644 sys/dev/sound/pci/gnu/emu10k1-alsa.h
 delete mode 100644 sys/dev/sound/pci/gnu/emu10k1.h
 delete mode 100644 sys/dev/sound/pci/gnu/maestro3_dsp.h
 delete mode 100644 sys/dev/sound/pci/gnu/maestro3_reg.h
 create mode 100644 sys/gnu/Makefile
 create mode 100644 sys/gnu/dev/sound/pci/csaimg.h
 create mode 100644 sys/gnu/dev/sound/pci/emu10k1-ac97.h
 create mode 100644 sys/gnu/dev/sound/pci/emu10k1-alsa.h
 create mode 100644 sys/gnu/dev/sound/pci/emu10k1.h
 create mode 100644 sys/gnu/dev/sound/pci/maestro3_dsp.h
 create mode 100644 sys/gnu/dev/sound/pci/maestro3_reg.h
 create mode 100644 sys/gnu/vfs/Makefile
 create mode 100644 sys/gnu/vfs/ext2fs/COPYRIGHT.INFO
 create mode 100644 sys/gnu/vfs/ext2fs/Makefile
 create mode 100644 sys/gnu/vfs/ext2fs/dinode.h
 create mode 100644 sys/gnu/vfs/ext2fs/dir.h
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_alloc.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_balloc.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_bitops.h
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_bmap.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_extern.h
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_fs.h
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_fs_sb.h
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_ihash.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_inode.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_inode_cnv.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_linux_balloc.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_linux_ialloc.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_lookup.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_quota.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_readwrite.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_subr.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_vfsops.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2_vnops.c
 create mode 100644 sys/gnu/vfs/ext2fs/ext2mount.h
 create mode 100644 sys/gnu/vfs/ext2fs/fs.h
 create mode 100644 sys/gnu/vfs/ext2fs/i386-bitops.h
 create mode 100644 sys/gnu/vfs/ext2fs/inode.h
 create mode 100644 sys/gnu/vfs/ext2fs/quota.h
 delete mode 100644 sys/vfs/gnu/Makefile
 delete mode 100644 sys/vfs/gnu/ext2fs/COPYRIGHT.INFO
 delete mode 100644 sys/vfs/gnu/ext2fs/Makefile
 delete mode 100644 sys/vfs/gnu/ext2fs/dinode.h
 delete mode 100644 sys/vfs/gnu/ext2fs/dir.h
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_alloc.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_balloc.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_bitops.h
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_bmap.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_extern.h
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_fs.h
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_fs_sb.h
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_ihash.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_inode.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_inode_cnv.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_linux_balloc.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_lookup.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_quota.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_readwrite.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_subr.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_vfsops.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2_vnops.c
 delete mode 100644 sys/vfs/gnu/ext2fs/ext2mount.h
 delete mode 100644 sys/vfs/gnu/ext2fs/fs.h
 delete mode 100644 sys/vfs/gnu/ext2fs/i386-bitops.h
 delete mode 100644 sys/vfs/gnu/ext2fs/inode.h
 delete mode 100644 sys/vfs/gnu/ext2fs/quota.h

diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc
index 1a09924..8af9ff6 100644
--- a/Makefile_upgrade.inc
+++ b/Makefile_upgrade.inc
@@ -1726,6 +1726,7 @@ TO_REMOVE+=/usr/share/misc/gprof.callg
 TO_REMOVE+=/usr/share/misc/gprof.flat
 TO_REMOVE+=/usr/share/man/cat4/i386/ndis.4.gz
 TO_REMOVE+=/usr/share/man/man4/i386/ndis.4.gz
+TO_REMOVE+=/usr/include/vfs/gnu
 
 .if ${MACHINE_ARCH} == "x86_64"
 TO_REMOVE+=/usr/libdata/stallion/2681.sys
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index e829d12..4cecf66 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -97,6 +97,12 @@
         linux
         ..
     ..
+    gnu
+        vfs
+            ext2fs
+            ..
+        ..
+    ..
     i4b_machine
     ..
     libmilter
@@ -270,10 +276,6 @@
         ..
         smbfs
         ..
-        gnu
-            ext2fs
-            ..
-        ..
         isofs
             cd9660
             ..
diff --git a/include/Makefile b/include/Makefile
index ae7d129..6e73459 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -54,7 +54,8 @@ LDIRS=	net netbt netgraph netinet netinet6 sys vm
 #
 LSUBDIRS=	bus/cam bus/cam/scsi \
 	emulation/linux \
-	vfs/msdosfs vfs/nfs vfs/ntfs vfs/nwfs vfs/gnu/ext2fs \
+	gnu/vfs/ext2fs \
+	vfs/msdosfs vfs/nfs vfs/ntfs vfs/nwfs \
 	vfs/smbfs vfs/udf vfs/ufs vfs/hammer \
 	net/vlan net/ipfw net/ip6fw net/dummynet net/sppp net/ip_mroute \
 	net/bridge net/tap net/tun net/ppp net/ppp_layer net/sl \
diff --git a/lib/libfsid/ext2.c b/lib/libfsid/ext2.c
index 26ce9fa..68391f3 100644
--- a/lib/libfsid/ext2.c
+++ b/lib/libfsid/ext2.c
@@ -32,8 +32,8 @@
  * SUCH DAMAGE.
  */
 
-#include <vfs/gnu/ext2fs/ext2_fs.h>
-#include <vfs/gnu/ext2fs/fs.h>
+#include <gnu/vfs/ext2fs/ext2_fs.h>
+#include <gnu/vfs/ext2fs/fs.h>
 
 #include "libfsid.h"
 
diff --git a/sys/Makefile.modules b/sys/Makefile.modules
index bd5f3ba..242fbbe 100644
--- a/sys/Makefile.modules
+++ b/sys/Makefile.modules
@@ -7,7 +7,7 @@ SUBDIR=${MODULES_OVERRIDE}
 .if ${MACHINE_PLATFORM} != "vkernel" && ${MACHINE_PLATFORM} != "vkernel64"
 SUBDIR=bus
 .endif
-SUBDIR+=crypto emulation dev kern net netbt netgraph netproto vfs
+SUBDIR+=crypto emulation dev gnu kern net netbt netgraph netproto vfs
 SUBDIR+=libiconv
 .endif
 
diff --git a/sys/conf/files b/sys/conf/files
index 3eea9ad..77c6506 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -31,8 +31,8 @@ aic79xx_reg_print.o		optional ahd pci ahd_reg_pretty_print	\
 	compile-with	"${NORMAL_C} ${WERROR}"			\
 	no-implicit-rule local
 emu10k1-alsa%diked.h		optional snd_emu10k1 pci			   \
-	dependency	"$S/tools/emu10k1-mkalsa.sh $S/dev/sound/pci/gnu/emu10k1-alsa.h" \
-	compile-with	"CC=${CC} AWK=${AWK} sh $S/tools/emu10k1-mkalsa.sh $S/dev/sound/pci/gnu/emu10k1-alsa.h emu10k1-alsa%diked.h" \
+	dependency	"$S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h" \
+	compile-with	"CC=${CC} AWK=${AWK} sh $S/tools/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/emu10k1-alsa.h emu10k1-alsa%diked.h" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"emu10k1-alsa%diked.h"
 kern/device_if.m			standard
@@ -773,19 +773,19 @@ dev/netif/rtw/smc93cx6.c		optional rtw
 dev/netif/rtw/if_rtw_pci.c		optional rtw pci
 dev/netif/xe/if_xe.c			optional xe
 dev/netif/xe/if_xe_pccard.c		optional xe pccard
-vfs/gnu/ext2fs/ext2_alloc.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_balloc.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_bmap.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_inode.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_inode_cnv.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_linux_balloc.c	optional ext2fs
-vfs/gnu/ext2fs/ext2_linux_ialloc.c	optional ext2fs
-vfs/gnu/ext2fs/ext2_lookup.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_subr.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_vfsops.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_vnops.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_ihash.c		optional ext2fs
-vfs/gnu/ext2fs/ext2_quota.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_alloc.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_balloc.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_bmap.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_inode.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_inode_cnv.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_linux_balloc.c	optional ext2fs
+gnu/vfs/ext2fs/ext2_linux_ialloc.c	optional ext2fs
+gnu/vfs/ext2fs/ext2_lookup.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_subr.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_vfsops.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_vnops.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_ihash.c		optional ext2fs
+gnu/vfs/ext2fs/ext2_quota.c		optional ext2fs
 #
 # isdn4bsd device drivers
 #
diff --git a/sys/dev/sound/driver/emu10k1/Makefile b/sys/dev/sound/driver/emu10k1/Makefile
index 2e07b2e..98f5922 100644
--- a/sys/dev/sound/driver/emu10k1/Makefile
+++ b/sys/dev/sound/driver/emu10k1/Makefile
@@ -1,8 +1,7 @@
 # $FreeBSD: src/sys/modules/sound/driver/emu10k1/Makefile,v 1.4 2004/01/11 10:30:56 obrien Exp $
-# $DragonFly: src/sys/dev/sound/driver/emu10k1/Makefile,v 1.3 2007/01/04 21:47:01 corecode Exp $
 
 .PATH: ${.CURDIR}/../../pci \
-       ${.CURDIR}/../../pci/gnu
+       ${.CURDIR}/../../../../gnu/dev/sound/pci
 
 KMOD=	snd_emu10k1
 SRCS=	device_if.h bus_if.h pci_if.h emu10k1-alsa%diked.h
diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c
index 94830fe..e1fafad 100644
--- a/sys/dev/sound/pci/csa.c
+++ b/sys/dev/sound/pci/csa.c
@@ -47,7 +47,7 @@
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
-#include <dev/sound/pci/gnu/csaimg.h>
+#include <gnu/dev/sound/pci/csaimg.h>
 
 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/csa.c,v 1.8 2007/01/04 21:47:02 corecode Exp $");
 
diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c
index 89dc886..15d33b7 100644
--- a/sys/dev/sound/pci/emu10k1.c
+++ b/sys/dev/sound/pci/emu10k1.c
@@ -30,7 +30,7 @@
 
 #include <dev/sound/pcm/sound.h>
 #include <dev/sound/pcm/ac97.h>
-#include <dev/sound/pci/gnu/emu10k1.h>
+#include <gnu/dev/sound/pci/emu10k1.h>
 #include "emu10k1-alsa%diked.h"
 
 #include <bus/pci/pcireg.h>
diff --git a/sys/dev/sound/pci/gnu/csaimg.h b/sys/dev/sound/pci/gnu/csaimg.h
deleted file mode 100644
index 8a2afff..0000000
--- a/sys/dev/sound/pci/gnu/csaimg.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*-
- ****************************************************************************
- * "CWCIMAGE.H"-- For CS46XX. Ver 1.04
- *      Copyright 1998-2001 (c) Cirrus Logic Corp.
- *      Version 1.04
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this program; if not, write to the Free
- *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- *     USA.
- *
- * $FreeBSD: src/sys/gnu/dev/sound/pci/csaimg.h,v 1.2 2005/01/06 18:27:30 imp Exp $
- * $DragonFly: src/sys/dev/sound/pci/gnu/csaimg.h,v 1.3 2007/01/04 21:47:03 corecode Exp $
- *
- ***************************************************************************/
-
-#ifndef __CS_IMAGE_H
-#define __CS_IMAGE_H
-
-#define CLEAR__COUNT     3
-#define FILL__COUNT      4
-#define BA1__DWORD_SIZE  13*1024+512
-
-static struct
-{
-        unsigned BA1__DestByteOffset;
-        unsigned BA1__SourceSize;
-} ClrStat[CLEAR__COUNT] ={ {0x00000000, 0x00003000 },
-                           {0x00010000, 0x00003800 },
-                           {0x00020000, 0x00007000 } };
-
-static u_int32_t FillArray1[]={
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00200040,0x00008010,0x00000000,
-0x00000000,0x80000001,0x00000001,0x00060000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00900080,0x00000173,0x00000000,
-0x00000000,0x00000010,0x00800000,0x00900000,
-0xf2c0000f,0x00000200,0x00000000,0x00010600,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000163,0x330300c2,
-0x06000000,0x00000000,0x80008000,0x80008000,
-0x3fc0000f,0x00000301,0x00010400,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-0x04800000,0x00000001,0x00800001,0x0000ffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x066a0600,0x06350070,0x0000929d,0x929d929d,
-0x00000000,0x0000735a,0x00000600,0x00000000,
-0x929d735a,0x00000000,0x00010000,0x735a735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000804f,0x000000c3,
-0x05000000,0x00a00010,0x00000000,0x80008000,
-0x00000000,0x00000000,0x00000700,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000080,0x00a00000,0x0000809a,0x000000c2,
-0x07400000,0x00000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x000107a0,
-0x00c80028,0x000000c2,0x06800000,0x00000000,
-0x06e00080,0x00300000,0x000080bb,0x000000c9,
-0x07a00000,0x04000000,0x80008000,0xffffffff,
-0x00c80028,0x00005555,0x00000000,0x00000780,
-0x00c80028,0x000000c5,0xff800000,0x00000000,
-0x00640080,0x00c00000,0x00008197,0x000000c9,
-0x07800000,0x04000000,0x80008000,0xffffffff,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000805e,0x000000c1,
-0x00000000,0x00800000,0x80008000,0x80008000,
-0x00020000,0x0000ffff,0x00000000,0x00000000};
-
-static u_int32_t FillArray2[]={
-0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x00100635,0x060b013f,0x00000004,
-0x00000001,0x007a0002,0x00000000,0x066e0610,
-0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-0x00000000,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0x00000000,0x06400136,
-0x0000270f,0x00010000,0x007a0000,0x00000000,
-0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-0x735a0100,0x00000000,0x00000000,0x00000000};
-
-static u_int32_t FillArray3[]={
-0x00000000,0x00000000,0x00000000,0x00010004};
-
-static u_int32_t FillArray4[]={
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00001705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00009705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00011705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00019705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00021705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00029705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00031705,0x00001400,0x000a411e,0x00001003,
-0x00040730,0x00001002,0x000f619e,0x00001003,
-0x00039705,0x00001400,0x000a411e,0x00001003,
-0x000fe19e,0x00001003,0x0009c730,0x00001003,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00009705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00011705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00019705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00021705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00029705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00031705,0x00001400,0x000a211e,0x00001003,
-0x00098730,0x00001002,0x000ee19e,0x00001003,
-0x00039705,0x00001400,0x000a211e,0x00001003,
-0x0000a730,0x00001008,0x000e2730,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x0000a731,0x00001002,0x0000a731,0x00001002,
-0x00000000,0x00000000,0x000f619c,0x00001003,
-0x0007f801,0x000c0000,0x00000037,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0000373c,0x00001000,0x00000000,0x00000000,
-0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000273c,0x00001000,
-0x00000033,0x00001000,0x000e679e,0x00001003,
-0x00007705,0x00001400,0x000ac71e,0x00001003,
-0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0000a730,0x00001003,
-0x00000033,0x00001000,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x000c0000,
-0x00000032,0x00001000,0x0000273d,0x00001000,
-0x0004a730,0x00001003,0x00000f41,0x00097140,
-0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-0x00002725,0x000aa400,0x00013705,0x00093a00,
-0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-0x00031705,0x00092240,0x00039f05,0x000932c0,
-0x0003520a,0x00000000,0x00040731,0x0000100b,
-0x00010705,0x000b20c0,0x00000000,0x000eba44,
-0x00032108,0x000c60c4,0x00065208,0x000c2917,
-0x000406b0,0x00001007,0x00012f05,0x00036880,
-0x0002818e,0x000c0000,0x0004410a,0x00000000,
-0x00040630,0x00001007,0x00029705,0x000c0000,
-0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-0x000683ad,0x00095241,0x00020f05,0x000991c1,
-0x00000000,0x00000000,0x00086f88,0x00001000,
-0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-0x000a1681,0x000b97c0,0x00021601,0x00002500,
-0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-0x00021681,0x00002d00,0x00020f81,0x000bd800,
-0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-0x00021681,0x00020d00,0x00020f81,0x000bde80,
-0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-0x0007e48a,0x00000000,0x00011f05,0x00084080,
-0x00000000,0x00000000,0x00001705,0x000b3540,
-0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-0x00055488,0x00000000,0x0000d482,0x0003fc40,
-0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-0x000c86b0,0x00001007,0x00008281,0x000bb240,
-0x0000b801,0x000b7140,0x00007888,0x00000000,
-0x0000073c,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x00055288,0x000c555c,
-0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-0x0000fa88,0x00000000,0x00000032,0x00001000,
-0x0000073d,0x00001000,0x0007f188,0x000c0000,
-0x00000000,0x00000000,0x0008c01c,0x00001003,
-0x00002705,0x00001008,0x0008b201,0x000c1392,
-0x0000ba01,0x00000000,0x00008731,0x00001400,
-0x0004c108,0x000fe0c4,0x00057488,0x00000000,
-0x000a6388,0x00001001,0x0008b334,0x000bc141,
-0x0003020e,0x00000000,0x000886b0,0x00001008,
-0x00003625,0x000c5dfa,0x000a638a,0x00001001,
-0x0008020e,0x00001002,0x0008a6b0,0x00001008,
-0x0007f301,0x00000000,0x00000000,0x00000000,
-0x00002725,0x000a8c40,0x000000ae,0x00000000,
-0x000d8630,0x00001008,0x00000000,0x000c74e0,
-0x0007d182,0x0002d640,0x000a8630,0x00001008,
-0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
-0x0007420a,0x000c0000,0x00062208,0x000c4117,
-0x00070630,0x00001009,0x00000000,0x000c0000,
-0x0001022e,0x00000000,0x0003a630,0x00001009,
-0x00000000,0x000c0000,0x00000036,0x00001000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x0002a730,0x00001008,0x0007f801,0x000c0000,
-0x00000037,0x00001000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x00000000,0x00000000,
-0x00000000,0x00000000,0x0002a730,0x00001008,
-0x00000033,0x00001000,0x0002a705,0x00001008,
-0x00007a01,0x000c0000,0x000e6288,0x000d550a,
-0x0006428a,0x00000000,0x00060730,0x0000100a,
-0x00000000,0x000c0000,0x00000000,0x00000000,
-0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-0x00057488,0x00000000,0x00033b94,0x00081140,
-0x000183ae,0x00000000,0x000786b0,0x0000100b,
-0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-0x00042731,0x00001003,0x0007aab0,0x00034880,
-0x00048fb0,0x0000100a,0x00057488,0x00000000,
-0x00033b94,0x00081140,0x000183ae,0x00000000,
-0x000806b0,0x0000100b,0x00022f05,0x00000000,
-0x00007401,0x00091140,0x00048f05,0x000951c0,
-0x00042731,0x00001003,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x000fe19e,0x00001003,0x00000000,0x00000000,
-0x0008e19c,0x00001003,0x000083c1,0x00093040,
-0x00000f41,0x00097140,0x0000a841,0x0009b240,
-0x0000a0c1,0x0009f040,0x0001c641,0x00093540,
-0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
-0x00055208,0x00000000,0x00010705,0x000a2880,
-0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
-0x0004ef0a,0x000c0000,0x00012f05,0x00036880,
-0x00065308,0x000c2997,0x000d86b0,0x0000100a,
-0x0004410a,0x000d40c7,0x00000000,0x00000000,
-0x00080730,0x00001004,0x00056f0a,0x000ea105,
-0x00000000,0x00000000,0x0000473d,0x00001000,
-0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
-0x0000273d,0x00001000,0x00000000,0x000eba44,
-0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x00000000,0x000e5084,
-0x00000000,0x000eba44,0x00087401,0x000e4782,
-0x00000734,0x00001000,0x00010705,0x000a6880,
-0x00006a88,0x000c75c4,0x0007c108,0x000c0000,
-0x0007e721,0x000bed40,0x00005f25,0x000badc0,
-0x0003ba97,0x000beb80,0x00065590,0x000b2e00,
-0x00033217,0x00003ec0,0x00065590,0x000b8e40,
-0x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
-0x000283a0,0x0000100c,0x000ee388,0x00042970,
-0x00008301,0x00021ef2,0x000b8f14,0x0000000f,
-0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
-0x000032ac,0x000c3916,0x0004edc2,0x00074c80,
-0x00078898,0x00001000,0x00038894,0x00000032,
-0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
-0x0004edc2,0x000c1956,0x0000722c,0x00034a00,
-0x00041705,0x0009ed40,0x00058730,0x00001400,
-0x000d7488,0x000c3a00,0x00048f05,0x00000000};
-
-static struct
-{   u_int32_t Offset;
-    u_int32_t Size;
-    u_int32_t *pFill;
-} FillStat[FILL__COUNT] = {
-                            {0x00000000, sizeof(FillArray1), FillArray1},
-                            {0x00001800, sizeof(FillArray2), FillArray2},
-                            {0x000137f0, sizeof(FillArray3), FillArray3},
-                            {0x00020000, sizeof(FillArray4), FillArray4}
-                          };
-
-
-#endif
diff --git a/sys/dev/sound/pci/gnu/emu10k1-ac97.h b/sys/dev/sound/pci/gnu/emu10k1-ac97.h
deleted file mode 100644
index 65b1be7..0000000
--- a/sys/dev/sound/pci/gnu/emu10k1-ac97.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1-ac97.h,v 1.2 2004/01/09 05:08:32 obrien Exp $ */
-/* $DragonFly: src/sys/dev/sound/pci/gnu/emu10k1-ac97.h,v 1.1 2007/01/04 21:47:03 corecode Exp $ */
-
-#ifndef _AC97_CODEC_H_
-#define _AC97_CODEC_H_
-
-#ifdef __linux__
-#include <linux/types.h>
-#include <linux/soundcard.h>
-#endif
-
-/* AC97 1.0 */
-#define  AC97_RESET               0x0000      //
-#define  AC97_MASTER_VOL_STEREO   0x0002      // Line Out
-#define  AC97_HEADPHONE_VOL       0x0004      // 
-#define  AC97_MASTER_VOL_MONO     0x0006      // TAD Output
-#define  AC97_MASTER_TONE         0x0008      //
-#define  AC97_PCBEEP_VOL          0x000a      // none
-#define  AC97_PHONE_VOL           0x000c      // TAD Input (mono)
-#define  AC97_MIC_VOL             0x000e      // MIC Input (mono)
-#define  AC97_LINEIN_VOL          0x0010      // Line Input (stereo)
-#define  AC97_CD_VOL              0x0012      // CD Input (stereo)
-#define  AC97_VIDEO_VOL           0x0014      // none
-#define  AC97_AUX_VOL             0x0016      // Aux Input (stereo)
-#define  AC97_PCMOUT_VOL          0x0018      // Wave Output (stereo)
-#define  AC97_RECORD_SELECT       0x001a      //
-#define  AC97_RECORD_GAIN         0x001c
-#define  AC97_RECORD_GAIN_MIC     0x001e
-#define  AC97_GENERAL_PURPOSE     0x0020
-#define  AC97_3D_CONTROL          0x0022
-#define  AC97_MODEM_RATE          0x0024
-#define  AC97_POWER_CONTROL       0x0026
-
-/* AC'97 2.0 */
-#define AC97_EXTENDED_ID          0x0028       /* Extended Audio ID */
-#define AC97_EXTENDED_STATUS      0x002A       /* Extended Audio Status */
-#define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
-#define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
-#define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR ADC Rate */
-#define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
-#define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
-#define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
-#define AC97_RESERVED_3A          0x003A       /* Reserved in AC '97 < 2.2 */
-
-/* AC'97 2.2 */
-#define AC97_SPDIF_CONTROL        0x003A       /* S/PDIF Control */
-
-/* range 0x3c-0x58 - MODEM */
-#define AC97_EXTENDED_MODEM_ID    0x003C
-#define AC97_EXTEND_MODEM_STAT    0x003E
-#define AC97_LINE1_RATE           0x0040
-#define AC97_LINE2_RATE           0x0042
-#define AC97_HANDSET_RATE         0x0044
-#define AC97_LINE1_LEVEL          0x0046
-#define AC97_LINE2_LEVEL          0x0048
-#define AC97_HANDSET_LEVEL        0x004A
-#define AC97_GPIO_CONFIG          0x004C
-#define AC97_GPIO_POLARITY        0x004E
-#define AC97_GPIO_STICKY          0x0050
-#define AC97_GPIO_WAKE_UP         0x0052
-#define AC97_GPIO_STATUS          0x0054
-#define AC97_MISC_MODEM_STAT      0x0056
-#define AC97_RESERVED_58          0x0058
-
-/* registers 0x005a - 0x007a are vendor reserved */
-
-#define AC97_VENDOR_ID1           0x007c
-#define AC97_VENDOR_ID2           0x007e
-
-/* volume control bit defines */
-#ifndef	AC97_MUTE
-#define AC97_MUTE                 0x8000
-#endif
-#define AC97_MICBOOST             0x0040
-#define AC97_LEFTVOL              0x3f00
-#define AC97_RIGHTVOL             0x003f
-
-/* record mux defines */
-#define AC97_RECMUX_MIC           0x0000
-#define AC97_RECMUX_CD            0x0101
-#define AC97_RECMUX_VIDEO         0x0202
-#define AC97_RECMUX_AUX           0x0303
-#define AC97_RECMUX_LINE          0x0404
-#define AC97_RECMUX_STEREO_MIX    0x0505
-#define AC97_RECMUX_MONO_MIX      0x0606
-#define AC97_RECMUX_PHONE         0x0707
-
-/* general purpose register bit defines */
-#define AC97_GP_LPBK              0x0080       /* Loopback mode */
-#define AC97_GP_MS                0x0100       /* Mic Select 0=Mic1, 1=Mic2 */
-#define AC97_GP_MIX               0x0200       /* Mono output select 0=Mix, 1=Mic */
-#define AC97_GP_RLBK              0x0400       /* Remote Loopback - Modem line codec */
-#define AC97_GP_LLBK              0x0800       /* Local Loopback - Modem Line codec */
-#define AC97_GP_LD                0x1000       /* Loudness 1=on */
-#define AC97_GP_3D                0x2000       /* 3D Enhancement 1=on */
-#define AC97_GP_ST                0x4000       /* Stereo Enhancement 1=on */
-#define AC97_GP_POP               0x8000       /* Pcm Out Path, 0=pre 3D, 1=post 3D */
-
-/* extended audio status and control bit defines */
-#define AC97_EA_VRA               0x0001       /* Variable bit rate enable bit */
-#define AC97_EA_DRA               0x0002       /* Double-rate audio enable bit */
-#define AC97_EA_SPDIF             0x0004       /* S/PDIF Enable bit */
-#define AC97_EA_VRM               0x0008       /* Variable bit rate for MIC enable bit */
-#define AC97_EA_CDAC              0x0040       /* PCM Center DAC is ready (Read only) */
-#define AC97_EA_SDAC              0x0040       /* PCM Surround DACs are ready (Read only) */
-#define AC97_EA_LDAC              0x0080       /* PCM LFE DAC is ready (Read only) */
-#define AC97_EA_MDAC              0x0100       /* MIC ADC is ready (Read only) */
-#define AC97_EA_SPCV              0x0400       /* S/PDIF configuration valid (Read only) */
-#define AC97_EA_PRI               0x0800       /* Turns the PCM Center DAC off */
-#define AC97_EA_PRJ               0x1000       /* Turns the PCM Surround DACs off */
-#define AC97_EA_PRK               0x2000       /* Turns the PCM LFE DAC off */
-#define AC97_EA_PRL               0x4000       /* Turns the MIC ADC off */
-#define AC97_EA_SLOT_MASK         0xffcf       /* Mask for slot assignment bits */
-#define AC97_EA_SPSA_3_4          0x0000       /* Slot assigned to 3 & 4 */
-#define AC97_EA_SPSA_7_8          0x0010       /* Slot assigned to 7 & 8 */
-#define AC97_EA_SPSA_6_9          0x0020       /* Slot assigned to 6 & 9 */
-#define AC97_EA_SPSA_10_11        0x0030       /* Slot assigned to 10 & 11 */
-
-/* S/PDIF control bit defines */
-#define AC97_SC_PRO               0x0001       /* Professional status */
-#define AC97_SC_NAUDIO            0x0002       /* Non audio stream */
-#define AC97_SC_COPY              0x0004       /* Copyright status */
-#define AC97_SC_PRE               0x0008       /* Preemphasis status */
-#define AC97_SC_CC_MASK           0x07f0       /* Category Code mask */
-#define AC97_SC_L                 0x0800       /* Generation Level status */
-#define AC97_SC_SPSR_MASK         0xcfff       /* S/PDIF Sample Rate bits */
-#define AC97_SC_SPSR_44K          0x0000       /* Use 44.1kHz Sample rate */
-#define AC97_SC_SPSR_48K          0x2000       /* Use 48kHz Sample rate */
-#define AC97_SC_SPSR_32K          0x3000       /* Use 32kHz Sample rate */
-#define AC97_SC_DRS               0x4000       /* Double Rate S/PDIF */
-#define AC97_SC_V                 0x8000       /* Validity status */
-
-/* powerdown control and status bit defines */
-
-/* status */
-#define AC97_PWR_MDM              0x0010       /* Modem section ready */
-#define AC97_PWR_REF              0x0008       /* Vref nominal */
-#define AC97_PWR_ANL              0x0004       /* Analog section ready */
-#define AC97_PWR_DAC              0x0002       /* DAC section ready */
-#define AC97_PWR_ADC              0x0001       /* ADC section ready */
-
-/* control */
-#define AC97_PWR_PR0              0x0100       /* ADC and Mux powerdown */
-#define AC97_PWR_PR1              0x0200       /* DAC powerdown */
-#define AC97_PWR_PR2              0x0400       /* Output mixer powerdown (Vref on) */
-#define AC97_PWR_PR3              0x0800       /* Output mixer powerdown (Vref off) */
-#define AC97_PWR_PR4              0x1000       /* AC-link powerdown */
-#define AC97_PWR_PR5              0x2000       /* Internal Clk disable */
-#define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
-#define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
-
-/* extended audio ID register bit defines */
-#define AC97_EXTID_VRA            0x0001
-#define AC97_EXTID_DRA            0x0002
-#define AC97_EXTID_SPDIF          0x0004
-#define AC97_EXTID_VRM            0x0008
-#define AC97_EXTID_DSA0           0x0010
-#define AC97_EXTID_DSA1           0x0020
-#define AC97_EXTID_CDAC           0x0040
-#define AC97_EXTID_SDAC           0x0080
-#define AC97_EXTID_LDAC           0x0100
-#define AC97_EXTID_AMAP           0x0200
-#define AC97_EXTID_REV0           0x0400
-#define AC97_EXTID_REV1           0x0800
-#define AC97_EXTID_ID0            0x4000
-#define AC97_EXTID_ID1            0x8000
-
-/* extended status register bit defines */
-#define AC97_EXTSTAT_VRA          0x0001
-#define AC97_EXTSTAT_DRA          0x0002
-#define AC97_EXTSTAT_SPDIF        0x0004
-#define AC97_EXTSTAT_VRM          0x0008
-#define AC97_EXTSTAT_SPSA0        0x0010
-#define AC97_EXTSTAT_SPSA1        0x0020
-#define AC97_EXTSTAT_CDAC         0x0040
-#define AC97_EXTSTAT_SDAC         0x0080
-#define AC97_EXTSTAT_LDAC         0x0100
-#define AC97_EXTSTAT_MADC         0x0200
-#define AC97_EXTSTAT_SPCV         0x0400
-#define AC97_EXTSTAT_PRI          0x0800
-#define AC97_EXTSTAT_PRJ          0x1000
-#define AC97_EXTSTAT_PRK          0x2000
-#define AC97_EXTSTAT_PRL          0x4000
-
-/* useful power states */
-#define AC97_PWR_D0               0x0000      /* everything on */
-#define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
-#define AC97_PWR_D2              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
-#define AC97_PWR_D3              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
-#define AC97_PWR_ANLOFF          AC97_PWR_PR2|AC97_PWR_PR3  /* analog section off */
-
-/* Total number of defined registers.  */
-#define AC97_REG_CNT 64
-
-
-/* OSS interface to the ac97s.. */
-#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\
-	SOUND_MASK_LINE|SOUND_MASK_CD|\
-	SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\
-	SOUND_MASK_LINE1|SOUND_MASK_VIDEO)
-
-#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
-	SOUND_MASK_BASS|SOUND_MASK_TREBLE|\
-	SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\
-	SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT)
-
-#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
-	SOUND_MASK_CD|SOUND_MASK_IGAIN|SOUND_MASK_VIDEO|\
-	SOUND_MASK_LINE1| SOUND_MASK_LINE|\
-	SOUND_MASK_PHONEIN)
-
-/* original check is not good enough in case FOO is greater than
- * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
- * SOUND_MIXER_NRDEVICES elements.
- * before matching the given mixer against the bitmask in supported_mixers we
- * check if mixer number exceeds maximum allowed size which is as mentioned
- * above SOUND_MIXER_NRDEVICES */
-#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \
-                                    (FOO < SOUND_MIXER_NRDEVICES) && \
-                                    (CODEC)->supported_mixers & (1<<FOO) )
-
-#ifdef __linux__
-struct ac97_codec {
-	/* AC97 controller connected with */
-	void *private_data;
-
-	char *name;
-	int id;
-	int dev_mixer; 
-	int type;
-
-	int modem:1;
-
-	struct ac97_ops *codec_ops;
-
-	/* controller specific lower leverl ac97 accessing routines */
-	u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
-	void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
-
-	/* Wait for codec-ready.  Ok to sleep here.  */
-	void  (*codec_wait)  (struct ac97_codec *codec);
-
-	/* OSS mixer masks */
-	int modcnt;
-	int supported_mixers;
-	int stereo_mixers;
-	int record_sources;
-
-	/* Property flags */
-	int flags;
-
-	int bit_resolution;
-
-	/* OSS mixer interface */
-	int  (*read_mixer) (struct ac97_codec *codec, int oss_channel);
-	void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
-			    unsigned int left, unsigned int right);
-	int  (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
-	int  (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
-
-	/* saved OSS mixer states */
-	unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-
-	/* Software Modem interface */
-	int  (*modem_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
-};
-
-/*
- *	Operation structures for each known AC97 chip
- */
- 
-struct ac97_ops
-{
-	/* Initialise */
-	int (*init)(struct ac97_codec *c);
-	/* Amplifier control */
-	int (*amplifier)(struct ac97_codec *codec, int on);
-	/* Digital mode control */
-	int (*digital)(struct ac97_codec *codec, int format);
-#define AC97_DELUDED_MODEM	1	/* Audio codec reports its a modem */
-#define AC97_NO_PCM_VOLUME	2	/* Volume control is missing 	   */
-};
-
-extern int ac97_read_proc (char *page_out, char **start, off_t off,
-			   int count, int *eof, void *data);
-extern int ac97_probe_codec(struct ac97_codec *);
-extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
-extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
-extern int ac97_save_state(struct ac97_codec *codec);
-extern int ac97_restore_state(struct ac97_codec *codec);
-#endif	/*__linux__*/
-
-#endif /* _AC97_CODEC_H_ */
diff --git a/sys/dev/sound/pci/gnu/emu10k1-alsa.h b/sys/dev/sound/pci/gnu/emu10k1-alsa.h
deleted file mode 100644
index 0b1488e..0000000
--- a/sys/dev/sound/pci/gnu/emu10k1-alsa.h
+++ /dev/null
@@ -1,1375 +0,0 @@
-#ifndef __SOUND_EMU10K1_H
-#define __SOUND_EMU10K1_H
-
-/*-
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
- *		     Creative Labs, Inc.
- *  Definitions for EMU10K1 (SB Live!) chips
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-/* $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1-alsa.h,v 1.2 2005/01/06 18:26:37 imp Exp $ */
-/* $DragonFly: src/sys/dev/sound/pci/gnu/emu10k1-alsa.h,v 1.2 2007/06/16 20:07:20 dillon Exp $ */
-
-#include <sys/ioccom.h>
-
-#ifdef __KERNEL__
-
-#include <sound/pcm.h>
-#include <sound/rawmidi.h>
-#include <sound/hwdep.h>
-#include <sound/ac97_codec.h>
-#include <sound/util_mem.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-
-#ifndef PCI_VENDOR_ID_CREATIVE
-#define PCI_VENDOR_ID_CREATIVE		0x1102
-#endif
-#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
-#define PCI_DEVICE_ID_CREATIVE_EMU10K1	0x0002
-#endif
-
-/* ------------------- DEFINES -------------------- */
-
-#define EMUPAGESIZE     4096
-#define MAXREQVOICES    8
-#define MAXPAGES        8192
-#define RESERVED        0
-#define NUM_MIDI        16
-#define NUM_G           64              /* use all channels */
-#define NUM_FXSENDS     4
-
-#define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
-#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit */
-
-#define TMEMSIZE        256*1024
-#define TMEMSIZEREG     4
-
-#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
-
-// Audigy specify registers are prefixed with 'A_'
-
-/************************************************************************************************/
-/* PCI function 0 registers, address = <val> + PCIBASE0						*/
-/************************************************************************************************/
-
-#define PTR			0x00		/* Indexed register set pointer register	*/
-						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
-						/* be modified independently of each other.	*/
-#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
-						/* channel number of the register to be		*/
-						/* accessed.  For non per-channel registers the	*/
-						/* value should be set to zero.			*/
-#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
-#define A_PTR_ADDRESS_MASK	0x0fff0000
-
-#define DATA			0x04		/* Indexed register set data register		*/
-
-#define IPR			0x08		/* Global interrupt pending register		*/
-						/* Clear pending interrupts by writing a 1 to	*/
-						/* the relevant bits and zero to the other bits	*/
-
-/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-#define IPR_A_MIDITRANSBUFEMPTY2 0x10000000	/* MIDI UART transmit buffer empty		*/
-#define IPR_A_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
-
-#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
-#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
-#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
-#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
-#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
-#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
-#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
-#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
-#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
-#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
-#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
-#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
-#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
-#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
-#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
-#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
-#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
-#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
-#define IPR_CHANNELLOOP		0x00000040	/* One or more channel loop interrupts pending	*/
-#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
-						/* Highest set channel in CLIPL or CLIPH.  When	*/
-						/* IP is written with CL set, the bit in CLIPL	*/
-						/* or CLIPH corresponding to the CIN value 	*/
-						/* written will be cleared.			*/
-
-#define INTE			0x0c		/* Interrupt enable register			*/
-#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
-#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
-#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
-#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
-#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
-#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
-#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
-#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
-#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
-#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
-#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
-#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
-#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
-#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
-#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
-#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
-#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
-#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
-
-#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
-						/* NOTE: There is no reason to use this under	*/
-						/* Linux, and it will cause odd hardware 	*/
-						/* behavior and possibly random segfaults and	*/
-						/* lockups if enabled.				*/
-
-/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-#define INTE_A_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
-#define INTE_A_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
-
-
-#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
-						/* NOTE: This bit must always be enabled       	*/
-#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
-#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
-#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
-#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
-#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
-#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
-#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
-#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
-#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
-#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
-#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
-#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
-#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
-
-#define WC			0x10		/* Wall Clock register				*/
-#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
-#define WC_SAMPLECOUNTER	0x14060010
-#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
-						/* NOTE: Each channel takes 1/64th of a sample	*/
-						/* period to be serviced.			*/
-
-#define HCFG			0x14		/* Hardware config register			*/
-						/* NOTE: There is no reason to use the legacy	*/
-						/* SoundBlaster emulation stuff described below	*/
-						/* under Linux, and all kinds of weird hardware	*/
-						/* behavior can result if you try.  Don't.	*/
-#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
-#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
-#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
-#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
-#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
-#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
-#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
-#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
-#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
-#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
-#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
-#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
-						/* NOTE: The rest of the bits in this register	*/
-						/* _are_ relevant under Linux.			*/
-#define HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format					*/
-#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
-#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
-#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
-#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
-#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
-#define HCFG_GPOUT0		0x00001000	/* External pin? (spdif enable on 5.1)		*/
-#define HCFG_GPOUT1		0x00000800	/* External pin? (IR)				*/
-#define HCFG_GPOUT2		0x00000400	/* External pin? (IR)				*/
-#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
-#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
-						/* 1 = Force all 3 async digital inputs to use	*/
-						/* the same async sample rate tracker (ZVIDEO)	*/
-#define HCFG_AC3ENABLE_MASK	0x000000e0	/* AC3 async input control - Not implemented	*/
-#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
-#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
-#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF             */
-#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
-						/* will automatically mute their output when	*/
-						/* they are not rate-locked to the external	*/
-						/* async audio source  				*/
-#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
-						/* NOTE: This should generally never be used.  	*/
-#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
-						/* NOTE: This should generally never be used.  	*/
-#define HCFG_LOCKTANKCACHE	0x01020014
-#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
-						/* NOTE: This is a 'cheap' way to implement a	*/
-						/* master mute function on the mute button, and	*/
-						/* in general should not be used unless a more	*/
-						/* sophisticated master mute function has not	*/
-						/* been written.       				*/
-#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
-						/* Should be set to 1 when the EMU10K1 is	*/
-						/* completely initialized.			*/
-
-//For Audigy, MPU port move to 0x70-0x74 ptr register
-
-#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
-
-#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
-#define MUCMD_RESET		0xff		/* RESET command				*/
-#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
-						/* NOTE: All other commands are ignored		*/
-
-#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
-#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
-#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
-
-#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
-#define A_GPINPUT_MASK		0xff00
-#define A_GPOUTPUT_MASK		0x00ff
-#define A_IOCFG_GPOUT0		0x0044		/* analog/digital? */
-#define A_IOCFG_GPOUT1		0x0002		/* IR */
-#define A_IOCFG_GPOUT2		0x0001		/* IR */
-
-#define TIMER			0x1a		/* Timer terminal count register		*/
-						/* NOTE: After the rate is changed, a maximum	*/
-						/* of 1024 sample periods should be allowed	*/
-						/* before the new rate is guaranteed accurate.	*/
-#define TIMER_RATE_MASK		0x000003ff	/* Timer interrupt rate in sample periods	*/
-						/* 0 == 1024 periods, [1..4] are not useful	*/
-#define TIMER_RATE		0x0a00001a
-
-#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
-
-#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
-#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
-#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
-
-/************************************************************************************************/
-/* PCI function 1 registers, address = <val> + PCIBASE1						*/
-/************************************************************************************************/
-
-#define JOYSTICK1		0x00		/* Analog joystick port register		*/
-#define JOYSTICK2		0x01		/* Analog joystick port register		*/
-#define JOYSTICK3		0x02		/* Analog joystick port register		*/
-#define JOYSTICK4		0x03		/* Analog joystick port register		*/
-#define JOYSTICK5		0x04		/* Analog joystick port register		*/
-#define JOYSTICK6		0x05		/* Analog joystick port register		*/
-#define JOYSTICK7		0x06		/* Analog joystick port register		*/
-#define JOYSTICK8		0x07		/* Analog joystick port register		*/
-
-/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on write.	*/
-/* When reading, use these bitfields: */
-#define JOYSTICK_BUTTONS	0x0f		/* Joystick button data				*/
-#define JOYSTICK_COMPARATOR	0xf0		/* Joystick comparator data			*/
-
-
-/********************************************************************************************************/
-/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
-/********************************************************************************************************/
-
-#define CPF			0x00		/* Current pitch and fraction register			*/
-#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
-#define CPF_CURRENTPITCH	0x10100000
-#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
-#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
-#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
-
-#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
-#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
-#define PTRX_PITCHTARGET	0x10100001
-#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
-#define PTRX_FXSENDAMOUNT_A	0x08080001
-#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
-#define PTRX_FXSENDAMOUNT_B	0x08000001
-
-#define CVCF			0x02		/* Current volume and filter cutoff register		*/
-#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
-#define CVCF_CURRENTVOL		0x10100002
-#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
-#define CVCF_CURRENTFILTER	0x10000002
-
-#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
-#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
-#define VTFT_VOLUMETARGET	0x10100003
-#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
-#define VTFT_FILTERTARGET	0x10000003
-
-#define Z1			0x05		/* Filter delay memory 1 register			*/
-
-#define Z2			0x04		/* Filter delay memory 2 register			*/
-
-#define PSST			0x06		/* Send C amount and loop start address register	*/
-#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
-
-#define PSST_FXSENDAMOUNT_C	0x08180006
-
-#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
-#define PSST_LOOPSTARTADDR	0x18000006
-
-#define DSL			0x07		/* Send D amount and loop start address register	*/
-#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
-
-#define DSL_FXSENDAMOUNT_D	0x08180007
-
-#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
-#define DSL_LOOPENDADDR		0x18000007
-
-#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
-#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
-#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
-						/* 1 == full band, 7 == lowpass				*/
-						/* ROM 0 is used when pitch shifting downward or less	*/
-						/* then 3 semitones upward.  Increasingly higher ROM	*/
-						/* numbers are used, typically in steps of 3 semitones,	*/
-						/* as upward pitch shifting is performed.		*/
-#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
-#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
-#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
-#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
-#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
-#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
-#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
-#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
-#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
-#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
-#define CCCA_CURRADDR		0x18000008
-
-#define CCR			0x09		/* Cache control register				*/
-#define CCR_CACHEINVALIDSIZE	0x07190009
-#define CCR_CACHEINVALIDSIZE_MASK	0xfe000000	/* Number of invalid samples cache for this channel    	*/
-#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
-#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
-#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
-#define CCR_READADDRESS		0x06100009
-#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
-#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
-						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
-#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
-#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
-
-#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
-						/* NOTE: This register is normally not used		*/
-#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
-
-#define FXRT			0x0b		/* Effects send routing register			*/
-						/* NOTE: It is illegal to assign the same routing to	*/
-						/* two effects sends.					*/
-#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
-#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
-#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
-#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
-
-#define MAPA			0x0c		/* Cache map A						*/
-
-#define MAPB			0x0d		/* Cache map B						*/
-
-#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
-#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
-
-#define ENVVOL			0x10		/* Volume envelope register				*/
-#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/  
-						/* 0x8000-n == 666*n usec delay	       			*/
-
-#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
-#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
-#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
-#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
-						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
-
-#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
-#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
-#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
-#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
-						/* this channel and from writing to pitch, filter and	*/
-						/* volume targets.					*/
-#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
-						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
-
-#define LFOVAL1 		0x13		/* Modulation LFO value					*/
-#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define ENVVAL			0x14		/* Modulation envelope register				*/
-#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
-#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
-#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
-#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
-						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
-
-#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
-#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
-#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
-#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
-						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
-
-#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
-#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define IP			0x18		/* Initial pitch register				*/
-#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
-						/* 4 bits of octave, 12 bits of fractional octave	*/
-#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
-
-#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
-#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
-						/* 6 most significant bits are semitones		*/
-						/* 2 least significant bits are fractions		*/
-#define IFATN_FILTERCUTOFF	0x08080019
-#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
-#define IFATN_ATTENUATION	0x08000019
-
-
-#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
-#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
-						/* Signed 2's complement, +/- one octave peak extremes	*/
-#define PEFE_PITCHAMOUNT	0x0808001a
-#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
-						/* Signed 2's complement, +/- six octaves peak extremes */
-#define PEFE_FILTERAMOUNT	0x0800001a
-#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
-#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
-						/* Signed 2's complement, +/- one octave extremes	*/
-#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
-						/* Signed 2's complement, +/- three octave extremes	*/
-
-
-#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
-#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
-						/* Signed 2's complement, with +/- 12dB extremes	*/
-
-#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
-						/* ??Hz steps, maximum of ?? Hz.			*/
-#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
-#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
-						/* Signed 2's complement, +/- one octave extremes	*/
-#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
-						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
-
-#define TEMPENV 		0x1e		/* Tempory envelope register				*/
-#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
-						/* NOTE: All channels contain internal variables; do	*/
-						/* not write to these locations.			*/
-
-#define CD0			0x20		/* Cache data 0 register				*/
-#define CD1			0x21		/* Cache data 1 register				*/
-#define CD2			0x22		/* Cache data 2 register				*/
-#define CD3			0x23		/* Cache data 3 register				*/
-#define CD4			0x24		/* Cache data 4 register				*/
-#define CD5			0x25		/* Cache data 5 register				*/
-#define CD6			0x26		/* Cache data 6 register				*/
-#define CD7			0x27		/* Cache data 7 register				*/
-#define CD8			0x28		/* Cache data 8 register				*/
-#define CD9			0x29		/* Cache data 9 register				*/
-#define CDA			0x2a		/* Cache data A register				*/
-#define CDB			0x2b		/* Cache data B register				*/
-#define CDC			0x2c		/* Cache data C register				*/
-#define CDD			0x2d		/* Cache data D register				*/
-#define CDE			0x2e		/* Cache data E register				*/
-#define CDF			0x2f		/* Cache data F register				*/
-
-#define PTB			0x40		/* Page table base register				*/
-#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
-
-#define TCB			0x41		/* Tank cache base register    				*/
-#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
-
-#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
-#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
-#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
-						/* NOTE: To guarantee phase coherency, both channels	*/
-						/* must be disabled prior to enabling both channels.	*/
-#define A_ADCCR_RCHANENABLE	0x00000020
-#define A_ADCCR_LCHANENABLE	0x00000010
-
-#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
-#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
-#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
-#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
-#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
-#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
-#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
-#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
-#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
-#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
-#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
-#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
-#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
-
-#define FXWC			0x43		/* FX output write channels register			*/
-						/* When set, each bit enables the writing of the	*/
-						/* corresponding FX output channel into host memory	*/
-#define FXWC_DEFAULTROUTE_C     (1<<0)		/* left emu out? */
-#define FXWC_DEFAULTROUTE_B     (1<<1)		/* right emu out? */
-#define FXWC_DEFAULTROUTE_A     (1<<12)
-#define FXWC_DEFAULTROUTE_D     (1<<13)
-#define FXWC_ADCLEFT            (1<<18)
-#define FXWC_CDROMSPDIFLEFT     (1<<18)
-#define FXWC_ADCRIGHT           (1<<19)
-#define FXWC_CDROMSPDIFRIGHT    (1<<19)
-#define FXWC_MIC                (1<<20)
-#define FXWC_ZOOMLEFT           (1<<20)
-#define FXWC_ZOOMRIGHT          (1<<21)
-#define FXWC_SPDIFLEFT          (1<<22)		/* 0x00400000 */
-#define FXWC_SPDIFRIGHT         (1<<23)		/* 0x00800000 */
-
-#define TCBS			0x44		/* Tank cache buffer size register			*/
-#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
-#define TCBS_BUFFSIZE_16K	0x00000000
-#define TCBS_BUFFSIZE_32K	0x00000001
-#define TCBS_BUFFSIZE_64K	0x00000002
-#define TCBS_BUFFSIZE_128K	0x00000003
-#define TCBS_BUFFSIZE_256K	0x00000004
-#define TCBS_BUFFSIZE_512K	0x00000005
-#define TCBS_BUFFSIZE_1024K	0x00000006
-#define TCBS_BUFFSIZE_2048K	0x00000007
-
-#define MICBA			0x45		/* AC97 microphone buffer address register		*/
-#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define ADCBA			0x46		/* ADC buffer address register				*/
-#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define FXBA			0x47		/* FX Buffer Address */
-#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define MICBS			0x49		/* Microphone buffer size register			*/
-
-#define ADCBS			0x4a		/* ADC buffer size register				*/
-
-#define FXBS			0x4b		/* FX buffer size register				*/
-
-/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
-#define ADCBS_BUFSIZE_NONE	0x00000000
-#define ADCBS_BUFSIZE_384	0x00000001
-#define ADCBS_BUFSIZE_448	0x00000002
-#define ADCBS_BUFSIZE_512	0x00000003
-#define ADCBS_BUFSIZE_640	0x00000004
-#define ADCBS_BUFSIZE_768	0x00000005
-#define ADCBS_BUFSIZE_896	0x00000006
-#define ADCBS_BUFSIZE_1024	0x00000007
-#define ADCBS_BUFSIZE_1280	0x00000008
-#define ADCBS_BUFSIZE_1536	0x00000009
-#define ADCBS_BUFSIZE_1792	0x0000000a
-#define ADCBS_BUFSIZE_2048	0x0000000b
-#define ADCBS_BUFSIZE_2560	0x0000000c
-#define ADCBS_BUFSIZE_3072	0x0000000d
-#define ADCBS_BUFSIZE_3584	0x0000000e
-#define ADCBS_BUFSIZE_4096	0x0000000f
-#define ADCBS_BUFSIZE_5120	0x00000010
-#define ADCBS_BUFSIZE_6144	0x00000011
-#define ADCBS_BUFSIZE_7168	0x00000012
-#define ADCBS_BUFSIZE_8192	0x00000013
-#define ADCBS_BUFSIZE_10240	0x00000014
-#define ADCBS_BUFSIZE_12288	0x00000015
-#define ADCBS_BUFSIZE_14366	0x00000016
-#define ADCBS_BUFSIZE_16384	0x00000017
-#define ADCBS_BUFSIZE_20480	0x00000018
-#define ADCBS_BUFSIZE_24576	0x00000019
-#define ADCBS_BUFSIZE_28672	0x0000001a
-#define ADCBS_BUFSIZE_32768	0x0000001b
-#define ADCBS_BUFSIZE_40960	0x0000001c
-#define ADCBS_BUFSIZE_49152	0x0000001d
-#define ADCBS_BUFSIZE_57344	0x0000001e
-#define ADCBS_BUFSIZE_65536	0x0000001f
-
-
-#define CDCS			0x50		/* CD-ROM digital channel status register	*/
-
-#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
-
-#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
-
-#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
-
-#define A_DBG			 0x53
-#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
-#define A_DBG_ZC		 0x40000000	/* zero tram counter */
-#define A_DBG_STEP_ADDR		 0x000003ff
-#define A_DBG_SATURATION_OCCURED 0x20000000
-#define A_DBG_SATURATION_ADDR	 0x0ffc0000
-
-#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
-
-#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
-
-#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
-
-#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
-#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
-#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
-#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
-#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
-#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
-#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
-#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
-#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
-#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
-#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
-#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
-#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
-#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
-#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
-#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
-#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
-#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
-#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
-#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
-#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
-#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
-#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
-
-/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
-#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
-
-#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
-
-#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
-
-#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
-
-#define SOLEL			0x5c		/* Stop on loop enable low register		*/
-
-#define SOLEH			0x5d		/* Stop on loop enable high register		*/
-
-#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
-#define SPBYPASS_ENABLE		0x00000001	/* Enable SPDIF bypass mode			*/
-
-#define AC97SLOT		0x5f            /* additional AC97 slots enable bits		*/
-#define AC97SLOT_CNTR		0x10            /* Center enable */
-#define AC97SLOT_LFE		0x20            /* LFE enable */
-
-#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
-
-#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
-
-#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
-						/* NOTE: This one has no SPDIFLOCKED field	*/
-						/* Assumes sample lock				*/
-
-/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
-#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
-#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
-#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
-
-/* Note that these values can vary +/- by a small amount                                        */
-#define SRCS_SPDIFRATE_44	0x0003acd9
-#define SRCS_SPDIFRATE_48	0x00040000
-#define SRCS_SPDIFRATE_96	0x00080000
-
-#define MICIDX                  0x63            /* Microphone recording buffer index register   */
-#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
-#define MICIDX_IDX		0x10000063
-
-#define ADCIDX			0x64		/* ADC recording buffer index register		*/
-#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
-#define ADCIDX_IDX		0x10000064
-
-#define A_ADCIDX		0x63
-#define A_ADCIDX_IDX		0x10000063
-
-#define A_MICIDX		0x64
-#define A_MICIDX_IDX		0x10000064
-
-#define FXIDX			0x65		/* FX recording buffer index register		*/
-#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
-#define FXIDX_IDX		0x10000065
-
-/* This is the MPU port on the card (via the game port)						*/
-#define A_MUDATA1		0x70
-#define A_MUCMD1		0x71
-#define A_MUSTAT1		A_MUCMD1
-
-/* This is the MPU port on the Audigy Drive 							*/
-#define A_MUDATA2		0x72
-#define A_MUCMD2		0x73
-#define A_MUSTAT2		A_MUCMD2	
-
-/* The next two are the Audigy equivalent of FXWC						*/
-/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
-/* Each bit selects a channel for recording */
-#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
-#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
-
-#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
-#define A_SPDIF_48000		0x00000080
-#define A_SPDIF_44100		0x00000000
-#define A_SPDIF_96000		0x00000040
-
-#define A_FXRT2			0x7c
-#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
-#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
-#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
-#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
-
-#define A_SENDAMOUNTS		0x7d
-#define A_FXSENDAMOUNT_E_MASK	0xFF000000
-#define A_FXSENDAMOUNT_F_MASK	0x00FF0000
-#define A_FXSENDAMOUNT_G_MASK	0x0000FF00
-#define A_FXSENDAMOUNT_H_MASK	0x000000FF
-
-/* The send amounts for this one are the same as used with the emu10k1 */
-#define A_FXRT1			0x7e
-#define A_FXRT_CHANNELA		0x0000003f
-#define A_FXRT_CHANNELB		0x00003f00
-#define A_FXRT_CHANNELC		0x003f0000
-#define A_FXRT_CHANNELD		0x3f000000
-
-
-/* Each FX general purpose register is 32 bits in length, all bits are used			*/
-#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
-#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
-
-/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
-/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
-/* locations are for external TRAM. 								*/
-#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
-#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
-
-/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
-#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
-#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
-#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
-#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
-#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
-
-#define MICROCODEBASE		0x400		/* Microcode data base address			*/
-
-/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
-/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
-#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
-#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
-#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
-#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
-#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
-
-
-/* Audigy Soundcard have a different instruction format */
-#define A_MICROCODEBASE		0x600
-#define A_LOWORD_OPY_MASK	0x000007ff
-#define A_LOWORD_OPX_MASK	0x007ff000
-#define A_HIWORD_OPCODE_MASK	0x0f000000
-#define A_HIWORD_RESULT_MASK	0x007ff000
-#define A_HIWORD_OPA_MASK	0x000007ff
-
-
-/* ------------------- STRUCTURES -------------------- */
-
-typedef struct _snd_emu10k1 emu10k1_t;
-typedef struct _snd_emu10k1_voice emu10k1_voice_t;
-typedef struct _snd_emu10k1_pcm emu10k1_pcm_t;
-
-typedef enum {
-	EMU10K1_PCM,
-	EMU10K1_SYNTH,
-	EMU10K1_MIDI
-} emu10k1_voice_type_t;
-
-struct _snd_emu10k1_voice {
-	emu10k1_t *emu;
-	int number;
-	int use: 1,
-	    pcm: 1,
-	    synth: 1,
-	    midi: 1;
-	void (*interrupt)(emu10k1_t *emu, emu10k1_voice_t *pvoice);
-
-	emu10k1_pcm_t *epcm;
-};
-
-typedef enum {
-	PLAYBACK_EMUVOICE,
-	CAPTURE_AC97ADC,
-	CAPTURE_AC97MIC,
-	CAPTURE_EFX
-} snd_emu10k1_pcm_type_t;
-
-struct _snd_emu10k1_pcm {
-	emu10k1_t *emu;
-	snd_emu10k1_pcm_type_t type;
-	snd_pcm_substream_t *substream;
-	emu10k1_voice_t *voices[2];
-	emu10k1_voice_t *extra;
-	unsigned short running;
-	unsigned short first_ptr;
-	snd_util_memblk_t *memblk;
-	unsigned int start_addr;
-	unsigned int ccca_start_addr;
-	unsigned int capture_ipr;	/* interrupt acknowledge mask */
-	unsigned int capture_inte;	/* interrupt enable mask */
-	unsigned int capture_ba_reg;	/* buffer address register */
-	unsigned int capture_bs_reg;	/* buffer size register */
-	unsigned int capture_idx_reg;	/* buffer index register */
-	unsigned int capture_cr_val;	/* control value */
-	unsigned int capture_cr_val2;	/* control value2 (for audigy) */
-	unsigned int capture_bs_val;	/* buffer size value */
-	unsigned int capture_bufsize;	/* buffer size in bytes */
-};
-
-typedef struct {
-	unsigned char send_routing[3][8];
-	unsigned char send_volume[3][8];
-	unsigned short attn[3];
-	emu10k1_pcm_t *epcm;
-} emu10k1_pcm_mixer_t;
-
-#define snd_emu10k1_compose_send_routing(route) \
-((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
-
-#define snd_emu10k1_compose_audigy_fxrt1(route) \
-(((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 12)) << 24)
-
-#define snd_emu10k1_compose_audigy_fxrt2(route) \
-(((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 12)) << 24)
-
-typedef struct snd_emu10k1_memblk {
-	snd_util_memblk_t mem;
-	/* private part */
-	short first_page, last_page, pages, mapped_page;
-	unsigned int map_locked;
-	struct list_head mapped_link;
-	struct list_head mapped_order_link;
-} emu10k1_memblk_t;
-
-#define snd_emu10k1_memblk_offset(blk)	(((blk)->mapped_page << PAGE_SHIFT) | ((blk)->mem.offset & (PAGE_SIZE - 1)))
-
-#define EMU10K1_MAX_TRAM_BLOCKS_PER_CODE	16
-
-typedef struct {
-	struct list_head list;		/* list link container */
-	unsigned int vcount;
-	unsigned int count;		/* count of GPR (1..16) */
-	unsigned char gpr[32];		/* GPR number(s) */
-	unsigned int value[32];
-	unsigned int min;		/* minimum range */
-	unsigned int max;		/* maximum range */
-	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
-	snd_kcontrol_t *kcontrol;
-} snd_emu10k1_fx8010_ctl_t;
-
-typedef void (snd_fx8010_irq_handler_t)(emu10k1_t *emu, void *private_data);
-
-typedef struct _snd_emu10k1_fx8010_irq {
-	struct _snd_emu10k1_fx8010_irq *next;
-	snd_fx8010_irq_handler_t *handler;
-	unsigned char gpr_running;
-	void *private_data;
-} snd_emu10k1_fx8010_irq_t;
-
-typedef struct {
-	unsigned int valid: 1,
-		     opened: 1,
-		     active: 1;
-	unsigned int channels;		/* 16-bit channels count */
-	unsigned int tram_start;	/* initial ring buffer position in TRAM (in samples) */
-	unsigned int buffer_size;	/* count of buffered samples */
-	unsigned char gpr_size;		/* GPR containing size of ring buffer in samples (host) */
-	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
-	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
-	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
-	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
-	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
-	unsigned char etram[32];	/* external TRAM address & data */
-	unsigned int sw_data, hw_data;
-	unsigned int sw_io, hw_io;
-	unsigned int sw_ready, hw_ready;
-	unsigned int appl_ptr;
-	unsigned int tram_pos;
-	unsigned int tram_shift;
-	snd_emu10k1_fx8010_irq_t *irq;
-} snd_emu10k1_fx8010_pcm_t;
-
-typedef struct {
-	unsigned short fxbus_mask;	/* used FX buses (bitmask) */
-	unsigned short extin_mask;	/* used external inputs (bitmask) */
-	unsigned short extout_mask;	/* used external outputs (bitmask) */
-	unsigned short pad1;
-	unsigned int itram_size;	/* internal TRAM size in samples */
-	unsigned int etram_size;	/* external TRAM size in samples */
-	void *etram_pages;		/* allocated pages for external TRAM */
-	dma_addr_t etram_pages_dmaaddr;
-	unsigned int dbg;		/* FX debugger register */
-	unsigned char name[128];
-	int gpr_size;			/* size of allocated GPR controls */
-	int gpr_count;			/* count of used kcontrols */
-	struct list_head gpr_ctl;	/* GPR controls */
-	struct semaphore lock;
-	snd_emu10k1_fx8010_pcm_t pcm[8];
-	sndlock_t irq_lock;
-	snd_emu10k1_fx8010_irq_t *irq_handlers;
-} snd_emu10k1_fx8010_t;
-
-#define emu10k1_gpr_ctl(n) list_entry(n, snd_emu10k1_fx8010_ctl_t, list)
-
-typedef struct {
-	struct _snd_emu10k1 *emu;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream_input;
-	snd_rawmidi_substream_t *substream_output;
-	unsigned int midi_mode;
-	sndlock_t input_lock;
-	sndlock_t output_lock;
-	sndlock_t open_lock;
-	int tx_enable, rx_enable;
-	int port;
-	int ipr_tx, ipr_rx;
-	void (*interrupt)(emu10k1_t *emu, unsigned int status);
-} emu10k1_midi_t;
-
-struct _snd_emu10k1 {
-	int irq;
-
-	unsigned long port;			/* I/O port number */
-	struct resource *res_port;
-	int APS: 1,				/* APS flag */
-	    no_ac97: 1,				/* no AC'97 */
-	    tos_link: 1;			/* tos link detected */
-	unsigned int audigy;			/* is Audigy? */
-	unsigned int revision;			/* chip revision */
-	unsigned int serial;			/* serial number */
-	unsigned short model;			/* subsystem id */
-	unsigned int card_type;			/* EMU10K1_CARD_* */
-	unsigned int ecard_ctrl;		/* ecard control bits */
-	unsigned long dma_mask;			/* PCI DMA mask */
-	int max_cache_pages;			/* max memory size / PAGE_SIZE */
-	void *silent_page;			/* silent page */
-	dma_addr_t silent_page_dmaaddr;
-	volatile u32 *ptb_pages;		/* page table pages */
-	dma_addr_t ptb_pages_dmaaddr;
-	snd_util_memhdr_t *memhdr;		/* page allocation list */
-	emu10k1_memblk_t *reserved_page;	/* reserved page */
-
-	struct list_head mapped_link_head;
-	struct list_head mapped_order_link_head;
-	void **page_ptr_table;
-	unsigned long *page_addr_table;
-	sndlock_t memblk_lock;
-
-	unsigned int spdif_bits[3];		/* s/pdif out setup */
-
-	snd_emu10k1_fx8010_t fx8010;		/* FX8010 info */
-	int gpr_base;
-	
-	ac97_t *ac97;
-
-	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_t *pcm_mic;
-	snd_pcm_t *pcm_efx;
-	snd_pcm_t *pcm_fx8010;
-
-	sndlock_t synth_lock;
-	void *synth;
-	int (*get_synth_voice)(emu10k1_t *emu);
-
-	sndlock_t reg_lock;
-	sndlock_t emu_lock;
-	sndlock_t voice_lock;
-	struct semaphore ptb_lock;
-
-	emu10k1_voice_t voices[64];
-	emu10k1_pcm_mixer_t pcm_mixer[32];
-	snd_kcontrol_t *ctl_send_routing;
-	snd_kcontrol_t *ctl_send_volume;
-	snd_kcontrol_t *ctl_attn;
-
-	void (*hwvol_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_mic_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_efx_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*timer_interrupt)(emu10k1_t *emu);
-	void (*spdif_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*dsp_interrupt)(emu10k1_t *emu);
-
-	snd_pcm_substream_t *pcm_capture_substream;
-	snd_pcm_substream_t *pcm_capture_mic_substream;
-	snd_pcm_substream_t *pcm_capture_efx_substream;
-
-	emu10k1_midi_t midi;
-	emu10k1_midi_t midi2; /* for audigy */
-
-	unsigned int efx_voices_mask[2];
-};
-
-int snd_emu10k1_create(snd_card_t * card,
-		       struct pci_dev *pci,
-		       unsigned short extin_mask,
-		       unsigned short extout_mask,
-		       long max_cache_bytes,
-		       int enable_ir,
-		       emu10k1_t ** remu);
-
-int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_mixer(emu10k1_t * emu);
-int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
-
-irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-/* initialization */
-void snd_emu10k1_voice_init(emu10k1_t * emu, int voice);
-int snd_emu10k1_init_efx(emu10k1_t *emu);
-void snd_emu10k1_free_efx(emu10k1_t *emu);
-int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size);
-
-/* I/O functions */
-unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
-void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
-void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data);
-unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
-void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
-void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
-void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait);
-static inline unsigned int snd_emu10k1_wc(emu10k1_t *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
-unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg);
-void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data);
-unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
-unsigned char snd_emu10k1_sum_vol_attn(unsigned int value);
-
-/* memory allocation */
-snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
-int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk);
-snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size);
-int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk);
-int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size);
-int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char *data, int size);
-int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk);
-
-/* voice allocation */
-int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int pair, emu10k1_voice_t **rvoice);
-int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice);
-
-/* MIDI uart */
-int snd_emu10k1_midi(emu10k1_t * emu);
-int snd_emu10k1_audigy_midi(emu10k1_t * emu);
-
-/* proc interface */
-int snd_emu10k1_proc_init(emu10k1_t * emu);
-
-#endif /* __KERNEL__ */
-
-/*
- * ---- FX8010 ----
- */
-
-#define EMU10K1_CARD_CREATIVE			0x00000000
-#define EMU10K1_CARD_EMUAPS			0x00000001
-
-#define EMU10K1_FX8010_PCM_COUNT		8
-
-/* instruction set */
-#define iMAC0	 0x00	/* R = A + (X * Y >> 31)   ; saturation */
-#define iMAC1	 0x01	/* R = A + (-X * Y >> 31)  ; saturation */
-#define iMAC2	 0x02	/* R = A + (X * Y >> 31)   ; wraparound */
-#define iMAC3	 0x03	/* R = A + (-X * Y >> 31)  ; wraparound */
-#define iMACINT0 0x04	/* R = A + X * Y	   ; saturation */
-#define iMACINT1 0x05	/* R = A + X * Y	   ; wraparound (31-bit) */
-#define iACC3	 0x06	/* R = A + X + Y	   ; saturation */
-#define iMACMV   0x07	/* R = A, acc += X * Y >> 31 */
-#define iANDXOR  0x08	/* R = (A & X) ^ Y */
-#define iTSTNEG  0x09	/* R = (A >= Y) ? X : ~X */
-#define iLIMITGE 0x0a	/* R = (A >= Y) ? X : Y */
-#define iLIMITLT 0x0b	/* R = (A < Y) ? X : Y */
-#define iLOG	 0x0c	/* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
-#define iEXP	 0x0d	/* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
-#define iINTERP  0x0e	/* R = A + (X * (Y - A) >> 31)  ; saturation */
-#define iSKIP    0x0f	/* R = A (cc_reg), X (count), Y (cc_test) */
-
-/* GPRs */
-#define FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x0f */
-#define EXTIN(x)	(0x10 + (x))	/* x = 0x00 - 0x0f */
-#define EXTOUT(x)	(0x20 + (x))	/* x = 0x00 - 0x0f */
-#define C_00000000	0x40
-#define C_00000001	0x41
-#define C_00000002	0x42
-#define C_00000003	0x43
-#define C_00000004	0x44
-#define C_00000008	0x45
-#define C_00000010	0x46
-#define C_00000020	0x47
-#define C_00000100	0x48
-#define C_00010000	0x49
-#define C_00080000	0x4a
-#define C_10000000	0x4b
-#define C_20000000	0x4c
-#define C_40000000	0x4d
-#define C_80000000	0x4e
-#define C_7fffffff	0x4f
-#define C_ffffffff	0x50
-#define C_fffffffe	0x51
-#define C_c0000000	0x52
-#define C_4f1bbcdc	0x53
-#define C_5a7ef9db	0x54
-#define C_00100000	0x55		/* ?? */
-#define GPR_ACCU	0x56		/* ACCUM, accumulator */
-#define GPR_COND	0x57		/* CCR, condition register */
-#define GPR_NOISE0	0x58		/* noise source */
-#define GPR_NOISE1	0x59		/* noise source */
-#define GPR_IRQ		0x5a		/* IRQ register */
-#define GPR_DBAC	0x5b		/* TRAM Delay Base Address Counter */
-#define GPR(x)		(FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
-#define ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
-#define ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
-#define ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
-#define ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
-
-#define A_FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x3f? */
-#define A_EXTIN(x)	(0x40 + (x))	/* x = 0x00 - 0x1f? */
-#define A_EXTOUT(x)	(0x60 + (x))	/* x = 0x00 - 0x1f? */
-#define A_GPR(x)	(A_FXGPREGBASE + (x))
-
-/* cc_reg constants */
-#define CC_REG_NORMALIZED C_00000001
-#define CC_REG_BORROW	C_00000002
-#define CC_REG_MINUS	C_00000004
-#define CC_REG_ZERO	C_00000008
-#define CC_REG_SATURATE	C_00000010
-#define CC_REG_NONZERO	C_00000100
-
-/* FX buses */
-#define FXBUS_PCM_LEFT		0x00
-#define FXBUS_PCM_RIGHT		0x01
-#define FXBUS_PCM_LEFT_REAR	0x02
-#define FXBUS_PCM_RIGHT_REAR	0x03
-#define FXBUS_MIDI_LEFT		0x04
-#define FXBUS_MIDI_RIGHT	0x05
-#define FXBUS_PCM_CENTER	0x06
-#define FXBUS_PCM_LFE		0x07
-#define FXBUS_PCM_LEFT_FRONT	0x08
-#define FXBUS_PCM_RIGHT_FRONT	0x09
-#define FXBUS_MIDI_REVERB	0x0c
-#define FXBUS_MIDI_CHORUS	0x0d
-#define FXBUS_PT_LEFT		0x14
-#define FXBUS_PT_RIGHT		0x15
-
-/* Inputs */
-#define EXTIN_AC97_L	   0x00	/* AC'97 capture channel - left */
-#define EXTIN_AC97_R	   0x01	/* AC'97 capture channel - right */
-#define EXTIN_SPDIF_CD_L   0x02	/* internal S/PDIF CD - onboard - left */
-#define EXTIN_SPDIF_CD_R   0x03	/* internal S/PDIF CD - onboard - right */
-#define EXTIN_ZOOM_L	   0x04	/* Zoom Video I2S - left */
-#define EXTIN_ZOOM_R	   0x05	/* Zoom Video I2S - right */
-#define EXTIN_TOSLINK_L	   0x06	/* LiveDrive - TOSLink Optical - left */
-#define EXTIN_TOSLINK_R    0x07	/* LiveDrive - TOSLink Optical - right */
-#define EXTIN_LINE1_L	   0x08	/* LiveDrive - Line/Mic 1 - left */
-#define EXTIN_LINE1_R	   0x09	/* LiveDrive - Line/Mic 1 - right */
-#define EXTIN_COAX_SPDIF_L 0x0a	/* LiveDrive - Coaxial S/PDIF - left */
-#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
-#define EXTIN_LINE2_L	   0x0c	/* LiveDrive - Line/Mic 2 - left */
-#define EXTIN_LINE2_R	   0x0d	/* LiveDrive - Line/Mic 2 - right */
-
-/* Outputs */
-#define EXTOUT_AC97_L	   0x00	/* AC'97 playback channel - left */
-#define EXTOUT_AC97_R	   0x01	/* AC'97 playback channel - right */
-#define EXTOUT_TOSLINK_L   0x02	/* LiveDrive - TOSLink Optical - left */
-#define EXTOUT_TOSLINK_R   0x03	/* LiveDrive - TOSLink Optical - right */
-#define EXTOUT_CENTER      0x04	/* SB Live 5.1 - center */
-#define EXTOUT_LFE         0x05 /* SB Live 5.1 - LFE */
-#define EXTOUT_HEADPHONE_L 0x06	/* LiveDrive - Headphone - left */
-#define EXTOUT_HEADPHONE_R 0x07	/* LiveDrive - Headphone - right */
-#define EXTOUT_REAR_L	   0x08	/* Rear channel - left */
-#define EXTOUT_REAR_R	   0x09	/* Rear channel - right */
-#define EXTOUT_ADC_CAP_L   0x0a	/* ADC Capture buffer - left */
-#define EXTOUT_ADC_CAP_R   0x0b	/* ADC Capture buffer - right */
-#define EXTOUT_MIC_CAP	   0x0c	/* MIC Capture buffer */
-#define EXTOUT_ACENTER	   0x11 /* Analog Center */
-#define EXTOUT_ALFE	   0x12 /* Analog LFE */
-
-/* Audigy Inputs */
-#define A_EXTIN_AC97_L		0x00	/* AC'97 capture channel - left */
-#define A_EXTIN_AC97_R		0x01	/* AC'97 capture channel - right */
-#define A_EXTIN_SPDIF_CD_L	0x02	/* digital CD left */
-#define A_EXTIN_SPDIF_CD_R	0x03	/* digital CD left */
-#define A_EXTIN_OPT_SPDIF_L     0x04    /* audigy drive Optical SPDIF - left */
-#define A_EXTIN_OPT_SPDIF_R     0x05    /*                              right */ 
-#define A_EXTIN_LINE2_L		0x08	/* audigy drive line2/mic2 - left */
-#define A_EXTIN_LINE2_R		0x09	/*                           right */
-#define A_EXTIN_ADC_L		0x0a    /* Philips ADC - left */
-#define A_EXTIN_ADC_R		0x0b    /*               right */
-#define A_EXTIN_AUX2_L		0x0c	/* audigy drive aux2 - left */
-#define A_EXTIN_AUX2_R		0x0d	/*                   - right */
-
-/* Audigiy Outputs */
-#define A_EXTOUT_FRONT_L	0x00	/* digital front left */
-#define A_EXTOUT_FRONT_R	0x01	/*               right */
-#define A_EXTOUT_CENTER		0x02	/* digital front center */
-#define A_EXTOUT_LFE		0x03	/* digital front lfe */
-#define A_EXTOUT_HEADPHONE_L	0x04	/* headphone audigy drive left */
-#define A_EXTOUT_HEADPHONE_R	0x05	/*                        right */
-#define A_EXTOUT_REAR_L		0x06	/* digital rear left */
-#define A_EXTOUT_REAR_R		0x07	/*              right */
-#define A_EXTOUT_AFRONT_L	0x08	/* analog front left */
-#define A_EXTOUT_AFRONT_R	0x09	/*              right */
-#define A_EXTOUT_ACENTER	0x0a	/* analog center */
-#define A_EXTOUT_ALFE		0x0b	/* analog LFE */
-/* 0x0c ?? */
-/* 0x0d ?? */
-#define A_EXTOUT_AREAR_L	0x0e	/* analog rear left */
-#define A_EXTOUT_AREAR_R	0x0f	/*             right */
-#define A_EXTOUT_AC97_L		0x10	/* AC97 left (front) */
-#define A_EXTOUT_AC97_R		0x11	/*      right */
-#define A_EXTOUT_ADC_CAP_L	0x16	/* ADC capture buffer left */
-#define A_EXTOUT_ADC_CAP_R	0x17	/*                    right */
-#define A_EXTOUT_MIC_CAP	0x18	/* Mic capture buffer */
-
-/* Audigy constants */
-#define A_C_00000000	0xc0
-#define A_C_00000001	0xc1
-#define A_C_00000002	0xc2
-#define A_C_00000003	0xc3
-#define A_C_00000004	0xc4
-#define A_C_00000008	0xc5
-#define A_C_00000010	0xc6
-#define A_C_00000020	0xc7
-#define A_C_00000100	0xc8
-#define A_C_00010000	0xc9
-#define A_C_00000800	0xca
-#define A_C_10000000	0xcb
-#define A_C_20000000	0xcc
-#define A_C_40000000	0xcd
-#define A_C_80000000	0xce
-#define A_C_7fffffff	0xcf
-#define A_C_ffffffff	0xd0
-#define A_C_fffffffe	0xd1
-#define A_C_c0000000	0xd2
-#define A_C_4f1bbcdc	0xd3
-#define A_C_5a7ef9db	0xd4
-#define A_C_00100000	0xd5
-#define A_GPR_ACCU	0xd6		/* ACCUM, accumulator */
-#define A_GPR_COND	0xd7		/* CCR, condition register */
-/* 0xd8 = noise1 */
-/* 0xd9 = noise2 */
-
-/* definitions for debug register */
-#define EMU10K1_DBG_ZC			0x80000000	/* zero tram counter */
-#define EMU10K1_DBG_SATURATION_OCCURED	0x02000000	/* saturation control */
-#define EMU10K1_DBG_SATURATION_ADDR	0x01ff0000	/* saturation address */
-#define EMU10K1_DBG_SINGLE_STEP		0x00008000	/* single step mode */
-#define EMU10K1_DBG_STEP		0x00004000	/* start single step */
-#define EMU10K1_DBG_CONDITION_CODE	0x00003e00	/* condition code */
-#define EMU10K1_DBG_SINGLE_STEP_ADDR	0x000001ff	/* single step address */
-
-/* tank memory address line */
-#ifndef __KERNEL__
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
-#define TANKMEMADDRREG_CLEAR	 0x00800000	/* Clear tank memory				*/
-#define TANKMEMADDRREG_ALIGN	 0x00400000	/* Align read or write relative to tank access	*/
-#define TANKMEMADDRREG_WRITE	 0x00200000	/* Write to tank memory				*/
-#define TANKMEMADDRREG_READ	 0x00100000	/* Read from tank memory			*/
-#endif
-
-typedef struct {
-	unsigned int card;			/* card type */
-	unsigned int internal_tram_size;	/* in samples */
-	unsigned int external_tram_size;	/* in samples */
-	char fxbus_names[16][32];		/* names of FXBUSes */
-	char extin_names[16][32];		/* names of external inputs */
-	char extout_names[32][32];		/* names of external outputs */
-	unsigned int gpr_controls;		/* count of GPR controls */
-} emu10k1_fx8010_info_t;
-
-#define EMU10K1_GPR_TRANSLATION_NONE		0
-#define EMU10K1_GPR_TRANSLATION_TABLE100	1
-#define EMU10K1_GPR_TRANSLATION_BASS		2
-#define EMU10K1_GPR_TRANSLATION_TREBLE		3
-#define EMU10K1_GPR_TRANSLATION_ONOFF		4
-
-typedef struct {
-	snd_ctl_elem_id_t id;		/* full control ID definition */
-	unsigned int vcount;		/* visible count */
-	unsigned int count;		/* count of GPR (1..16) */
-	unsigned char gpr[32];		/* GPR number(s) */
-	unsigned int value[32];		/* initial values */
-	unsigned int min;		/* minimum range */
-	unsigned int max;		/* maximum range */
-	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
-} emu10k1_fx8010_control_gpr_t;
-
-typedef struct {
-	char name[128];
-
-	unsigned long gpr_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
-	unsigned int gpr_map[0x100];	  /* initializers */
-
-	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
-	emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */
-
-	unsigned int gpr_del_control_count; /* count of GPR controls to remove */
-	snd_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
-
-	unsigned int gpr_list_control_count; /* count of GPR controls to list */
-	unsigned int gpr_list_control_total; /* total count of GPR controls */
-	emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
-
-	unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
-	unsigned int tram_data_map[0xa0]; /* data initializers */
-	unsigned int tram_addr_map[0xa0]; /* map initializers */
-
-	unsigned long code_valid[512/(sizeof(unsigned long)*8)];  /* bitmask of valid instructions */
-	unsigned int code[512][2];	  /* one instruction - 64 bits */
-} emu10k1_fx8010_code_t;
-
-typedef struct {
-	unsigned int address;		/* 31.bit == 1 -> external TRAM */
-	unsigned int size;		/* size in samples (4 bytes) */
-	unsigned int *samples;		/* pointer to samples (20-bit) */
-					/* NULL->clear memory */
-} emu10k1_fx8010_tram_t;
-
-typedef struct {
-	unsigned int substream;		/* substream number */
-	unsigned int res1;		/* reserved */
-	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
-	unsigned int tram_start;	/* ring buffer position in TRAM (in samples) */
-	unsigned int buffer_size;	/* count of buffered samples */
-	unsigned char gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
-	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
-	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
-	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
-	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
-	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
-	unsigned char pad;		/* reserved */
-	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
-	unsigned int res2;		/* reserved */
-} emu10k1_fx8010_pcm_t;
-
-#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, emu10k1_fx8010_info_t)
-#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, emu10k1_fx8010_code_t)
-#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, emu10k1_fx8010_code_t)
-#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP	_IOW ('H', 0x20, int)
-#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, emu10k1_fx8010_tram_t)
-#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, emu10k1_fx8010_tram_t)
-#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
-#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
-#define SNDRV_EMU10K1_IOCTL_STOP	_IO  ('H', 0x80)
-#define SNDRV_EMU10K1_IOCTL_CONTINUE	_IO  ('H', 0x81)
-#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
-#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP	_IOW ('H', 0x83, int)
-#define SNDRV_EMU10K1_IOCTL_DBG_READ	_IOR ('H', 0x84, int)
-
-#endif	/* __SOUND_EMU10K1_H */
diff --git a/sys/dev/sound/pci/gnu/emu10k1.h b/sys/dev/sound/pci/gnu/emu10k1.h
deleted file mode 100644
index 1853008..0000000
--- a/sys/dev/sound/pci/gnu/emu10k1.h
+++ /dev/null
@@ -1,741 +0,0 @@
-/*-
- **********************************************************************
- *     emu10k1.h, derived from 8010.h
- *     Copyright 1999-2001 Creative Labs, Inc.
- *
- **********************************************************************
- *
- *     Date		    Author	    Summary of changes
- *     ----		    ------	    ------------------
- *     October 20, 1999     Bertrand Lee    base code release
- *     November 2, 1999     Alan Cox	    Cleaned of 8bit chars, DOS
- *					    line endings
- *     December 8, 1999     Jon Taylor	    Added lots of new register info
- *     May 16, 2001         Daniel Bertrand Added unofficial DBG register info
- *     Oct-Nov 2001         D.B.            Added unofficial Audigy registers 
- *
- **********************************************************************
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this program; if not, write to the Free
- *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- *     USA.
- *
- *
- **********************************************************************
- * $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1.h,v 1.8 2005/01/06 18:27:30 imp Exp $
- * $DragonFly: src/sys/dev/sound/pci/gnu/emu10k1.h,v 1.4 2007/01/04 21:47:03 corecode Exp $
- */
-
-
-#ifndef _8010_H
-#define _8010_H
-
-	/*
-#include <linux/types.h>
-	*/
-
-/* Driver version: */
-#define MAJOR_VER 0
-#define MINOR_VER 20
-#define DRIVER_VERSION "0.20a"
-
-
-/* Audigy specify registers are prefixed with 'A_' */
-
-/************************************************************************************************/
-/* PCI function 0 registers, address = <val> + PCIBASE0						*/
-/************************************************************************************************/
-
-#define PTR			0x00		/* Indexed register set pointer register	*/
-						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
-						/* be modified independently of each other.	*/
-#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
-						/* channel number of the register to be		*/
-						/* accessed.  For non per-channel registers the	*/
-						/* value should be set to zero.			*/
-#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
-
-#define DATA			0x04		/* Indexed register set data register		*/
-
-#define IPR			0x08		/* Global interrupt pending register		*/
-						/* Clear pending interrupts by writing a 1 to	*/
-						/* the relevant bits and zero to the other bits	*/
-
-/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-#define A_IPR_MIDITRANSBUFEMPTY2	0x10000000	/* MIDI UART transmit buffer empty		*/
-#define A_IPR_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
-
-#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
-#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
-#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
-#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
-#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
-#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
-#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
-#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
-#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
-#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
-#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
-#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
-#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
-#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
-#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
-#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
-#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
-#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
-#define IPR_CHANNELLOOP		0x00000040	/* One or more channel loop interrupts pending	*/
-#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
-						/* Highest set channel in CLIPL or CLIPH.  When	*/
-						/* IP is written with CL set, the bit in CLIPL	*/
-						/* or CLIPH corresponding to the CIN value 	*/
-						/* written will be cleared.			*/
-#define A_IPR_MIDITRANSBUFEMPTY1	IPR_MIDITRANSBUFEMPTY	/* MIDI UART transmit buffer empty		*/
-#define A_IPR_MIDIRECVBUFEMPTY1	IPR_MIDIRECVBUFEMPTY	/* MIDI UART receive buffer empty		*/
-
-
-
-#define INTE			0x0c		/* Interrupt enable register			*/
-#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
-#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
-#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
-#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
-#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
-#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
-#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
-#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
-#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
-#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
-#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
-#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
-#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
-#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
-#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
-#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
-#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
-#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
-
-#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
-						/* NOTE: There is no reason to use this under	*/
-						/* Linux, and it will cause odd hardware 	*/
-						/* behavior and possibly random segfaults and	*/
-						/* lockups if enabled.				*/
-
-/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
-#define A_INTE_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
-#define A_INTE_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
-
-
-#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
-						/* NOTE: This bit must always be enabled       	*/
-#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
-#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
-#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
-#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
-#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
-#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
-#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
-#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
-#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
-#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
-#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
-#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
-#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
-
-/* The next two interrupts are for the midi port on the Audigy (A_MPU2)	*/
-#define A_INTE_MIDITXENABLE1  	INTE_MIDITXENABLE
-#define A_INTE_MIDIRXENABLE1	INTE_MIDIRXENABLE
-
-#define WC			0x10		/* Wall Clock register				*/
-#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
-#define WC_SAMPLECOUNTER	0x14060010
-#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
-						/* NOTE: Each channel takes 1/64th of a sample	*/
-						/* period to be serviced.			*/
-
-#define HCFG			0x14		/* Hardware config register			*/
-						/* NOTE: There is no reason to use the legacy	*/
-						/* SoundBlaster emulation stuff described below	*/
-						/* under Linux, and all kinds of weird hardware	*/
-						/* behavior can result if you try.  Don't.	*/
-#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
-#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
-#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
-#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
-#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
-#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
-#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
-#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
-#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
-#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
-#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
-#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
-						/* NOTE: The rest of the bits in this register	*/
-						/* _are_ relevant under Linux.			*/
-#define HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format					*/
-#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
-#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
-#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
-#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
-
-#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
-#define HCFG_GPOUT0		0x00001000	/* set to enable digital out on 5.1 cards	*/
-
-#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
-#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
-						/* 1 = Force all 3 async digital inputs to use	*/
-						/* the same async sample rate tracker (ZVIDEO)	*/
-#define HCFG_AC3ENABLE_MASK	0x0x0000e0	/* AC3 async input control - Not implemented	*/
-#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
-#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
-#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF             */
-#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
-						/* will automatically mute their output when	*/
-						/* they are not rate-locked to the external	*/
-						/* async audio source  				*/
-#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
-						/* NOTE: This should generally never be used.  	*/
-#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
-						/* NOTE: This should generally never be used.  	*/
-#define HCFG_LOCKTANKCACHE	0x01020014
-#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
-						/* NOTE: This is a 'cheap' way to implement a	*/
-						/* master mute function on the mute button, and	*/
-						/* in general should not be used unless a more	*/
-						/* sophisticated master mute function has not	*/
-						/* been written.       				*/
-#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
-						/* Should be set to 1 when the EMU10K1 is	*/
-						/* completely initialized.			*/
-
-/* For Audigy, MPU port move to 0x70-0x74 ptr register */
-
-#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
-
-#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
-#define MUCMD_RESET		0xff		/* RESET command				*/
-#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
-						/* NOTE: All other commands are ignored		*/
-
-#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
-#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
-#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
-
-#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
-#define A_GPINPUT_MASK		0xff00
-#define A_GPOUTPUT_MASK		0x00ff
-
-#define TIMER			0x1a		/* Timer terminal count register (16-bit)	*/
-						/* NOTE: After the rate is changed, a maximum	*/
-						/* of 1024 sample periods should be allowed	*/
-						/* before the new rate is guaranteed accurate.	*/
-#define TIMER_RATE_MASK		0x03ff		/* Timer interrupt rate in sample periods	*/
-						/* 0 == 1024 periods, [1..4] are not useful	*/
-
-#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
-
-#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
-#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
-#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
-
-/********************************************************************************************************/
-/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
-/********************************************************************************************************/
-
-#define CPF			0x00		/* Current pitch and fraction register			*/
-#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
-#define CPF_CURRENTPITCH	0x10100000
-#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
-#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
-#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
-
-#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
-#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
-#define PTRX_PITCHTARGET	0x10100001
-#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
-#define PTRX_FXSENDAMOUNT_A	0x08080001
-#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
-#define PTRX_FXSENDAMOUNT_B	0x08000001
-
-#define CVCF			0x02		/* Current volume and filter cutoff register		*/
-#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
-#define CVCF_CURRENTVOL		0x10100002
-#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
-#define CVCF_CURRENTFILTER	0x10000002
-
-#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
-#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
-#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
-
-#define Z1			0x05		/* Filter delay memory 1 register			*/
-
-#define Z2			0x04		/* Filter delay memory 2 register			*/
-
-#define PSST			0x06		/* Send C amount and loop start address register	*/
-#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
-
-#define PSST_FXSENDAMOUNT_C	0x08180006
-
-#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
-#define PSST_LOOPSTARTADDR	0x18000006
-
-#define DSL			0x07		/* Send D amount and loop start address register	*/
-#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
-
-#define DSL_FXSENDAMOUNT_D	0x08180007
-
-#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
-#define DSL_LOOPENDADDR		0x18000007
-
-#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
-#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
-#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
-						/* 1 == full band, 7 == lowpass				*/
-						/* ROM 0 is used when pitch shifting downward or less	*/
-						/* then 3 semitones upward.  Increasingly higher ROM	*/
-						/* numbers are used, typically in steps of 3 semitones,	*/
-						/* as upward pitch shifting is performed.		*/
-#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
-#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
-#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
-#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
-#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
-#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
-#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
-#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
-#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
-#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
-#define CCCA_CURRADDR		0x18000008
-
-#define CCR			0x09		/* Cache control register				*/
-#define CCR_CACHEINVALIDSIZE	0x07190009
-#define CCR_CACHEINVALIDSIZE_MASK	0xfe000000	/* Number of invalid samples cache for this channel    	*/
-#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
-#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
-#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
-#define CCR_READADDRESS		0x06100009
-#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
-#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
-						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
-#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
-#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
-
-#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
-						/* NOTE: This register is normally not used		*/
-#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
-
-#define FXRT			0x0b		/* Effects send routing register			*/
-						/* NOTE: It is illegal to assign the same routing to	*/
-						/* two effects sends.					*/
-#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
-#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
-#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
-#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
-
-#define MAPA			0x0c		/* Cache map A						*/
-
-#define MAPB			0x0d		/* Cache map B						*/
-
-#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
-#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
-
-#define ENVVOL			0x10		/* Volume envelope register				*/
-#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/  
-						/* 0x8000-n == 666*n usec delay	       			*/
-
-#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
-#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
-#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
-#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
-						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
-
-#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
-#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
-#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
-#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
-						/* this channel and from writing to pitch, filter and	*/
-						/* volume targets.					*/
-#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
-						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
-
-#define LFOVAL1 		0x13		/* Modulation LFO value					*/
-#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define ENVVAL			0x14		/* Modulation envelope register				*/
-#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
-#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
-#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
-#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
-						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
-
-#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
-#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
-#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
-#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
-						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
-
-#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
-#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
-						/* 0x8000-n == 666*n usec delay				*/
-
-#define IP			0x18		/* Initial pitch register				*/
-#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
-						/* 4 bits of octave, 12 bits of fractional octave	*/
-#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
-
-#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
-#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
-						/* 6 most significant bits are semitones		*/
-						/* 2 least significant bits are fractions		*/
-#define IFATN_FILTERCUTOFF	0x08080019
-#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
-#define IFATN_ATTENUATION	0x08000019
-
-
-#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
-#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
-						/* Signed 2's complement, +/- one octave peak extremes	*/
-#define PEFE_PITCHAMOUNT	0x0808001a
-#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
-						/* Signed 2's complement, +/- six octaves peak extremes */
-#define PEFE_FILTERAMOUNT	0x0800001a
-#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
-#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
-						/* Signed 2's complement, +/- one octave extremes	*/
-#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
-						/* Signed 2's complement, +/- three octave extremes	*/
-
-
-#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
-#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
-						/* Signed 2's complement, with +/- 12dB extremes	*/
-#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
-						/* ??Hz steps, maximum of ?? Hz.			*/
-
-#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
-#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
-						/* Signed 2's complement, +/- one octave extremes	*/
-#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
-						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
-
-#define TEMPENV 		0x1e		/* Tempory envelope register				*/
-#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
-						/* NOTE: All channels contain internal variables; do	*/
-						/* not write to these locations.			*/
-
-#define CD0			0x20		/* Cache data 0 register				*/
-#define CD1			0x21		/* Cache data 1 register				*/
-#define CD2			0x22		/* Cache data 2 register				*/
-#define CD3			0x23		/* Cache data 3 register				*/
-#define CD4			0x24		/* Cache data 4 register				*/
-#define CD5			0x25		/* Cache data 5 register				*/
-#define CD6			0x26		/* Cache data 6 register				*/
-#define CD7			0x27		/* Cache data 7 register				*/
-#define CD8			0x28		/* Cache data 8 register				*/
-#define CD9			0x29		/* Cache data 9 register				*/
-#define CDA			0x2a		/* Cache data A register				*/
-#define CDB			0x2b		/* Cache data B register				*/
-#define CDC			0x2c		/* Cache data C register				*/
-#define CDD			0x2d		/* Cache data D register				*/
-#define CDE			0x2e		/* Cache data E register				*/
-#define CDF			0x2f		/* Cache data F register				*/
-
-#define PTB			0x40		/* Page table base register				*/
-#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
-
-#define TCB			0x41		/* Tank cache base register    				*/
-#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
-
-#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
-#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
-#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
-						/* NOTE: To guarantee phase coherency, both channels	*/
-						/* must be disabled prior to enabling both channels.	*/
-#define A_ADCCR_RCHANENABLE	0x00000020
-#define A_ADCCR_LCHANENABLE	0x00000010
-
-#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
-#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
-
-#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
-#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
-#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
-#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
-#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
-#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
-#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
-#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
-
-#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
-#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
-#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
-
-#define FXWC			0x43		/* FX output write channels register			*/
-						/* When set, each bit enables the writing of the	*/
-						/* corresponding FX output channel (internal registers  */
-						/* 0x20-0x3f) into host memory. This mode of recording	*/
-						/* is 16bit, 48KHz only. All 32	channels can be enabled */
-						/* simultaneously.					*/
-#define TCBS			0x44		/* Tank cache buffer size register			*/
-#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
-#define TCBS_BUFFSIZE_16K	0x00000000
-#define TCBS_BUFFSIZE_32K	0x00000001
-#define TCBS_BUFFSIZE_64K	0x00000002
-#define TCBS_BUFFSIZE_128K	0x00000003
-#define TCBS_BUFFSIZE_256K	0x00000004
-#define TCBS_BUFFSIZE_512K	0x00000005
-#define TCBS_BUFFSIZE_1024K	0x00000006
-#define TCBS_BUFFSIZE_2048K	0x00000007
-
-#define MICBA			0x45		/* AC97 microphone buffer address register		*/
-#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define ADCBA			0x46		/* ADC buffer address register				*/
-#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define FXBA			0x47		/* FX Buffer Address */
-#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
-
-#define MICBS			0x49		/* Microphone buffer size register			*/
-
-#define ADCBS			0x4a		/* ADC buffer size register				*/
-
-#define FXBS			0x4b		/* FX buffer size register				*/
-
-/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
-#define ADCBS_BUFSIZE_NONE	0x00000000
-#define ADCBS_BUFSIZE_384	0x00000001
-#define ADCBS_BUFSIZE_448	0x00000002
-#define ADCBS_BUFSIZE_512	0x00000003
-#define ADCBS_BUFSIZE_640	0x00000004
-#define ADCBS_BUFSIZE_768	0x00000005
-#define ADCBS_BUFSIZE_896	0x00000006
-#define ADCBS_BUFSIZE_1024	0x00000007
-#define ADCBS_BUFSIZE_1280	0x00000008
-#define ADCBS_BUFSIZE_1536	0x00000009
-#define ADCBS_BUFSIZE_1792	0x0000000a
-#define ADCBS_BUFSIZE_2048	0x0000000b
-#define ADCBS_BUFSIZE_2560	0x0000000c
-#define ADCBS_BUFSIZE_3072	0x0000000d
-#define ADCBS_BUFSIZE_3584	0x0000000e
-#define ADCBS_BUFSIZE_4096	0x0000000f
-#define ADCBS_BUFSIZE_5120	0x00000010
-#define ADCBS_BUFSIZE_6144	0x00000011
-#define ADCBS_BUFSIZE_7168	0x00000012
-#define ADCBS_BUFSIZE_8192	0x00000013
-#define ADCBS_BUFSIZE_10240	0x00000014
-#define ADCBS_BUFSIZE_12288	0x00000015
-#define ADCBS_BUFSIZE_14366	0x00000016
-#define ADCBS_BUFSIZE_16384	0x00000017
-#define ADCBS_BUFSIZE_20480	0x00000018
-#define ADCBS_BUFSIZE_24576	0x00000019
-#define ADCBS_BUFSIZE_28672	0x0000001a
-#define ADCBS_BUFSIZE_32768	0x0000001b
-#define ADCBS_BUFSIZE_40960	0x0000001c
-#define ADCBS_BUFSIZE_49152	0x0000001d
-#define ADCBS_BUFSIZE_57344	0x0000001e
-#define ADCBS_BUFSIZE_65536	0x0000001f
-
-
-#define CDCS			0x50		/* CD-ROM digital channel status register	*/
-
-#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
-
-#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
-
-/* definitions for debug register - taken from the alsa drivers */
-#define DBG_ZC                  0x80000000      /* zero tram counter */
-#define DBG_SATURATION_OCCURED  0x02000000      /* saturation control */
-#define DBG_SATURATION_ADDR     0x01ff0000      /* saturation address */
-#define DBG_SINGLE_STEP         0x00008000      /* single step mode */
-#define DBG_STEP                0x00004000      /* start single step */
-#define DBG_CONDITION_CODE      0x00003e00      /* condition code */
-#define DBG_SINGLE_STEP_ADDR    0x000001ff      /* single step address */
-
-
-#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
-
-#define A_DBG			 0x53
-#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
-#define A_DBG_ZC		 0x40000000	/* zero tram counter */
-#define A_DBG_STEP_ADDR		 0x000003ff
-#define A_DBG_SATURATION_OCCURED 0x20000000
-#define A_DBG_SATURATION_ADDR	 0x0ffc0000
-
-#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
-
-#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
-
-#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
-
-#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
-#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
-#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
-#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
-#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
-#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
-#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
-#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
-#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
-#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
-#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
-#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
-#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
-#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
-#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
-#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
-#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
-#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
-#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
-#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
-#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
-#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
-#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
-
-/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
-#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
-
-#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
-
-#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
-
-#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
-
-#define SOLEL			0x5c		/* Stop on loop enable low register		*/
-
-#define SOLEH			0x5d		/* Stop on loop enable high register		*/
-
-#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
-#define SPBYPASS_ENABLE		0x00000001	/* Enable SPDIF bypass mode			*/
-
-#define AC97SLOT		0x5f		/* additional AC97 slots enable bits */
-#define AC97SLOT_CNTR		0x10		/* Center enable */
-#define AC97SLOT_LFE		0x20		/* LFE enable */
-
-#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
-
-#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
-
-#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
-						/* NOTE: This one has no SPDIFLOCKED field	*/
-						/* Assumes sample lock				*/
-
-/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
-#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
-#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
-#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
-
-
-/* Note that these values can vary +/- by a small amount                                        */
-#define SRCS_SPDIFRATE_44	0x0003acd9
-#define SRCS_SPDIFRATE_48	0x00040000
-#define SRCS_SPDIFRATE_96	0x00080000
-
-#define MICIDX                  0x63            /* Microphone recording buffer index register   */
-#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
-#define MICIDX_IDX		0x10000063
-
-#define A_ADCIDX		0x63
-#define A_ADCIDX_IDX		0x10000063
-
-#define ADCIDX			0x64		/* ADC recording buffer index register		*/
-#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
-#define ADCIDX_IDX		0x10000064
-
-#define FXIDX			0x65		/* FX recording buffer index register		*/
-#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
-#define FXIDX_IDX		0x10000065
-
-/* This is the MPU port on the card (via the game port)						*/
-#define A_MUDATA1		0x70
-#define A_MUCMD1		0x71
-#define A_MUSTAT1		A_MUCMD1
-
-/* This is the MPU port on the Audigy Drive 							*/
-#define A_MUDATA2		0x72
-#define A_MUCMD2		0x73
-#define A_MUSTAT2		A_MUCMD2	
-
-/* The next two are the Audigy equivalent of FXWC						*/
-/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
-/* Each bit selects a channel for recording */
-#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
-#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
-
-#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
-#define A_SPDIF_48000		0x00000080
-#define A_SPDIF_44100		0x00000000
-#define A_SPDIF_96000		0x00000040
-
-#define A_FXRT2			0x7c
-#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
-#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
-#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
-#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
-
-#define A_SENDAMOUNTS		0x7d
-#define A_FXSENDAMOUNT_E_MASK	0xff000000
-#define A_FXSENDAMOUNT_F_MASK	0x00ff0000
-#define A_FXSENDAMOUNT_G_MASK	0x0000ff00
-#define A_FXSENDAMOUNT_H_MASK	0x000000ff
-
-/* The send amounts for this one are the same as used with the emu10k1 */
-#define A_FXRT1			0x7e
-#define A_FXRT_CHANNELA		0x0000003f
-#define A_FXRT_CHANNELB		0x00003f00
-#define A_FXRT_CHANNELC		0x003f0000
-#define A_FXRT_CHANNELD		0x3f000000
-
-
-/* Each FX general purpose register is 32 bits in length, all bits are used			*/
-#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
-#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
-/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
-/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
-/* locations are for external TRAM. 								*/
-#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
-#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
-
-/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
-#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
-#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
-#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
-#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
-#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
-
-#define MICROCODEBASE		0x400		/* Microcode data base address			*/
-
-/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
-/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
-#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
-#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
-#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
-#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
-#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
-
-
-/* Audigy Soundcard have a different instruction format */
-#define AUDIGY_CODEBASE		0x600
-#define A_LOWORD_OPY_MASK	0x000007ff		
-#define A_LOWORD_OPX_MASK	0x007ff000
-#define A_HIWORD_OPCODE_MASK	0x0f000000
-#define A_HIWORD_RESULT_MASK	0x007ff000
-#define A_HIWORD_OPA_MASK	0x000007ff
-
-
-#endif /* _8010_H */
diff --git a/sys/dev/sound/pci/gnu/maestro3_dsp.h b/sys/dev/sound/pci/gnu/maestro3_dsp.h
deleted file mode 100644
index 5cd3863..0000000
--- a/sys/dev/sound/pci/gnu/maestro3_dsp.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $FreeBSD: src/sys/gnu/dev/sound/pci/maestro3_dsp.h,v 1.5 2005/01/06 18:27:30 imp Exp $ */
-/* $DragonFly: src/sys/dev/sound/pci/gnu/maestro3_dsp.h,v 1.3 2007/01/04 21:47:03 corecode Exp $ */
-/*-
- *      ESS Technology allegro audio driver.
- *
- *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *      Hacked for the maestro3 driver by zab
- */
-
-/*
- * DSP Code images
- */
-
-u_int16_t assp_kernel_image[] = {
-    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
-    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, 
-    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, 
-    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, 
-    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, 
-    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, 
-    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, 
-    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, 
-    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, 
-    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, 
-    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, 
-    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, 
-    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, 
-    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, 
-    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, 
-    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, 
-    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, 
-    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, 
-    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, 
-    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, 
-    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, 
-    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, 
-    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, 
-    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, 
-    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, 
-    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, 
-    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, 
-    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, 
-    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, 
-    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, 
-    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 
-    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, 
-    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, 
-    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, 
-    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, 
-    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 
-    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, 
-    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, 
-    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, 
-    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, 
-    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, 
-    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 
-    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, 
-    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, 
-    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, 
-    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 
-    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, 
-    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, 
-    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, 
-    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, 
-    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, 
-    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, 
-    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, 
-    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 
-    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, 
-    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 
-    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, 
-    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, 
-    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, 
-    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, 
-    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, 
-    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, 
-    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, 
-    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, 
-    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, 
-    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, 
-    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, 
-    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, 
-    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, 
-    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, 
-    0xBE3A, 
-};
-
-/*
- * Mini sample rate converter code image
- * that is to be loaded at 0x400 on the DSP.
- */
-u_int16_t assp_minisrc_image[] = {
-    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
-    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
-    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, 
-    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, 
-    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, 
-    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, 
-    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, 
-    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, 
-    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, 
-    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, 
-    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, 
-    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, 
-    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, 
-    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, 
-    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, 
-    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, 
-    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, 
-    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, 
-    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, 
-    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, 
-    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, 
-    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, 
-    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, 
-    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, 
-    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, 
-    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, 
-    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, 
-    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, 
-    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, 
-    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, 
-    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, 
-    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-};
-
-u_int16_t minisrc_lpf_image[] = {
-	0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
-	0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
-};
-
-/*
- * an arbitrary volume we set the internal volume settings to so that the
- * ac97 volume range is a little less insane.  0x7fff is max.
- */
-#define ARB_VOLUME 0x6800
-
-static struct play_vals {
-	u_int16_t addr, val;
-} pv[] = {
-	{CDATA_LEFT_VOLUME, ARB_VOLUME},
-	{CDATA_RIGHT_VOLUME, ARB_VOLUME},
-	{SRC3_DIRECTION_OFFSET, 0} ,
-	/* +1, +2 are stereo/16 bit */
-	{SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-	{SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-	{SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-	{SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-	{SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-	{SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-	{SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-	{SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-	{SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-	{SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-	{SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-	{SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-	{SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
-	{SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
-	{SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
-	{SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-	{SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
-};
-
-static struct rec_vals {
-	u_int16_t addr, val;
-} rv[] = {
-	{CDATA_LEFT_VOLUME, ARB_VOLUME},
-	{CDATA_RIGHT_VOLUME, ARB_VOLUME},
-	{SRC3_DIRECTION_OFFSET, 1},
-	/* +1, +2 are stereo/16 bit */
-	{SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-	{SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-	{SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-	{SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-	{SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-	{SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-	{SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-	{SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-	{SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-	{SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-	{SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-	{SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-	{SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
-	{SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
-	{SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
-	{SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
-	{SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-	{SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
-	{SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
-};
diff --git a/sys/dev/sound/pci/gnu/maestro3_reg.h b/sys/dev/sound/pci/gnu/maestro3_reg.h
deleted file mode 100644
index de34410..0000000
--- a/sys/dev/sound/pci/gnu/maestro3_reg.h
+++ /dev/null
@@ -1,693 +0,0 @@
-/* $FreeBSD: src/sys/gnu/dev/sound/pci/maestro3_reg.h,v 1.5 2005/01/06 18:27:30 imp Exp $ */
-/* $DragonFly: src/sys/dev/sound/pci/gnu/maestro3_reg.h,v 1.3 2007/01/04 21:47:03 corecode Exp $ */
-/*-
- *      ESS Technology allegro audio driver.
- *
- *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *      Hacked for the maestro3 driver by zab
- */
-
-/* Allegro PCI configuration registers */
-#define PCI_LEGACY_AUDIO_CTRL   0x40
-#define SOUND_BLASTER_ENABLE    0x00000001
-#define FM_SYNTHESIS_ENABLE     0x00000002
-#define GAME_PORT_ENABLE        0x00000004
-#define MPU401_IO_ENABLE        0x00000008
-#define MPU401_IRQ_ENABLE       0x00000010
-#define ALIAS_10BIT_IO          0x00000020
-#define SB_DMA_MASK             0x000000C0
-#define SB_DMA_0                0x00000040
-#define SB_DMA_1                0x00000040
-#define SB_DMA_R                0x00000080
-#define SB_DMA_3                0x000000C0
-#define SB_IRQ_MASK             0x00000700
-#define SB_IRQ_5                0x00000000
-#define SB_IRQ_7                0x00000100
-#define SB_IRQ_9                0x00000200
-#define SB_IRQ_10               0x00000300
-#define MIDI_IRQ_MASK           0x00003800
-#define SERIAL_IRQ_ENABLE       0x00004000
-#define DISABLE_LEGACY          0x00008000
-
-#define PCI_ALLEGRO_CONFIG      0x50
-#define SB_ADDR_240             0x00000004
-#define MPU_ADDR_MASK           0x00000018
-#define MPU_ADDR_330            0x00000000
-#define MPU_ADDR_300            0x00000008
-#define MPU_ADDR_320            0x00000010
-#define MPU_ADDR_340            0x00000018
-#define USE_PCI_TIMING          0x00000040
-#define POSTED_WRITE_ENABLE     0x00000080
-#define DMA_POLICY_MASK         0x00000700
-#define DMA_DDMA                0x00000000
-#define DMA_TDMA                0x00000100
-#define DMA_PCPCI               0x00000200
-#define DMA_WBDMA16             0x00000400
-#define DMA_WBDMA4              0x00000500
-#define DMA_WBDMA2              0x00000600
-#define DMA_WBDMA1              0x00000700
-#define DMA_SAFE_GUARD          0x00000800
-#define HI_PERF_GP_ENABLE       0x00001000
-#define PIC_SNOOP_MODE_0        0x00002000
-#define PIC_SNOOP_MODE_1        0x00004000
-#define SOUNDBLASTER_IRQ_MASK   0x00008000
-#define RING_IN_ENABLE          0x00010000
-#define SPDIF_TEST_MODE         0x00020000
-#define CLK_MULT_MODE_SELECT_2  0x00040000
-#define EEPROM_WRITE_ENABLE     0x00080000
-#define CODEC_DIR_IN            0x00100000
-#define HV_BUTTON_FROM_GD       0x00200000
-#define REDUCED_DEBOUNCE        0x00400000
-#define HV_CTRL_ENABLE          0x00800000
-#define SPDIF_ENABLE            0x01000000
-#define CLK_DIV_SELECT          0x06000000
-#define CLK_DIV_BY_48           0x00000000
-#define CLK_DIV_BY_49           0x02000000
-#define CLK_DIV_BY_50           0x04000000
-#define CLK_DIV_RESERVED        0x06000000
-#define PM_CTRL_ENABLE          0x08000000
-#define CLK_MULT_MODE_SELECT    0x30000000
-#define CLK_MULT_MODE_SHIFT     28
-#define CLK_MULT_MODE_0         0x00000000
-#define CLK_MULT_MODE_1         0x10000000
-#define CLK_MULT_MODE_2         0x20000000
-#define CLK_MULT_MODE_3         0x30000000
-#define INT_CLK_SELECT          0x40000000
-#define INT_CLK_MULT_RESET      0x80000000
-
-/* M3 */
-#define INT_CLK_SRC_NOT_PCI     0x00100000
-#define INT_CLK_MULT_ENABLE     0x80000000
-
-#define PCI_ACPI_CONTROL        0x54
-#define PCI_ACPI_D0             0x00000000
-#define PCI_ACPI_D1             0xB4F70000
-#define PCI_ACPI_D2             0xB4F7B4F7
-
-#define PCI_USER_CONFIG         0x58
-#define EXT_PCI_MASTER_ENABLE   0x00000001
-#define SPDIF_OUT_SELECT        0x00000002
-#define TEST_PIN_DIR_CTRL       0x00000004
-#define AC97_CODEC_TEST         0x00000020
-#define TRI_STATE_BUFFER        0x00000080
-#define IN_CLK_12MHZ_SELECT     0x00000100
-#define MULTI_FUNC_DISABLE      0x00000200
-#define EXT_MASTER_PAIR_SEL     0x00000400
-#define PCI_MASTER_SUPPORT      0x00000800
-#define STOP_CLOCK_ENABLE       0x00001000
-#define EAPD_DRIVE_ENABLE       0x00002000
-#define REQ_TRI_STATE_ENABLE    0x00004000
-#define REQ_LOW_ENABLE          0x00008000
-#define MIDI_1_ENABLE           0x00010000
-#define MIDI_2_ENABLE           0x00020000
-#define SB_AUDIO_SYNC           0x00040000
-#define HV_CTRL_TEST            0x00100000
-#define SOUNDBLASTER_TEST       0x00400000
-
-#define PCI_USER_CONFIG_C       0x5C
-
-#define PCI_DDMA_CTRL           0x60
-#define DDMA_ENABLE             0x00000001
-
-
-/* Allegro registers */
-#define HOST_INT_CTRL           0x18
-#define SB_INT_ENABLE           0x0001
-#define MPU401_INT_ENABLE       0x0002
-#define ASSP_INT_ENABLE         0x0010
-#define RING_INT_ENABLE         0x0020
-#define HV_INT_ENABLE           0x0040
-#define CLKRUN_GEN_ENABLE       0x0100
-#define HV_CTRL_TO_PME          0x0400
-#define SOFTWARE_RESET_ENABLE   0x8000
-
-/*
- * should be using the above defines, probably.
- */
-#define REGB_ENABLE_RESET       0x01
-#define REGB_STOP_CLOCK         0x10
-
-#define HOST_INT_STATUS         0x1A
-#define SB_INT_PENDING          0x01
-#define MPU401_INT_PENDING      0x02
-#define ASSP_INT_PENDING        0x10
-#define RING_INT_PENDING        0x20
-#define HV_INT_PENDING          0x40
-
-#define HARDWARE_VOL_CTRL       0x1B
-#define SHADOW_MIX_REG_VOICE    0x1C
-#define HW_VOL_COUNTER_VOICE    0x1D
-#define SHADOW_MIX_REG_MASTER   0x1E
-#define HW_VOL_COUNTER_MASTER   0x1F
-
-#define CODEC_COMMAND           0x30
-#define CODEC_READ_B            0x80
-
-#define CODEC_STATUS            0x30
-#define CODEC_BUSY_B            0x01
-
-#define CODEC_DATA              0x32
-
-#define RING_BUS_CTRL_A         0x36
-#define RAC_PME_ENABLE          0x0100
-#define RAC_SDFS_ENABLE         0x0200
-#define LAC_PME_ENABLE          0x0400
-#define LAC_SDFS_ENABLE         0x0800
-#define SERIAL_AC_LINK_ENABLE   0x1000
-#define IO_SRAM_ENABLE          0x2000
-#define IIS_INPUT_ENABLE        0x8000
-
-#define RING_BUS_CTRL_B         0x38
-#define SECOND_CODEC_ID_MASK    0x0003
-#define SPDIF_FUNC_ENABLE       0x0010
-#define SECOND_AC_ENABLE        0x0020
-#define SB_MODULE_INTF_ENABLE   0x0040
-#define SSPE_ENABLE             0x0040
-#define M3I_DOCK_ENABLE         0x0080
-
-#define SDO_OUT_DEST_CTRL       0x3A
-#define COMMAND_ADDR_OUT        0x0003
-#define PCM_LR_OUT_LOCAL        0x0000
-#define PCM_LR_OUT_REMOTE       0x0004
-#define PCM_LR_OUT_MUTE         0x0008
-#define PCM_LR_OUT_BOTH         0x000C
-#define LINE1_DAC_OUT_LOCAL     0x0000
-#define LINE1_DAC_OUT_REMOTE    0x0010
-#define LINE1_DAC_OUT_MUTE      0x0020
-#define LINE1_DAC_OUT_BOTH      0x0030
-#define PCM_CLS_OUT_LOCAL       0x0000
-#define PCM_CLS_OUT_REMOTE      0x0040
-#define PCM_CLS_OUT_MUTE        0x0080
-#define PCM_CLS_OUT_BOTH        0x00C0
-#define PCM_RLF_OUT_LOCAL       0x0000
-#define PCM_RLF_OUT_REMOTE      0x0100
-#define PCM_RLF_OUT_MUTE        0x0200
-#define PCM_RLF_OUT_BOTH        0x0300
-#define LINE2_DAC_OUT_LOCAL     0x0000
-#define LINE2_DAC_OUT_REMOTE    0x0400
-#define LINE2_DAC_OUT_MUTE      0x0800
-#define LINE2_DAC_OUT_BOTH      0x0C00
-#define HANDSET_OUT_LOCAL       0x0000
-#define HANDSET_OUT_REMOTE      0x1000
-#define HANDSET_OUT_MUTE        0x2000
-#define HANDSET_OUT_BOTH        0x3000
-#define IO_CTRL_OUT_LOCAL       0x0000
-#define IO_CTRL_OUT_REMOTE      0x4000
-#define IO_CTRL_OUT_MUTE        0x8000
-#define IO_CTRL_OUT_BOTH        0xC000
-
-#define SDO_IN_DEST_CTRL        0x3C
-#define STATUS_ADDR_IN          0x0003
-#define PCM_LR_IN_LOCAL         0x0000
-#define PCM_LR_IN_REMOTE        0x0004
-#define PCM_LR_RESERVED         0x0008
-#define PCM_LR_IN_BOTH          0x000C
-#define LINE1_ADC_IN_LOCAL      0x0000
-#define LINE1_ADC_IN_REMOTE     0x0010
-#define LINE1_ADC_IN_MUTE       0x0020
-#define MIC_ADC_IN_LOCAL        0x0000
-#define MIC_ADC_IN_REMOTE       0x0040
-#define MIC_ADC_IN_MUTE         0x0080
-#define LINE2_DAC_IN_LOCAL      0x0000
-#define LINE2_DAC_IN_REMOTE     0x0400
-#define LINE2_DAC_IN_MUTE       0x0800
-#define HANDSET_IN_LOCAL        0x0000
-#define HANDSET_IN_REMOTE       0x1000
-#define HANDSET_IN_MUTE         0x2000
-#define IO_STATUS_IN_LOCAL      0x0000
-#define IO_STATUS_IN_REMOTE     0x4000
-
-#define SPDIF_IN_CTRL           0x3E
-#define SPDIF_IN_ENABLE         0x0001
-
-#define GPIO_DATA               0x60
-#define GPIO_DATA_MASK          0x0FFF
-#define GPIO_HV_STATUS          0x3000
-#define GPIO_PME_STATUS         0x4000
-
-#define GPIO_MASK               0x64
-#define GPIO_DIRECTION          0x68
-#define GPO_PRIMARY_AC97        0x0001
-#define GPI_LINEOUT_SENSE       0x0004
-#define GPO_SECONDARY_AC97      0x0008
-#define GPI_VOL_DOWN            0x0010
-#define GPI_VOL_UP              0x0020
-#define GPI_IIS_CLK             0x0040
-#define GPI_IIS_LRCLK           0x0080
-#define GPI_IIS_DATA            0x0100
-#define GPI_DOCKING_STATUS      0x0100
-#define GPI_HEADPHONE_SENSE     0x0200
-#define GPO_EXT_AMP_SHUTDOWN    0x1000
-
-/* M3 */
-#define GPO_M3_EXT_AMP_SHUTDN   0x0002
-
-#define ASSP_INDEX_PORT         0x80
-#define ASSP_MEMORY_PORT        0x82
-#define ASSP_DATA_PORT          0x84
-
-#define MPU401_DATA_PORT        0x98
-#define MPU401_STATUS_PORT      0x99
-
-#define CLK_MULT_DATA_PORT      0x9C
-
-#define ASSP_CONTROL_A          0xA2
-#define ASSP_0_WS_ENABLE        0x01
-#define ASSP_CTRL_A_RESERVED1   0x02
-#define ASSP_CTRL_A_RESERVED2   0x04
-#define ASSP_CLK_49MHZ_SELECT   0x08
-#define FAST_PLU_ENABLE         0x10
-#define ASSP_CTRL_A_RESERVED3   0x20
-#define DSP_CLK_36MHZ_SELECT    0x40
-
-#define ASSP_CONTROL_B          0xA4
-#define RESET_ASSP              0x00
-#define RUN_ASSP                0x01
-#define ENABLE_ASSP_CLOCK       0x00
-#define STOP_ASSP_CLOCK         0x10
-#define RESET_TOGGLE            0x40
-
-#define ASSP_CONTROL_C          0xA6
-#define ASSP_HOST_INT_ENABLE    0x01
-#define FM_ADDR_REMAP_DISABLE   0x02
-#define HOST_WRITE_PORT_ENABLE  0x08
-
-#define ASSP_HOST_INT_STATUS    0xAC
-#define DSP2HOST_REQ_PIORECORD  0x01
-#define DSP2HOST_REQ_I2SRATE    0x02
-#define DSP2HOST_REQ_TIMER      0x04
-
-/* AC97 registers */
-/* XXX fix this crap up */
-/*#define AC97_RESET              0x00*/
-
-#define AC97_VOL_MUTE_B         0x8000
-#define AC97_VOL_M              0x1F
-#define AC97_LEFT_VOL_S         8
-
-#define AC97_MASTER_VOL         0x02
-#define AC97_LINE_LEVEL_VOL     0x04
-#define AC97_MASTER_MONO_VOL    0x06
-#define AC97_PC_BEEP_VOL        0x0A
-#define AC97_PC_BEEP_VOL_M      0x0F
-#define AC97_SROUND_MASTER_VOL  0x38
-#define AC97_PC_BEEP_VOL_S      1
-
-/*#define AC97_PHONE_VOL          0x0C
-#define AC97_MIC_VOL            0x0E*/
-#define AC97_MIC_20DB_ENABLE    0x40
-
-/*#define AC97_LINEIN_VOL         0x10
-#define AC97_CD_VOL             0x12
-#define AC97_VIDEO_VOL          0x14
-#define AC97_AUX_VOL            0x16*/
-#define AC97_PCM_OUT_VOL        0x18
-/*#define AC97_RECORD_SELECT      0x1A*/
-#define AC97_RECORD_MIC         0x00
-#define AC97_RECORD_CD          0x01
-#define AC97_RECORD_VIDEO       0x02
-#define AC97_RECORD_AUX         0x03
-#define AC97_RECORD_MONO_MUX    0x02
-#define AC97_RECORD_DIGITAL     0x03
-#define AC97_RECORD_LINE        0x04
-#define AC97_RECORD_STEREO      0x05
-#define AC97_RECORD_MONO        0x06
-#define AC97_RECORD_PHONE       0x07
-
-/*#define AC97_RECORD_GAIN        0x1C*/
-#define AC97_RECORD_VOL_M       0x0F
-
-/*#define AC97_GENERAL_PURPOSE    0x20*/
-#define AC97_POWER_DOWN_CTRL    0x26
-#define AC97_ADC_READY          0x0001
-#define AC97_DAC_READY          0x0002
-#define AC97_ANALOG_READY       0x0004
-#define AC97_VREF_ON            0x0008
-#define AC97_PR0                0x0100
-#define AC97_PR1                0x0200
-#define AC97_PR2                0x0400
-#define AC97_PR3                0x0800
-#define AC97_PR4                0x1000
-
-#define AC97_RESERVED1          0x28
-
-#define AC97_VENDOR_TEST        0x5A
-
-#define AC97_CLOCK_DELAY        0x5C
-#define AC97_LINEOUT_MUX_SEL    0x0001
-#define AC97_MONO_MUX_SEL       0x0002
-#define AC97_CLOCK_DELAY_SEL    0x1F
-#define AC97_DAC_CDS_SHIFT      6
-#define AC97_ADC_CDS_SHIFT      11
-
-#define AC97_MULTI_CHANNEL_SEL  0x74
-
-/*#define AC97_VENDOR_ID1         0x7C
-#define AC97_VENDOR_ID2         0x7E*/
-
-/*
- * ASSP control regs
- */
-#define DSP_PORT_TIMER_COUNT    0x06
-
-#define DSP_PORT_MEMORY_INDEX   0x80
-
-#define DSP_PORT_MEMORY_TYPE    0x82
-#define MEMTYPE_INTERNAL_CODE   0x0002
-#define MEMTYPE_INTERNAL_DATA   0x0003
-#define MEMTYPE_MASK            0x0003
-
-#define DSP_PORT_MEMORY_DATA    0x84
-
-#define DSP_PORT_CONTROL_REG_A  0xA2
-#define DSP_PORT_CONTROL_REG_B  0xA4
-#define DSP_PORT_CONTROL_REG_C  0xA6
-
-#define REV_A_CODE_MEMORY_BEGIN         0x0000
-#define REV_A_CODE_MEMORY_END           0x0FFF
-#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
-
-#define REV_B_CODE_MEMORY_BEGIN         0x0000
-#define REV_B_CODE_MEMORY_END           0x0BFF
-#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
-
-#define REV_A_DATA_MEMORY_BEGIN         0x1000
-#define REV_A_DATA_MEMORY_END           0x2FFF
-#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
-
-#define REV_B_DATA_MEMORY_BEGIN         0x1000
-#define REV_B_DATA_MEMORY_END           0x2BFF
-#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
-
-
-#define NUM_UNITS_KERNEL_CODE          16
-#define NUM_UNITS_KERNEL_DATA           2
-
-#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
-#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
-
-/*
- * Kernel data layout
- */
-
-#define DP_SHIFT_COUNT                  7
-
-#define KDATA_BASE_ADDR                 0x1000
-#define KDATA_BASE_ADDR2                0x1080
-
-#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
-#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
-#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
-#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
-#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
-#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
-#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
-#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
-#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
-
-#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
-#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
-
-#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
-#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
-#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
-#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
-#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
-#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
-#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
-#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
-#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
-#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
-
-#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
-#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
-
-#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
-#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
-
-#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
-#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
-
-#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
-#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
-#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
-
-#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
-#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
-#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
-#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
-#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
-
-#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
-#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
-#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
-
-#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
-#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
-#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
-
-#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
-#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
-#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
-#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
-#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
-#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
-#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
-#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
-#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
-#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
-
-#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
-#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
-#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
-
-#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
-#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
-
-#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
-#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
-#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
-
-#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
-#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
-#define KDATA_ADC1_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x003D)
-#define KDATA_ADC1_RIGHT_VOLUME  		(KDATA_BASE_ADDR + 0x003E)
-#define KDATA_ADC1_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x003F)
-#define KDATA_ADC1_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0040)
-
-#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
-#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
-#define KDATA_ADC2_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0043)
-#define KDATA_ADC2_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x0044)
-#define KDATA_ADC2_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x0045)
-#define KDATA_ADC2_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0046)
-
-#define KDATA_CD_XFER0					(KDATA_BASE_ADDR + 0x0047)					
-#define KDATA_CD_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x0048)
-#define KDATA_CD_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0049)
-#define KDATA_CD_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x004A)
-#define KDATA_CD_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x004B)
-#define KDATA_CD_RIGHT_SUR_VOL			(KDATA_BASE_ADDR + 0x004C)
-
-#define KDATA_MIC_XFER0					(KDATA_BASE_ADDR + 0x004D)
-#define KDATA_MIC_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x004E)
-#define KDATA_MIC_VOLUME				(KDATA_BASE_ADDR + 0x004F)
-#define KDATA_MIC_SUR_VOL				(KDATA_BASE_ADDR + 0x0050)
-
-#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
-#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
-
-#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
-#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
-
-#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
-#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
-#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
-#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
-#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
-
-#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
-#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
-
-#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
-#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
-#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
-
-#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
-#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
-
-#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
-
-#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
-#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
-#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
-#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
-#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
-#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
-#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
-#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
-#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
-#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
-#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
-#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
-
-#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
-#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
-#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
-#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
-
-#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
-#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
-
-#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
-#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
-#define KDATA_CD_REQUEST				(KDATA_BASE_ADDR + 0x0076)
-#define KDATA_MIC_REQUEST				(KDATA_BASE_ADDR + 0x0077)
-
-#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
-#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
-#define KDATA_CD_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007A)
-#define KDATA_MIC_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007B)
-#define KDATA_MIC_SYNC_COUNTER			(KDATA_BASE_ADDR + 0x007C)
-
-/*
- * second 'segment' (?) reserved for mixer
- * buffers..
- */
-
-#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
-#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
-#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
-#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
-#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
-#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
-#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
-#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
-#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
-#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
-#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
-#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
-#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
-#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
-#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
-#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
-
-#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
-#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
-#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
-#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
-#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
-#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
-#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
-#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
-#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
-#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
-#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
-
-#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
-#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
-#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
-#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
-#define KDATA_DAC_LEFT_VOLUME	        (KDATA_BASE_ADDR2 + 0x001F)
-#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
-
-#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
-#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
-#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
-#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
-
-/*
- * client data area offsets
- */
-#define CDATA_INSTANCE_READY            0x00
-
-#define CDATA_HOST_SRC_ADDRL            0x01
-#define CDATA_HOST_SRC_ADDRH            0x02
-#define CDATA_HOST_SRC_END_PLUS_1L      0x03
-#define CDATA_HOST_SRC_END_PLUS_1H      0x04
-#define CDATA_HOST_SRC_CURRENTL         0x05
-#define CDATA_HOST_SRC_CURRENTH         0x06
-
-#define CDATA_IN_BUF_CONNECT            0x07
-#define CDATA_OUT_BUF_CONNECT           0x08
-
-#define CDATA_IN_BUF_BEGIN              0x09
-#define CDATA_IN_BUF_END_PLUS_1         0x0A
-#define CDATA_IN_BUF_HEAD               0x0B
-#define CDATA_IN_BUF_TAIL               0x0C
-#define CDATA_OUT_BUF_BEGIN             0x0D
-#define CDATA_OUT_BUF_END_PLUS_1        0x0E
-#define CDATA_OUT_BUF_HEAD              0x0F
-#define CDATA_OUT_BUF_TAIL              0x10
-
-#define CDATA_DMA_CONTROL               0x11
-#define CDATA_RESERVED                  0x12
-
-#define CDATA_FREQUENCY                 0x13
-#define CDATA_LEFT_VOLUME               0x14
-#define CDATA_RIGHT_VOLUME              0x15
-#define CDATA_LEFT_SUR_VOL              0x16
-#define CDATA_RIGHT_SUR_VOL             0x17
-
-#define CDATA_HEADER_LEN                0x18
-
-#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
-#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
-#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
-#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
-#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
-#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
-#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
-#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
-
-#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
-#define MINISRC_BIQUAD_STAGE    2
-#define MINISRC_COEF_LOC          0X175
-
-#define DMACONTROL_BLOCK_MASK           0x000F
-#define  DMAC_BLOCK0_SELECTOR           0x0000
-#define  DMAC_BLOCK1_SELECTOR           0x0001
-#define  DMAC_BLOCK2_SELECTOR           0x0002
-#define  DMAC_BLOCK3_SELECTOR           0x0003
-#define  DMAC_BLOCK4_SELECTOR           0x0004
-#define  DMAC_BLOCK5_SELECTOR           0x0005
-#define  DMAC_BLOCK6_SELECTOR           0x0006
-#define  DMAC_BLOCK7_SELECTOR           0x0007
-#define  DMAC_BLOCK8_SELECTOR           0x0008
-#define  DMAC_BLOCK9_SELECTOR           0x0009
-#define  DMAC_BLOCKA_SELECTOR           0x000A
-#define  DMAC_BLOCKB_SELECTOR           0x000B
-#define  DMAC_BLOCKC_SELECTOR           0x000C
-#define  DMAC_BLOCKD_SELECTOR           0x000D
-#define  DMAC_BLOCKE_SELECTOR           0x000E
-#define  DMAC_BLOCKF_SELECTOR           0x000F
-#define DMACONTROL_PAGE_MASK            0x00F0
-#define  DMAC_PAGE0_SELECTOR            0x0030
-#define  DMAC_PAGE1_SELECTOR            0x0020
-#define  DMAC_PAGE2_SELECTOR            0x0010
-#define  DMAC_PAGE3_SELECTOR            0x0000
-#define DMACONTROL_AUTOREPEAT           0x1000
-#define DMACONTROL_STOPPED              0x2000
-#define DMACONTROL_DIRECTION            0x0100
diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c
index 603fa21..587af38 100644
--- a/sys/dev/sound/pci/maestro3.c
+++ b/sys/dev/sound/pci/maestro3.c
@@ -60,8 +60,8 @@
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
-#include <dev/sound/pci/gnu/maestro3_reg.h>
-#include <dev/sound/pci/gnu/maestro3_dsp.h>
+#include <gnu/dev/sound/pci/maestro3_reg.h>
+#include <gnu/dev/sound/pci/maestro3_dsp.h>
 
 /* -------------------------------------------------------------------- */
 
diff --git a/sys/gnu/Makefile b/sys/gnu/Makefile
new file mode 100644
index 0000000..9cd3fec
--- /dev/null
+++ b/sys/gnu/Makefile
@@ -0,0 +1,3 @@
+SUBDIR=	vfs
+
+.include <bsd.subdir.mk>
diff --git a/sys/gnu/dev/sound/pci/csaimg.h b/sys/gnu/dev/sound/pci/csaimg.h
new file mode 100644
index 0000000..6d87f3a
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/csaimg.h
@@ -0,0 +1,341 @@
+/*-
+ ****************************************************************************
+ * "CWCIMAGE.H"-- For CS46XX. Ver 1.04
+ *      Copyright 1998-2001 (c) Cirrus Logic Corp.
+ *      Version 1.04
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ * $FreeBSD: src/sys/gnu/dev/sound/pci/csaimg.h,v 1.2 2005/01/06 18:27:30 imp Exp $
+ *
+ ***************************************************************************/
+
+#ifndef __CS_IMAGE_H
+#define __CS_IMAGE_H
+
+#define CLEAR__COUNT     3
+#define FILL__COUNT      4
+#define BA1__DWORD_SIZE  13*1024+512
+
+static struct
+{
+        unsigned BA1__DestByteOffset;
+        unsigned BA1__SourceSize;
+} ClrStat[CLEAR__COUNT] ={ {0x00000000, 0x00003000 },
+                           {0x00010000, 0x00003800 },
+                           {0x00020000, 0x00007000 } };
+
+static u_int32_t FillArray1[]={
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000163,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00200040,0x00008010,0x00000000,
+0x00000000,0x80000001,0x00000001,0x00060000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00900080,0x00000173,0x00000000,
+0x00000000,0x00000010,0x00800000,0x00900000,
+0xf2c0000f,0x00000200,0x00000000,0x00010600,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000163,0x330300c2,
+0x06000000,0x00000000,0x80008000,0x80008000,
+0x3fc0000f,0x00000301,0x00010400,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00b00000,0x00d0806d,0x330480c3,
+0x04800000,0x00000001,0x00800001,0x0000ffff,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x066a0600,0x06350070,0x0000929d,0x929d929d,
+0x00000000,0x0000735a,0x00000600,0x00000000,
+0x929d735a,0x00000000,0x00010000,0x735a735a,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000804f,0x000000c3,
+0x05000000,0x00a00010,0x00000000,0x80008000,
+0x00000000,0x00000000,0x00000700,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000080,0x00a00000,0x0000809a,0x000000c2,
+0x07400000,0x00000000,0x80008000,0xffffffff,
+0x00c80028,0x00005555,0x00000000,0x000107a0,
+0x00c80028,0x000000c2,0x06800000,0x00000000,
+0x06e00080,0x00300000,0x000080bb,0x000000c9,
+0x07a00000,0x04000000,0x80008000,0xffffffff,
+0x00c80028,0x00005555,0x00000000,0x00000780,
+0x00c80028,0x000000c5,0xff800000,0x00000000,
+0x00640080,0x00c00000,0x00008197,0x000000c9,
+0x07800000,0x04000000,0x80008000,0xffffffff,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000805e,0x000000c1,
+0x00000000,0x00800000,0x80008000,0x80008000,
+0x00020000,0x0000ffff,0x00000000,0x00000000};
+
+static u_int32_t FillArray2[]={
+0x929d0600,0x929d929d,0x929d929d,0x929d0000,
+0x929d929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x00100635,0x060b013f,0x00000004,
+0x00000001,0x007a0002,0x00000000,0x066e0610,
+0x0105929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
+0x00000000,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0x00000000,0x06400136,
+0x0000270f,0x00010000,0x007a0000,0x00000000,
+0x068e0645,0x0105929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0x735a0100,0x00000000,0x00000000,0x00000000};
+
+static u_int32_t FillArray3[]={
+0x00000000,0x00000000,0x00000000,0x00010004};
+
+static u_int32_t FillArray4[]={
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00001705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00009705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00011705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00019705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00021705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00029705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00031705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00039705,0x00001400,0x000a411e,0x00001003,
+0x000fe19e,0x00001003,0x0009c730,0x00001003,
+0x0008e19c,0x00001003,0x000083c1,0x00093040,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00009705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00011705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00019705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00021705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00029705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00031705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00039705,0x00001400,0x000a211e,0x00001003,
+0x0000a730,0x00001008,0x000e2730,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x00000000,0x00000000,0x000f619c,0x00001003,
+0x0007f801,0x000c0000,0x00000037,0x00001000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x000c0000,0x00000000,0x00000000,
+0x0000373c,0x00001000,0x00000000,0x00000000,
+0x000ee19c,0x00001003,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000273c,0x00001000,
+0x00000033,0x00001000,0x000e679e,0x00001003,
+0x00007705,0x00001400,0x000ac71e,0x00001003,
+0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000a730,0x00001003,
+0x00000033,0x00001000,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x000c0000,
+0x00000032,0x00001000,0x0000273d,0x00001000,
+0x0004a730,0x00001003,0x00000f41,0x00097140,
+0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
+0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
+0x00000000,0x00000000,0x0001bf05,0x0003fc40,
+0x00002725,0x000aa400,0x00013705,0x00093a00,
+0x0000002e,0x0009d6c0,0x00038630,0x00001004,
+0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
+0x00000000,0x000c70e0,0x0007d182,0x0002c640,
+0x00000630,0x00001004,0x000799b8,0x0002c6c0,
+0x00031705,0x00092240,0x00039f05,0x000932c0,
+0x0003520a,0x00000000,0x00040731,0x0000100b,
+0x00010705,0x000b20c0,0x00000000,0x000eba44,
+0x00032108,0x000c60c4,0x00065208,0x000c2917,
+0x000406b0,0x00001007,0x00012f05,0x00036880,
+0x0002818e,0x000c0000,0x0004410a,0x00000000,
+0x00040630,0x00001007,0x00029705,0x000c0000,
+0x00000000,0x00000000,0x00003fc1,0x0003fc40,
+0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
+0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
+0x000037c1,0x00000000,0x00003fc1,0x000991c0,
+0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
+0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
+0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
+0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
+0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
+0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
+0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
+0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
+0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
+0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
+0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
+0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
+0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
+0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
+0x000683ad,0x00095241,0x00020f05,0x000991c1,
+0x00000000,0x00000000,0x00086f88,0x00001000,
+0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
+0x0009de81,0x000bd300,0x0009d601,0x000b1700,
+0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
+0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
+0x000a1681,0x000b97c0,0x00021601,0x00002500,
+0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
+0x00021681,0x00002d00,0x00020f81,0x000bd800,
+0x000a0701,0x000b5bc0,0x00021601,0x00003500,
+0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
+0x00021681,0x00003d00,0x00020f81,0x000b1d00,
+0x000a0701,0x000b1fc0,0x00021601,0x00020500,
+0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
+0x00021681,0x00020d00,0x00020f81,0x000bde80,
+0x000a0701,0x000bdfc0,0x00021601,0x00021500,
+0x00020f81,0x000b9341,0x00020701,0x000b53c1,
+0x00021681,0x00021d00,0x000a0f81,0x000d0380,
+0x0000b601,0x000b15c0,0x00007b01,0x00000000,
+0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
+0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
+0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
+0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
+0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
+0x0007e48a,0x00000000,0x00011f05,0x00084080,
+0x00000000,0x00000000,0x00001705,0x000b3540,
+0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
+0x00055488,0x00000000,0x0000d482,0x0003fc40,
+0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
+0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
+0x000c86b0,0x00001007,0x00008281,0x000bb240,
+0x0000b801,0x000b7140,0x00007888,0x00000000,
+0x0000073c,0x00001000,0x0007f188,0x000c0000,
+0x00000000,0x00000000,0x00055288,0x000c555c,
+0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
+0x0000fa88,0x00000000,0x00000032,0x00001000,
+0x0000073d,0x00001000,0x0007f188,0x000c0000,
+0x00000000,0x00000000,0x0008c01c,0x00001003,
+0x00002705,0x00001008,0x0008b201,0x000c1392,
+0x0000ba01,0x00000000,0x00008731,0x00001400,
+0x0004c108,0x000fe0c4,0x00057488,0x00000000,
+0x000a6388,0x00001001,0x0008b334,0x000bc141,
+0x0003020e,0x00000000,0x000886b0,0x00001008,
+0x00003625,0x000c5dfa,0x000a638a,0x00001001,
+0x0008020e,0x00001002,0x0008a6b0,0x00001008,
+0x0007f301,0x00000000,0x00000000,0x00000000,
+0x00002725,0x000a8c40,0x000000ae,0x00000000,
+0x000d8630,0x00001008,0x00000000,0x000c74e0,
+0x0007d182,0x0002d640,0x000a8630,0x00001008,
+0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
+0x0007420a,0x000c0000,0x00062208,0x000c4117,
+0x00070630,0x00001009,0x00000000,0x000c0000,
+0x0001022e,0x00000000,0x0003a630,0x00001009,
+0x00000000,0x000c0000,0x00000036,0x00001000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x0002a730,0x00001008,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0002a730,0x00001008,
+0x00000033,0x00001000,0x0002a705,0x00001008,
+0x00007a01,0x000c0000,0x000e6288,0x000d550a,
+0x0006428a,0x00000000,0x00060730,0x0000100a,
+0x00000000,0x000c0000,0x00000000,0x00000000,
+0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
+0x00057488,0x00000000,0x00033b94,0x00081140,
+0x000183ae,0x00000000,0x000786b0,0x0000100b,
+0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
+0x00042731,0x00001003,0x0007aab0,0x00034880,
+0x00048fb0,0x0000100a,0x00057488,0x00000000,
+0x00033b94,0x00081140,0x000183ae,0x00000000,
+0x000806b0,0x0000100b,0x00022f05,0x00000000,
+0x00007401,0x00091140,0x00048f05,0x000951c0,
+0x00042731,0x00001003,0x0000473d,0x00001000,
+0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
+0x000fe19e,0x00001003,0x00000000,0x00000000,
+0x0008e19c,0x00001003,0x000083c1,0x00093040,
+0x00000f41,0x00097140,0x0000a841,0x0009b240,
+0x0000a0c1,0x0009f040,0x0001c641,0x00093540,
+0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
+0x00055208,0x00000000,0x00010705,0x000a2880,
+0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
+0x0004ef0a,0x000c0000,0x00012f05,0x00036880,
+0x00065308,0x000c2997,0x000d86b0,0x0000100a,
+0x0004410a,0x000d40c7,0x00000000,0x00000000,
+0x00080730,0x00001004,0x00056f0a,0x000ea105,
+0x00000000,0x00000000,0x0000473d,0x00001000,
+0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
+0x0000273d,0x00001000,0x00000000,0x000eba44,
+0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
+0x00000734,0x00001000,0x00010705,0x000a6880,
+0x00006a88,0x000c75c4,0x00000000,0x000e5084,
+0x00000000,0x000eba44,0x00087401,0x000e4782,
+0x00000734,0x00001000,0x00010705,0x000a6880,
+0x00006a88,0x000c75c4,0x0007c108,0x000c0000,
+0x0007e721,0x000bed40,0x00005f25,0x000badc0,
+0x0003ba97,0x000beb80,0x00065590,0x000b2e00,
+0x00033217,0x00003ec0,0x00065590,0x000b8e40,
+0x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
+0x000283a0,0x0000100c,0x000ee388,0x00042970,
+0x00008301,0x00021ef2,0x000b8f14,0x0000000f,
+0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
+0x000032ac,0x000c3916,0x0004edc2,0x00074c80,
+0x00078898,0x00001000,0x00038894,0x00000032,
+0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
+0x0004edc2,0x000c1956,0x0000722c,0x00034a00,
+0x00041705,0x0009ed40,0x00058730,0x00001400,
+0x000d7488,0x000c3a00,0x00048f05,0x00000000};
+
+static struct
+{   u_int32_t Offset;
+    u_int32_t Size;
+    u_int32_t *pFill;
+} FillStat[FILL__COUNT] = {
+                            {0x00000000, sizeof(FillArray1), FillArray1},
+                            {0x00001800, sizeof(FillArray2), FillArray2},
+                            {0x000137f0, sizeof(FillArray3), FillArray3},
+                            {0x00020000, sizeof(FillArray4), FillArray4}
+                          };
+
+
+#endif
diff --git a/sys/gnu/dev/sound/pci/emu10k1-ac97.h b/sys/gnu/dev/sound/pci/emu10k1-ac97.h
new file mode 100644
index 0000000..3cf3c84
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/emu10k1-ac97.h
@@ -0,0 +1,293 @@
+/* $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1-ac97.h,v 1.2 2004/01/09 05:08:32 obrien Exp $ */
+
+#ifndef _AC97_CODEC_H_
+#define _AC97_CODEC_H_
+
+#ifdef __linux__
+#include <linux/types.h>
+#include <linux/soundcard.h>
+#endif
+
+/* AC97 1.0 */
+#define  AC97_RESET               0x0000      //
+#define  AC97_MASTER_VOL_STEREO   0x0002      // Line Out
+#define  AC97_HEADPHONE_VOL       0x0004      //
+#define  AC97_MASTER_VOL_MONO     0x0006      // TAD Output
+#define  AC97_MASTER_TONE         0x0008      //
+#define  AC97_PCBEEP_VOL          0x000a      // none
+#define  AC97_PHONE_VOL           0x000c      // TAD Input (mono)
+#define  AC97_MIC_VOL             0x000e      // MIC Input (mono)
+#define  AC97_LINEIN_VOL          0x0010      // Line Input (stereo)
+#define  AC97_CD_VOL              0x0012      // CD Input (stereo)
+#define  AC97_VIDEO_VOL           0x0014      // none
+#define  AC97_AUX_VOL             0x0016      // Aux Input (stereo)
+#define  AC97_PCMOUT_VOL          0x0018      // Wave Output (stereo)
+#define  AC97_RECORD_SELECT       0x001a      //
+#define  AC97_RECORD_GAIN         0x001c
+#define  AC97_RECORD_GAIN_MIC     0x001e
+#define  AC97_GENERAL_PURPOSE     0x0020
+#define  AC97_3D_CONTROL          0x0022
+#define  AC97_MODEM_RATE          0x0024
+#define  AC97_POWER_CONTROL       0x0026
+
+/* AC'97 2.0 */
+#define AC97_EXTENDED_ID          0x0028       /* Extended Audio ID */
+#define AC97_EXTENDED_STATUS      0x002A       /* Extended Audio Status */
+#define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
+#define AC97_RESERVED_3A          0x003A       /* Reserved in AC '97 < 2.2 */
+
+/* AC'97 2.2 */
+#define AC97_SPDIF_CONTROL        0x003A       /* S/PDIF Control */
+
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MODEM_ID    0x003C
+#define AC97_EXTEND_MODEM_STAT    0x003E
+#define AC97_LINE1_RATE           0x0040
+#define AC97_LINE2_RATE           0x0042
+#define AC97_HANDSET_RATE         0x0044
+#define AC97_LINE1_LEVEL          0x0046
+#define AC97_LINE2_LEVEL          0x0048
+#define AC97_HANDSET_LEVEL        0x004A
+#define AC97_GPIO_CONFIG          0x004C
+#define AC97_GPIO_POLARITY        0x004E
+#define AC97_GPIO_STICKY          0x0050
+#define AC97_GPIO_WAKE_UP         0x0052
+#define AC97_GPIO_STATUS          0x0054
+#define AC97_MISC_MODEM_STAT      0x0056
+#define AC97_RESERVED_58          0x0058
+
+/* registers 0x005a - 0x007a are vendor reserved */
+
+#define AC97_VENDOR_ID1           0x007c
+#define AC97_VENDOR_ID2           0x007e
+
+/* volume control bit defines */
+#ifndef	AC97_MUTE
+#define AC97_MUTE                 0x8000
+#endif
+#define AC97_MICBOOST             0x0040
+#define AC97_LEFTVOL              0x3f00
+#define AC97_RIGHTVOL             0x003f
+
+/* record mux defines */
+#define AC97_RECMUX_MIC           0x0000
+#define AC97_RECMUX_CD            0x0101
+#define AC97_RECMUX_VIDEO         0x0202
+#define AC97_RECMUX_AUX           0x0303
+#define AC97_RECMUX_LINE          0x0404
+#define AC97_RECMUX_STEREO_MIX    0x0505
+#define AC97_RECMUX_MONO_MIX      0x0606
+#define AC97_RECMUX_PHONE         0x0707
+
+/* general purpose register bit defines */
+#define AC97_GP_LPBK              0x0080       /* Loopback mode */
+#define AC97_GP_MS                0x0100       /* Mic Select 0=Mic1, 1=Mic2 */
+#define AC97_GP_MIX               0x0200       /* Mono output select 0=Mix, 1=Mic */
+#define AC97_GP_RLBK              0x0400       /* Remote Loopback - Modem line codec */
+#define AC97_GP_LLBK              0x0800       /* Local Loopback - Modem Line codec */
+#define AC97_GP_LD                0x1000       /* Loudness 1=on */
+#define AC97_GP_3D                0x2000       /* 3D Enhancement 1=on */
+#define AC97_GP_ST                0x4000       /* Stereo Enhancement 1=on */
+#define AC97_GP_POP               0x8000       /* Pcm Out Path, 0=pre 3D, 1=post 3D */
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA               0x0001       /* Variable bit rate enable bit */
+#define AC97_EA_DRA               0x0002       /* Double-rate audio enable bit */
+#define AC97_EA_SPDIF             0x0004       /* S/PDIF Enable bit */
+#define AC97_EA_VRM               0x0008       /* Variable bit rate for MIC enable bit */
+#define AC97_EA_CDAC              0x0040       /* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC              0x0040       /* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC              0x0080       /* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC              0x0100       /* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV              0x0400       /* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI               0x0800       /* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ               0x1000       /* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK               0x2000       /* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL               0x4000       /* Turns the MIC ADC off */
+#define AC97_EA_SLOT_MASK         0xffcf       /* Mask for slot assignment bits */
+#define AC97_EA_SPSA_3_4          0x0000       /* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8          0x0010       /* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9          0x0020       /* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11        0x0030       /* Slot assigned to 10 & 11 */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO               0x0001       /* Professional status */
+#define AC97_SC_NAUDIO            0x0002       /* Non audio stream */
+#define AC97_SC_COPY              0x0004       /* Copyright status */
+#define AC97_SC_PRE               0x0008       /* Preemphasis status */
+#define AC97_SC_CC_MASK           0x07f0       /* Category Code mask */
+#define AC97_SC_L                 0x0800       /* Generation Level status */
+#define AC97_SC_SPSR_MASK         0xcfff       /* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_44K          0x0000       /* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K          0x2000       /* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K          0x3000       /* Use 32kHz Sample rate */
+#define AC97_SC_DRS               0x4000       /* Double Rate S/PDIF */
+#define AC97_SC_V                 0x8000       /* Validity status */
+
+/* powerdown control and status bit defines */
+
+/* status */
+#define AC97_PWR_MDM              0x0010       /* Modem section ready */
+#define AC97_PWR_REF              0x0008       /* Vref nominal */
+#define AC97_PWR_ANL              0x0004       /* Analog section ready */
+#define AC97_PWR_DAC              0x0002       /* DAC section ready */
+#define AC97_PWR_ADC              0x0001       /* ADC section ready */
+
+/* control */
+#define AC97_PWR_PR0              0x0100       /* ADC and Mux powerdown */
+#define AC97_PWR_PR1              0x0200       /* DAC powerdown */
+#define AC97_PWR_PR2              0x0400       /* Output mixer powerdown (Vref on) */
+#define AC97_PWR_PR3              0x0800       /* Output mixer powerdown (Vref off) */
+#define AC97_PWR_PR4              0x1000       /* AC-link powerdown */
+#define AC97_PWR_PR5              0x2000       /* Internal Clk disable */
+#define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
+#define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
+
+/* extended audio ID register bit defines */
+#define AC97_EXTID_VRA            0x0001
+#define AC97_EXTID_DRA            0x0002
+#define AC97_EXTID_SPDIF          0x0004
+#define AC97_EXTID_VRM            0x0008
+#define AC97_EXTID_DSA0           0x0010
+#define AC97_EXTID_DSA1           0x0020
+#define AC97_EXTID_CDAC           0x0040
+#define AC97_EXTID_SDAC           0x0080
+#define AC97_EXTID_LDAC           0x0100
+#define AC97_EXTID_AMAP           0x0200
+#define AC97_EXTID_REV0           0x0400
+#define AC97_EXTID_REV1           0x0800
+#define AC97_EXTID_ID0            0x4000
+#define AC97_EXTID_ID1            0x8000
+
+/* extended status register bit defines */
+#define AC97_EXTSTAT_VRA          0x0001
+#define AC97_EXTSTAT_DRA          0x0002
+#define AC97_EXTSTAT_SPDIF        0x0004
+#define AC97_EXTSTAT_VRM          0x0008
+#define AC97_EXTSTAT_SPSA0        0x0010
+#define AC97_EXTSTAT_SPSA1        0x0020
+#define AC97_EXTSTAT_CDAC         0x0040
+#define AC97_EXTSTAT_SDAC         0x0080
+#define AC97_EXTSTAT_LDAC         0x0100
+#define AC97_EXTSTAT_MADC         0x0200
+#define AC97_EXTSTAT_SPCV         0x0400
+#define AC97_EXTSTAT_PRI          0x0800
+#define AC97_EXTSTAT_PRJ          0x1000
+#define AC97_EXTSTAT_PRK          0x2000
+#define AC97_EXTSTAT_PRL          0x4000
+
+/* useful power states */
+#define AC97_PWR_D0               0x0000      /* everything on */
+#define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
+#define AC97_PWR_D2              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
+#define AC97_PWR_D3              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4
+#define AC97_PWR_ANLOFF          AC97_PWR_PR2|AC97_PWR_PR3  /* analog section off */
+
+/* Total number of defined registers.  */
+#define AC97_REG_CNT 64
+
+
+/* OSS interface to the ac97s.. */
+#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\
+	SOUND_MASK_LINE|SOUND_MASK_CD|\
+	SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\
+	SOUND_MASK_LINE1|SOUND_MASK_VIDEO)
+
+#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
+	SOUND_MASK_BASS|SOUND_MASK_TREBLE|\
+	SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\
+	SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT)
+
+#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
+	SOUND_MASK_CD|SOUND_MASK_IGAIN|SOUND_MASK_VIDEO|\
+	SOUND_MASK_LINE1| SOUND_MASK_LINE|\
+	SOUND_MASK_PHONEIN)
+
+/* original check is not good enough in case FOO is greater than
+ * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
+ * SOUND_MIXER_NRDEVICES elements.
+ * before matching the given mixer against the bitmask in supported_mixers we
+ * check if mixer number exceeds maximum allowed size which is as mentioned
+ * above SOUND_MIXER_NRDEVICES */
+#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \
+                                    (FOO < SOUND_MIXER_NRDEVICES) && \
+                                    (CODEC)->supported_mixers & (1<<FOO) )
+
+#ifdef __linux__
+struct ac97_codec {
+	/* AC97 controller connected with */
+	void *private_data;
+
+	char *name;
+	int id;
+	int dev_mixer;
+	int type;
+
+	int modem:1;
+
+	struct ac97_ops *codec_ops;
+
+	/* controller specific lower leverl ac97 accessing routines */
+	u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
+	void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
+
+	/* Wait for codec-ready.  Ok to sleep here.  */
+	void  (*codec_wait)  (struct ac97_codec *codec);
+
+	/* OSS mixer masks */
+	int modcnt;
+	int supported_mixers;
+	int stereo_mixers;
+	int record_sources;
+
+	/* Property flags */
+	int flags;
+
+	int bit_resolution;
+
+	/* OSS mixer interface */
+	int  (*read_mixer) (struct ac97_codec *codec, int oss_channel);
+	void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
+			    unsigned int left, unsigned int right);
+	int  (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
+	int  (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
+
+	/* saved OSS mixer states */
+	unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
+
+	/* Software Modem interface */
+	int  (*modem_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long arg);
+};
+
+/*
+ *	Operation structures for each known AC97 chip
+ */
+
+struct ac97_ops
+{
+	/* Initialise */
+	int (*init)(struct ac97_codec *c);
+	/* Amplifier control */
+	int (*amplifier)(struct ac97_codec *codec, int on);
+	/* Digital mode control */
+	int (*digital)(struct ac97_codec *codec, int format);
+#define AC97_DELUDED_MODEM	1	/* Audio codec reports its a modem */
+#define AC97_NO_PCM_VOLUME	2	/* Volume control is missing 	   */
+};
+
+extern int ac97_read_proc (char *page_out, char **start, off_t off,
+			   int count, int *eof, void *data);
+extern int ac97_probe_codec(struct ac97_codec *);
+extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
+extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
+extern int ac97_save_state(struct ac97_codec *codec);
+extern int ac97_restore_state(struct ac97_codec *codec);
+#endif	/*__linux__*/
+
+#endif /* _AC97_CODEC_H_ */
diff --git a/sys/gnu/dev/sound/pci/emu10k1-alsa.h b/sys/gnu/dev/sound/pci/emu10k1-alsa.h
new file mode 100644
index 0000000..79f3afc
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/emu10k1-alsa.h
@@ -0,0 +1,1374 @@
+#ifndef __SOUND_EMU10K1_H
+#define __SOUND_EMU10K1_H
+
+/*-
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ *		     Creative Labs, Inc.
+ *  Definitions for EMU10K1 (SB Live!) chips
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/* $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1-alsa.h,v 1.2 2005/01/06 18:26:37 imp Exp $ */
+
+#include <sys/ioccom.h>
+
+#ifdef __KERNEL__
+
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/hwdep.h>
+#include <sound/ac97_codec.h>
+#include <sound/util_mem.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#ifndef PCI_VENDOR_ID_CREATIVE
+#define PCI_VENDOR_ID_CREATIVE		0x1102
+#endif
+#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1	0x0002
+#endif
+
+/* ------------------- DEFINES -------------------- */
+
+#define EMUPAGESIZE     4096
+#define MAXREQVOICES    8
+#define MAXPAGES        8192
+#define RESERVED        0
+#define NUM_MIDI        16
+#define NUM_G           64              /* use all channels */
+#define NUM_FXSENDS     4
+
+#define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
+#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit */
+
+#define TMEMSIZE        256*1024
+#define TMEMSIZEREG     4
+
+#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
+
+// Audigy specify registers are prefixed with 'A_'
+
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
+						/* channel number of the register to be		*/
+						/* accessed.  For non per-channel registers the	*/
+						/* value should be set to zero.			*/
+#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
+#define A_PTR_ADDRESS_MASK	0x0fff0000
+
+#define DATA			0x04		/* Indexed register set data register		*/
+
+#define IPR			0x08		/* Global interrupt pending register		*/
+						/* Clear pending interrupts by writing a 1 to	*/
+						/* the relevant bits and zero to the other bits	*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define IPR_A_MIDITRANSBUFEMPTY2 0x10000000	/* MIDI UART transmit buffer empty		*/
+#define IPR_A_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
+
+#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
+#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
+#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
+#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
+#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
+#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
+#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
+#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
+#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
+#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
+#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
+#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
+#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
+#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
+#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
+#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
+#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
+#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
+#define IPR_CHANNELLOOP		0x00000040	/* One or more channel loop interrupts pending	*/
+#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
+						/* Highest set channel in CLIPL or CLIPH.  When	*/
+						/* IP is written with CL set, the bit in CLIPL	*/
+						/* or CLIPH corresponding to the CIN value 	*/
+						/* written will be cleared.			*/
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
+#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
+#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
+#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
+#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
+#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
+#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
+#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
+#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
+#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
+#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
+#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
+#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
+#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
+#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
+#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
+#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
+#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
+
+#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
+						/* NOTE: There is no reason to use this under	*/
+						/* Linux, and it will cause odd hardware 	*/
+						/* behavior and possibly random segfaults and	*/
+						/* lockups if enabled.				*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define INTE_A_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_A_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+
+#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
+						/* NOTE: This bit must always be enabled       	*/
+#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
+#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
+#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
+#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
+#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
+#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
+#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
+#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
+#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
+#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
+#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
+#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+#define WC			0x10		/* Wall Clock register				*/
+#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
+#define WC_SAMPLECOUNTER	0x14060010
+#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
+						/* NOTE: Each channel takes 1/64th of a sample	*/
+						/* period to be serviced.			*/
+
+#define HCFG			0x14		/* Hardware config register			*/
+						/* NOTE: There is no reason to use the legacy	*/
+						/* SoundBlaster emulation stuff described below	*/
+						/* under Linux, and all kinds of weird hardware	*/
+						/* behavior can result if you try.  Don't.	*/
+#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
+#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
+#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
+#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
+#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
+#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
+#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
+#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
+#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
+#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
+#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
+#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
+						/* NOTE: The rest of the bits in this register	*/
+						/* _are_ relevant under Linux.			*/
+#define HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format					*/
+#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
+#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
+#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
+#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
+#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
+#define HCFG_GPOUT0		0x00001000	/* External pin? (spdif enable on 5.1)		*/
+#define HCFG_GPOUT1		0x00000800	/* External pin? (IR)				*/
+#define HCFG_GPOUT2		0x00000400	/* External pin? (IR)				*/
+#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
+#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
+						/* 1 = Force all 3 async digital inputs to use	*/
+						/* the same async sample rate tracker (ZVIDEO)	*/
+#define HCFG_AC3ENABLE_MASK	0x000000e0	/* AC3 async input control - Not implemented	*/
+#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
+#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
+#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF             */
+#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* they are not rate-locked to the external	*/
+						/* async audio source  				*/
+#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE	0x01020014
+#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
+						/* NOTE: This is a 'cheap' way to implement a	*/
+						/* master mute function on the mute button, and	*/
+						/* in general should not be used unless a more	*/
+						/* sophisticated master mute function has not	*/
+						/* been written.       				*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+
+//For Audigy, MPU port move to 0x70-0x74 ptr register
+
+#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
+
+#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
+#define MUCMD_RESET		0xff		/* RESET command				*/
+#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
+						/* NOTE: All other commands are ignored		*/
+
+#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
+#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
+#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
+
+#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
+#define A_GPINPUT_MASK		0xff00
+#define A_GPOUTPUT_MASK		0x00ff
+#define A_IOCFG_GPOUT0		0x0044		/* analog/digital? */
+#define A_IOCFG_GPOUT1		0x0002		/* IR */
+#define A_IOCFG_GPOUT2		0x0001		/* IR */
+
+#define TIMER			0x1a		/* Timer terminal count register		*/
+						/* NOTE: After the rate is changed, a maximum	*/
+						/* of 1024 sample periods should be allowed	*/
+						/* before the new rate is guaranteed accurate.	*/
+#define TIMER_RATE_MASK		0x000003ff	/* Timer interrupt rate in sample periods	*/
+						/* 0 == 1024 periods, [1..4] are not useful	*/
+#define TIMER_RATE		0x0a00001a
+
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
+#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
+
+/************************************************************************************************/
+/* PCI function 1 registers, address = <val> + PCIBASE1						*/
+/************************************************************************************************/
+
+#define JOYSTICK1		0x00		/* Analog joystick port register		*/
+#define JOYSTICK2		0x01		/* Analog joystick port register		*/
+#define JOYSTICK3		0x02		/* Analog joystick port register		*/
+#define JOYSTICK4		0x03		/* Analog joystick port register		*/
+#define JOYSTICK5		0x04		/* Analog joystick port register		*/
+#define JOYSTICK6		0x05		/* Analog joystick port register		*/
+#define JOYSTICK7		0x06		/* Analog joystick port register		*/
+#define JOYSTICK8		0x07		/* Analog joystick port register		*/
+
+/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on write.	*/
+/* When reading, use these bitfields: */
+#define JOYSTICK_BUTTONS	0x0f		/* Joystick button data				*/
+#define JOYSTICK_COMPARATOR	0xf0		/* Joystick comparator data			*/
+
+
+/********************************************************************************************************/
+/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
+/********************************************************************************************************/
+
+#define CPF			0x00		/* Current pitch and fraction register			*/
+#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
+#define CPF_CURRENTPITCH	0x10100000
+#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
+#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
+#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
+
+#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
+#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
+#define PTRX_PITCHTARGET	0x10100001
+#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
+#define PTRX_FXSENDAMOUNT_A	0x08080001
+#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
+#define PTRX_FXSENDAMOUNT_B	0x08000001
+
+#define CVCF			0x02		/* Current volume and filter cutoff register		*/
+#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
+#define CVCF_CURRENTVOL		0x10100002
+#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
+#define CVCF_CURRENTFILTER	0x10000002
+
+#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
+#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
+#define VTFT_VOLUMETARGET	0x10100003
+#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
+#define VTFT_FILTERTARGET	0x10000003
+
+#define Z1			0x05		/* Filter delay memory 1 register			*/
+
+#define Z2			0x04		/* Filter delay memory 2 register			*/
+
+#define PSST			0x06		/* Send C amount and loop start address register	*/
+#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
+
+#define PSST_FXSENDAMOUNT_C	0x08180006
+
+#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
+#define PSST_LOOPSTARTADDR	0x18000006
+
+#define DSL			0x07		/* Send D amount and loop start address register	*/
+#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
+
+#define DSL_FXSENDAMOUNT_D	0x08180007
+
+#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
+#define DSL_LOOPENDADDR		0x18000007
+
+#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
+#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
+#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
+						/* 1 == full band, 7 == lowpass				*/
+						/* ROM 0 is used when pitch shifting downward or less	*/
+						/* then 3 semitones upward.  Increasingly higher ROM	*/
+						/* numbers are used, typically in steps of 3 semitones,	*/
+						/* as upward pitch shifting is performed.		*/
+#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
+#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
+#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
+#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
+#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
+#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
+#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
+#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
+#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
+#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
+#define CCCA_CURRADDR		0x18000008
+
+#define CCR			0x09		/* Cache control register				*/
+#define CCR_CACHEINVALIDSIZE	0x07190009
+#define CCR_CACHEINVALIDSIZE_MASK	0xfe000000	/* Number of invalid samples cache for this channel    	*/
+#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
+#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
+#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
+#define CCR_READADDRESS		0x06100009
+#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
+#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
+						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
+#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
+#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
+
+#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
+						/* NOTE: This register is normally not used		*/
+#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
+
+#define FXRT			0x0b		/* Effects send routing register			*/
+						/* NOTE: It is illegal to assign the same routing to	*/
+						/* two effects sends.					*/
+#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
+#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
+#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
+#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
+
+#define MAPA			0x0c		/* Cache map A						*/
+
+#define MAPB			0x0d		/* Cache map B						*/
+
+#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+
+#define ENVVOL			0x10		/* Volume envelope register				*/
+#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/
+						/* 0x8000-n == 666*n usec delay	       			*/
+
+#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
+#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
+#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
+
+#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
+#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
+						/* this channel and from writing to pitch, filter and	*/
+						/* volume targets.					*/
+#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL1 		0x13		/* Modulation LFO value					*/
+#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ENVVAL			0x14		/* Modulation envelope register				*/
+#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
+#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
+#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
+
+#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
+#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
+#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define IP			0x18		/* Initial pitch register				*/
+#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
+						/* 4 bits of octave, 12 bits of fractional octave	*/
+#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
+
+#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
+#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
+						/* 6 most significant bits are semitones		*/
+						/* 2 least significant bits are fractions		*/
+#define IFATN_FILTERCUTOFF	0x08080019
+#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
+#define IFATN_ATTENUATION	0x08000019
+
+
+#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
+#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
+						/* Signed 2's complement, +/- one octave peak extremes	*/
+#define PEFE_PITCHAMOUNT	0x0808001a
+#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
+						/* Signed 2's complement, +/- six octaves peak extremes */
+#define PEFE_FILTERAMOUNT	0x0800001a
+#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
+#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
+						/* Signed 2's complement, +/- three octave extremes	*/
+
+
+#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
+#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
+						/* Signed 2's complement, with +/- 12dB extremes	*/
+
+#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
+						/* ??Hz steps, maximum of ?? Hz.			*/
+#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
+#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
+						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
+
+#define TEMPENV 		0x1e		/* Tempory envelope register				*/
+#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
+						/* NOTE: All channels contain internal variables; do	*/
+						/* not write to these locations.			*/
+
+#define CD0			0x20		/* Cache data 0 register				*/
+#define CD1			0x21		/* Cache data 1 register				*/
+#define CD2			0x22		/* Cache data 2 register				*/
+#define CD3			0x23		/* Cache data 3 register				*/
+#define CD4			0x24		/* Cache data 4 register				*/
+#define CD5			0x25		/* Cache data 5 register				*/
+#define CD6			0x26		/* Cache data 6 register				*/
+#define CD7			0x27		/* Cache data 7 register				*/
+#define CD8			0x28		/* Cache data 8 register				*/
+#define CD9			0x29		/* Cache data 9 register				*/
+#define CDA			0x2a		/* Cache data A register				*/
+#define CDB			0x2b		/* Cache data B register				*/
+#define CDC			0x2c		/* Cache data C register				*/
+#define CDD			0x2d		/* Cache data D register				*/
+#define CDE			0x2e		/* Cache data E register				*/
+#define CDF			0x2f		/* Cache data F register				*/
+
+#define PTB			0x40		/* Page table base register				*/
+#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
+
+#define TCB			0x41		/* Tank cache base register    				*/
+#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
+
+#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
+#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
+#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
+						/* NOTE: To guarantee phase coherency, both channels	*/
+						/* must be disabled prior to enabling both channels.	*/
+#define A_ADCCR_RCHANENABLE	0x00000020
+#define A_ADCCR_LCHANENABLE	0x00000010
+
+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
+#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
+#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
+#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
+#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
+#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
+#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
+#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
+#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
+#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
+#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
+#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
+#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
+
+#define FXWC			0x43		/* FX output write channels register			*/
+						/* When set, each bit enables the writing of the	*/
+						/* corresponding FX output channel into host memory	*/
+#define FXWC_DEFAULTROUTE_C     (1<<0)		/* left emu out? */
+#define FXWC_DEFAULTROUTE_B     (1<<1)		/* right emu out? */
+#define FXWC_DEFAULTROUTE_A     (1<<12)
+#define FXWC_DEFAULTROUTE_D     (1<<13)
+#define FXWC_ADCLEFT            (1<<18)
+#define FXWC_CDROMSPDIFLEFT     (1<<18)
+#define FXWC_ADCRIGHT           (1<<19)
+#define FXWC_CDROMSPDIFRIGHT    (1<<19)
+#define FXWC_MIC                (1<<20)
+#define FXWC_ZOOMLEFT           (1<<20)
+#define FXWC_ZOOMRIGHT          (1<<21)
+#define FXWC_SPDIFLEFT          (1<<22)		/* 0x00400000 */
+#define FXWC_SPDIFRIGHT         (1<<23)		/* 0x00800000 */
+
+#define TCBS			0x44		/* Tank cache buffer size register			*/
+#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
+#define TCBS_BUFFSIZE_16K	0x00000000
+#define TCBS_BUFFSIZE_32K	0x00000001
+#define TCBS_BUFFSIZE_64K	0x00000002
+#define TCBS_BUFFSIZE_128K	0x00000003
+#define TCBS_BUFFSIZE_256K	0x00000004
+#define TCBS_BUFFSIZE_512K	0x00000005
+#define TCBS_BUFFSIZE_1024K	0x00000006
+#define TCBS_BUFFSIZE_2048K	0x00000007
+
+#define MICBA			0x45		/* AC97 microphone buffer address register		*/
+#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define ADCBA			0x46		/* ADC buffer address register				*/
+#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define FXBA			0x47		/* FX Buffer Address */
+#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define MICBS			0x49		/* Microphone buffer size register			*/
+
+#define ADCBS			0x4a		/* ADC buffer size register				*/
+
+#define FXBS			0x4b		/* FX buffer size register				*/
+
+/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
+#define ADCBS_BUFSIZE_NONE	0x00000000
+#define ADCBS_BUFSIZE_384	0x00000001
+#define ADCBS_BUFSIZE_448	0x00000002
+#define ADCBS_BUFSIZE_512	0x00000003
+#define ADCBS_BUFSIZE_640	0x00000004
+#define ADCBS_BUFSIZE_768	0x00000005
+#define ADCBS_BUFSIZE_896	0x00000006
+#define ADCBS_BUFSIZE_1024	0x00000007
+#define ADCBS_BUFSIZE_1280	0x00000008
+#define ADCBS_BUFSIZE_1536	0x00000009
+#define ADCBS_BUFSIZE_1792	0x0000000a
+#define ADCBS_BUFSIZE_2048	0x0000000b
+#define ADCBS_BUFSIZE_2560	0x0000000c
+#define ADCBS_BUFSIZE_3072	0x0000000d
+#define ADCBS_BUFSIZE_3584	0x0000000e
+#define ADCBS_BUFSIZE_4096	0x0000000f
+#define ADCBS_BUFSIZE_5120	0x00000010
+#define ADCBS_BUFSIZE_6144	0x00000011
+#define ADCBS_BUFSIZE_7168	0x00000012
+#define ADCBS_BUFSIZE_8192	0x00000013
+#define ADCBS_BUFSIZE_10240	0x00000014
+#define ADCBS_BUFSIZE_12288	0x00000015
+#define ADCBS_BUFSIZE_14366	0x00000016
+#define ADCBS_BUFSIZE_16384	0x00000017
+#define ADCBS_BUFSIZE_20480	0x00000018
+#define ADCBS_BUFSIZE_24576	0x00000019
+#define ADCBS_BUFSIZE_28672	0x0000001a
+#define ADCBS_BUFSIZE_32768	0x0000001b
+#define ADCBS_BUFSIZE_40960	0x0000001c
+#define ADCBS_BUFSIZE_49152	0x0000001d
+#define ADCBS_BUFSIZE_57344	0x0000001e
+#define ADCBS_BUFSIZE_65536	0x0000001f
+
+
+#define CDCS			0x50		/* CD-ROM digital channel status register	*/
+
+#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
+
+#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define A_DBG			 0x53
+#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
+#define A_DBG_ZC		 0x40000000	/* zero tram counter */
+#define A_DBG_STEP_ADDR		 0x000003ff
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR	 0x0ffc0000
+
+#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
+
+#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
+
+#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
+
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
+#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
+
+#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
+
+#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
+
+#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
+
+#define SOLEL			0x5c		/* Stop on loop enable low register		*/
+
+#define SOLEH			0x5d		/* Stop on loop enable high register		*/
+
+#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
+#define SPBYPASS_ENABLE		0x00000001	/* Enable SPDIF bypass mode			*/
+
+#define AC97SLOT		0x5f            /* additional AC97 slots enable bits		*/
+#define AC97SLOT_CNTR		0x10            /* Center enable */
+#define AC97SLOT_LFE		0x20            /* LFE enable */
+
+#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
+
+#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
+
+#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
+						/* NOTE: This one has no SPDIFLOCKED field	*/
+						/* Assumes sample lock				*/
+
+/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
+#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
+#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
+#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
+
+/* Note that these values can vary +/- by a small amount                                        */
+#define SRCS_SPDIFRATE_44	0x0003acd9
+#define SRCS_SPDIFRATE_48	0x00040000
+#define SRCS_SPDIFRATE_96	0x00080000
+
+#define MICIDX                  0x63            /* Microphone recording buffer index register   */
+#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
+#define MICIDX_IDX		0x10000063
+
+#define ADCIDX			0x64		/* ADC recording buffer index register		*/
+#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
+#define ADCIDX_IDX		0x10000064
+
+#define A_ADCIDX		0x63
+#define A_ADCIDX_IDX		0x10000063
+
+#define A_MICIDX		0x64
+#define A_MICIDX_IDX		0x10000064
+
+#define FXIDX			0x65		/* FX recording buffer index register		*/
+#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
+#define FXIDX_IDX		0x10000065
+
+/* This is the MPU port on the card (via the game port)						*/
+#define A_MUDATA1		0x70
+#define A_MUCMD1		0x71
+#define A_MUSTAT1		A_MUCMD1
+
+/* This is the MPU port on the Audigy Drive 							*/
+#define A_MUDATA2		0x72
+#define A_MUCMD2		0x73
+#define A_MUSTAT2		A_MUCMD2
+
+/* The next two are the Audigy equivalent of FXWC						*/
+/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
+/* Each bit selects a channel for recording */
+#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
+#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
+
+#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
+#define A_SPDIF_48000		0x00000080
+#define A_SPDIF_44100		0x00000000
+#define A_SPDIF_96000		0x00000040
+
+#define A_FXRT2			0x7c
+#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
+#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
+#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
+#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
+
+#define A_SENDAMOUNTS		0x7d
+#define A_FXSENDAMOUNT_E_MASK	0xFF000000
+#define A_FXSENDAMOUNT_F_MASK	0x00FF0000
+#define A_FXSENDAMOUNT_G_MASK	0x0000FF00
+#define A_FXSENDAMOUNT_H_MASK	0x000000FF
+
+/* The send amounts for this one are the same as used with the emu10k1 */
+#define A_FXRT1			0x7e
+#define A_FXRT_CHANNELA		0x0000003f
+#define A_FXRT_CHANNELB		0x00003f00
+#define A_FXRT_CHANNELC		0x003f0000
+#define A_FXRT_CHANNELD		0x3f000000
+
+
+/* Each FX general purpose register is 32 bits in length, all bits are used			*/
+#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
+#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
+
+/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
+/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
+/* locations are for external TRAM. 								*/
+#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
+#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
+
+/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
+#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
+
+#define MICROCODEBASE		0x400		/* Microcode data base address			*/
+
+/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
+/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
+#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
+#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
+#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
+#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
+#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
+
+
+/* Audigy Soundcard have a different instruction format */
+#define A_MICROCODEBASE		0x600
+#define A_LOWORD_OPY_MASK	0x000007ff
+#define A_LOWORD_OPX_MASK	0x007ff000
+#define A_HIWORD_OPCODE_MASK	0x0f000000
+#define A_HIWORD_RESULT_MASK	0x007ff000
+#define A_HIWORD_OPA_MASK	0x000007ff
+
+
+/* ------------------- STRUCTURES -------------------- */
+
+typedef struct _snd_emu10k1 emu10k1_t;
+typedef struct _snd_emu10k1_voice emu10k1_voice_t;
+typedef struct _snd_emu10k1_pcm emu10k1_pcm_t;
+
+typedef enum {
+	EMU10K1_PCM,
+	EMU10K1_SYNTH,
+	EMU10K1_MIDI
+} emu10k1_voice_type_t;
+
+struct _snd_emu10k1_voice {
+	emu10k1_t *emu;
+	int number;
+	int use: 1,
+	    pcm: 1,
+	    synth: 1,
+	    midi: 1;
+	void (*interrupt)(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+
+	emu10k1_pcm_t *epcm;
+};
+
+typedef enum {
+	PLAYBACK_EMUVOICE,
+	CAPTURE_AC97ADC,
+	CAPTURE_AC97MIC,
+	CAPTURE_EFX
+} snd_emu10k1_pcm_type_t;
+
+struct _snd_emu10k1_pcm {
+	emu10k1_t *emu;
+	snd_emu10k1_pcm_type_t type;
+	snd_pcm_substream_t *substream;
+	emu10k1_voice_t *voices[2];
+	emu10k1_voice_t *extra;
+	unsigned short running;
+	unsigned short first_ptr;
+	snd_util_memblk_t *memblk;
+	unsigned int start_addr;
+	unsigned int ccca_start_addr;
+	unsigned int capture_ipr;	/* interrupt acknowledge mask */
+	unsigned int capture_inte;	/* interrupt enable mask */
+	unsigned int capture_ba_reg;	/* buffer address register */
+	unsigned int capture_bs_reg;	/* buffer size register */
+	unsigned int capture_idx_reg;	/* buffer index register */
+	unsigned int capture_cr_val;	/* control value */
+	unsigned int capture_cr_val2;	/* control value2 (for audigy) */
+	unsigned int capture_bs_val;	/* buffer size value */
+	unsigned int capture_bufsize;	/* buffer size in bytes */
+};
+
+typedef struct {
+	unsigned char send_routing[3][8];
+	unsigned char send_volume[3][8];
+	unsigned short attn[3];
+	emu10k1_pcm_t *epcm;
+} emu10k1_pcm_mixer_t;
+
+#define snd_emu10k1_compose_send_routing(route) \
+((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
+
+#define snd_emu10k1_compose_audigy_fxrt1(route) \
+(((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 12)) << 24)
+
+#define snd_emu10k1_compose_audigy_fxrt2(route) \
+(((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 12)) << 24)
+
+typedef struct snd_emu10k1_memblk {
+	snd_util_memblk_t mem;
+	/* private part */
+	short first_page, last_page, pages, mapped_page;
+	unsigned int map_locked;
+	struct list_head mapped_link;
+	struct list_head mapped_order_link;
+} emu10k1_memblk_t;
+
+#define snd_emu10k1_memblk_offset(blk)	(((blk)->mapped_page << PAGE_SHIFT) | ((blk)->mem.offset & (PAGE_SIZE - 1)))
+
+#define EMU10K1_MAX_TRAM_BLOCKS_PER_CODE	16
+
+typedef struct {
+	struct list_head list;		/* list link container */
+	unsigned int vcount;
+	unsigned int count;		/* count of GPR (1..16) */
+	unsigned char gpr[32];		/* GPR number(s) */
+	unsigned int value[32];
+	unsigned int min;		/* minimum range */
+	unsigned int max;		/* maximum range */
+	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
+	snd_kcontrol_t *kcontrol;
+} snd_emu10k1_fx8010_ctl_t;
+
+typedef void (snd_fx8010_irq_handler_t)(emu10k1_t *emu, void *private_data);
+
+typedef struct _snd_emu10k1_fx8010_irq {
+	struct _snd_emu10k1_fx8010_irq *next;
+	snd_fx8010_irq_handler_t *handler;
+	unsigned char gpr_running;
+	void *private_data;
+} snd_emu10k1_fx8010_irq_t;
+
+typedef struct {
+	unsigned int valid: 1,
+		     opened: 1,
+		     active: 1;
+	unsigned int channels;		/* 16-bit channels count */
+	unsigned int tram_start;	/* initial ring buffer position in TRAM (in samples) */
+	unsigned int buffer_size;	/* count of buffered samples */
+	unsigned char gpr_size;		/* GPR containing size of ring buffer in samples (host) */
+	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned char etram[32];	/* external TRAM address & data */
+	unsigned int sw_data, hw_data;
+	unsigned int sw_io, hw_io;
+	unsigned int sw_ready, hw_ready;
+	unsigned int appl_ptr;
+	unsigned int tram_pos;
+	unsigned int tram_shift;
+	snd_emu10k1_fx8010_irq_t *irq;
+} snd_emu10k1_fx8010_pcm_t;
+
+typedef struct {
+	unsigned short fxbus_mask;	/* used FX buses (bitmask) */
+	unsigned short extin_mask;	/* used external inputs (bitmask) */
+	unsigned short extout_mask;	/* used external outputs (bitmask) */
+	unsigned short pad1;
+	unsigned int itram_size;	/* internal TRAM size in samples */
+	unsigned int etram_size;	/* external TRAM size in samples */
+	void *etram_pages;		/* allocated pages for external TRAM */
+	dma_addr_t etram_pages_dmaaddr;
+	unsigned int dbg;		/* FX debugger register */
+	unsigned char name[128];
+	int gpr_size;			/* size of allocated GPR controls */
+	int gpr_count;			/* count of used kcontrols */
+	struct list_head gpr_ctl;	/* GPR controls */
+	struct semaphore lock;
+	snd_emu10k1_fx8010_pcm_t pcm[8];
+	sndlock_t irq_lock;
+	snd_emu10k1_fx8010_irq_t *irq_handlers;
+} snd_emu10k1_fx8010_t;
+
+#define emu10k1_gpr_ctl(n) list_entry(n, snd_emu10k1_fx8010_ctl_t, list)
+
+typedef struct {
+	struct _snd_emu10k1 *emu;
+	snd_rawmidi_t *rmidi;
+	snd_rawmidi_substream_t *substream_input;
+	snd_rawmidi_substream_t *substream_output;
+	unsigned int midi_mode;
+	sndlock_t input_lock;
+	sndlock_t output_lock;
+	sndlock_t open_lock;
+	int tx_enable, rx_enable;
+	int port;
+	int ipr_tx, ipr_rx;
+	void (*interrupt)(emu10k1_t *emu, unsigned int status);
+} emu10k1_midi_t;
+
+struct _snd_emu10k1 {
+	int irq;
+
+	unsigned long port;			/* I/O port number */
+	struct resource *res_port;
+	int APS: 1,				/* APS flag */
+	    no_ac97: 1,				/* no AC'97 */
+	    tos_link: 1;			/* tos link detected */
+	unsigned int audigy;			/* is Audigy? */
+	unsigned int revision;			/* chip revision */
+	unsigned int serial;			/* serial number */
+	unsigned short model;			/* subsystem id */
+	unsigned int card_type;			/* EMU10K1_CARD_* */
+	unsigned int ecard_ctrl;		/* ecard control bits */
+	unsigned long dma_mask;			/* PCI DMA mask */
+	int max_cache_pages;			/* max memory size / PAGE_SIZE */
+	void *silent_page;			/* silent page */
+	dma_addr_t silent_page_dmaaddr;
+	volatile u32 *ptb_pages;		/* page table pages */
+	dma_addr_t ptb_pages_dmaaddr;
+	snd_util_memhdr_t *memhdr;		/* page allocation list */
+	emu10k1_memblk_t *reserved_page;	/* reserved page */
+
+	struct list_head mapped_link_head;
+	struct list_head mapped_order_link_head;
+	void **page_ptr_table;
+	unsigned long *page_addr_table;
+	sndlock_t memblk_lock;
+
+	unsigned int spdif_bits[3];		/* s/pdif out setup */
+
+	snd_emu10k1_fx8010_t fx8010;		/* FX8010 info */
+	int gpr_base;
+
+	ac97_t *ac97;
+
+	struct pci_dev *pci;
+	snd_card_t *card;
+	snd_pcm_t *pcm;
+	snd_pcm_t *pcm_mic;
+	snd_pcm_t *pcm_efx;
+	snd_pcm_t *pcm_fx8010;
+
+	sndlock_t synth_lock;
+	void *synth;
+	int (*get_synth_voice)(emu10k1_t *emu);
+
+	sndlock_t reg_lock;
+	sndlock_t emu_lock;
+	sndlock_t voice_lock;
+	struct semaphore ptb_lock;
+
+	emu10k1_voice_t voices[64];
+	emu10k1_pcm_mixer_t pcm_mixer[32];
+	snd_kcontrol_t *ctl_send_routing;
+	snd_kcontrol_t *ctl_send_volume;
+	snd_kcontrol_t *ctl_attn;
+
+	void (*hwvol_interrupt)(emu10k1_t *emu, unsigned int status);
+	void (*capture_interrupt)(emu10k1_t *emu, unsigned int status);
+	void (*capture_mic_interrupt)(emu10k1_t *emu, unsigned int status);
+	void (*capture_efx_interrupt)(emu10k1_t *emu, unsigned int status);
+	void (*timer_interrupt)(emu10k1_t *emu);
+	void (*spdif_interrupt)(emu10k1_t *emu, unsigned int status);
+	void (*dsp_interrupt)(emu10k1_t *emu);
+
+	snd_pcm_substream_t *pcm_capture_substream;
+	snd_pcm_substream_t *pcm_capture_mic_substream;
+	snd_pcm_substream_t *pcm_capture_efx_substream;
+
+	emu10k1_midi_t midi;
+	emu10k1_midi_t midi2; /* for audigy */
+
+	unsigned int efx_voices_mask[2];
+};
+
+int snd_emu10k1_create(snd_card_t * card,
+		       struct pci_dev *pci,
+		       unsigned short extin_mask,
+		       unsigned short extout_mask,
+		       long max_cache_bytes,
+		       int enable_ir,
+		       emu10k1_t ** remu);
+
+int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_mixer(emu10k1_t * emu);
+int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
+
+irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* initialization */
+void snd_emu10k1_voice_init(emu10k1_t * emu, int voice);
+int snd_emu10k1_init_efx(emu10k1_t *emu);
+void snd_emu10k1_free_efx(emu10k1_t *emu);
+int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size);
+
+/* I/O functions */
+unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
+void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data);
+unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
+void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
+void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
+void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait);
+static inline unsigned int snd_emu10k1_wc(emu10k1_t *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
+unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg);
+void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data);
+unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
+unsigned char snd_emu10k1_sum_vol_attn(unsigned int value);
+
+/* memory allocation */
+snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
+int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk);
+snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size);
+int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk);
+int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size);
+int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char *data, int size);
+int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk);
+
+/* voice allocation */
+int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int pair, emu10k1_voice_t **rvoice);
+int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+
+/* MIDI uart */
+int snd_emu10k1_midi(emu10k1_t * emu);
+int snd_emu10k1_audigy_midi(emu10k1_t * emu);
+
+/* proc interface */
+int snd_emu10k1_proc_init(emu10k1_t * emu);
+
+#endif /* __KERNEL__ */
+
+/*
+ * ---- FX8010 ----
+ */
+
+#define EMU10K1_CARD_CREATIVE			0x00000000
+#define EMU10K1_CARD_EMUAPS			0x00000001
+
+#define EMU10K1_FX8010_PCM_COUNT		8
+
+/* instruction set */
+#define iMAC0	 0x00	/* R = A + (X * Y >> 31)   ; saturation */
+#define iMAC1	 0x01	/* R = A + (-X * Y >> 31)  ; saturation */
+#define iMAC2	 0x02	/* R = A + (X * Y >> 31)   ; wraparound */
+#define iMAC3	 0x03	/* R = A + (-X * Y >> 31)  ; wraparound */
+#define iMACINT0 0x04	/* R = A + X * Y	   ; saturation */
+#define iMACINT1 0x05	/* R = A + X * Y	   ; wraparound (31-bit) */
+#define iACC3	 0x06	/* R = A + X + Y	   ; saturation */
+#define iMACMV   0x07	/* R = A, acc += X * Y >> 31 */
+#define iANDXOR  0x08	/* R = (A & X) ^ Y */
+#define iTSTNEG  0x09	/* R = (A >= Y) ? X : ~X */
+#define iLIMITGE 0x0a	/* R = (A >= Y) ? X : Y */
+#define iLIMITLT 0x0b	/* R = (A < Y) ? X : Y */
+#define iLOG	 0x0c	/* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
+#define iEXP	 0x0d	/* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
+#define iINTERP  0x0e	/* R = A + (X * (Y - A) >> 31)  ; saturation */
+#define iSKIP    0x0f	/* R = A (cc_reg), X (count), Y (cc_test) */
+
+/* GPRs */
+#define FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x0f */
+#define EXTIN(x)	(0x10 + (x))	/* x = 0x00 - 0x0f */
+#define EXTOUT(x)	(0x20 + (x))	/* x = 0x00 - 0x0f */
+#define C_00000000	0x40
+#define C_00000001	0x41
+#define C_00000002	0x42
+#define C_00000003	0x43
+#define C_00000004	0x44
+#define C_00000008	0x45
+#define C_00000010	0x46
+#define C_00000020	0x47
+#define C_00000100	0x48
+#define C_00010000	0x49
+#define C_00080000	0x4a
+#define C_10000000	0x4b
+#define C_20000000	0x4c
+#define C_40000000	0x4d
+#define C_80000000	0x4e
+#define C_7fffffff	0x4f
+#define C_ffffffff	0x50
+#define C_fffffffe	0x51
+#define C_c0000000	0x52
+#define C_4f1bbcdc	0x53
+#define C_5a7ef9db	0x54
+#define C_00100000	0x55		/* ?? */
+#define GPR_ACCU	0x56		/* ACCUM, accumulator */
+#define GPR_COND	0x57		/* CCR, condition register */
+#define GPR_NOISE0	0x58		/* noise source */
+#define GPR_NOISE1	0x59		/* noise source */
+#define GPR_IRQ		0x5a		/* IRQ register */
+#define GPR_DBAC	0x5b		/* TRAM Delay Base Address Counter */
+#define GPR(x)		(FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
+#define ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+#define ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+
+#define A_FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x3f? */
+#define A_EXTIN(x)	(0x40 + (x))	/* x = 0x00 - 0x1f? */
+#define A_EXTOUT(x)	(0x60 + (x))	/* x = 0x00 - 0x1f? */
+#define A_GPR(x)	(A_FXGPREGBASE + (x))
+
+/* cc_reg constants */
+#define CC_REG_NORMALIZED C_00000001
+#define CC_REG_BORROW	C_00000002
+#define CC_REG_MINUS	C_00000004
+#define CC_REG_ZERO	C_00000008
+#define CC_REG_SATURATE	C_00000010
+#define CC_REG_NONZERO	C_00000100
+
+/* FX buses */
+#define FXBUS_PCM_LEFT		0x00
+#define FXBUS_PCM_RIGHT		0x01
+#define FXBUS_PCM_LEFT_REAR	0x02
+#define FXBUS_PCM_RIGHT_REAR	0x03
+#define FXBUS_MIDI_LEFT		0x04
+#define FXBUS_MIDI_RIGHT	0x05
+#define FXBUS_PCM_CENTER	0x06
+#define FXBUS_PCM_LFE		0x07
+#define FXBUS_PCM_LEFT_FRONT	0x08
+#define FXBUS_PCM_RIGHT_FRONT	0x09
+#define FXBUS_MIDI_REVERB	0x0c
+#define FXBUS_MIDI_CHORUS	0x0d
+#define FXBUS_PT_LEFT		0x14
+#define FXBUS_PT_RIGHT		0x15
+
+/* Inputs */
+#define EXTIN_AC97_L	   0x00	/* AC'97 capture channel - left */
+#define EXTIN_AC97_R	   0x01	/* AC'97 capture channel - right */
+#define EXTIN_SPDIF_CD_L   0x02	/* internal S/PDIF CD - onboard - left */
+#define EXTIN_SPDIF_CD_R   0x03	/* internal S/PDIF CD - onboard - right */
+#define EXTIN_ZOOM_L	   0x04	/* Zoom Video I2S - left */
+#define EXTIN_ZOOM_R	   0x05	/* Zoom Video I2S - right */
+#define EXTIN_TOSLINK_L	   0x06	/* LiveDrive - TOSLink Optical - left */
+#define EXTIN_TOSLINK_R    0x07	/* LiveDrive - TOSLink Optical - right */
+#define EXTIN_LINE1_L	   0x08	/* LiveDrive - Line/Mic 1 - left */
+#define EXTIN_LINE1_R	   0x09	/* LiveDrive - Line/Mic 1 - right */
+#define EXTIN_COAX_SPDIF_L 0x0a	/* LiveDrive - Coaxial S/PDIF - left */
+#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
+#define EXTIN_LINE2_L	   0x0c	/* LiveDrive - Line/Mic 2 - left */
+#define EXTIN_LINE2_R	   0x0d	/* LiveDrive - Line/Mic 2 - right */
+
+/* Outputs */
+#define EXTOUT_AC97_L	   0x00	/* AC'97 playback channel - left */
+#define EXTOUT_AC97_R	   0x01	/* AC'97 playback channel - right */
+#define EXTOUT_TOSLINK_L   0x02	/* LiveDrive - TOSLink Optical - left */
+#define EXTOUT_TOSLINK_R   0x03	/* LiveDrive - TOSLink Optical - right */
+#define EXTOUT_CENTER      0x04	/* SB Live 5.1 - center */
+#define EXTOUT_LFE         0x05 /* SB Live 5.1 - LFE */
+#define EXTOUT_HEADPHONE_L 0x06	/* LiveDrive - Headphone - left */
+#define EXTOUT_HEADPHONE_R 0x07	/* LiveDrive - Headphone - right */
+#define EXTOUT_REAR_L	   0x08	/* Rear channel - left */
+#define EXTOUT_REAR_R	   0x09	/* Rear channel - right */
+#define EXTOUT_ADC_CAP_L   0x0a	/* ADC Capture buffer - left */
+#define EXTOUT_ADC_CAP_R   0x0b	/* ADC Capture buffer - right */
+#define EXTOUT_MIC_CAP	   0x0c	/* MIC Capture buffer */
+#define EXTOUT_ACENTER	   0x11 /* Analog Center */
+#define EXTOUT_ALFE	   0x12 /* Analog LFE */
+
+/* Audigy Inputs */
+#define A_EXTIN_AC97_L		0x00	/* AC'97 capture channel - left */
+#define A_EXTIN_AC97_R		0x01	/* AC'97 capture channel - right */
+#define A_EXTIN_SPDIF_CD_L	0x02	/* digital CD left */
+#define A_EXTIN_SPDIF_CD_R	0x03	/* digital CD left */
+#define A_EXTIN_OPT_SPDIF_L     0x04    /* audigy drive Optical SPDIF - left */
+#define A_EXTIN_OPT_SPDIF_R     0x05    /*                              right */
+#define A_EXTIN_LINE2_L		0x08	/* audigy drive line2/mic2 - left */
+#define A_EXTIN_LINE2_R		0x09	/*                           right */
+#define A_EXTIN_ADC_L		0x0a    /* Philips ADC - left */
+#define A_EXTIN_ADC_R		0x0b    /*               right */
+#define A_EXTIN_AUX2_L		0x0c	/* audigy drive aux2 - left */
+#define A_EXTIN_AUX2_R		0x0d	/*                   - right */
+
+/* Audigiy Outputs */
+#define A_EXTOUT_FRONT_L	0x00	/* digital front left */
+#define A_EXTOUT_FRONT_R	0x01	/*               right */
+#define A_EXTOUT_CENTER		0x02	/* digital front center */
+#define A_EXTOUT_LFE		0x03	/* digital front lfe */
+#define A_EXTOUT_HEADPHONE_L	0x04	/* headphone audigy drive left */
+#define A_EXTOUT_HEADPHONE_R	0x05	/*                        right */
+#define A_EXTOUT_REAR_L		0x06	/* digital rear left */
+#define A_EXTOUT_REAR_R		0x07	/*              right */
+#define A_EXTOUT_AFRONT_L	0x08	/* analog front left */
+#define A_EXTOUT_AFRONT_R	0x09	/*              right */
+#define A_EXTOUT_ACENTER	0x0a	/* analog center */
+#define A_EXTOUT_ALFE		0x0b	/* analog LFE */
+/* 0x0c ?? */
+/* 0x0d ?? */
+#define A_EXTOUT_AREAR_L	0x0e	/* analog rear left */
+#define A_EXTOUT_AREAR_R	0x0f	/*             right */
+#define A_EXTOUT_AC97_L		0x10	/* AC97 left (front) */
+#define A_EXTOUT_AC97_R		0x11	/*      right */
+#define A_EXTOUT_ADC_CAP_L	0x16	/* ADC capture buffer left */
+#define A_EXTOUT_ADC_CAP_R	0x17	/*                    right */
+#define A_EXTOUT_MIC_CAP	0x18	/* Mic capture buffer */
+
+/* Audigy constants */
+#define A_C_00000000	0xc0
+#define A_C_00000001	0xc1
+#define A_C_00000002	0xc2
+#define A_C_00000003	0xc3
+#define A_C_00000004	0xc4
+#define A_C_00000008	0xc5
+#define A_C_00000010	0xc6
+#define A_C_00000020	0xc7
+#define A_C_00000100	0xc8
+#define A_C_00010000	0xc9
+#define A_C_00000800	0xca
+#define A_C_10000000	0xcb
+#define A_C_20000000	0xcc
+#define A_C_40000000	0xcd
+#define A_C_80000000	0xce
+#define A_C_7fffffff	0xcf
+#define A_C_ffffffff	0xd0
+#define A_C_fffffffe	0xd1
+#define A_C_c0000000	0xd2
+#define A_C_4f1bbcdc	0xd3
+#define A_C_5a7ef9db	0xd4
+#define A_C_00100000	0xd5
+#define A_GPR_ACCU	0xd6		/* ACCUM, accumulator */
+#define A_GPR_COND	0xd7		/* CCR, condition register */
+/* 0xd8 = noise1 */
+/* 0xd9 = noise2 */
+
+/* definitions for debug register */
+#define EMU10K1_DBG_ZC			0x80000000	/* zero tram counter */
+#define EMU10K1_DBG_SATURATION_OCCURED	0x02000000	/* saturation control */
+#define EMU10K1_DBG_SATURATION_ADDR	0x01ff0000	/* saturation address */
+#define EMU10K1_DBG_SINGLE_STEP		0x00008000	/* single step mode */
+#define EMU10K1_DBG_STEP		0x00004000	/* start single step */
+#define EMU10K1_DBG_CONDITION_CODE	0x00003e00	/* condition code */
+#define EMU10K1_DBG_SINGLE_STEP_ADDR	0x000001ff	/* single step address */
+
+/* tank memory address line */
+#ifndef __KERNEL__
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	 0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	 0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	 0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	 0x00100000	/* Read from tank memory			*/
+#endif
+
+typedef struct {
+	unsigned int card;			/* card type */
+	unsigned int internal_tram_size;	/* in samples */
+	unsigned int external_tram_size;	/* in samples */
+	char fxbus_names[16][32];		/* names of FXBUSes */
+	char extin_names[16][32];		/* names of external inputs */
+	char extout_names[32][32];		/* names of external outputs */
+	unsigned int gpr_controls;		/* count of GPR controls */
+} emu10k1_fx8010_info_t;
+
+#define EMU10K1_GPR_TRANSLATION_NONE		0
+#define EMU10K1_GPR_TRANSLATION_TABLE100	1
+#define EMU10K1_GPR_TRANSLATION_BASS		2
+#define EMU10K1_GPR_TRANSLATION_TREBLE		3
+#define EMU10K1_GPR_TRANSLATION_ONOFF		4
+
+typedef struct {
+	snd_ctl_elem_id_t id;		/* full control ID definition */
+	unsigned int vcount;		/* visible count */
+	unsigned int count;		/* count of GPR (1..16) */
+	unsigned char gpr[32];		/* GPR number(s) */
+	unsigned int value[32];		/* initial values */
+	unsigned int min;		/* minimum range */
+	unsigned int max;		/* maximum range */
+	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
+} emu10k1_fx8010_control_gpr_t;
+
+typedef struct {
+	char name[128];
+
+	unsigned long gpr_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
+	unsigned int gpr_map[0x100];	  /* initializers */
+
+	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
+	emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */
+
+	unsigned int gpr_del_control_count; /* count of GPR controls to remove */
+	snd_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
+
+	unsigned int gpr_list_control_count; /* count of GPR controls to list */
+	unsigned int gpr_list_control_total; /* total count of GPR controls */
+	emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
+
+	unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
+	unsigned int tram_data_map[0xa0]; /* data initializers */
+	unsigned int tram_addr_map[0xa0]; /* map initializers */
+
+	unsigned long code_valid[512/(sizeof(unsigned long)*8)];  /* bitmask of valid instructions */
+	unsigned int code[512][2];	  /* one instruction - 64 bits */
+} emu10k1_fx8010_code_t;
+
+typedef struct {
+	unsigned int address;		/* 31.bit == 1 -> external TRAM */
+	unsigned int size;		/* size in samples (4 bytes) */
+	unsigned int *samples;		/* pointer to samples (20-bit) */
+					/* NULL->clear memory */
+} emu10k1_fx8010_tram_t;
+
+typedef struct {
+	unsigned int substream;		/* substream number */
+	unsigned int res1;		/* reserved */
+	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
+	unsigned int tram_start;	/* ring buffer position in TRAM (in samples) */
+	unsigned int buffer_size;	/* count of buffered samples */
+	unsigned char gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
+	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned char pad;		/* reserved */
+	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
+	unsigned int res2;		/* reserved */
+} emu10k1_fx8010_pcm_t;
+
+#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, emu10k1_fx8010_info_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP	_IOW ('H', 0x20, int)
+#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_STOP	_IO  ('H', 0x80)
+#define SNDRV_EMU10K1_IOCTL_CONTINUE	_IO  ('H', 0x81)
+#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
+#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP	_IOW ('H', 0x83, int)
+#define SNDRV_EMU10K1_IOCTL_DBG_READ	_IOR ('H', 0x84, int)
+
+#endif	/* __SOUND_EMU10K1_H */
diff --git a/sys/gnu/dev/sound/pci/emu10k1.h b/sys/gnu/dev/sound/pci/emu10k1.h
new file mode 100644
index 0000000..95cc760
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/emu10k1.h
@@ -0,0 +1,740 @@
+/*-
+ **********************************************************************
+ *     emu10k1.h, derived from 8010.h
+ *     Copyright 1999-2001 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date		    Author	    Summary of changes
+ *     ----		    ------	    ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox	    Cleaned of 8bit chars, DOS
+ *					    line endings
+ *     December 8, 1999     Jon Taylor	    Added lots of new register info
+ *     May 16, 2001         Daniel Bertrand Added unofficial DBG register info
+ *     Oct-Nov 2001         D.B.            Added unofficial Audigy registers
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ *
+ **********************************************************************
+ * $FreeBSD: src/sys/gnu/dev/sound/pci/emu10k1.h,v 1.8 2005/01/06 18:27:30 imp Exp $
+ */
+
+
+#ifndef _8010_H
+#define _8010_H
+
+	/*
+#include <linux/types.h>
+	*/
+
+/* Driver version: */
+#define MAJOR_VER 0
+#define MINOR_VER 20
+#define DRIVER_VERSION "0.20a"
+
+
+/* Audigy specify registers are prefixed with 'A_' */
+
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
+						/* channel number of the register to be		*/
+						/* accessed.  For non per-channel registers the	*/
+						/* value should be set to zero.			*/
+#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
+
+#define DATA			0x04		/* Indexed register set data register		*/
+
+#define IPR			0x08		/* Global interrupt pending register		*/
+						/* Clear pending interrupts by writing a 1 to	*/
+						/* the relevant bits and zero to the other bits	*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define A_IPR_MIDITRANSBUFEMPTY2	0x10000000	/* MIDI UART transmit buffer empty		*/
+#define A_IPR_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
+
+#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
+#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
+#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
+#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
+#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
+#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
+#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
+#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
+#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
+#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
+#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
+#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
+#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
+#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
+#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
+#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
+#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
+#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
+#define IPR_CHANNELLOOP		0x00000040	/* One or more channel loop interrupts pending	*/
+#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
+						/* Highest set channel in CLIPL or CLIPH.  When	*/
+						/* IP is written with CL set, the bit in CLIPL	*/
+						/* or CLIPH corresponding to the CIN value 	*/
+						/* written will be cleared.			*/
+#define A_IPR_MIDITRANSBUFEMPTY1	IPR_MIDITRANSBUFEMPTY	/* MIDI UART transmit buffer empty		*/
+#define A_IPR_MIDIRECVBUFEMPTY1	IPR_MIDIRECVBUFEMPTY	/* MIDI UART receive buffer empty		*/
+
+
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
+#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
+#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
+#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
+#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
+#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
+#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
+#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
+#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
+#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
+#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
+#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
+#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
+#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
+#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
+#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
+#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
+#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
+
+#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
+						/* NOTE: There is no reason to use this under	*/
+						/* Linux, and it will cause odd hardware 	*/
+						/* behavior and possibly random segfaults and	*/
+						/* lockups if enabled.				*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define A_INTE_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define A_INTE_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+
+#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
+						/* NOTE: This bit must always be enabled       	*/
+#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
+#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
+#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
+#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
+#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
+#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
+#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
+#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
+#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
+#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
+#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
+#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+/* The next two interrupts are for the midi port on the Audigy (A_MPU2)	*/
+#define A_INTE_MIDITXENABLE1  	INTE_MIDITXENABLE
+#define A_INTE_MIDIRXENABLE1	INTE_MIDIRXENABLE
+
+#define WC			0x10		/* Wall Clock register				*/
+#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
+#define WC_SAMPLECOUNTER	0x14060010
+#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
+						/* NOTE: Each channel takes 1/64th of a sample	*/
+						/* period to be serviced.			*/
+
+#define HCFG			0x14		/* Hardware config register			*/
+						/* NOTE: There is no reason to use the legacy	*/
+						/* SoundBlaster emulation stuff described below	*/
+						/* under Linux, and all kinds of weird hardware	*/
+						/* behavior can result if you try.  Don't.	*/
+#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
+#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
+#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
+#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
+#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
+#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
+#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
+#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
+#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
+#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
+#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
+#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
+						/* NOTE: The rest of the bits in this register	*/
+						/* _are_ relevant under Linux.			*/
+#define HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format					*/
+#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
+#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
+#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
+#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
+
+#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
+#define HCFG_GPOUT0		0x00001000	/* set to enable digital out on 5.1 cards	*/
+
+#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
+#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
+						/* 1 = Force all 3 async digital inputs to use	*/
+						/* the same async sample rate tracker (ZVIDEO)	*/
+#define HCFG_AC3ENABLE_MASK	0x0x0000e0	/* AC3 async input control - Not implemented	*/
+#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
+#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
+#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF             */
+#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* they are not rate-locked to the external	*/
+						/* async audio source  				*/
+#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE	0x01020014
+#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
+						/* NOTE: This is a 'cheap' way to implement a	*/
+						/* master mute function on the mute button, and	*/
+						/* in general should not be used unless a more	*/
+						/* sophisticated master mute function has not	*/
+						/* been written.       				*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+
+/* For Audigy, MPU port move to 0x70-0x74 ptr register */
+
+#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
+
+#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
+#define MUCMD_RESET		0xff		/* RESET command				*/
+#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
+						/* NOTE: All other commands are ignored		*/
+
+#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
+#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
+#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
+
+#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
+#define A_GPINPUT_MASK		0xff00
+#define A_GPOUTPUT_MASK		0x00ff
+
+#define TIMER			0x1a		/* Timer terminal count register (16-bit)	*/
+						/* NOTE: After the rate is changed, a maximum	*/
+						/* of 1024 sample periods should be allowed	*/
+						/* before the new rate is guaranteed accurate.	*/
+#define TIMER_RATE_MASK		0x03ff		/* Timer interrupt rate in sample periods	*/
+						/* 0 == 1024 periods, [1..4] are not useful	*/
+
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
+#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
+
+/********************************************************************************************************/
+/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
+/********************************************************************************************************/
+
+#define CPF			0x00		/* Current pitch and fraction register			*/
+#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
+#define CPF_CURRENTPITCH	0x10100000
+#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
+#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
+#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
+
+#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
+#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
+#define PTRX_PITCHTARGET	0x10100001
+#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
+#define PTRX_FXSENDAMOUNT_A	0x08080001
+#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
+#define PTRX_FXSENDAMOUNT_B	0x08000001
+
+#define CVCF			0x02		/* Current volume and filter cutoff register		*/
+#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
+#define CVCF_CURRENTVOL		0x10100002
+#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
+#define CVCF_CURRENTFILTER	0x10000002
+
+#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
+#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
+#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
+
+#define Z1			0x05		/* Filter delay memory 1 register			*/
+
+#define Z2			0x04		/* Filter delay memory 2 register			*/
+
+#define PSST			0x06		/* Send C amount and loop start address register	*/
+#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
+
+#define PSST_FXSENDAMOUNT_C	0x08180006
+
+#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
+#define PSST_LOOPSTARTADDR	0x18000006
+
+#define DSL			0x07		/* Send D amount and loop start address register	*/
+#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
+
+#define DSL_FXSENDAMOUNT_D	0x08180007
+
+#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
+#define DSL_LOOPENDADDR		0x18000007
+
+#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
+#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
+#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
+						/* 1 == full band, 7 == lowpass				*/
+						/* ROM 0 is used when pitch shifting downward or less	*/
+						/* then 3 semitones upward.  Increasingly higher ROM	*/
+						/* numbers are used, typically in steps of 3 semitones,	*/
+						/* as upward pitch shifting is performed.		*/
+#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
+#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
+#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
+#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
+#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
+#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
+#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
+#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
+#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
+#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
+#define CCCA_CURRADDR		0x18000008
+
+#define CCR			0x09		/* Cache control register				*/
+#define CCR_CACHEINVALIDSIZE	0x07190009
+#define CCR_CACHEINVALIDSIZE_MASK	0xfe000000	/* Number of invalid samples cache for this channel    	*/
+#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
+#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
+#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
+#define CCR_READADDRESS		0x06100009
+#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
+#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
+						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
+#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
+#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
+
+#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
+						/* NOTE: This register is normally not used		*/
+#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
+
+#define FXRT			0x0b		/* Effects send routing register			*/
+						/* NOTE: It is illegal to assign the same routing to	*/
+						/* two effects sends.					*/
+#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
+#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
+#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
+#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
+
+#define MAPA			0x0c		/* Cache map A						*/
+
+#define MAPB			0x0d		/* Cache map B						*/
+
+#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+
+#define ENVVOL			0x10		/* Volume envelope register				*/
+#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/
+						/* 0x8000-n == 666*n usec delay	       			*/
+
+#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
+#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
+#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
+
+#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
+#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
+						/* this channel and from writing to pitch, filter and	*/
+						/* volume targets.					*/
+#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL1 		0x13		/* Modulation LFO value					*/
+#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ENVVAL			0x14		/* Modulation envelope register				*/
+#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
+#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
+#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
+
+#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
+#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
+#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define IP			0x18		/* Initial pitch register				*/
+#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
+						/* 4 bits of octave, 12 bits of fractional octave	*/
+#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
+
+#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
+#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
+						/* 6 most significant bits are semitones		*/
+						/* 2 least significant bits are fractions		*/
+#define IFATN_FILTERCUTOFF	0x08080019
+#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
+#define IFATN_ATTENUATION	0x08000019
+
+
+#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
+#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
+						/* Signed 2's complement, +/- one octave peak extremes	*/
+#define PEFE_PITCHAMOUNT	0x0808001a
+#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
+						/* Signed 2's complement, +/- six octaves peak extremes */
+#define PEFE_FILTERAMOUNT	0x0800001a
+#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
+#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
+						/* Signed 2's complement, +/- three octave extremes	*/
+
+
+#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
+#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
+						/* Signed 2's complement, with +/- 12dB extremes	*/
+#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
+						/* ??Hz steps, maximum of ?? Hz.			*/
+
+#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
+#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
+						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
+
+#define TEMPENV 		0x1e		/* Tempory envelope register				*/
+#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
+						/* NOTE: All channels contain internal variables; do	*/
+						/* not write to these locations.			*/
+
+#define CD0			0x20		/* Cache data 0 register				*/
+#define CD1			0x21		/* Cache data 1 register				*/
+#define CD2			0x22		/* Cache data 2 register				*/
+#define CD3			0x23		/* Cache data 3 register				*/
+#define CD4			0x24		/* Cache data 4 register				*/
+#define CD5			0x25		/* Cache data 5 register				*/
+#define CD6			0x26		/* Cache data 6 register				*/
+#define CD7			0x27		/* Cache data 7 register				*/
+#define CD8			0x28		/* Cache data 8 register				*/
+#define CD9			0x29		/* Cache data 9 register				*/
+#define CDA			0x2a		/* Cache data A register				*/
+#define CDB			0x2b		/* Cache data B register				*/
+#define CDC			0x2c		/* Cache data C register				*/
+#define CDD			0x2d		/* Cache data D register				*/
+#define CDE			0x2e		/* Cache data E register				*/
+#define CDF			0x2f		/* Cache data F register				*/
+
+#define PTB			0x40		/* Page table base register				*/
+#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
+
+#define TCB			0x41		/* Tank cache base register    				*/
+#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
+
+#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
+#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
+#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
+						/* NOTE: To guarantee phase coherency, both channels	*/
+						/* must be disabled prior to enabling both channels.	*/
+#define A_ADCCR_RCHANENABLE	0x00000020
+#define A_ADCCR_LCHANENABLE	0x00000010
+
+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
+#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
+
+#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
+#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
+#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
+#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
+#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
+#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
+#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
+#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
+
+#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
+#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
+#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
+
+#define FXWC			0x43		/* FX output write channels register			*/
+						/* When set, each bit enables the writing of the	*/
+						/* corresponding FX output channel (internal registers  */
+						/* 0x20-0x3f) into host memory. This mode of recording	*/
+						/* is 16bit, 48KHz only. All 32	channels can be enabled */
+						/* simultaneously.					*/
+#define TCBS			0x44		/* Tank cache buffer size register			*/
+#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
+#define TCBS_BUFFSIZE_16K	0x00000000
+#define TCBS_BUFFSIZE_32K	0x00000001
+#define TCBS_BUFFSIZE_64K	0x00000002
+#define TCBS_BUFFSIZE_128K	0x00000003
+#define TCBS_BUFFSIZE_256K	0x00000004
+#define TCBS_BUFFSIZE_512K	0x00000005
+#define TCBS_BUFFSIZE_1024K	0x00000006
+#define TCBS_BUFFSIZE_2048K	0x00000007
+
+#define MICBA			0x45		/* AC97 microphone buffer address register		*/
+#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define ADCBA			0x46		/* ADC buffer address register				*/
+#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define FXBA			0x47		/* FX Buffer Address */
+#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define MICBS			0x49		/* Microphone buffer size register			*/
+
+#define ADCBS			0x4a		/* ADC buffer size register				*/
+
+#define FXBS			0x4b		/* FX buffer size register				*/
+
+/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
+#define ADCBS_BUFSIZE_NONE	0x00000000
+#define ADCBS_BUFSIZE_384	0x00000001
+#define ADCBS_BUFSIZE_448	0x00000002
+#define ADCBS_BUFSIZE_512	0x00000003
+#define ADCBS_BUFSIZE_640	0x00000004
+#define ADCBS_BUFSIZE_768	0x00000005
+#define ADCBS_BUFSIZE_896	0x00000006
+#define ADCBS_BUFSIZE_1024	0x00000007
+#define ADCBS_BUFSIZE_1280	0x00000008
+#define ADCBS_BUFSIZE_1536	0x00000009
+#define ADCBS_BUFSIZE_1792	0x0000000a
+#define ADCBS_BUFSIZE_2048	0x0000000b
+#define ADCBS_BUFSIZE_2560	0x0000000c
+#define ADCBS_BUFSIZE_3072	0x0000000d
+#define ADCBS_BUFSIZE_3584	0x0000000e
+#define ADCBS_BUFSIZE_4096	0x0000000f
+#define ADCBS_BUFSIZE_5120	0x00000010
+#define ADCBS_BUFSIZE_6144	0x00000011
+#define ADCBS_BUFSIZE_7168	0x00000012
+#define ADCBS_BUFSIZE_8192	0x00000013
+#define ADCBS_BUFSIZE_10240	0x00000014
+#define ADCBS_BUFSIZE_12288	0x00000015
+#define ADCBS_BUFSIZE_14366	0x00000016
+#define ADCBS_BUFSIZE_16384	0x00000017
+#define ADCBS_BUFSIZE_20480	0x00000018
+#define ADCBS_BUFSIZE_24576	0x00000019
+#define ADCBS_BUFSIZE_28672	0x0000001a
+#define ADCBS_BUFSIZE_32768	0x0000001b
+#define ADCBS_BUFSIZE_40960	0x0000001c
+#define ADCBS_BUFSIZE_49152	0x0000001d
+#define ADCBS_BUFSIZE_57344	0x0000001e
+#define ADCBS_BUFSIZE_65536	0x0000001f
+
+
+#define CDCS			0x50		/* CD-ROM digital channel status register	*/
+
+#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
+
+#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+/* definitions for debug register - taken from the alsa drivers */
+#define DBG_ZC                  0x80000000      /* zero tram counter */
+#define DBG_SATURATION_OCCURED  0x02000000      /* saturation control */
+#define DBG_SATURATION_ADDR     0x01ff0000      /* saturation address */
+#define DBG_SINGLE_STEP         0x00008000      /* single step mode */
+#define DBG_STEP                0x00004000      /* start single step */
+#define DBG_CONDITION_CODE      0x00003e00      /* condition code */
+#define DBG_SINGLE_STEP_ADDR    0x000001ff      /* single step address */
+
+
+#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define A_DBG			 0x53
+#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
+#define A_DBG_ZC		 0x40000000	/* zero tram counter */
+#define A_DBG_STEP_ADDR		 0x000003ff
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR	 0x0ffc0000
+
+#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
+
+#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
+
+#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
+
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
+#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
+
+#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
+
+#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
+
+#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
+
+#define SOLEL			0x5c		/* Stop on loop enable low register		*/
+
+#define SOLEH			0x5d		/* Stop on loop enable high register		*/
+
+#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
+#define SPBYPASS_ENABLE		0x00000001	/* Enable SPDIF bypass mode			*/
+
+#define AC97SLOT		0x5f		/* additional AC97 slots enable bits */
+#define AC97SLOT_CNTR		0x10		/* Center enable */
+#define AC97SLOT_LFE		0x20		/* LFE enable */
+
+#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
+
+#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
+
+#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
+						/* NOTE: This one has no SPDIFLOCKED field	*/
+						/* Assumes sample lock				*/
+
+/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
+#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
+#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
+#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
+
+
+/* Note that these values can vary +/- by a small amount                                        */
+#define SRCS_SPDIFRATE_44	0x0003acd9
+#define SRCS_SPDIFRATE_48	0x00040000
+#define SRCS_SPDIFRATE_96	0x00080000
+
+#define MICIDX                  0x63            /* Microphone recording buffer index register   */
+#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
+#define MICIDX_IDX		0x10000063
+
+#define A_ADCIDX		0x63
+#define A_ADCIDX_IDX		0x10000063
+
+#define ADCIDX			0x64		/* ADC recording buffer index register		*/
+#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
+#define ADCIDX_IDX		0x10000064
+
+#define FXIDX			0x65		/* FX recording buffer index register		*/
+#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
+#define FXIDX_IDX		0x10000065
+
+/* This is the MPU port on the card (via the game port)						*/
+#define A_MUDATA1		0x70
+#define A_MUCMD1		0x71
+#define A_MUSTAT1		A_MUCMD1
+
+/* This is the MPU port on the Audigy Drive 							*/
+#define A_MUDATA2		0x72
+#define A_MUCMD2		0x73
+#define A_MUSTAT2		A_MUCMD2
+
+/* The next two are the Audigy equivalent of FXWC						*/
+/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
+/* Each bit selects a channel for recording */
+#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
+#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
+
+#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
+#define A_SPDIF_48000		0x00000080
+#define A_SPDIF_44100		0x00000000
+#define A_SPDIF_96000		0x00000040
+
+#define A_FXRT2			0x7c
+#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
+#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
+#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
+#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
+
+#define A_SENDAMOUNTS		0x7d
+#define A_FXSENDAMOUNT_E_MASK	0xff000000
+#define A_FXSENDAMOUNT_F_MASK	0x00ff0000
+#define A_FXSENDAMOUNT_G_MASK	0x0000ff00
+#define A_FXSENDAMOUNT_H_MASK	0x000000ff
+
+/* The send amounts for this one are the same as used with the emu10k1 */
+#define A_FXRT1			0x7e
+#define A_FXRT_CHANNELA		0x0000003f
+#define A_FXRT_CHANNELB		0x00003f00
+#define A_FXRT_CHANNELC		0x003f0000
+#define A_FXRT_CHANNELD		0x3f000000
+
+
+/* Each FX general purpose register is 32 bits in length, all bits are used			*/
+#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
+#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
+/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
+/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
+/* locations are for external TRAM. 								*/
+#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
+#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
+
+/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
+#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
+
+#define MICROCODEBASE		0x400		/* Microcode data base address			*/
+
+/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
+/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
+#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
+#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
+#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
+#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
+#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
+
+
+/* Audigy Soundcard have a different instruction format */
+#define AUDIGY_CODEBASE		0x600
+#define A_LOWORD_OPY_MASK	0x000007ff
+#define A_LOWORD_OPX_MASK	0x007ff000
+#define A_HIWORD_OPCODE_MASK	0x0f000000
+#define A_HIWORD_RESULT_MASK	0x007ff000
+#define A_HIWORD_OPA_MASK	0x000007ff
+
+
+#endif /* _8010_H */
diff --git a/sys/gnu/dev/sound/pci/maestro3_dsp.h b/sys/gnu/dev/sound/pci/maestro3_dsp.h
new file mode 100644
index 0000000..5aecad2
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/maestro3_dsp.h
@@ -0,0 +1,214 @@
+/* $FreeBSD: src/sys/gnu/dev/sound/pci/maestro3_dsp.h,v 1.5 2005/01/06 18:27:30 imp Exp $ */
+/*-
+ *      ESS Technology allegro audio driver.
+ *
+ *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *      Hacked for the maestro3 driver by zab
+ */
+
+/*
+ * DSP Code images
+ */
+
+u_int16_t assp_kernel_image[] = {
+    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4,
+    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
+    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
+    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4,
+    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08,
+    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909,
+    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41,
+    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308,
+    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910,
+    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00,
+    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026,
+    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0,
+    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012,
+    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A,
+    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000,
+    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05,
+    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26,
+    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300,
+    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88,
+    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008,
+    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80,
+    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71,
+    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A,
+    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100,
+    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900,
+    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903,
+    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309,
+    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B,
+    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540,
+    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C,
+    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380,
+    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340,
+    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041,
+    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18,
+    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40,
+    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9,
+    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8,
+    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A,
+    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80,
+    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40,
+    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80,
+    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A,
+    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F,
+    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1,
+    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034,
+    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E,
+    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977,
+    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B,
+    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388,
+    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80,
+    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473,
+    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473,
+    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880,
+    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80,
+    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6,
+    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909,
+    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED,
+    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005,
+    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388,
+    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4,
+    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100,
+    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10,
+    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070,
+    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71,
+    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A,
+    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061,
+    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A,
+    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6,
+    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A,
+    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6,
+    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358,
+    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6,
+    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9,
+    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379,
+    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6,
+    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C,
+    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166,
+    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B,
+    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A,
+    0xBE3A,
+};
+
+/*
+ * Mini sample rate converter code image
+ * that is to be loaded at 0x400 on the DSP.
+ */
+u_int16_t assp_minisrc_image[] = {
+    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412,
+    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41,
+    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907,
+    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01,
+    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904,
+    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D,
+    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD,
+    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22,
+    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0,
+    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9,
+    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89,
+    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0,
+    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484,
+    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80,
+    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624,
+    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4,
+    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027,
+    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903,
+    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809,
+    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46,
+    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47,
+    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0,
+    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516,
+    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E,
+    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C,
+    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180,
+    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E,
+    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0,
+    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0,
+    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0,
+    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F,
+    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+u_int16_t minisrc_lpf_image[] = {
+	0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
+	0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
+};
+
+/*
+ * an arbitrary volume we set the internal volume settings to so that the
+ * ac97 volume range is a little less insane.  0x7fff is max.
+ */
+#define ARB_VOLUME 0x6800
+
+static struct play_vals {
+	u_int16_t addr, val;
+} pv[] = {
+	{CDATA_LEFT_VOLUME, ARB_VOLUME},
+	{CDATA_RIGHT_VOLUME, ARB_VOLUME},
+	{SRC3_DIRECTION_OFFSET, 0} ,
+	/* +1, +2 are stereo/16 bit */
+	{SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
+	{SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
+	{SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
+	{SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
+	{SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
+	{SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
+	{SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
+	{SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
+	{SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
+	{SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
+	{SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
+	{SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
+	{SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
+	{SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
+	{SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
+	{SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
+	{SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
+};
+
+static struct rec_vals {
+	u_int16_t addr, val;
+} rv[] = {
+	{CDATA_LEFT_VOLUME, ARB_VOLUME},
+	{CDATA_RIGHT_VOLUME, ARB_VOLUME},
+	{SRC3_DIRECTION_OFFSET, 1},
+	/* +1, +2 are stereo/16 bit */
+	{SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
+	{SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
+	{SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
+	{SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
+	{SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
+	{SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
+	{SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
+	{SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
+	{SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
+	{SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
+	{SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
+	{SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
+	{SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
+	{SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
+	{SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
+	{SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
+	{SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
+	{SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
+	{SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
+};
diff --git a/sys/gnu/dev/sound/pci/maestro3_reg.h b/sys/gnu/dev/sound/pci/maestro3_reg.h
new file mode 100644
index 0000000..0422197
--- /dev/null
+++ b/sys/gnu/dev/sound/pci/maestro3_reg.h
@@ -0,0 +1,692 @@
+/* $FreeBSD: src/sys/gnu/dev/sound/pci/maestro3_reg.h,v 1.5 2005/01/06 18:27:30 imp Exp $ */
+/*-
+ *      ESS Technology allegro audio driver.
+ *
+ *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *      Hacked for the maestro3 driver by zab
+ */
+
+/* Allegro PCI configuration registers */
+#define PCI_LEGACY_AUDIO_CTRL   0x40
+#define SOUND_BLASTER_ENABLE    0x00000001
+#define FM_SYNTHESIS_ENABLE     0x00000002
+#define GAME_PORT_ENABLE        0x00000004
+#define MPU401_IO_ENABLE        0x00000008
+#define MPU401_IRQ_ENABLE       0x00000010
+#define ALIAS_10BIT_IO          0x00000020
+#define SB_DMA_MASK             0x000000C0
+#define SB_DMA_0                0x00000040
+#define SB_DMA_1                0x00000040
+#define SB_DMA_R                0x00000080
+#define SB_DMA_3                0x000000C0
+#define SB_IRQ_MASK             0x00000700
+#define SB_IRQ_5                0x00000000
+#define SB_IRQ_7                0x00000100
+#define SB_IRQ_9                0x00000200
+#define SB_IRQ_10               0x00000300
+#define MIDI_IRQ_MASK           0x00003800
+#define SERIAL_IRQ_ENABLE       0x00004000
+#define DISABLE_LEGACY          0x00008000
+
+#define PCI_ALLEGRO_CONFIG      0x50
+#define SB_ADDR_240             0x00000004
+#define MPU_ADDR_MASK           0x00000018
+#define MPU_ADDR_330            0x00000000
+#define MPU_ADDR_300            0x00000008
+#define MPU_ADDR_320            0x00000010
+#define MPU_ADDR_340            0x00000018
+#define USE_PCI_TIMING          0x00000040
+#define POSTED_WRITE_ENABLE     0x00000080
+#define DMA_POLICY_MASK         0x00000700
+#define DMA_DDMA                0x00000000
+#define DMA_TDMA                0x00000100
+#define DMA_PCPCI               0x00000200
+#define DMA_WBDMA16             0x00000400
+#define DMA_WBDMA4              0x00000500
+#define DMA_WBDMA2              0x00000600
+#define DMA_WBDMA1              0x00000700
+#define DMA_SAFE_GUARD          0x00000800
+#define HI_PERF_GP_ENABLE       0x00001000
+#define PIC_SNOOP_MODE_0        0x00002000
+#define PIC_SNOOP_MODE_1        0x00004000
+#define SOUNDBLASTER_IRQ_MASK   0x00008000
+#define RING_IN_ENABLE          0x00010000
+#define SPDIF_TEST_MODE         0x00020000
+#define CLK_MULT_MODE_SELECT_2  0x00040000
+#define EEPROM_WRITE_ENABLE     0x00080000
+#define CODEC_DIR_IN            0x00100000
+#define HV_BUTTON_FROM_GD       0x00200000
+#define REDUCED_DEBOUNCE        0x00400000
+#define HV_CTRL_ENABLE          0x00800000
+#define SPDIF_ENABLE            0x01000000
+#define CLK_DIV_SELECT          0x06000000
+#define CLK_DIV_BY_48           0x00000000
+#define CLK_DIV_BY_49           0x02000000
+#define CLK_DIV_BY_50           0x04000000
+#define CLK_DIV_RESERVED        0x06000000
+#define PM_CTRL_ENABLE          0x08000000
+#define CLK_MULT_MODE_SELECT    0x30000000
+#define CLK_MULT_MODE_SHIFT     28
+#define CLK_MULT_MODE_0         0x00000000
+#define CLK_MULT_MODE_1         0x10000000
+#define CLK_MULT_MODE_2         0x20000000
+#define CLK_MULT_MODE_3         0x30000000
+#define INT_CLK_SELECT          0x40000000
+#define INT_CLK_MULT_RESET      0x80000000
+
+/* M3 */
+#define INT_CLK_SRC_NOT_PCI     0x00100000
+#define INT_CLK_MULT_ENABLE     0x80000000
+
+#define PCI_ACPI_CONTROL        0x54
+#define PCI_ACPI_D0             0x00000000
+#define PCI_ACPI_D1             0xB4F70000
+#define PCI_ACPI_D2             0xB4F7B4F7
+
+#define PCI_USER_CONFIG         0x58
+#define EXT_PCI_MASTER_ENABLE   0x00000001
+#define SPDIF_OUT_SELECT        0x00000002
+#define TEST_PIN_DIR_CTRL       0x00000004
+#define AC97_CODEC_TEST         0x00000020
+#define TRI_STATE_BUFFER        0x00000080
+#define IN_CLK_12MHZ_SELECT     0x00000100
+#define MULTI_FUNC_DISABLE      0x00000200
+#define EXT_MASTER_PAIR_SEL     0x00000400
+#define PCI_MASTER_SUPPORT      0x00000800
+#define STOP_CLOCK_ENABLE       0x00001000
+#define EAPD_DRIVE_ENABLE       0x00002000
+#define REQ_TRI_STATE_ENABLE    0x00004000
+#define REQ_LOW_ENABLE          0x00008000
+#define MIDI_1_ENABLE           0x00010000
+#define MIDI_2_ENABLE           0x00020000
+#define SB_AUDIO_SYNC           0x00040000
+#define HV_CTRL_TEST            0x00100000
+#define SOUNDBLASTER_TEST       0x00400000
+
+#define PCI_USER_CONFIG_C       0x5C
+
+#define PCI_DDMA_CTRL           0x60
+#define DDMA_ENABLE             0x00000001
+
+
+/* Allegro registers */
+#define HOST_INT_CTRL           0x18
+#define SB_INT_ENABLE           0x0001
+#define MPU401_INT_ENABLE       0x0002
+#define ASSP_INT_ENABLE         0x0010
+#define RING_INT_ENABLE         0x0020
+#define HV_INT_ENABLE           0x0040
+#define CLKRUN_GEN_ENABLE       0x0100
+#define HV_CTRL_TO_PME          0x0400
+#define SOFTWARE_RESET_ENABLE   0x8000
+
+/*
+ * should be using the above defines, probably.
+ */
+#define REGB_ENABLE_RESET       0x01
+#define REGB_STOP_CLOCK         0x10
+
+#define HOST_INT_STATUS         0x1A
+#define SB_INT_PENDING          0x01
+#define MPU401_INT_PENDING      0x02
+#define ASSP_INT_PENDING        0x10
+#define RING_INT_PENDING        0x20
+#define HV_INT_PENDING          0x40
+
+#define HARDWARE_VOL_CTRL       0x1B
+#define SHADOW_MIX_REG_VOICE    0x1C
+#define HW_VOL_COUNTER_VOICE    0x1D
+#define SHADOW_MIX_REG_MASTER   0x1E
+#define HW_VOL_COUNTER_MASTER   0x1F
+
+#define CODEC_COMMAND           0x30
+#define CODEC_READ_B            0x80
+
+#define CODEC_STATUS            0x30
+#define CODEC_BUSY_B            0x01
+
+#define CODEC_DATA              0x32
+
+#define RING_BUS_CTRL_A         0x36
+#define RAC_PME_ENABLE          0x0100
+#define RAC_SDFS_ENABLE         0x0200
+#define LAC_PME_ENABLE          0x0400
+#define LAC_SDFS_ENABLE         0x0800
+#define SERIAL_AC_LINK_ENABLE   0x1000
+#define IO_SRAM_ENABLE          0x2000
+#define IIS_INPUT_ENABLE        0x8000
+
+#define RING_BUS_CTRL_B         0x38
+#define SECOND_CODEC_ID_MASK    0x0003
+#define SPDIF_FUNC_ENABLE       0x0010
+#define SECOND_AC_ENABLE        0x0020
+#define SB_MODULE_INTF_ENABLE   0x0040
+#define SSPE_ENABLE             0x0040
+#define M3I_DOCK_ENABLE         0x0080
+
+#define SDO_OUT_DEST_CTRL       0x3A
+#define COMMAND_ADDR_OUT        0x0003
+#define PCM_LR_OUT_LOCAL        0x0000
+#define PCM_LR_OUT_REMOTE       0x0004
+#define PCM_LR_OUT_MUTE         0x0008
+#define PCM_LR_OUT_BOTH         0x000C
+#define LINE1_DAC_OUT_LOCAL     0x0000
+#define LINE1_DAC_OUT_REMOTE    0x0010
+#define LINE1_DAC_OUT_MUTE      0x0020
+#define LINE1_DAC_OUT_BOTH      0x0030
+#define PCM_CLS_OUT_LOCAL       0x0000
+#define PCM_CLS_OUT_REMOTE      0x0040
+#define PCM_CLS_OUT_MUTE        0x0080
+#define PCM_CLS_OUT_BOTH        0x00C0
+#define PCM_RLF_OUT_LOCAL       0x0000
+#define PCM_RLF_OUT_REMOTE      0x0100
+#define PCM_RLF_OUT_MUTE        0x0200
+#define PCM_RLF_OUT_BOTH        0x0300
+#define LINE2_DAC_OUT_LOCAL     0x0000
+#define LINE2_DAC_OUT_REMOTE    0x0400
+#define LINE2_DAC_OUT_MUTE      0x0800
+#define LINE2_DAC_OUT_BOTH      0x0C00
+#define HANDSET_OUT_LOCAL       0x0000
+#define HANDSET_OUT_REMOTE      0x1000
+#define HANDSET_OUT_MUTE        0x2000
+#define HANDSET_OUT_BOTH        0x3000
+#define IO_CTRL_OUT_LOCAL       0x0000
+#define IO_CTRL_OUT_REMOTE      0x4000
+#define IO_CTRL_OUT_MUTE        0x8000
+#define IO_CTRL_OUT_BOTH        0xC000
+
+#define SDO_IN_DEST_CTRL        0x3C
+#define STATUS_ADDR_IN          0x0003
+#define PCM_LR_IN_LOCAL         0x0000
+#define PCM_LR_IN_REMOTE        0x0004
+#define PCM_LR_RESERVED         0x0008
+#define PCM_LR_IN_BOTH          0x000C
+#define LINE1_ADC_IN_LOCAL      0x0000
+#define LINE1_ADC_IN_REMOTE     0x0010
+#define LINE1_ADC_IN_MUTE       0x0020
+#define MIC_ADC_IN_LOCAL        0x0000
+#define MIC_ADC_IN_REMOTE       0x0040
+#define MIC_ADC_IN_MUTE         0x0080
+#define LINE2_DAC_IN_LOCAL      0x0000
+#define LINE2_DAC_IN_REMOTE     0x0400
+#define LINE2_DAC_IN_MUTE       0x0800
+#define HANDSET_IN_LOCAL        0x0000
+#define HANDSET_IN_REMOTE       0x1000
+#define HANDSET_IN_MUTE         0x2000
+#define IO_STATUS_IN_LOCAL      0x0000
+#define IO_STATUS_IN_REMOTE     0x4000
+
+#define SPDIF_IN_CTRL           0x3E
+#define SPDIF_IN_ENABLE         0x0001
+
+#define GPIO_DATA               0x60
+#define GPIO_DATA_MASK          0x0FFF
+#define GPIO_HV_STATUS          0x3000
+#define GPIO_PME_STATUS         0x4000
+
+#define GPIO_MASK               0x64
+#define GPIO_DIRECTION          0x68
+#define GPO_PRIMARY_AC97        0x0001
+#define GPI_LINEOUT_SENSE       0x0004
+#define GPO_SECONDARY_AC97      0x0008
+#define GPI_VOL_DOWN            0x0010
+#define GPI_VOL_UP              0x0020
+#define GPI_IIS_CLK             0x0040
+#define GPI_IIS_LRCLK           0x0080
+#define GPI_IIS_DATA            0x0100
+#define GPI_DOCKING_STATUS      0x0100
+#define GPI_HEADPHONE_SENSE     0x0200
+#define GPO_EXT_AMP_SHUTDOWN    0x1000
+
+/* M3 */
+#define GPO_M3_EXT_AMP_SHUTDN   0x0002
+
+#define ASSP_INDEX_PORT         0x80
+#define ASSP_MEMORY_PORT        0x82
+#define ASSP_DATA_PORT          0x84
+
+#define MPU401_DATA_PORT        0x98
+#define MPU401_STATUS_PORT      0x99
+
+#define CLK_MULT_DATA_PORT      0x9C
+
+#define ASSP_CONTROL_A          0xA2
+#define ASSP_0_WS_ENABLE        0x01
+#define ASSP_CTRL_A_RESERVED1   0x02
+#define ASSP_CTRL_A_RESERVED2   0x04
+#define ASSP_CLK_49MHZ_SELECT   0x08
+#define FAST_PLU_ENABLE         0x10
+#define ASSP_CTRL_A_RESERVED3   0x20
+#define DSP_CLK_36MHZ_SELECT    0x40
+
+#define ASSP_CONTROL_B          0xA4
+#define RESET_ASSP              0x00
+#define RUN_ASSP                0x01
+#define ENABLE_ASSP_CLOCK       0x00
+#define STOP_ASSP_CLOCK         0x10
+#define RESET_TOGGLE            0x40
+
+#define ASSP_CONTROL_C          0xA6
+#define ASSP_HOST_INT_ENABLE    0x01
+#define FM_ADDR_REMAP_DISABLE   0x02
+#define HOST_WRITE_PORT_ENABLE  0x08
+
+#define ASSP_HOST_INT_STATUS    0xAC
+#define DSP2HOST_REQ_PIORECORD  0x01
+#define DSP2HOST_REQ_I2SRATE    0x02
+#define DSP2HOST_REQ_TIMER      0x04
+
+/* AC97 registers */
+/* XXX fix this crap up */
+/*#define AC97_RESET              0x00*/
+
+#define AC97_VOL_MUTE_B         0x8000
+#define AC97_VOL_M              0x1F
+#define AC97_LEFT_VOL_S         8
+
+#define AC97_MASTER_VOL         0x02
+#define AC97_LINE_LEVEL_VOL     0x04
+#define AC97_MASTER_MONO_VOL    0x06
+#define AC97_PC_BEEP_VOL        0x0A
+#define AC97_PC_BEEP_VOL_M      0x0F
+#define AC97_SROUND_MASTER_VOL  0x38
+#define AC97_PC_BEEP_VOL_S      1
+
+/*#define AC97_PHONE_VOL          0x0C
+#define AC97_MIC_VOL            0x0E*/
+#define AC97_MIC_20DB_ENABLE    0x40
+
+/*#define AC97_LINEIN_VOL         0x10
+#define AC97_CD_VOL             0x12
+#define AC97_VIDEO_VOL          0x14
+#define AC97_AUX_VOL            0x16*/
+#define AC97_PCM_OUT_VOL        0x18
+/*#define AC97_RECORD_SELECT      0x1A*/
+#define AC97_RECORD_MIC         0x00
+#define AC97_RECORD_CD          0x01
+#define AC97_RECORD_VIDEO       0x02
+#define AC97_RECORD_AUX         0x03
+#define AC97_RECORD_MONO_MUX    0x02
+#define AC97_RECORD_DIGITAL     0x03
+#define AC97_RECORD_LINE        0x04
+#define AC97_RECORD_STEREO      0x05
+#define AC97_RECORD_MONO        0x06
+#define AC97_RECORD_PHONE       0x07
+
+/*#define AC97_RECORD_GAIN        0x1C*/
+#define AC97_RECORD_VOL_M       0x0F
+
+/*#define AC97_GENERAL_PURPOSE    0x20*/
+#define AC97_POWER_DOWN_CTRL    0x26
+#define AC97_ADC_READY          0x0001
+#define AC97_DAC_READY          0x0002
+#define AC97_ANALOG_READY       0x0004
+#define AC97_VREF_ON            0x0008
+#define AC97_PR0                0x0100
+#define AC97_PR1                0x0200
+#define AC97_PR2                0x0400
+#define AC97_PR3                0x0800
+#define AC97_PR4                0x1000
+
+#define AC97_RESERVED1          0x28
+
+#define AC97_VENDOR_TEST        0x5A
+
+#define AC97_CLOCK_DELAY        0x5C
+#define AC97_LINEOUT_MUX_SEL    0x0001
+#define AC97_MONO_MUX_SEL       0x0002
+#define AC97_CLOCK_DELAY_SEL    0x1F
+#define AC97_DAC_CDS_SHIFT      6
+#define AC97_ADC_CDS_SHIFT      11
+
+#define AC97_MULTI_CHANNEL_SEL  0x74
+
+/*#define AC97_VENDOR_ID1         0x7C
+#define AC97_VENDOR_ID2         0x7E*/
+
+/*
+ * ASSP control regs
+ */
+#define DSP_PORT_TIMER_COUNT    0x06
+
+#define DSP_PORT_MEMORY_INDEX   0x80
+
+#define DSP_PORT_MEMORY_TYPE    0x82
+#define MEMTYPE_INTERNAL_CODE   0x0002
+#define MEMTYPE_INTERNAL_DATA   0x0003
+#define MEMTYPE_MASK            0x0003
+
+#define DSP_PORT_MEMORY_DATA    0x84
+
+#define DSP_PORT_CONTROL_REG_A  0xA2
+#define DSP_PORT_CONTROL_REG_B  0xA4
+#define DSP_PORT_CONTROL_REG_C  0xA6
+
+#define REV_A_CODE_MEMORY_BEGIN         0x0000
+#define REV_A_CODE_MEMORY_END           0x0FFF
+#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
+#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
+
+#define REV_B_CODE_MEMORY_BEGIN         0x0000
+#define REV_B_CODE_MEMORY_END           0x0BFF
+#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
+#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
+
+#define REV_A_DATA_MEMORY_BEGIN         0x1000
+#define REV_A_DATA_MEMORY_END           0x2FFF
+#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
+#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
+
+#define REV_B_DATA_MEMORY_BEGIN         0x1000
+#define REV_B_DATA_MEMORY_END           0x2BFF
+#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
+#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
+
+
+#define NUM_UNITS_KERNEL_CODE          16
+#define NUM_UNITS_KERNEL_DATA           2
+
+#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
+#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
+
+/*
+ * Kernel data layout
+ */
+
+#define DP_SHIFT_COUNT                  7
+
+#define KDATA_BASE_ADDR                 0x1000
+#define KDATA_BASE_ADDR2                0x1080
+
+#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
+#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
+#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
+#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
+#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
+#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
+#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
+#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
+#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
+
+#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
+#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
+
+#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
+#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
+#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
+#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
+#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
+#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
+#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
+#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
+#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
+#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
+
+#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
+#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
+
+#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
+#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
+
+#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
+#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
+
+#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
+#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
+#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
+
+#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
+#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
+#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
+#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
+#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
+
+#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
+#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
+#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
+
+#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
+#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
+#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
+
+#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
+#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
+#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
+#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
+#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
+#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
+#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
+#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
+#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
+#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
+
+#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
+#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
+#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
+
+#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
+#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
+
+#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
+#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
+#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
+
+#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
+#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
+#define KDATA_ADC1_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x003D)
+#define KDATA_ADC1_RIGHT_VOLUME  		(KDATA_BASE_ADDR + 0x003E)
+#define KDATA_ADC1_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x003F)
+#define KDATA_ADC1_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0040)
+
+#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
+#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
+#define KDATA_ADC2_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0043)
+#define KDATA_ADC2_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x0044)
+#define KDATA_ADC2_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x0045)
+#define KDATA_ADC2_RIGHT_SUR_VOL		(KDATA_BASE_ADDR + 0x0046)
+
+#define KDATA_CD_XFER0					(KDATA_BASE_ADDR + 0x0047)
+#define KDATA_CD_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x0048)
+#define KDATA_CD_LEFT_VOLUME			(KDATA_BASE_ADDR + 0x0049)
+#define KDATA_CD_RIGHT_VOLUME			(KDATA_BASE_ADDR + 0x004A)
+#define KDATA_CD_LEFT_SUR_VOL			(KDATA_BASE_ADDR + 0x004B)
+#define KDATA_CD_RIGHT_SUR_VOL			(KDATA_BASE_ADDR + 0x004C)
+
+#define KDATA_MIC_XFER0					(KDATA_BASE_ADDR + 0x004D)
+#define KDATA_MIC_XFER_ENDMARK			(KDATA_BASE_ADDR + 0x004E)
+#define KDATA_MIC_VOLUME				(KDATA_BASE_ADDR + 0x004F)
+#define KDATA_MIC_SUR_VOL				(KDATA_BASE_ADDR + 0x0050)
+
+#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
+#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
+
+#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
+#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
+
+#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
+#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
+#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
+#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
+#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
+
+#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
+#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
+
+#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
+#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
+#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
+
+#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
+#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
+
+#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
+
+#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
+#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
+#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
+#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
+#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
+#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
+#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
+#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
+#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
+#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
+#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
+#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
+
+#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
+#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
+#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
+#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
+
+#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
+#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
+
+#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
+#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
+#define KDATA_CD_REQUEST				(KDATA_BASE_ADDR + 0x0076)
+#define KDATA_MIC_REQUEST				(KDATA_BASE_ADDR + 0x0077)
+
+#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
+#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
+#define KDATA_CD_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007A)
+#define KDATA_MIC_MIXER_REQUEST			(KDATA_BASE_ADDR + 0x007B)
+#define KDATA_MIC_SYNC_COUNTER			(KDATA_BASE_ADDR + 0x007C)
+
+/*
+ * second 'segment' (?) reserved for mixer
+ * buffers..
+ */
+
+#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
+#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
+#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
+#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
+#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
+#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
+#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
+#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
+#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
+#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
+#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
+#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
+#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
+#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
+#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
+#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
+
+#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
+#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
+#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
+#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
+#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
+#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
+#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
+#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
+#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
+#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
+#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
+
+#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
+#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
+#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
+#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
+#define KDATA_DAC_LEFT_VOLUME	        (KDATA_BASE_ADDR2 + 0x001F)
+#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
+
+#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
+#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
+#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
+#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
+
+/*
+ * client data area offsets
+ */
+#define CDATA_INSTANCE_READY            0x00
+
+#define CDATA_HOST_SRC_ADDRL            0x01
+#define CDATA_HOST_SRC_ADDRH            0x02
+#define CDATA_HOST_SRC_END_PLUS_1L      0x03
+#define CDATA_HOST_SRC_END_PLUS_1H      0x04
+#define CDATA_HOST_SRC_CURRENTL         0x05
+#define CDATA_HOST_SRC_CURRENTH         0x06
+
+#define CDATA_IN_BUF_CONNECT            0x07
+#define CDATA_OUT_BUF_CONNECT           0x08
+
+#define CDATA_IN_BUF_BEGIN              0x09
+#define CDATA_IN_BUF_END_PLUS_1         0x0A
+#define CDATA_IN_BUF_HEAD               0x0B
+#define CDATA_IN_BUF_TAIL               0x0C
+#define CDATA_OUT_BUF_BEGIN             0x0D
+#define CDATA_OUT_BUF_END_PLUS_1        0x0E
+#define CDATA_OUT_BUF_HEAD              0x0F
+#define CDATA_OUT_BUF_TAIL              0x10
+
+#define CDATA_DMA_CONTROL               0x11
+#define CDATA_RESERVED                  0x12
+
+#define CDATA_FREQUENCY                 0x13
+#define CDATA_LEFT_VOLUME               0x14
+#define CDATA_RIGHT_VOLUME              0x15
+#define CDATA_LEFT_SUR_VOL              0x16
+#define CDATA_RIGHT_SUR_VOL             0x17
+
+#define CDATA_HEADER_LEN                0x18
+
+#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
+#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
+#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
+#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
+#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
+#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
+#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
+#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
+
+#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
+#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
+#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
+#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
+#define MINISRC_BIQUAD_STAGE    2
+#define MINISRC_COEF_LOC          0X175
+
+#define DMACONTROL_BLOCK_MASK           0x000F
+#define  DMAC_BLOCK0_SELECTOR           0x0000
+#define  DMAC_BLOCK1_SELECTOR           0x0001
+#define  DMAC_BLOCK2_SELECTOR           0x0002
+#define  DMAC_BLOCK3_SELECTOR           0x0003
+#define  DMAC_BLOCK4_SELECTOR           0x0004
+#define  DMAC_BLOCK5_SELECTOR           0x0005
+#define  DMAC_BLOCK6_SELECTOR           0x0006
+#define  DMAC_BLOCK7_SELECTOR           0x0007
+#define  DMAC_BLOCK8_SELECTOR           0x0008
+#define  DMAC_BLOCK9_SELECTOR           0x0009
+#define  DMAC_BLOCKA_SELECTOR           0x000A
+#define  DMAC_BLOCKB_SELECTOR           0x000B
+#define  DMAC_BLOCKC_SELECTOR           0x000C
+#define  DMAC_BLOCKD_SELECTOR           0x000D
+#define  DMAC_BLOCKE_SELECTOR           0x000E
+#define  DMAC_BLOCKF_SELECTOR           0x000F
+#define DMACONTROL_PAGE_MASK            0x00F0
+#define  DMAC_PAGE0_SELECTOR            0x0030
+#define  DMAC_PAGE1_SELECTOR            0x0020
+#define  DMAC_PAGE2_SELECTOR            0x0010
+#define  DMAC_PAGE3_SELECTOR            0x0000
+#define DMACONTROL_AUTOREPEAT           0x1000
+#define DMACONTROL_STOPPED              0x2000
+#define DMACONTROL_DIRECTION            0x0100
diff --git a/sys/gnu/vfs/Makefile b/sys/gnu/vfs/Makefile
new file mode 100644
index 0000000..e09e815
--- /dev/null
+++ b/sys/gnu/vfs/Makefile
@@ -0,0 +1,3 @@
+SUBDIR=ext2fs
+
+.include <bsd.subdir.mk>
diff --git a/sys/gnu/vfs/ext2fs/COPYRIGHT.INFO b/sys/gnu/vfs/ext2fs/COPYRIGHT.INFO
new file mode 100644
index 0000000..d475f9b
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/COPYRIGHT.INFO
@@ -0,0 +1,55 @@
+$FreeBSD: src/sys/gnu/ext2fs/COPYRIGHT.INFO,v 1.3 2000/01/01 11:27:50 bde Exp $
+
+Most of the files in this directory are written by Godmar Back or modified
+by him using the CSRG sources.  Those files are covered by the Berkeley-style
+copyright.  However the following files are covered by GPL.  Since the policy
+of the FreeBSD project is to keep the files with the more restrictive
+copyright in the gnu tree and it is a good idea to keep the filesystem code
+all together, the EXT2FS in its entirety resides under the gnu tree.  Note
+that only the files below are under the GPL.  In the eventuality that these
+files are redesigned or rewritten, this tree can be moved back into the less
+restrictive FreeBSD tree.
+
+	ext2_bitmap.c		(in the cvs attic)
+	ext2_fs.h
+	ext2_fs_i.h
+	ext2_fs_sb.h
+	ext2_linux_balloc.c
+	ext2_linux_ialloc.c
+	ext2_super.c		(in the cvs attic)
+	ext2_vfsops.c		(has some GPL'ed code from ext2_super.c)
+	i386-bitops.h
+
+PS.
+	THANKS GODMAR!!!
+
+Note that this port has been modified by John Dyson and others on
+the FreeBSD team, and it is best to send the bug reports to the FreeBSD
+team.  If there are any non-FreeBSD specific bugs, fixes will be sent to
+Godmar to help him fix the original code base.  It is also our intention
+to send Godmar any FreeBSD specific porting changes so that he can keep
+control of his code....
+
+John
+dyson@freebsd.org
+
+		-----------------------------------------
+				04 April 2006
+
+    EXT2 has been divorced from UFS.  The following files have been copied
+    from the UFS tree and renamed:
+
+	dinode.h
+	dir.h
+	ext2_bmap.c
+	ext2_ihash.c
+	ext2_quota.c
+	ext2mount.h
+	inode.h
+	quota.h
+
+    In addition, all other UFS procedures that EXT2 used to call,
+    especially in ext2_vnops.c and ext2_vfsops.c, have been copied from
+    the UFS tree into the EXT2 tree and renamed.
+
+				Matthew Dillon <dillon@apollo.backplane.com>
diff --git a/sys/gnu/vfs/ext2fs/Makefile b/sys/gnu/vfs/ext2fs/Makefile
new file mode 100644
index 0000000..4e6f8c2
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD: src/sys/modules/ext2fs/Makefile,v 1.4.2.1 2002/08/06 14:14:25 mdodd Exp $
+
+KMOD=	ext2fs
+SRCS=	opt_ddb.h opt_quota.h opt_suiddir.h \
+	ext2_alloc.c ext2_balloc.c ext2_inode.c ext2_inode_cnv.c \
+	ext2_linux_balloc.c ext2_linux_ialloc.c ext2_lookup.c \
+	ext2_subr.c ext2_vfsops.c ext2_vnops.c ext2_bmap.c \
+	ext2_ihash.c ext2_quota.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/gnu/vfs/ext2fs/dinode.h b/sys/gnu/vfs/ext2fs/dinode.h
new file mode 100644
index 0000000..c807d48
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/dinode.h
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 1982, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)dinode.h	8.3 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.7 1999/08/28 00:52:27 peter Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_DINODE_H_
+#define _VFS_GNU_EXT2FS_DINODE_H_
+
+typedef __uint32_t	ext2_ino_t;
+
+/*
+ * The root inode is the root of the filesystem.  Inode 0 can't be used for
+ * normal purposes and historically bad blocks were linked to inode 1, thus
+ * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
+ * numerous dump tapes make this assumption, so we are stuck with it).
+ */
+#define	ROOTINO	((ino_t)2)
+
+/*
+ * The Whiteout inode# is a dummy non-zero inode number which will
+ * never be allocated to a real file.  It is used as a place holder
+ * in the directory entry which has been tagged as a DT_W entry.
+ * See the comments about ROOTINO above.
+ */
+#define	WINO	((ino_t)1)
+
+/*
+ * A dinode contains all the meta-data associated with a EXT2 file.
+ * This structure defines the on-disk format of a dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+
+typedef __int32_t       ext2_daddr_t;
+
+#define	NDADDR	12			/* Direct addresses in inode. */
+#define	NIADDR	3			/* Indirect addresses in inode. */
+
+struct ext2_dinode {
+	uint16_t	di_mode;	/*   0: IFMT, permissions; see below. */
+	int16_t		di_nlink;	/*   2: File link count. */
+	union {
+		uint16_t oldids[2];	/*   4: Ffs: old user and group ids. */
+		int32_t	  inumber;	/*   4: Lfs: inode number. */
+	} di_u;
+	uint64_t	di_size;	/*   8: File byte count. */
+	int32_t		di_atime;	/*  16: Last access time. */
+	int32_t		di_atimensec;	/*  20: Last access time. */
+	int32_t		di_mtime;	/*  24: Last modified time. */
+	int32_t		di_mtimensec;	/*  28: Last modified time. */
+	int32_t		di_ctime;	/*  32: Last inode change time. */
+	int32_t		di_ctimensec;	/*  36: Last inode change time. */
+	ext2_daddr_t	di_db[NDADDR];	/*  40: Direct disk blocks. */
+	ext2_daddr_t	di_ib[NIADDR];	/*  88: Indirect disk blocks. */
+	uint32_t	di_flags;	/* 100: Status flags (chflags). */
+	int32_t		di_blocks;	/* 104: Blocks actually held. */
+	int32_t		di_gen;		/* 108: Generation number. */
+	uint32_t	di_uid;		/* 112: File owner. */
+	uint32_t	di_gid;		/* 116: File group. */
+	int32_t		di_spare[2];	/* 120: used by ext2fs */
+};
+
+/*
+ * The di_db fields may be overlaid with other information for
+ * file types that do not have associated disk storage. Block
+ * and character devices overlay the first data block with their
+ * cdev_t value. Short symbolic links place their path in the
+ * di_db area.
+ */
+#define	di_inumber	di_u.inumber
+#define	di_ogid		di_u.oldids[1]
+#define	di_ouid		di_u.oldids[0]
+#define	di_rdev		di_db[0]
+#define	di_shortlink	di_db
+#define	MAXSYMLINKLEN	((NDADDR + NIADDR) * sizeof(ext2_daddr_t))
+
+/* File permissions. */
+#define	IEXEC		0000100		/* Executable. */
+#define	IWRITE		0000200		/* Writeable. */
+#define	IREAD		0000400		/* Readable. */
+#define	ISVTX		0001000		/* Sticky bit. */
+#define	ISGID		0002000		/* Set-gid. */
+#define	ISUID		0004000		/* Set-uid. */
+
+/* File types. */
+#define	IFMT		0170000		/* Mask of file type. */
+#define	IFIFO		0010000		/* Named pipe (fifo). */
+#define	IFCHR		0020000		/* Character device. */
+#define	IFDIR		0040000		/* Directory file. */
+#define	IFBLK		0060000		/* Block device. */
+#define	IFREG		0100000		/* Regular file. */
+#define	IFLNK		0120000		/* Symbolic link. */
+#define	IFSOCK		0140000		/* UNIX domain socket. */
+#define	IFWHT		0160000		/* Whiteout. */
+
+#endif /* !_VFS_GNU_EXT2FS_DINODE_H_ */
diff --git a/sys/gnu/vfs/ext2fs/dir.h b/sys/gnu/vfs/ext2fs/dir.h
new file mode 100644
index 0000000..9103a3a
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/dir.h
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)dir.h	8.2 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/ufs/ufs/dir.h,v 1.9 1999/08/28 00:52:27 peter Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_DIR_H_
+#define	_VFS_GNU_EXT2FS_DIR_H_
+
+/*
+ * Theoretically, directories can be more than 2Gb in length, however, in
+ * practice this seems unlikely. So, we define the type doff_t as a 32-bit
+ * quantity to keep down the cost of doing lookup on a 32-bit machine.
+ */
+#define	doff_t		int32_t
+#define MAXDIRSIZE	(0x7fffffff)
+
+/*
+ * A directory consists of some number of blocks of DIRBLKSIZ
+ * bytes, where DIRBLKSIZ is chosen such that it can be transferred
+ * to disk in a single atomic operation (e.g. 512 bytes on most machines).
+ *
+ * Each DIRBLKSIZ byte block contains some number of directory entry
+ * structures, which are of variable length.  Each directory entry has
+ * a struct direct at the front of it, containing its inode number,
+ * the length of the entry, and the length of the name contained in
+ * the entry.  These are followed by the name padded to a 4 byte boundary
+ * with null bytes.  All names are guaranteed null terminated.
+ * The maximum length of a name in a directory is MAXNAMLEN.
+ *
+ * The macro DIRSIZ(fmt, dp) gives the amount of space required to represent
+ * a directory entry.  Free space in a directory is represented by
+ * entries which have dp->d_reclen > DIRSIZ(fmt, dp).  All DIRBLKSIZ bytes
+ * in a directory block are claimed by the directory entries.  This
+ * usually results in the last entry in a directory having a large
+ * dp->d_reclen.  When entries are deleted from a directory, the
+ * space is returned to the previous entry in the same directory
+ * block by increasing its dp->d_reclen.  If the first entry of
+ * a directory block is free, then its dp->d_ino is set to 0.
+ * Entries other than the first in a directory do not normally have
+ * dp->d_ino set to 0.
+ */
+#define DIRBLKSIZ	DEV_BSIZE
+#define	MAXNAMLEN	255
+
+struct	direct {
+	uint32_t d_ino;		/* inode number of entry */
+	uint16_t d_reclen;		/* length of this record */
+	uint8_t  d_type; 		/* file type, see below */
+	uint8_t  d_namlen;		/* length of string in d_name */
+	char	  d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
+};
+
+/*
+ * File types
+ */
+#define	DT_UNKNOWN	 0
+#define	DT_FIFO		 1
+#define	DT_CHR		 2
+#define	DT_DIR		 4
+#define	DT_BLK		 6
+#define	DT_REG		 8
+#define	DT_LNK		10
+#define	DT_SOCK		12
+#define	DT_WHT		14
+
+/*
+ * Convert between stat structure types and directory types.
+ */
+#define	IFTODT(mode)	(((mode) & 0170000) >> 12)
+#define	DTTOIF(dirtype)	((dirtype) << 12)
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry.  This requires the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ *
+ *
+ */
+#define	DIRECTSIZ(namlen)						\
+	(((int)&((struct direct *)0)->d_name +				\
+	  ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3)
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define DIRSIZ(oldfmt, dp) \
+    ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
+#else
+#define DIRSIZ(oldfmt, dp) \
+    DIRECTSIZ((dp)->d_namlen)
+#endif
+#define OLDDIRFMT	1
+#define NEWDIRFMT	0
+
+/*
+ * Template for manipulating directories.  Should use struct direct's,
+ * but the name field is MAXNAMLEN - 1, and this just won't do.
+ */
+struct dirtemplate {
+	uint32_t	dot_ino;
+	int16_t		dot_reclen;
+	uint8_t	dot_type;
+	uint8_t	dot_namlen;
+	char		dot_name[4];	/* must be multiple of 4 */
+	uint32_t	dotdot_ino;
+	int16_t		dotdot_reclen;
+	uint8_t	dotdot_type;
+	uint8_t	dotdot_namlen;
+	char		dotdot_name[4];	/* ditto */
+};
+
+/*
+ * This is the old format of directories, sanz type element.
+ */
+struct odirtemplate {
+	uint32_t	dot_ino;
+	int16_t		dot_reclen;
+	uint16_t	dot_namlen;
+	char		dot_name[4];	/* must be multiple of 4 */
+	uint32_t	dotdot_ino;
+	int16_t		dotdot_reclen;
+	uint16_t	dotdot_namlen;
+	char		dotdot_name[4];	/* ditto */
+};
+#endif /* _VFS_GNU_EXT2FS_DIR_H_ */
diff --git a/sys/gnu/vfs/ext2fs/ext2_alloc.c b/sys/gnu/vfs/ext2fs/ext2_alloc.c
new file mode 100644
index 0000000..ce53409
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_alloc.c
@@ -0,0 +1,537 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ext2_alloc.c	8.8 (Berkeley) 2/21/94
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_alloc.c,v 1.28.2.2 2002/07/01 00:18:51 iedowse Exp $
+ */
+
+#include "opt_quota.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/vnode.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/syslog.h>
+
+#include <machine/inttypes.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "ext2mount.h"
+
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+#include "ext2_extern.h"
+
+static void	ext2_fserr (struct ext2_sb_info *, u_int, char *);
+
+/*
+ * Linux calls this functions at the following locations:
+ * (1) the inode is freed
+ * (2) a preallocation miss occurs
+ * (3) truncate is called
+ * (4) release_file is called and f_mode & 2
+ *
+ * I call it in ext2_inactive, ext2_truncate, ext2_vfree and in (2)
+ * the call in vfree might be redundant
+ */
+void
+ext2_discard_prealloc(struct inode *ip)
+{
+#ifdef EXT2_PREALLOCATE
+        if (ip->i_prealloc_count) {
+                int i = ip->i_prealloc_count;
+                ip->i_prealloc_count = 0;
+                ext2_free_blocks (ITOV(ip)->v_mount,
+                                  ip->i_prealloc_block,
+                                  i);
+        }
+#endif
+}
+
+/*
+ * Allocate a block in the file system.
+ *
+ * this takes the framework from ffs_alloc. To implement the
+ * actual allocation, it calls ext2_new_block, the ported version
+ * of the same Linux routine.
+ *
+ * we note that this is always called in connection with ext2_blkpref
+ *
+ * preallocation is done as Linux does it
+ */
+int
+ext2_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size,
+	   struct ucred *cred, daddr_t *bnp)
+{
+	struct ext2_sb_info *fs;
+	daddr_t bno;
+#if QUOTA
+	int error;
+#endif
+
+	*bnp = 0;
+	fs = ip->i_e2fs;
+#if DIAGNOSTIC
+	if ((u_int)size > fs->s_blocksize || blkoff(fs, size) != 0) {
+		kprintf("dev = %s, bsize = %lu, size = %d, fs = %s\n",
+		    devtoname(ip->i_dev), fs->s_blocksize, size, fs->fs_fsmnt);
+		panic("ext2_alloc: bad size");
+	}
+	if (cred == NOCRED)
+		panic("ext2_alloc: missing credential");
+#endif /* DIAGNOSTIC */
+	if (size == fs->s_blocksize && fs->s_es->s_free_blocks_count == 0)
+		goto nospace;
+	if (cred->cr_uid != 0 &&
+		fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count)
+		goto nospace;
+#if QUOTA
+	if ((error = ext2_chkdq(ip, (long)btodb(size), cred, 0)) != 0)
+		return (error);
+#endif
+	if (bpref >= fs->s_es->s_blocks_count)
+		bpref = 0;
+	/* call the Linux code */
+#ifdef EXT2_PREALLOCATE
+	/* To have a preallocation hit, we must
+	 * - have at least one block preallocated
+	 * - and our preferred block must have that block number or one below
+	 */
+        if (ip->i_prealloc_count &&
+            (bpref == ip->i_prealloc_block ||
+             bpref + 1 == ip->i_prealloc_block))
+        {
+                bno = ip->i_prealloc_block++;
+                ip->i_prealloc_count--;
+                /* ext2_debug ("preallocation hit (%lu/%lu).\n",
+                            ++alloc_hits, ++alloc_attempts); */
+
+		/* Linux gets, clears, and releases the buffer at this
+		   point - we don't have to that; we leave it to the caller
+		 */
+        } else {
+                ext2_discard_prealloc (ip);
+                /* ext2_debug ("preallocation miss (%lu/%lu).\n",
+                            alloc_hits, ++alloc_attempts); */
+                if (S_ISREG(ip->i_mode))
+                        bno = ext2_new_block
+                                (ITOV(ip)->v_mount, bpref,
+                                 &ip->i_prealloc_count,
+                                 &ip->i_prealloc_block);
+                else
+			bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount,
+					bpref, 0, 0);
+        }
+#else
+	bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, bpref, 0, 0);
+#endif
+
+	if (bno > 0) {
+		/* set next_alloc fields as done in block_getblk */
+		ip->i_next_alloc_block = lbn;
+		ip->i_next_alloc_goal = bno;
+
+		ip->i_blocks += btodb(size);
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		*bnp = bno;
+		return (0);
+	}
+#if QUOTA
+	/*
+	 * Restore user's disk quota because allocation failed.
+	 */
+	ext2_chkdq(ip, (long)-btodb(size), cred, FORCE);
+#endif
+nospace:
+	ext2_fserr(fs, cred->cr_uid, "file system full");
+	uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
+	return (ENOSPC);
+}
+
+/*
+ * Reallocate a sequence of blocks into a contiguous sequence of blocks.
+ *
+ * The vnode and an array of buffer pointers for a range of sequential
+ * logical blocks to be made contiguous is given. The allocator attempts
+ * to find a range of sequential blocks starting as close as possible to
+ * an fs_rotdelay offset from the end of the allocation for the logical
+ * block immediately preceeding the current range. If successful, the
+ * physical block numbers in the buffer pointers and in the inode are
+ * changed to reflect the new allocation. If unsuccessful, the allocation
+ * is left unchanged. The success in doing the reallocation is returned.
+ * Note that the error return is not reflected back to the user. Rather
+ * the previous block allocation will be used.
+ */
+
+#ifdef FANCY_REALLOC
+#include <sys/sysctl.h>
+static int doasyncfree = 1;
+#ifdef	OPT_DEBUG
+SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
+#endif	/* OPT_DEBUG */
+#endif
+
+/*
+ * ext2_reallocblks(struct vnode *a_vp, struct cluster_save *a_buflist)
+ */
+int
+ext2_reallocblks(struct vop_reallocblks_args *ap)
+{
+#ifndef FANCY_REALLOC
+/* kprintf("ext2_reallocblks not implemented\n"); */
+return ENOSPC;
+#else
+
+	struct ext2_sb_info *fs;
+	struct inode *ip;
+	struct vnode *vp;
+	struct buf *sbp, *ebp;
+	daddr_t *bap, *sbap, *ebap;
+	struct cluster_save *buflist;
+	daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno;
+	struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
+	int i, len, start_lvl, end_lvl, pref, ssize;
+
+	vp = ap->a_vp;
+	ip = VTOI(vp);
+	fs = ip->i_e2fs;
+#ifdef UNKLAR
+	if (fs->fs_contigsumsize <= 0)
+		return (ENOSPC);
+#endif
+	buflist = ap->a_buflist;
+	len = buflist->bs_nchildren;
+	start_lbn = lblkno(fs, buflist->bs_children[0]->b_loffset);
+	end_lbn = start_lbn + len - 1;
+#if DIAGNOSTIC
+	for (i = 1; i < len; i++) {
+		if (buflist->bs_children[i]->b_loffset != lblktodoff(fs, start_lbn) + lblktodoff(fs, i))
+			panic("ext2_reallocblks: non-cluster");
+	}
+#endif
+	/*
+	 * If the latest allocation is in a new cylinder group, assume that
+	 * the filesystem has decided to move and do not force it back to
+	 * the previous cylinder group.
+	 */
+	if (dtog(fs, dofftofsb(fs, buflist->bs_children[0]->b_bio2.bio_offset)) !=
+	    dtog(fs, dofftofsb(fs, buflist->bs_children[len - 1]->b_bio2.bio_offset)))
+		return (ENOSPC);
+	if (ext2_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
+	    ext2_getlbns(vp, end_lbn, end_ap, &end_lvl))
+		return (ENOSPC);
+	/*
+	 * Get the starting offset and block map for the first block.
+	 */
+	if (start_lvl == 0) {
+		sbap = &ip->i_db[0];
+		soff = start_lbn;
+	} else {
+		idp = &start_ap[start_lvl - 1];
+		if (bread(vp, lblktodoff(fs, idp->in_lbn), (int)fs->s_blocksize, NOCRED, &sbp)) {
+			brelse(sbp);
+			return (ENOSPC);
+		}
+		sbap = (daddr_t *)sbp->b_data;
+		soff = idp->in_off;
+	}
+	/*
+	 * Find the preferred location for the cluster.
+	 */
+	pref = ext2_blkpref(ip, start_lbn, soff, sbap);
+	/*
+	 * If the block range spans two block maps, get the second map.
+	 */
+	if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
+		ssize = len;
+	} else {
+#if DIAGNOSTIC
+		if (start_ap[start_lvl-1].in_lbn == idp->in_lbn)
+			panic("ext2_reallocblk: start == end");
+#endif
+		ssize = len - (idp->in_off + 1);
+		if (bread(vp, lblktodoff(fs, idp->in_lbn), (int)fs->s_blocksize, NOCRED, &ebp))
+			goto fail;
+		ebap = (daddr_t *)ebp->b_data;
+	}
+	/*
+	 * Search the block map looking for an allocation of the desired size.
+	 */
+	if ((newblk = (daddr_t)ext2_hashalloc(ip, dtog(fs, pref), (long)pref,
+	    len, (u_long (*)())ext2_clusteralloc)) == 0)
+		goto fail;
+	/*
+	 * We have found a new contiguous block.
+	 *
+	 * First we have to replace the old block pointers with the new
+	 * block pointers in the inode and indirect blocks associated
+	 * with the file.
+	 */
+	blkno = newblk;
+	for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
+		if (i == ssize)
+			bap = ebap;
+#if DIAGNOSTIC
+		if (buflist->bs_children[i]->b_bio2.bio_offset != fsbtodoff(fs, *bap))
+			panic("ext2_reallocblks: alloc mismatch");
+#endif
+		*bap++ = blkno;
+	}
+	/*
+	 * Next we must write out the modified inode and indirect blocks.
+	 * For strict correctness, the writes should be synchronous since
+	 * the old block values may have been written to disk. In practise
+	 * they are almost never written, but if we are concerned about
+	 * strict correctness, the `doasyncfree' flag should be set to zero.
+	 *
+	 * The test on `doasyncfree' should be changed to test a flag
+	 * that shows whether the associated buffers and inodes have
+	 * been written. The flag should be set when the cluster is
+	 * started and cleared whenever the buffer or inode is flushed.
+	 * We can then check below to see if it is set, and do the
+	 * synchronous write only when it has been cleared.
+	 */
+	if (sbap != &ip->i_db[0]) {
+		if (doasyncfree)
+			bdwrite(sbp);
+		else
+			bwrite(sbp);
+	} else {
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		if (!doasyncfree)
+			EXT2_UPDATE(vp, 1);
+	}
+	if (ssize < len)
+		if (doasyncfree)
+			bdwrite(ebp);
+		else
+			bwrite(ebp);
+	/*
+	 * Last, free the old blocks and assign the new blocks to the buffers.
+	 */
+	for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
+		ext2_blkfree(ip, dofftofsb(fs, buflist->bs_children[i]->b_bio2.bio_offset),
+		    fs->s_blocksize);
+		buflist->bs_children[i]->b_bio2.bio_offset = fsbtodoff(fs, blkno);
+	}
+	return (0);
+
+fail:
+	if (ssize < len)
+		brelse(ebp);
+	if (sbap != &ip->i_db[0])
+		brelse(sbp);
+	return (ENOSPC);
+
+#endif /* FANCY_REALLOC */
+}
+
+/*
+ * Allocate an inode in the file system.
+ *
+ * we leave the actual allocation strategy to the (modified)
+ * ext2_new_inode(), to make sure we get the policies right
+ */
+int
+ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp)
+{
+	struct inode *pip;
+	struct ext2_sb_info *fs;
+	struct inode *ip;
+	ino_t ino;
+	int i, error;
+
+	*vpp = NULL;
+	pip = VTOI(pvp);
+	fs = pip->i_e2fs;
+	if (fs->s_es->s_free_inodes_count == 0)
+		goto noinodes;
+
+	/* call the Linux routine - it returns the inode number only */
+	ino = ext2_new_inode(pip, mode);
+
+	if (ino == 0)
+		goto noinodes;
+	error = VFS_VGET(pvp->v_mount, NULL, ino, vpp);
+	if (error) {
+		EXT2_VFREE(pvp, ino, mode);
+		return (error);
+	}
+	ip = VTOI(*vpp);
+
+	/*
+	  the question is whether using VGET was such good idea at all -
+	  Linux doesn't read the old inode in when it's allocating a
+	  new one. I will set at least i_size & i_blocks the zero.
+	*/
+	ip->i_mode = 0;
+	ip->i_size = 0;
+	ip->i_blocks = 0;
+	ip->i_flags = 0;
+        /* now we want to make sure that the block pointers are zeroed out */
+        for (i = 0; i < NDADDR; i++)
+                ip->i_db[i] = 0;
+        for (i = 0; i < NIADDR; i++)
+                ip->i_ib[i] = 0;
+
+	/*
+	 * Set up a new generation number for this inode.
+	 * XXX check if this makes sense in ext2
+	 */
+	if (ip->i_gen == 0 || ++ip->i_gen == 0)
+		ip->i_gen = krandom() / 2 + 1;
+/*
+kprintf("ext2_valloc: allocated inode %d\n", ino);
+*/
+	return (0);
+noinodes:
+	ext2_fserr(fs, cred->cr_uid, "out of inodes");
+	uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
+	return (ENOSPC);
+}
+
+/*
+ * Select the desired position for the next block in a file.
+ *
+ * we try to mimic what Remy does in inode_getblk/block_getblk
+ *
+ * we note: blocknr == 0 means that we're about to allocate either
+ * a direct block or a pointer block at the first level of indirection
+ * (In other words, stuff that will go in i_db[] or i_ib[])
+ *
+ * blocknr != 0 means that we're allocating a block that is none
+ * of the above. Then, blocknr tells us the number of the block
+ * that will hold the pointer
+ */
+daddr_t
+ext2_blkpref(struct inode *ip, daddr_t lbn, int indx, daddr_t *bap,
+	     daddr_t blocknr)
+{
+	int	tmp;
+
+	/*
+	 * if the next block is actually what we thought it is,
+	 * then set the goal to what we thought it should be
+	 */
+	if (ip->i_next_alloc_block == lbn && ip->i_next_alloc_goal != 0)
+		return ip->i_next_alloc_goal;
+
+	/* now check whether we were provided with an array that basically
+	   tells us previous blocks to which we want to stay closeby
+	*/
+	if(bap)
+                for (tmp = indx - 1; tmp >= 0; tmp--)
+			if (bap[tmp])
+				return bap[tmp];
+
+	/*
+	 * else let's fall back to the blocknr, or, if there is none,
+	 * follow the rule that a block should be allocated near its inode
+	 */
+	return blocknr ? blocknr :
+			(daddr_t)(ip->i_block_group *
+			EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) +
+			ip->i_e2fs->s_es->s_first_data_block;
+}
+
+/*
+ * Free a block or fragment.
+ *
+ * pass on to the Linux code
+ */
+void
+ext2_blkfree(struct inode *ip, daddr_t bno, long size)
+{
+	struct ext2_sb_info *fs;
+
+	fs = ip->i_e2fs;
+	/*
+	 *	call Linux code with mount *, block number, count
+	 */
+	ext2_free_blocks(ITOV(ip)->v_mount, bno, size / fs->s_frag_size);
+}
+
+/*
+ * Free an inode.
+ *
+ * the maintenance of the actual bitmaps is again up to the linux code
+ */
+int
+ext2_vfree(struct vnode *pvp, ino_t ino, int mode)
+{
+	struct ext2_sb_info *fs;
+	struct inode *pip;
+	mode_t save_i_mode;
+
+	pip = VTOI(pvp);
+	fs = pip->i_e2fs;
+	if ((u_int)ino > fs->s_inodes_per_group * fs->s_groups_count)
+		panic("ext2_vfree: range: dev = (%d, %d), ino = %"PRId64", fs = %s",
+		    major(pip->i_dev), minor(pip->i_dev), ino, fs->fs_fsmnt);
+
+/* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, mode);
+ */
+	ext2_discard_prealloc(pip);
+
+	/* we need to make sure that ext2_free_inode can adjust the
+	   used_dir_counts in the group summary information - I'd
+	   really like to know what the rationale behind this
+	   'set i_mode to zero to denote an unused inode' is
+	 */
+	save_i_mode = pip->i_mode;
+	pip->i_mode = mode;
+	ext2_free_inode(pip);
+	pip->i_mode = save_i_mode;
+	return (0);
+}
+
+/*
+ * Fserr prints the name of a file system with an error diagnostic.
+ *
+ * The form of the error message is:
+ *	fs: error message
+ */
+static void
+ext2_fserr(struct ext2_sb_info *fs, u_int uid, char *cp)
+{
+	log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_balloc.c b/sys/gnu/vfs/ext2fs/ext2_balloc.c
new file mode 100644
index 0000000..e1547a3
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_balloc.c
@@ -0,0 +1,313 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ffs_balloc.c	8.4 (Berkeley) 9/23/93
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_balloc.c,v 1.9.2.1 2000/08/03 00:52:57 peter Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/lock.h>
+#include <sys/ucred.h>
+#include <sys/vnode.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+#include "ext2_extern.h"
+
+/*
+ * Balloc defines the structure of file system storage
+ * by allocating the physical blocks on a device given
+ * the inode and the logical block number in a file.
+ */
+int
+ext2_balloc(struct inode *ip, daddr_t bn, int size, struct ucred *cred,
+	    struct buf **bpp, int flags)
+{
+	struct ext2_sb_info *fs;
+	daddr_t nb;
+	struct buf *bp, *nbp;
+	struct vnode *vp = ITOV(ip);
+	struct indir indirs[NIADDR + 2];
+	daddr_t newb, lbn, *bap, pref;
+	int osize, nsize, num, i, error;
+/*
+ext2_debug("ext2_balloc called (%d, %d, %d)\n",
+	ip->i_number, (int)bn, (int)size);
+*/
+	*bpp = NULL;
+	if (bn < 0)
+		return (EFBIG);
+	fs = ip->i_e2fs;
+	lbn = bn;
+
+	/*
+	 * check if this is a sequential block allocation.
+	 * If so, increment next_alloc fields to allow ext2_blkpref
+	 * to make a good guess
+	 */
+        if (lbn == ip->i_next_alloc_block + 1) {
+		ip->i_next_alloc_block++;
+		ip->i_next_alloc_goal++;
+	}
+
+	/*
+	 * The first NDADDR blocks are direct blocks
+	 */
+	if (bn < NDADDR) {
+		nb = ip->i_db[bn];
+		/* no new block is to be allocated, and no need to expand
+		   the file */
+		if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) {
+			error = bread(vp, lblktodoff(fs, bn),
+				      fs->s_blocksize, &bp);
+			if (error) {
+				brelse(bp);
+				return (error);
+			}
+			*bpp = bp;
+			return (0);
+		}
+		if (nb != 0) {
+			/*
+			 * Consider need to reallocate a fragment.
+			 */
+			osize = fragroundup(fs, blkoff(fs, ip->i_size));
+			nsize = fragroundup(fs, size);
+			if (nsize <= osize) {
+				error = bread(vp, lblktodoff(fs, bn),
+					      osize, &bp);
+				if (error) {
+					brelse(bp);
+					return (error);
+				}
+			} else {
+			/* Godmar thinks: this shouldn't happen w/o fragments */
+				kprintf("nsize %d(%d) > osize %d(%d) nb %d\n",
+					(int)nsize, (int)size, (int)osize,
+					(int)ip->i_size, (int)nb);
+				panic(
+				    "ext2_balloc: Something is terribly wrong");
+/*
+ * please note there haven't been any changes from here on -
+ * FFS seems to work.
+ */
+			}
+		} else {
+			if (ip->i_size < (bn + 1) * fs->s_blocksize)
+				nsize = fragroundup(fs, size);
+			else
+				nsize = fs->s_blocksize;
+			error = ext2_alloc(ip, bn,
+			    ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0),
+			    nsize, cred, &newb);
+			if (error)
+				return (error);
+			bp = getblk(vp, lblktodoff(fs, bn), nsize, 0, 0);
+			bp->b_bio2.bio_offset = fsbtodoff(fs, newb);
+			if (flags & B_CLRBUF)
+				vfs_bio_clrbuf(bp);
+		}
+		ip->i_db[bn] = dofftofsb(fs, bp->b_bio2.bio_offset);
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		*bpp = bp;
+		return (0);
+	}
+	/*
+	 * Determine the number of levels of indirection.
+	 */
+	pref = 0;
+	if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0)
+		return(error);
+#if DIAGNOSTIC
+	if (num < 1)
+		panic ("ext2_balloc: ext2_bmaparray returned indirect block");
+#endif
+	/*
+	 * Fetch the first indirect block allocating if necessary.
+	 */
+	--num;
+	nb = ip->i_ib[indirs[0].in_off];
+	if (nb == 0) {
+#if 0
+		pref = ext2_blkpref(ip, lbn, 0, NULL, 0);
+#else
+		/* see the comment by ext2_blkpref. What we do here is
+		   to pretend that it'd be good for a block holding indirect
+		   pointers to be allocated near its predecessor in terms
+		   of indirection, or the last direct block.
+		   We shamelessly exploit the fact that i_ib immediately
+		   follows i_db.
+		   Godmar thinks it make sense to allocate i_ib[0] immediately
+		   after i_db[11], but it's not utterly clear whether this also
+		   applies to i_ib[1] and i_ib[0]
+		*/
+
+		pref = ext2_blkpref(ip, lbn, indirs[0].in_off +
+					     EXT2_NDIR_BLOCKS, &ip->i_db[0], 0);
+#endif
+	        if ((error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize,
+		    cred, &newb)) != 0)
+			return (error);
+		nb = newb;
+		bp = getblk(vp, lblktodoff(fs, indirs[1].in_lbn),
+			    fs->s_blocksize, 0, 0);
+		bp->b_bio2.bio_offset = fsbtodoff(fs, newb);
+		vfs_bio_clrbuf(bp);
+		/*
+		 * Write synchronously so that indirect blocks
+		 * never point at garbage.
+		 */
+		if ((error = bwrite(bp)) != 0) {
+			ext2_blkfree(ip, nb, fs->s_blocksize);
+			return (error);
+		}
+		ip->i_ib[indirs[0].in_off] = newb;
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	}
+	/*
+	 * Fetch through the indirect blocks, allocating as necessary.
+	 */
+	for (i = 1;;) {
+		error = bread(vp,
+			      lblktodoff(fs, indirs[i].in_lbn),
+			      (int)fs->s_blocksize, &bp);
+		if (error) {
+			brelse(bp);
+			return (error);
+		}
+		bap = (daddr_t *)bp->b_data;
+		nb = bap[indirs[i].in_off];
+		if (i == num)
+			break;
+		i += 1;
+		if (nb != 0) {
+			brelse(bp);
+			continue;
+		}
+		if (pref == 0)
+#if 1
+			/* see the comment above and by ext2_blkpref
+			 * I think this implements Linux policy, but
+			 * does it really make sense to allocate to
+			 * block containing pointers together ?
+			 * Also, will it ever succeed ?
+			 */
+			pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap,
+						lblkno(fs, bp->b_loffset));
+#else
+			pref = ext2_blkpref(ip, lbn, 0, NULL, 0);
+#endif
+		if ((error =
+		    ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) {
+			brelse(bp);
+			return (error);
+		}
+		nb = newb;
+		nbp = getblk(vp, lblktodoff(fs, indirs[i].in_lbn),
+			     fs->s_blocksize, 0, 0);
+		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
+		vfs_bio_clrbuf(nbp);
+		/*
+		 * Write synchronously so that indirect blocks
+		 * never point at garbage.
+		 */
+		if ((error = bwrite(nbp)) != 0) {
+			ext2_blkfree(ip, nb, fs->s_blocksize);
+			brelse(bp);
+			return (error);
+		}
+		bap[indirs[i - 1].in_off] = nb;
+		/*
+		 * If required, write synchronously, otherwise use
+		 * delayed write.
+		 */
+		if (flags & B_SYNC) {
+			bwrite(bp);
+		} else {
+			bdwrite(bp);
+		}
+	}
+	/*
+	 * Get the data block, allocating if necessary.
+	 */
+	if (nb == 0) {
+		pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0],
+				lblkno(fs, bp->b_loffset));
+		if ((error = ext2_alloc(ip,
+		    lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) {
+			brelse(bp);
+			return (error);
+		}
+		nb = newb;
+		nbp = getblk(vp, lblktodoff(fs, lbn), fs->s_blocksize, 0, 0);
+		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
+		if (flags & B_CLRBUF)
+			vfs_bio_clrbuf(nbp);
+		bap[indirs[i].in_off] = nb;
+		/*
+		 * If required, write synchronously, otherwise use
+		 * delayed write.
+		 */
+		if (flags & B_SYNC) {
+			bwrite(bp);
+		} else {
+			bdwrite(bp);
+		}
+		*bpp = nbp;
+		return (0);
+	}
+	brelse(bp);
+	if (flags & B_CLRBUF) {
+		error = bread(vp, lblktodoff(fs, lbn),
+			      (int)fs->s_blocksize, &nbp);
+		if (error) {
+			brelse(nbp);
+			return (error);
+		}
+	} else {
+		nbp = getblk(vp, lblktodoff(fs, lbn), fs->s_blocksize, 0, 0);
+		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
+	}
+	*bpp = nbp;
+	return (0);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_bitops.h b/sys/gnu/vfs/ext2fs/ext2_bitops.h
new file mode 100644
index 0000000..bc83174
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_bitops.h
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/gnu/fs/ext2fs/ext2_bitops.h,v 1.3 2006/04/13 19:37:32 cracauer Exp $
+ */
+
+#ifndef _SYS_GNU_EXT2FS_EXT2_BITOPS_H_
+#define _SYS_GNU_EXT2FS_EXT2_BITOPS_H_
+
+#define	find_first_zero_bit(data, sz)		find_next_zero_bit(data, sz, 0)
+
+static __inline int
+clear_bit(int no, void *data)
+{
+	uint32_t *p;
+	uint32_t mask, new, old;
+
+	p = (uint32_t*)data + (no >> 5);
+	mask = (1U << (no & 31));
+	do {
+		old = *p;
+		new = old & ~mask;
+	} while (!atomic_cmpset_32(p, old, new));
+	return (old & mask);
+}
+
+static __inline int
+set_bit(int no, void *data)
+{
+	uint32_t *p;
+	uint32_t mask, new, old;
+
+	p = (uint32_t*)data + (no >> 5);
+	mask = (1U << (no & 31));
+	do {
+		old = *p;
+		new = old | mask;
+	} while (!atomic_cmpset_32(p, old, new));
+	return (old & mask);
+}
+
+static __inline int
+test_bit(int no, void *data)
+{
+	uint32_t *p;
+	uint32_t mask;
+
+	p = (uint32_t*)data + (no >> 5);
+	mask = (1U << (no & 31));
+	return (*p & mask);
+}
+
+static __inline size_t
+find_next_zero_bit(void *data, size_t sz, size_t ofs)
+{
+	uint32_t *p;
+	uint32_t mask;
+	int bit;
+
+	p = (uint32_t*)data + (ofs >> 5);
+	if (ofs & 31) {
+		mask = ~0U << (ofs & 31);
+		bit = *p | ~mask;
+		if (bit != ~0U)
+			return (ffs(~bit) + ofs - 1);
+		p++;
+		ofs = (ofs + 31U) & ~31U;
+	}
+	while(ofs < sz && *p == ~0U) {
+		p++;
+		ofs += 32;
+	}
+	if (ofs == sz)
+		return (ofs);
+	bit = *p;
+	return (ffs(~bit) + ofs - 1);
+}
+
+static __inline void *
+memscan(void *data, int c, size_t sz)
+{
+	uint8_t *p;
+
+	p = data;
+	while (sz && *p != c) {
+		p++;
+		sz--;
+	}
+	return (p);
+}
+
+#endif /* _SYS_GNU_EXT2FS_EXT2_BITOPS_H_ */
diff --git a/sys/gnu/vfs/ext2fs/ext2_bmap.c b/sys/gnu/vfs/ext2fs/ext2_bmap.c
new file mode 100644
index 0000000..d7cc9ea
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_bmap.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1989, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ufs_bmap.c	8.7 (Berkeley) 3/21/95
+ * $FreeBSD: src/sys/ufs/ufs/ufs_bmap.c,v 1.34.2.1 2000/03/17 10:12:14 ps Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/resourcevar.h>
+#include <sys/conf.h>
+
+#include "quota.h"
+#include "dinode.h"
+#include "inode.h"
+#include "ext2_fs_sb.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+#include "fs.h"
+
+static int ext2_bmaparray(struct vnode *vp, ext2_daddr_t bn,
+			  ext2_daddr_t *bnp, struct indir *ap, int *nump,
+			  int *runp, int *runb);
+
+/*
+ * Bmap converts the logical block number of a file to its physical block
+ * number on the disk. The conversion is done by using the logical block
+ * number to index into the array of block pointers described by the dinode.
+ *
+ * BMAP must return the contiguous before and after run in bytes, inclusive
+ * of the returned block.
+ *
+ * ext2_bmap(struct vnode *a_vp, off_t a_loffset,
+ *	    off_t *a_doffsetp, int *a_runp, int *a_runb)
+ */
+int
+ext2_bmap(struct vop_bmap_args *ap)
+{
+	struct ext2_sb_info *fs;
+	ext2_daddr_t lbn;
+	ext2_daddr_t dbn;
+	int error;
+
+	/*
+	 * Check for underlying vnode requests and ensure that logical
+	 * to physical mapping is requested.
+	 */
+	if (ap->a_doffsetp == NULL)
+		return (0);
+
+	fs = VTOI(ap->a_vp)->i_e2fs;
+	KKASSERT(((int)ap->a_loffset & ((1 << fs->s_bshift) - 1)) == 0);
+	lbn = ap->a_loffset >> fs->s_bshift;
+
+	error = ext2_bmaparray(ap->a_vp, lbn, &dbn, NULL, NULL,
+			      ap->a_runp, ap->a_runb);
+
+	if (error || dbn == (ext2_daddr_t)-1) {
+		*ap->a_doffsetp = NOOFFSET;
+	} else {
+		*ap->a_doffsetp = dbtodoff(fs, dbn);
+		if (ap->a_runp)
+			*ap->a_runp = (*ap->a_runp + 1) << fs->s_bshift;
+		if (ap->a_runb)
+			*ap->a_runb = *ap->a_runb << fs->s_bshift;
+	}
+	return (error);
+}
+
+/*
+ * Indirect blocks are now on the vnode for the file.  They are given negative
+ * logical block numbers.  Indirect blocks are addressed by the negative
+ * address of the first data block to which they point.  Double indirect blocks
+ * are addressed by one less than the address of the first indirect block to
+ * which they point.  Triple indirect blocks are addressed by one less than
+ * the address of the first double indirect block to which they point.
+ *
+ * ext2_bmaparray does the bmap conversion, and if requested returns the
+ * array of logical blocks which must be traversed to get to a block.
+ * Each entry contains the offset into that block that gets you to the
+ * next block and the disk address of the block (if it is assigned).
+ */
+static
+int
+ext2_bmaparray(struct vnode *vp, ext2_daddr_t bn, ext2_daddr_t *bnp,
+	      struct indir *ap, int *nump, int *runp, int *runb)
+{
+	struct inode *ip;
+	struct buf *bp;
+	struct ext2mount *ump;
+	struct mount *mp;
+	struct ext2_sb_info *fs;
+	struct indir a[NIADDR+1], *xap;
+	ext2_daddr_t daddr;
+	long metalbn;
+	int error, maxrun, num;
+
+	ip = VTOI(vp);
+	mp = vp->v_mount;
+	ump = VFSTOEXT2(mp);
+	fs = ip->i_e2fs;
+#ifdef DIAGNOSTIC
+	if ((ap != NULL && nump == NULL) || (ap == NULL && nump != NULL))
+		panic("ext2_bmaparray: invalid arguments");
+#endif
+
+	if (runp) {
+		*runp = 0;
+	}
+
+	if (runb) {
+		*runb = 0;
+	}
+
+	maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1;
+
+	xap = ap == NULL ? a : ap;
+	if (!nump)
+		nump = &num;
+	error = ext2_getlbns(vp, bn, xap, nump);
+	if (error)
+		return (error);
+
+	num = *nump;
+	if (num == 0) {
+		*bnp = blkptrtodb(ump, ip->i_db[bn]);
+		if (*bnp == 0)
+			*bnp = -1;
+		else if (runp) {
+			daddr_t bnb = bn;
+			for (++bn; bn < NDADDR && *runp < maxrun &&
+			    is_sequential(ump, ip->i_db[bn - 1], ip->i_db[bn]);
+			    ++bn, ++*runp);
+			bn = bnb;
+			if (runb && (bn > 0)) {
+				for (--bn; (bn >= 0) && (*runb < maxrun) &&
+					is_sequential(ump, ip->i_db[bn],
+						ip->i_db[bn+1]);
+						--bn, ++*runb);
+			}
+		}
+		return (0);
+	}
+
+
+	/* Get disk address out of indirect block array */
+	daddr = ip->i_ib[xap->in_off];
+
+	for (bp = NULL, ++xap; --num; ++xap) {
+		/*
+		 * Exit the loop if there is no disk address assigned yet and
+		 * the indirect block isn't in the cache, or if we were
+		 * looking for an indirect block and we've found it.
+		 */
+
+		metalbn = xap->in_lbn;
+		if ((daddr == 0 &&
+		     !findblk(vp, dbtodoff(fs, metalbn), FINDBLK_TEST)) ||
+		    metalbn == bn) {
+			break;
+		}
+		/*
+		 * If we get here, we've either got the block in the cache
+		 * or we have a disk address for it, go fetch it.
+		 */
+		if (bp)
+			bqrelse(bp);
+
+		xap->in_exists = 1;
+		bp = getblk(vp, lblktodoff(fs, metalbn),
+			    mp->mnt_stat.f_iosize, 0, 0);
+		if ((bp->b_flags & B_CACHE) == 0) {
+#ifdef DIAGNOSTIC
+			if (!daddr)
+				panic("ext2_bmaparray: indirect block not in cache");
+#endif
+			/*
+			 * This runs through ext2_strategy using bio2 to
+			 * cache the disk offset, then comes back through
+			 * bio1.  So we want to wait on bio1
+			 */
+			bp->b_bio1.bio_done = biodone_sync;
+			bp->b_bio1.bio_flags |= BIO_SYNC;
+			bp->b_bio2.bio_offset = fsbtodoff(fs, daddr);
+			bp->b_flags &= ~(B_INVAL|B_ERROR);
+			bp->b_cmd = BUF_CMD_READ;
+			vfs_busy_pages(bp->b_vp, bp);
+			vn_strategy(bp->b_vp, &bp->b_bio1);
+			error = biowait(&bp->b_bio1, "biord");
+			if (error) {
+				brelse(bp);
+				return (error);
+			}
+		}
+
+		daddr = ((ext2_daddr_t *)bp->b_data)[xap->in_off];
+		if (num == 1 && daddr && runp) {
+			for (bn = xap->in_off + 1;
+			    bn < MNINDIR(ump) && *runp < maxrun &&
+			    is_sequential(ump,
+			    ((ext2_daddr_t *)bp->b_data)[bn - 1],
+			    ((ext2_daddr_t *)bp->b_data)[bn]);
+			    ++bn, ++*runp);
+			bn = xap->in_off;
+			if (runb && bn) {
+				for(--bn; bn >= 0 && *runb < maxrun &&
+					is_sequential(ump, ((daddr_t *)bp->b_data)[bn],
+					    ((daddr_t *)bp->b_data)[bn+1]);
+					--bn, ++*runb);
+			}
+		}
+	}
+	if (bp)
+		bqrelse(bp);
+
+	daddr = blkptrtodb(ump, daddr);
+	*bnp = daddr == 0 ? -1 : daddr;
+	return (0);
+}
+
+/*
+ * Create an array of logical block number/offset pairs which represent the
+ * path of indirect blocks required to access a data block.  The first "pair"
+ * contains the logical block number of the appropriate single, double or
+ * triple indirect block and the offset into the inode indirect block array.
+ * Note, the logical block number of the inode single/double/triple indirect
+ * block appears twice in the array, once with the offset into the i_ib and
+ * once with the offset into the page itself.
+ */
+int
+ext2_getlbns(struct vnode *vp, ext2_daddr_t bn, struct indir *ap, int *nump)
+{
+	long blockcnt, metalbn, realbn;
+	struct ext2mount *ump;
+	int i, numlevels, off;
+	int64_t qblockcnt;
+
+	ump = VFSTOEXT2(vp->v_mount);
+	if (nump)
+		*nump = 0;
+	numlevels = 0;
+	realbn = bn;
+	if ((long)bn < 0)
+		bn = -(long)bn;
+
+	/* The first NDADDR blocks are direct blocks. */
+	if (bn < NDADDR)
+		return (0);
+
+	/*
+	 * Determine the number of levels of indirection.  After this loop
+	 * is done, blockcnt indicates the number of data blocks possible
+	 * at the previous level of indirection, and NIADDR - i is the number
+	 * of levels of indirection needed to locate the requested block.
+	 */
+	for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) {
+		if (i == 0)
+			return (EFBIG);
+		/*
+		 * Use int64_t's here to avoid overflow for triple indirect
+		 * blocks when longs have 32 bits and the block size is more
+		 * than 4K.
+		 */
+		qblockcnt = (int64_t)blockcnt * MNINDIR(ump);
+		if (bn < qblockcnt)
+			break;
+		blockcnt = qblockcnt;
+	}
+
+	/* Calculate the address of the first meta-block. */
+	if (realbn >= 0)
+		metalbn = -(realbn - bn + NIADDR - i);
+	else
+		metalbn = -(-realbn - bn + NIADDR - i);
+
+	/*
+	 * At each iteration, off is the offset into the bap array which is
+	 * an array of disk addresses at the current level of indirection.
+	 * The logical block number and the offset in that block are stored
+	 * into the argument array.
+	 */
+	ap->in_lbn = metalbn;
+	ap->in_off = off = NIADDR - i;
+	ap->in_exists = 0;
+	ap++;
+	for (++numlevels; i <= NIADDR; i++) {
+		/* If searching for a meta-data block, quit when found. */
+		if (metalbn == realbn)
+			break;
+
+		off = (bn / blockcnt) % MNINDIR(ump);
+
+		++numlevels;
+		ap->in_lbn = metalbn;
+		ap->in_off = off;
+		ap->in_exists = 0;
+		++ap;
+
+		metalbn -= -1 + off * blockcnt;
+		blockcnt /= MNINDIR(ump);
+	}
+	if (nump)
+		*nump = numlevels;
+	return (0);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_extern.h b/sys/gnu/vfs/ext2fs/ext2_extern.h
new file mode 100644
index 0000000..40acf72
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_extern.h
@@ -0,0 +1,120 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ffs_extern.h	8.3 (Berkeley) 4/16/94
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_extern.h,v 1.22.6.1 2000/11/05 19:17:40 bde Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_EXT2_EXTERN_H_
+#define	_VFS_GNU_EXT2FS_EXT2_EXTERN_H_
+
+struct ext2_dinode;
+struct ext2_inode;
+struct inode;
+struct mount;
+struct vfsconf;
+struct vnode;
+struct indir;
+
+int	ext2_alloc (struct inode *,
+	    daddr_t, daddr_t, int, struct ucred *, daddr_t *);
+int	ext2_balloc (struct inode *,
+	    daddr_t, int, struct ucred *, struct buf **, int);
+int	ext2_blkatoff (struct vnode *, off_t, char **, struct buf **);
+void	ext2_blkfree (struct inode *, daddr_t, long);
+daddr_t	ext2_blkpref (struct inode *, daddr_t, int, daddr_t *, daddr_t);
+int	ext2_bmap (struct vop_bmap_args *);
+int	ext2_reallocblks (struct vop_reallocblks_args *);
+int	ext2_reclaim (struct vop_reclaim_args *);
+void	ext2_setblock (struct ext2_sb_info *, u_char *, daddr_t);
+int	ext2_truncate (struct vnode *, off_t, int, struct ucred *);
+int	ext2_update (struct vnode *, int);
+int	ext2_valloc (struct vnode *, int, struct ucred *, struct vnode **);
+int	ext2_vfree (struct vnode *, ino_t, int);
+int 	ext2_lookup (struct vop_old_lookup_args *);
+int 	ext2_readdir (struct vop_readdir_args *);
+void	ext2_print_dinode (struct ext2_dinode *);
+void	ext2_print_inode (struct inode *);
+int	ext2_direnter (struct inode *,
+		struct vnode *, struct componentname *);
+int	ext2_dirremove (struct vnode *, struct componentname *);
+int	ext2_dirrewrite (struct inode *,
+		struct inode *, struct componentname *);
+int	ext2_dirempty (struct inode *, ino_t, struct ucred *);
+int	ext2_checkpath (struct inode *, struct inode *, struct ucred *);
+struct  ext2_group_desc * get_group_desc (struct mount * ,
+		unsigned int , struct buf ** );
+int	ext2_group_sparse (int group);
+void	ext2_discard_prealloc (struct inode *);
+int	ext2_inactive (struct vop_inactive_args *);
+int	ext2_new_block (struct mount * mp, unsigned long goal,
+			    u_int32_t * prealloc_count,
+			    u_int32_t * prealloc_block);
+ino_t	ext2_new_inode (const struct inode * dir, int mode);
+unsigned long ext2_count_free (struct buf *map, unsigned int numchars);
+void	ext2_free_blocks (struct mount * mp, unsigned long block,
+			      unsigned long count);
+void	ext2_free_inode (struct inode * inode);
+void	ext2_ei2di (struct ext2_inode *ei, struct ext2_dinode *di);
+void	ext2_di2ei (struct ext2_dinode *di, struct ext2_inode *ei);
+void	mark_buffer_dirty (struct buf *bh);
+
+int	ext2_getlbns(struct vnode *, ext2_daddr_t, struct indir *, int *);
+void	ext2_itimes(struct vnode *vp);
+struct vnode *ext2_ihashget(cdev_t, ino_t);
+int	ext2_ihashins(struct inode *);
+void	ext2_ihashrem(struct inode *);
+void	ext2_dirbad(struct inode *, doff_t, char *);
+int	ext2_check_export(struct mount *, struct sockaddr *, int *,
+			struct ucred **);
+int	ext2_vinit(struct mount *, struct vnode **);
+int	ext2_vnoperate(struct vop_generic_args *);
+int	ext2_vnoperatefifo(struct vop_generic_args *);
+int	ext2_vnoperatespec(struct vop_generic_args *);
+int	ext2_uninit(struct vfsconf *);
+void	ext2_ihashinit(void);
+struct vnode *ext2_ihashlookup(cdev_t dev, ino_t inum);
+int	ext2_ihashcheck(cdev_t dev, ino_t inum);
+
+/*
+ * This macro allows the ufs code to distinguish between an EXT2 and a
+ * non-ext2(FFS/LFS) vnode.
+ */
+#define  IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS)
+
+#endif /* !_VFS_GNU_EXT2FS_EXT2_EXTERN_H_ */
diff --git a/sys/gnu/vfs/ext2fs/ext2_fs.h b/sys/gnu/vfs/ext2fs/ext2_fs.h
new file mode 100644
index 0000000..5b3938e
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_fs.h
@@ -0,0 +1,566 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ *
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_fs.h,v 1.8.2.2 2001/09/29 12:52:47 iedowse Exp $
+ */
+/*
+ *  linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT2_FS_H
+#define _LINUX_EXT2_FS_H
+
+#include <sys/types.h>
+#include <sys/ioccom.h>
+
+#define __u32 u_int32_t
+#define u32   u_int32_t
+#define __u16 u_int16_t
+#define __u8  u_int8_t
+
+#define __s32 int32_t
+#define __s16 int16_t
+#define __s8  int8_t
+
+#define umode_t mode_t
+#define loff_t  off_t
+
+/* the Linux implementation of EXT2 stores some information about
+ * an inode in a ext2_inode_info structure which is part of the incore
+ * inode in Linux
+ * I decided to use the "spare" fields instead - we'll see how this
+ * works out
+ */
+
+#define i_block_group		i_spare[0]
+#define i_next_alloc_block	i_spare[1]
+#define i_next_alloc_goal	i_spare[2]
+#define i_prealloc_block	i_din.di_spare[0]
+#define i_prealloc_count	i_din.di_spare[1]
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT2FS_DEBUG to produce debug messages
+ */
+#undef EXT2FS_DEBUG
+
+/*
+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ */
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS	8
+
+/*
+ * The second extended file system version
+ */
+#define EXT2FS_DATE		"95/08/09"
+#define EXT2FS_VERSION		"0.5b"
+
+/*
+ * Debug code
+ */
+#ifdef EXT2FS_DEBUG
+#	define ext2_debug(f, a...)	{ \
+					kprintf ("EXT2-fs DEBUG (%s, %d): %s:", \
+						__FILE__, __LINE__, __func__); \
+					kprintf (f, ## a); \
+					}
+#else
+#	define ext2_debug(f, a...)	/**/
+#endif
+
+/*
+ * Special inodes numbers
+ */
+#define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+#define EXT2_ROOT_INO		 2	/* Root inode */
+#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+#define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO	11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC	0xEF53
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX		32000
+
+/*
+ * Note: under FreeBSD, the "user" versions of the following macros are
+ * used (and must be used) in most cases, because ((s)->u.ext2_sb.s_es is
+ * not accessible.  This depends on __KERNEL__ not being defined for
+ * kernel builds under FreeBSD.
+ */
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_SIZE		1024
+#define	EXT2_MAX_BLOCK_SIZE		4096
+#define EXT2_MIN_BLOCK_LOG_SIZE		  10
+#if defined(__KERNEL__) || (defined(__DragonFly__) && defined(_KERNEL))
+# define EXT2_BLOCK_SIZE(s)		((s)->s_blocksize)
+#else
+# define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+#define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+#else
+# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
+#endif
+#if defined(__KERNEL__) || defined _KERNEL
+#define	EXT2_ADDR_PER_BLOCK_BITS(s)	((s)->s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s)		((s)->s_inode_size)
+#define EXT2_FIRST_INO(s)		((s)->s_first_ino)
+#else
+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_INODE_SIZE : \
+				 (s)->s_inode_size)
+#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_FIRST_INO : \
+				 (s)->s_first_ino)
+#endif
+#define	EXT2_INODES_PER_BLOCK(s)	((s)->s_inodes_per_block)
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT2_MIN_FRAG_SIZE		1024
+#define	EXT2_MAX_FRAG_SIZE		4096
+#define EXT2_MIN_FRAG_LOG_SIZE		  10
+#ifdef __KERNEL__
+# define EXT2_FRAG_SIZE(s)		((s)->u.ext2_sb.s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s)	((s)->u.ext2_sb.s_frags_per_block)
+#else
+# if defined(_KERNEL) && defined(__DragonFly__)
+# define EXT2_FRAG_SIZE(s)		((s)->s_frag_size)
+# else
+# define EXT2_FRAG_SIZE(s)		(EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# endif
+# define EXT2_FRAGS_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+#endif
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header	/* Header of Access Control Lists */
+{
+	__u32	aclh_size;
+	__u32	aclh_file_count;
+	__u32	aclh_acle_count;
+	__u32	aclh_first_acle;
+};
+
+struct ext2_acl_entry	/* Access Control List Entry */
+{
+	__u32	acle_size;
+	__u16	acle_perms;	/* Access permissions */
+	__u16	acle_type;	/* Type of entry */
+	__u16	acle_tag;	/* User or group identity */
+	__u16	acle_pad1;
+	__u32	acle_next;	/* Pointer on next entry for the */
+					/* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+	__u32	bg_block_bitmap;		/* Blocks bitmap block */
+	__u32	bg_inode_bitmap;		/* Inodes bitmap block */
+	__u32	bg_inode_table;		/* Inodes table block */
+	__u16	bg_free_blocks_count;	/* Free blocks count */
+	__u16	bg_free_inodes_count;	/* Free inodes count */
+	__u16	bg_used_dirs_count;	/* Directories count */
+	__u16	bg_pad;
+	__u32	bg_reserved[3];
+};
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT2_BLOCKS_PER_GROUP(s)	((s)->u.ext2_sb.s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)		((s)->u.ext2_sb.s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s)	((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_desc_per_block_bits)
+#else
+# define EXT2_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+# define EXT2_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define	EXT2_NDIR_BLOCKS		12
+#define	EXT2_IND_BLOCK			EXT2_NDIR_BLOCKS
+#define	EXT2_DIND_BLOCK			(EXT2_IND_BLOCK + 1)
+#define	EXT2_TIND_BLOCK			(EXT2_DIND_BLOCK + 1)
+#define	EXT2_N_BLOCKS			(EXT2_TIND_BLOCK + 1)
+#define EXT2_MAXSYMLINKLEN		(EXT2_N_BLOCKS * sizeof (__u32))
+
+/*
+ * Inode flags
+ */
+#define	EXT2_SECRM_FL			0x00000001 /* Secure deletion */
+#define	EXT2_UNRM_FL			0x00000002 /* Undelete */
+#define	EXT2_COMPR_FL			0x00000004 /* Compress file */
+#define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
+#define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT2_DIRTY_FL			0x00000100
+#define EXT2_COMPRBLK_FL		0x00000200 /* One or more compressed clusters */
+#define EXT2_NOCOMP_FL			0x00000400 /* Don't compress */
+#define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT2_BTREE_FL			0x00001000 /* btree format dir */
+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE		0x00001FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+#define	EXT2_IOC_GETFLAGS		_IOR('f', 1, long)
+#define	EXT2_IOC_SETFLAGS		_IOW('f', 2, long)
+#define	EXT2_IOC_GETVERSION		_IOR('v', 1, long)
+#define	EXT2_IOC_SETVERSION		_IOW('v', 2, long)
+
+/*
+ * Only declare `struct ext2_inode' if <vfs/ufs/inode.h> hasn't made things
+ * difficult by #defining i_mode and other struct members.  The details of
+ * the struct are only needed in ext2_inode_cnv.c where the ext2fs on-disk
+ * inode is converted to a ufs in-core inode.
+ */
+#ifndef i_mode
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Creation time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
+	union {
+		struct {
+			__u32  l_i_reserved1;
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+		struct {
+			__u32  m_i_reserved1;
+		} masix1;
+	} osd1;				/* OS dependent 1 */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_generation;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_dir_acl;	/* Directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u8	l_i_frag;	/* Fragment number */
+			__u8	l_i_fsize;	/* Fragment size */
+			__u16	i_pad1;
+			__u32	l_i_reserved2[2];
+		} linux2;
+		struct {
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
+		} hurd2;
+		struct {
+			__u8	m_i_frag;	/* Fragment number */
+			__u8	m_i_fsize;	/* Fragment size */
+			__u16	m_pad1;
+			__u32	m_i_reserved2[2];
+		} masix2;
+	} osd2;				/* OS dependent 2 */
+};
+
+#define i_size_high	i_dir_acl
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1	osd1.linux1.l_i_reserved1
+#define i_frag		osd2.linux2.l_i_frag
+#define i_fsize		osd2.linux2.l_i_fsize
+#define i_reserved2	osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef	__hurd__
+#define i_translator	osd1.hurd1.h_i_translator
+#define i_frag		osd2.hurd2.h_i_frag;
+#define i_fsize		osd2.hurd2.h_i_fsize;
+#define i_uid_high	osd2.hurd2.h_i_uid_high
+#define i_gid_high	osd2.hurd2.h_i_gid_high
+#define i_author	osd2.hurd2.h_i_author
+#endif
+
+#ifdef	__masix__
+#define i_reserved1	osd1.masix1.m_i_reserved1
+#define i_frag		osd2.masix2.m_i_frag
+#define i_fsize		osd2.masix2.m_i_fsize
+#define i_reserved2	osd2.masix2.m_i_reserved2
+#endif
+
+#endif /* i_mode */
+
+/*
+ * File system states
+ */
+#define	EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
+#define	EXT2_ERROR_FS			0x0002	/* Errors detected */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK_NORMAL		0x0001	/* Do some more checks */
+#define EXT2_MOUNT_CHECK_STRICT		0x0002	/* Do again more checks */
+#define EXT2_MOUNT_CHECK		(EXT2_MOUNT_CHECK_NORMAL | \
+					 EXT2_MOUNT_CHECK_STRICT)
+#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+
+#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt)		((sb)->u.ext2_sb.s_mount_opt & \
+					 EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT		20	/* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL		0	/* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE		1	/* Continue execution */
+#define EXT2_ERRORS_RO			2	/* Remount fs read-only */
+#define EXT2_ERRORS_PANIC		3	/* Panic */
+#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__s32	s_log_frag_size;	/* Fragment size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_frags_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level; 	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 *
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16]; 	/* volume name */
+	char	s_last_mounted[64]; 	/* directory where last mounted */
+	__u32	s_algorithm_usage_bitmap; /* For compression */
+	/*
+	 * Performance hints.  Directory preallocation should only
+	 * happen if the EXT2_COMPAT_PREALLOC flag is on.
+	 */
+	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
+	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
+	__u16	s_padding1;
+	__u32	s_reserved[204];	/* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb)	(sb)
+#endif
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX		0
+#define EXT2_OS_HURD		1
+#define EXT2_OS_MASIX		2
+#define EXT2_OS_FREEBSD		3
+#define EXT2_OS_LITES		4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
+#define EXT2_DYNAMIC_REV	1 	/* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
+
+#define EXT2_FEATURE_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+#ifdef notyet
+#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#else
+#define EXT2_FEATURE_RO_COMPAT_SUPP	EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+#endif
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define	EXT2_DEF_RESUID		0
+#define	EXT2_DEF_RESGID		0
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u16	name_len;		/* Name length */
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u8	name_len;		/* Name length */
+	__u8	file_type;
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN		0
+#define EXT2_FT_REG_FILE	1
+#define EXT2_FT_DIR		2
+#define EXT2_FT_CHRDEV		3
+#define EXT2_FT_BLKDEV 		4
+#define EXT2_FT_FIFO		5
+#define EXT2_FT_SOCK		6
+#define EXT2_FT_SYMLINK		7
+
+#define EXT2_FT_MAX		8
+
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD		 	4
+#define EXT2_DIR_ROUND 			(EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
+					 ~EXT2_DIR_ROUND)
+
+#endif	/* _LINUX_EXT2_FS_H */
diff --git a/sys/gnu/vfs/ext2fs/ext2_fs_sb.h b/sys/gnu/vfs/ext2fs/ext2_fs_sb.h
new file mode 100644
index 0000000..10c752a
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_fs_sb.h
@@ -0,0 +1,85 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ *  linux/include/linux/ext2_fs_sb.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs_sb.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT2_FS_SB
+#define _LINUX_EXT2_FS_SB
+
+/*
+ * The following is not needed anymore since the descriptors buffer
+ * heads are now dynamically allocated
+ */
+/* #define EXT2_MAX_GROUP_DESC	8 */
+
+#define EXT2_MAX_GROUP_LOADED	8
+
+#define buffer_head buf
+#define MAXMNTLEN	512
+
+/*
+ * second extended-fs super-block data in memory
+ */
+struct ext2_sb_info {
+	unsigned long s_frag_size;	/* Size of a fragment in bytes */
+	unsigned long s_frags_per_block;/* Number of fragments per block */
+	unsigned long s_inodes_per_block;/* Number of inodes per block */
+	unsigned long s_frags_per_group;/* Number of fragments in a group */
+	unsigned long s_blocks_per_group;/* Number of blocks in a group */
+	unsigned long s_inodes_per_group;/* Number of inodes in a group */
+	unsigned long s_itb_per_group;	/* Number of inode table blocks per group */
+	unsigned long s_db_per_group;	/* Number of descriptor blocks per group */
+	unsigned long s_desc_per_block;	/* Number of group descriptors per block */
+	unsigned long s_groups_count;	/* Number of groups in the fs */
+	struct buffer_head * s_sbh;	/* Buffer containing the super block */
+	struct ext2_super_block * s_es;	/* Pointer to the super block in the buffer */
+	struct buffer_head ** s_group_desc;
+	unsigned short s_loaded_inode_bitmaps;
+	unsigned short s_loaded_block_bitmaps;
+	unsigned long s_inode_bitmap_number[EXT2_MAX_GROUP_LOADED];
+	struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED];
+	unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED];
+	struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED];
+	int s_rename_lock;
+	unsigned long  s_mount_opt;
+#ifdef notyet
+	unsigned short s_resuid;
+	unsigned short s_resgid;
+#endif
+    unsigned short s_inode_size;
+    unsigned int s_first_ino;
+	unsigned short s_mount_state;
+	/*
+	   stuff that FFS keeps in its super block or that linux
+	   has in its non-ext2 specific super block and which is
+	   generally considered useful
+	*/
+	unsigned long s_blocksize;
+	unsigned long s_blocksize_bits;
+	unsigned int  s_bshift;			/* = log2(s_blocksize) */
+	quad_t	 s_qbmask;			/* = s_blocksize - 1 */
+	unsigned int  s_fsbtodb;		/* shift to get disk block */
+	char    s_rd_only;                      /* read-only 		*/
+	char    s_dirt;                         /* fs modified flag */
+	char	s_wasvalid;			/* valid at mount time */
+
+	char    fs_fsmnt[MAXMNTLEN];            /* name mounted on */
+};
+
+#endif	/* _LINUX_EXT2_FS_SB */
diff --git a/sys/gnu/vfs/ext2fs/ext2_ihash.c b/sys/gnu/vfs/ext2fs/ext2_ihash.c
new file mode 100644
index 0000000..e010ea4
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_ihash.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ufs_ihash.c	8.7 (Berkeley) 5/17/95
+ * $FreeBSD: src/sys/ufs/ufs/ufs_ihash.c,v 1.20 1999/08/28 00:52:29 peter Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+
+#include "quota.h"
+#include "dinode.h"
+#include "inode.h"
+#include "ext2_extern.h"
+
+static MALLOC_DEFINE(M_EXT2IHASH, "EXT2 ihash", "EXT2 Inode hash tables");
+/*
+ * Structures associated with inode cacheing.
+ */
+static struct inode **ext2_ihashtbl;
+static u_long	ext2_ihash;		/* size of hash table - 1 */
+static struct lwkt_token ext2_ihash_token;
+
+#define	INOHASH(device, inum)	(&ext2_ihashtbl[(minor(device) + (inum)) & ext2_ihash])
+
+/*
+ * Initialize inode hash table.
+ */
+void
+ext2_ihashinit(void)
+{
+	ext2_ihash = 16;
+	while (ext2_ihash < desiredvnodes)
+		ext2_ihash <<= 1;
+	ext2_ihashtbl = kmalloc(sizeof(void *) * ext2_ihash, M_EXT2IHASH, M_WAITOK|M_ZERO);
+	--ext2_ihash;
+	lwkt_token_init(&ext2_ihash_token, "ext2ihash");
+}
+
+int
+ext2_uninit(struct vfsconf *vfc)
+{
+    lwkt_gettoken(&ext2_ihash_token);
+    if (ext2_ihashtbl)
+		kfree(ext2_ihashtbl, M_EXT2IHASH);
+    lwkt_reltoken(&ext2_ihash_token);
+
+    return (0);
+}
+/*
+ * Use the device/inum pair to find the incore inode, and return a pointer
+ * to it. If it is in core, return it, even if it is locked.
+ */
+struct vnode *
+ext2_ihashlookup(cdev_t dev, ino_t inum)
+{
+	struct inode *ip;
+
+	lwkt_gettoken(&ext2_ihash_token);
+	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+		if (inum == ip->i_number && dev == ip->i_dev)
+			break;
+	}
+	lwkt_reltoken(&ext2_ihash_token);
+	if (ip)
+		return (ITOV(ip));
+	return (NULLVP);
+}
+
+/*
+ * Use the device/inum pair to find the incore inode, and return a pointer
+ * to it. If it is in core, but locked, wait for it.
+ *
+ * Note that the serializing tokens do not prevent other processes from
+ * playing with the data structure being protected while we are blocked.
+ * They do protect us from preemptive interrupts which might try to
+ * play with the protected data structure.
+ */
+struct vnode *
+ext2_ihashget(cdev_t dev, ino_t inum)
+{
+	struct inode *ip;
+	struct vnode *vp;
+
+	lwkt_gettoken(&ext2_ihash_token);
+loop:
+	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+		if (inum != ip->i_number || dev != ip->i_dev)
+			continue;
+		vp = ITOV(ip);
+		if (vget(vp, LK_EXCLUSIVE))
+			goto loop;
+		/*
+		 * We must check to see if the inode has been ripped
+		 * out from under us after blocking.
+		 */
+		for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+			if (inum == ip->i_number && dev == ip->i_dev)
+				break;
+		}
+		if (ip == NULL || ITOV(ip) != vp) {
+			vput(vp);
+			goto loop;
+		}
+		lwkt_reltoken(&ext2_ihash_token);
+		return (vp);
+	}
+	lwkt_reltoken(&ext2_ihash_token);
+	return (NULL);
+}
+
+/*
+ * Check to see if an inode is in the hash table.  This is used to interlock
+ * file free operations to ensure that the vnode is not reused due to a
+ * reallocate of its inode number before we have had a chance to recycle it.
+ */
+int
+ext2_ihashcheck(cdev_t dev, ino_t inum)
+{
+	struct inode *ip;
+
+	lwkt_gettoken(&ext2_ihash_token);
+	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
+		if (inum == ip->i_number && dev == ip->i_dev)
+			break;
+	}
+	lwkt_reltoken(&ext2_ihash_token);
+	return(ip ? 1 : 0);
+}
+
+/*
+ * Insert the inode into the hash table, and return it locked.
+ */
+int
+ext2_ihashins(struct inode *ip)
+{
+	struct inode **ipp;
+	struct inode *iq;
+
+	KKASSERT((ip->i_flag & IN_HASHED) == 0);
+	lwkt_gettoken(&ext2_ihash_token);
+	ipp = INOHASH(ip->i_dev, ip->i_number);
+	while ((iq = *ipp) != NULL) {
+		if (ip->i_dev == iq->i_dev && ip->i_number == iq->i_number) {
+			lwkt_reltoken(&ext2_ihash_token);
+			return(EBUSY);
+		}
+		ipp = &iq->i_next;
+	}
+	ip->i_next = NULL;
+	*ipp = ip;
+	ip->i_flag |= IN_HASHED;
+	lwkt_reltoken(&ext2_ihash_token);
+	return(0);
+}
+
+/*
+ * Remove the inode from the hash table.
+ */
+void
+ext2_ihashrem(struct inode *ip)
+{
+	struct inode **ipp;
+	struct inode *iq;
+
+	lwkt_gettoken(&ext2_ihash_token);
+	if (ip->i_flag & IN_HASHED) {
+		ipp = INOHASH(ip->i_dev, ip->i_number);
+		while ((iq = *ipp) != NULL) {
+			if (ip == iq)
+				break;
+			ipp = &iq->i_next;
+		}
+		KKASSERT(ip == iq);
+		*ipp = ip->i_next;
+		ip->i_next = NULL;
+		ip->i_flag &= ~IN_HASHED;
+	}
+	lwkt_reltoken(&ext2_ihash_token);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_inode.c b/sys/gnu/vfs/ext2fs/ext2_inode.c
new file mode 100644
index 0000000..41e6ceb
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_inode.c
@@ -0,0 +1,575 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ext2_inode.c	8.5 (Berkeley) 12/30/93
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode.c,v 1.24.2.1 2000/08/03 00:52:57 peter Exp $
+ */
+
+#include "opt_quota.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <sys/buf.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "ext2mount.h"
+
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+#include "ext2_extern.h"
+
+static int ext2_indirtrunc (struct inode *, daddr_t, off_t, daddr_t,
+			    int, long *);
+
+/*
+ * Update the access, modified, and inode change times as specified by the
+ * IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively.  Write the inode
+ * to disk if the IN_MODIFIED flag is set (it may be set initially, or by
+ * the timestamp update).  The IN_LAZYMOD flag is set to force a write
+ * later if not now.  If we write now, then clear both IN_MODIFIED and
+ * IN_LAZYMOD to reflect the presumably successful write, and if waitfor is
+ * set, then wait for the write to complete.
+ */
+int
+ext2_update(struct vnode *vp, int waitfor)
+{
+	struct ext2_sb_info *fs;
+	struct buf *bp;
+	struct inode *ip;
+	int error;
+
+	ext2_itimes(vp);
+	ip = VTOI(vp);
+	if ((ip->i_flag & IN_MODIFIED) == 0)
+		return (0);
+	ip->i_flag &= ~(IN_LAZYMOD | IN_MODIFIED);
+	if (vp->v_mount->mnt_flag & MNT_RDONLY)
+		return (0);
+	fs = ip->i_e2fs;
+	error = bread(ip->i_devvp,
+		      fsbtodoff(fs, ino_to_fsba(fs, ip->i_number)),
+		      (int)fs->s_blocksize, &bp);
+	if (error) {
+		brelse(bp);
+		return (error);
+	}
+	ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
+	    ino_to_fsbo(fs, ip->i_number)));
+/*
+	if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
+		return (bwrite(bp));
+	else {
+*/
+		bdwrite(bp);
+		return (0);
+/*
+	}
+*/
+}
+
+#define	SINGLE	0	/* index of single indirect block */
+#define	DOUBLE	1	/* index of double indirect block */
+#define	TRIPLE	2	/* index of triple indirect block */
+/*
+ * Truncate the inode oip to at most length size, freeing the
+ * disk blocks.
+ */
+int
+ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred)
+{
+	struct vnode *ovp = vp;
+	daddr_t lastblock;
+	struct inode *oip;
+	daddr_t bn, lbn, lastiblock[NIADDR], indir_lbn[NIADDR];
+	daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR];
+	struct ext2_sb_info *fs;
+	struct buf *bp;
+	int offset, size, level;
+	long count, nblocks, blocksreleased = 0;
+	int i;
+	int aflags, error, allerror;
+	off_t osize;
+/*
+kprintf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
+*/	/*
+	 * negative file sizes will totally break the code below and
+	 * are not meaningful anyways.
+	 */
+	if (length < 0)
+	    return EFBIG;
+
+	oip = VTOI(ovp);
+	if (ovp->v_type == VLNK &&
+	    oip->i_size < ovp->v_mount->mnt_maxsymlinklen) {
+#if DIAGNOSTIC
+		if (length != 0)
+			panic("ext2_truncate: partial truncate of symlink");
+#endif
+		bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
+		oip->i_size = 0;
+		oip->i_flag |= IN_CHANGE | IN_UPDATE;
+		return (EXT2_UPDATE(ovp, 1));
+	}
+	if (oip->i_size == length) {
+		oip->i_flag |= IN_CHANGE | IN_UPDATE;
+		return (EXT2_UPDATE(ovp, 0));
+	}
+#if QUOTA
+	if ((error = ext2_getinoquota(oip)) != 0)
+		return (error);
+#endif
+	fs = oip->i_e2fs;
+	osize = oip->i_size;
+	ext2_discard_prealloc(oip);
+	/*
+	 * Lengthen the size of the file. We must ensure that the
+	 * last byte of the file is allocated. Since the smallest
+	 * value of osize is 0, length will be at least 1.
+	 */
+	if (osize < length) {
+		offset = blkoff(fs, length - 1);
+		lbn = lblkno(fs, length - 1);
+		aflags = B_CLRBUF;
+		if (flags & IO_SYNC)
+			aflags |= B_SYNC;
+		vnode_pager_setsize(ovp, length);
+		error = ext2_balloc(oip, lbn, offset + 1, cred, &bp, aflags);
+		if (error) {
+			vnode_pager_setsize(ovp, osize);
+			return (error);
+		}
+		oip->i_size = length;
+		if (aflags & IO_SYNC)
+			bwrite(bp);
+		else
+			bawrite(bp);
+		oip->i_flag |= IN_CHANGE | IN_UPDATE;
+		return (EXT2_UPDATE(ovp, 1));
+	}
+	/*
+	 * Shorten the size of the file. If the file is not being
+	 * truncated to a block boundry, the contents of the
+	 * partial block following the end of the file must be
+	 * zero'ed in case it ever become accessable again because
+	 * of subsequent file growth.
+	 */
+	/* I don't understand the comment above */
+	offset = blkoff(fs, length);
+	if (offset == 0) {
+		oip->i_size = length;
+	} else {
+		lbn = lblkno(fs, length);
+		aflags = B_CLRBUF;
+		if (flags & IO_SYNC)
+			aflags |= B_SYNC;
+		error = ext2_balloc(oip, lbn, offset, cred, &bp, aflags);
+		if (error)
+			return (error);
+		oip->i_size = length;
+		size = blksize(fs, oip, lbn);
+		bzero((char *)bp->b_data + offset, (u_int)(size - offset));
+		allocbuf(bp, size);
+		if (aflags & IO_SYNC)
+			bwrite(bp);
+		else
+			bawrite(bp);
+	}
+	/*
+	 * Calculate index into inode's block list of
+	 * last direct and indirect blocks (if any)
+	 * which we want to keep.  Lastblock is -1 when
+	 * the file is truncated to 0.
+	 */
+	lastblock = lblkno(fs, length + fs->s_blocksize - 1) - 1;
+	lastiblock[SINGLE] = lastblock - NDADDR;
+	lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
+	lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
+	nblocks = btodb(fs->s_blocksize);
+	/*
+	 * Update file and block pointers on disk before we start freeing
+	 * blocks.  If we crash before free'ing blocks below, the blocks
+	 * will be returned to the free list.  lastiblock values are also
+	 * normalized to -1 for calls to ext2_indirtrunc below.
+	 */
+	bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof oldblks);
+	for (level = TRIPLE; level >= SINGLE; level--)
+		if (lastiblock[level] < 0) {
+			oip->i_ib[level] = 0;
+			lastiblock[level] = -1;
+		}
+	for (i = NDADDR - 1; i > lastblock; i--)
+		oip->i_db[i] = 0;
+	oip->i_flag |= IN_CHANGE | IN_UPDATE;
+	allerror = EXT2_UPDATE(ovp, 1);
+
+	/*
+	 * Having written the new inode to disk, save its new configuration
+	 * and put back the old block pointers long enough to process them.
+	 * Note that we save the new block configuration so we can check it
+	 * when we are done.
+	 */
+	bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof newblks);
+	bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof oldblks);
+	oip->i_size = osize;
+	error = vtruncbuf(ovp, length, (int)fs->s_blocksize);
+	if (error && (allerror == 0))
+		allerror = error;
+
+	/*
+	 * Indirect blocks first.
+	 */
+	indir_lbn[SINGLE] = -NDADDR;
+	indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1;
+	indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1;
+	for (level = TRIPLE; level >= SINGLE; level--) {
+		bn = oip->i_ib[level];
+		if (bn != 0) {
+			error = ext2_indirtrunc(oip, indir_lbn[level],
+			    fsbtodoff(fs, bn), lastiblock[level], level, &count);
+			if (error)
+				allerror = error;
+			blocksreleased += count;
+			if (lastiblock[level] < 0) {
+				oip->i_ib[level] = 0;
+				ext2_blkfree(oip, bn, fs->s_frag_size);
+				blocksreleased += nblocks;
+			}
+		}
+		if (lastiblock[level] >= 0)
+			goto done;
+	}
+
+	/*
+	 * All whole direct blocks or frags.
+	 */
+	for (i = NDADDR - 1; i > lastblock; i--) {
+		long bsize;
+
+		bn = oip->i_db[i];
+		if (bn == 0)
+			continue;
+		oip->i_db[i] = 0;
+		bsize = blksize(fs, oip, i);
+		ext2_blkfree(oip, bn, bsize);
+		blocksreleased += btodb(bsize);
+	}
+	if (lastblock < 0)
+		goto done;
+
+	/*
+	 * Finally, look for a change in size of the
+	 * last direct block; release any frags.
+	 */
+	bn = oip->i_db[lastblock];
+	if (bn != 0) {
+		long oldspace, newspace;
+
+		/*
+		 * Calculate amount of space we're giving
+		 * back as old block size minus new block size.
+		 */
+		oldspace = blksize(fs, oip, lastblock);
+		oip->i_size = length;
+		newspace = blksize(fs, oip, lastblock);
+		if (newspace == 0)
+			panic("itrunc: newspace");
+		if (oldspace - newspace > 0) {
+			/*
+			 * Block number of space to be free'd is
+			 * the old block # plus the number of frags
+			 * required for the storage we're keeping.
+			 */
+			bn += numfrags(fs, newspace);
+			ext2_blkfree(oip, bn, oldspace - newspace);
+			blocksreleased += btodb(oldspace - newspace);
+		}
+	}
+done:
+#if DIAGNOSTIC
+	for (level = SINGLE; level <= TRIPLE; level++)
+		if (newblks[NDADDR + level] != oip->i_ib[level])
+			panic("itrunc1");
+	for (i = 0; i < NDADDR; i++)
+		if (newblks[i] != oip->i_db[i])
+			panic("itrunc2");
+	if (length == 0 && (!RB_EMPTY(&ovp->v_rbdirty_tree) ||
+			    !RB_EMPTY(&ovp->v_rbclean_tree)))
+		panic("itrunc3");
+#endif /* DIAGNOSTIC */
+	/*
+	 * Put back the real size.
+	 */
+	oip->i_size = length;
+	oip->i_blocks -= blocksreleased;
+	if (oip->i_blocks < 0)			/* sanity */
+		oip->i_blocks = 0;
+	oip->i_flag |= IN_CHANGE;
+	vnode_pager_setsize(ovp, length);
+#if QUOTA
+	ext2_chkdq(oip, -blocksreleased, NOCRED, 0);
+#endif
+	return (allerror);
+}
+
+/*
+ * Release blocks associated with the inode ip and stored in the indirect
+ * block bn.  Blocks are free'd in LIFO order up to (but not including)
+ * lastbn.  If level is greater than SINGLE, the block is an indirect block
+ * and recursive calls to indirtrunc must be used to cleanse other indirect
+ * blocks.
+ *
+ * NB: triple indirect blocks are untested.
+ */
+
+static int
+ext2_indirtrunc(struct inode *ip, daddr_t lbn, off_t doffset, daddr_t lastbn,
+		int level, long *countp)
+{
+	int i;
+	struct buf *bp;
+	struct ext2_sb_info *fs = ip->i_e2fs;
+	daddr_t *bap;
+	struct vnode *vp;
+	daddr_t *copy, nb, nlbn, last;
+	long blkcount, factor;
+	int nblocks, blocksreleased = 0;
+	int error = 0, allerror = 0;
+
+	/*
+	 * Calculate index in current block of last
+	 * block to be kept.  -1 indicates the entire
+	 * block so we need not calculate the index.
+	 */
+	factor = 1;
+	for (i = SINGLE; i < level; i++)
+		factor *= NINDIR(fs);
+	last = lastbn;
+	if (lastbn > 0)
+		last /= factor;
+	nblocks = btodb(fs->s_blocksize);
+	/*
+	 * Get buffer of block pointers, zero those entries corresponding
+	 * to blocks to be free'd, and update on disk copy first.  Since
+	 * double(triple) indirect before single(double) indirect, calls
+	 * to bmap on these blocks will fail.  However, we already have
+	 * the on disk address, so we have to set the bio_offset field
+	 * explicitly instead of letting bread do everything for us.
+	 */
+	vp = ITOV(ip);
+	bp = getblk(vp, lblktodoff(fs, lbn), (int)fs->s_blocksize, 0, 0);
+	if ((bp->b_flags & B_CACHE) == 0) {
+		bp->b_flags &= ~(B_ERROR | B_INVAL);
+		bp->b_cmd = BUF_CMD_READ;
+		if (bp->b_bcount > bp->b_bufsize)
+			panic("ext2_indirtrunc: bad buffer size");
+		bp->b_bio2.bio_offset = doffset;
+		bp->b_bio1.bio_done = biodone_sync;
+		bp->b_bio1.bio_flags |= BIO_SYNC;
+		vfs_busy_pages(bp->b_vp, bp);
+		vn_strategy(vp, &bp->b_bio1);
+		error = biowait(&bp->b_bio1, "biord");
+	}
+	if (error) {
+		brelse(bp);
+		*countp = 0;
+		return (error);
+	}
+
+	bap = (daddr_t *)bp->b_data;
+	MALLOC(copy, daddr_t *, fs->s_blocksize, M_TEMP, M_WAITOK);
+	bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->s_blocksize);
+	bzero((caddr_t)&bap[last + 1],
+	  (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
+	if (last == -1)
+		bp->b_flags |= B_INVAL;
+	error = bwrite(bp);
+	if (error)
+		allerror = error;
+	bap = copy;
+
+	/*
+	 * Recursively free totally unused blocks.
+	 */
+	for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
+	    i--, nlbn += factor) {
+		nb = bap[i];
+		if (nb == 0)
+			continue;
+		if (level > SINGLE) {
+			if ((error = ext2_indirtrunc(ip, nlbn,
+			    fsbtodoff(fs, nb), (daddr_t)-1, level - 1, &blkcount)) != 0)
+				allerror = error;
+			blocksreleased += blkcount;
+		}
+		ext2_blkfree(ip, nb, fs->s_blocksize);
+		blocksreleased += nblocks;
+	}
+
+	/*
+	 * Recursively free last partial block.
+	 */
+	if (level > SINGLE && lastbn >= 0) {
+		last = lastbn % factor;
+		nb = bap[i];
+		if (nb != 0) {
+			error = ext2_indirtrunc(ip, nlbn, fsbtodoff(fs, nb),
+						last, level - 1, &blkcount);
+			if (error)
+				allerror = error;
+			blocksreleased += blkcount;
+		}
+	}
+	FREE(copy, M_TEMP);
+	*countp = blocksreleased;
+	return (allerror);
+}
+
+/*
+ * Last reference to an inode.  If necessary, write or delete it.
+ *
+ * ext2_inactive(struct vnode *a_vp)
+ */
+int
+ext2_inactive(struct vop_inactive_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	int mode, error = 0;
+
+	ext2_discard_prealloc(ip);
+	if (prtactive && vp->v_sysref.refcnt > 1)
+		vprint("ext2_inactive: pushing active", vp);
+
+	/*
+	 * Ignore inodes related to stale file handles.
+	 */
+	if (ip == NULL || ip->i_mode == 0)
+		goto out;
+	if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+#ifdef QUOTA
+		if (!ext2_getinoquota(ip))
+			(void)ext2_chkiq(ip, -1, NOCRED, FORCE);
+#endif
+		error = EXT2_TRUNCATE(vp, (off_t)0, 0, NOCRED);
+		ip->i_rdev = 0;
+		mode = ip->i_mode;
+		ip->i_mode = 0;
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		EXT2_VFREE(vp, ip->i_number, mode);
+	}
+	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))
+		EXT2_UPDATE(vp, 0);
+out:
+	/*
+	 * If we are done with the inode, reclaim it
+	 * so that it can be reused immediately.
+	 */
+	if (ip == NULL || ip->i_mode == 0)
+		vrecycle(vp);
+	return (error);
+}
+
+/*
+ * Reclaim an inode so that it can be used for other purposes.
+ *
+ * ext2_reclaim(struct vnode *a_vp)
+ */
+int
+ext2_reclaim(struct vop_reclaim_args *ap)
+{
+	struct inode *ip;
+	struct vnode *vp = ap->a_vp;
+#ifdef QUOTA
+	int i;
+#endif
+
+	if (prtactive && vp->v_sysref.refcnt > 1)
+		vprint("ext2_reclaim: pushing active", vp);
+	ip = VTOI(vp);
+
+	/*
+	 * Lazy updates.
+	 */
+	if (ip) {
+		if (ip->i_flag & IN_LAZYMOD) {
+			ip->i_flag |= IN_MODIFIED;
+			EXT2_UPDATE(vp, 0);
+		}
+	}
+#ifdef INVARIANTS
+	if (ip && (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))) {
+		kprintf("WARNING: INODE %ld flags %08x: modified inode being released!\n", (long)ip->i_number, (int)ip->i_flag);
+		ip->i_flag |= IN_MODIFIED;
+		EXT2_UPDATE(vp, 0);
+	}
+#endif
+	/*
+	 * Remove the inode from its hash chain and purge namecache
+	 * data associated with the vnode.
+	 */
+	vp->v_data = NULL;
+	if (ip) {
+		ext2_ihashrem(ip);
+		if (ip->i_devvp) {
+			vrele(ip->i_devvp);
+			ip->i_devvp = 0;
+		}
+#ifdef QUOTA
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if (ip->i_dquot[i] != NODQUOT) {
+				ext2_dqrele(vp, ip->i_dquot[i]);
+				ip->i_dquot[i] = NODQUOT;
+			}
+		}
+#endif
+#ifdef UFS_DIRHASH
+		if (ip->i_dirhash != NULL)
+			ext2dirhash_free(ip);
+#endif
+		kfree(ip, VFSTOEXT2(vp->v_mount)->um_malloctype);
+	}
+	return (0);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_inode_cnv.c b/sys/gnu/vfs/ext2fs/ext2_inode_cnv.c
new file mode 100644
index 0000000..fc9b517
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_inode_cnv.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1995 The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ *      Utah $Hdr$
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode_cnv.c,v 1.11 2000/01/01 17:39:21 bde Exp $
+ */
+
+/*
+ * routines to convert on disk ext2 inodes in dinodes and back
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/stat.h>
+#include <sys/vnode.h>
+
+#include <machine/inttypes.h>
+
+#include "quota.h"
+
+#define NO_I_DEFINES
+#include "inode.h"
+#include "ext2_fs.h"
+#include "ext2_extern.h"
+
+void
+ext2_print_dinode(struct ext2_dinode *di)
+{
+	int i;
+	kprintf( /* "Inode: %5d" */
+		" Type: %10s Mode: 0x%o Flags: 0x%x  Version: %d\n",
+		"n/a", di->di_mode, di->di_flags, di->di_gen);
+	kprintf( "User: %5lu Group: %5lu  Size: %lu\n",
+		(unsigned long)di->di_uid, (unsigned long)di->di_gid,
+		(unsigned long)di->di_size);
+	kprintf( "Links: %3d Blockcount: %d\n",
+		di->di_nlink, di->di_blocks);
+	kprintf( "ctime: 0x%x", di->di_ctime);
+	kprintf( "atime: 0x%x", di->di_atime);
+	kprintf( "mtime: 0x%x", di->di_mtime);
+	kprintf( "BLOCKS: ");
+	for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
+		kprintf("%d ", di->di_db[i]);
+	kprintf("\n");
+}
+
+void
+ext2_print_inode(struct inode *in)
+{
+	kprintf( "Inode: %"PRId64, in->i_number);
+	ext2_print_dinode(&in->i_din);
+}
+
+/*
+ *	raw ext2 inode to dinode
+ */
+void
+ext2_ei2di(struct ext2_inode *ei, struct ext2_dinode *di)
+{
+        int     i;
+
+        di->di_nlink    = ei->i_links_count;
+	/* Godmar thinks - if the link count is zero, then the inode is
+	   unused - according to ext2 standards. Ufs marks this fact
+	   by setting i_mode to zero - why ?
+	   I can see that this might lead to problems in an undelete.
+	*/
+	di->di_mode     = ei->i_links_count ? ei->i_mode : 0;
+        di->di_size     = ei->i_size;
+        di->di_atime	= ei->i_atime;
+        di->di_mtime	= ei->i_mtime;
+        di->di_ctime	= ei->i_ctime;
+        di->di_flags    = 0;
+        di->di_flags    |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
+        di->di_flags    |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
+        di->di_blocks   = ei->i_blocks;
+        di->di_gen      = ei->i_generation;
+        di->di_uid      = ei->i_uid;
+        di->di_gid      = ei->i_gid;
+	/* XXX use memcpy */
+        for(i = 0; i < NDADDR; i++)
+                di->di_db[i] = ei->i_block[i];
+        for(i = 0; i < NIADDR; i++)
+                di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
+}
+
+/*
+ *	dinode to raw ext2 inode
+ */
+void
+ext2_di2ei(struct ext2_dinode *di, struct ext2_inode *ei)
+{
+        int     i;
+
+        ei->i_mode              = di->di_mode;
+        ei->i_links_count       = di->di_nlink;
+	/*
+	   Godmar thinks: if dtime is nonzero, ext2 says this inode
+	   has been deleted, this would correspond to a zero link count
+	 */
+        ei->i_dtime             = ei->i_links_count ? 0 : di->di_mtime;
+        ei->i_size              = di->di_size;
+        ei->i_atime             = di->di_atime;
+        ei->i_mtime             = di->di_mtime;
+        ei->i_ctime             = di->di_ctime;
+        ei->i_flags             = di->di_flags;
+        ei->i_flags    		= 0;
+        ei->i_flags    		|= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;
+        ei->i_flags    		|= (di->di_flags & IMMUTABLE)
+							? EXT2_IMMUTABLE_FL: 0;
+        ei->i_blocks            = di->di_blocks;
+        ei->i_generation        = di->di_gen;
+        ei->i_uid               = di->di_uid;
+        ei->i_gid               = di->di_gid;
+	/* XXX use memcpy */
+        for(i = 0; i < NDADDR; i++)
+                ei->i_block[i] = di->di_db[i];
+        for(i = 0; i < NIADDR; i++)
+                ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i];
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_linux_balloc.c b/sys/gnu/vfs/ext2fs/ext2_linux_balloc.c
new file mode 100644
index 0000000..c28f336
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_linux_balloc.c
@@ -0,0 +1,621 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ *
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_linux_balloc.c,v 1.11.2.3 2001/08/14 18:03:19 gallatin Exp $
+ */
+/*
+ *  linux/fs/ext2/balloc.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
+ */
+
+/*
+ * The free blocks are managed by bitmaps.  A file system contains several
+ * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
+ * block for inodes, N blocks for the inode table and data blocks.
+ *
+ * The file system contains group descriptors which are located after the
+ * super block.  Each descriptor contains the number of the bitmap block and
+ * the free blocks count in the block.  The descriptors are loaded in memory
+ * when a file system is mounted (see ext2_read_super).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/buf2.h>
+#include <sys/thread2.h>
+
+#include "quota.h"
+#include "dinode.h"
+#include "inode.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+
+#ifdef __i386__
+#include "i386-bitops.h"
+#else
+#include "ext2_bitops.h"
+#endif
+
+#define in_range(b, first, len)		((b) >= (first) && (b) <= (first) + (len) - 1)
+
+/* got rid of get_group_desc since it can already be found in
+ * ext2_linux_ialloc.c
+ */
+
+static void
+read_block_bitmap(struct mount *mp, unsigned int block_group,
+		  unsigned long bitmap_nr)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct ext2_group_desc * gdp;
+	struct buffer_head * bh;
+	int    error;
+
+	gdp = get_group_desc (mp, block_group, NULL);
+	error = bread(VFSTOEXT2(mp)->um_devvp,
+		      fsbtodoff(sb, gdp->bg_block_bitmap),
+		      sb->s_blocksize, &bh);
+	if (error) {
+		panic ( "read_block_bitmap: "
+			    "Cannot read block bitmap - "
+			    "block_group = %d, block_bitmap = %lu",
+			    block_group, (unsigned long) gdp->bg_block_bitmap);
+	}
+	sb->s_block_bitmap_number[bitmap_nr] = block_group;
+	sb->s_block_bitmap[bitmap_nr] = bh;
+	LCK_BUF(bh)
+}
+
+/*
+ * load_block_bitmap loads the block bitmap for a blocks group
+ *
+ * It maintains a cache for the last bitmaps loaded.  This cache is managed
+ * with a LRU algorithm.
+ *
+ * Notes:
+ * 1/ There is one cache per mounted file system.
+ * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
+ *    this function reads the bitmap without maintaining a LRU cache.
+ */
+static int
+load__block_bitmap(struct mount *mp, unsigned int block_group)
+{
+	int i, j;
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	unsigned long block_bitmap_number;
+	struct buffer_head * block_bitmap;
+
+	if (block_group >= sb->s_groups_count)
+		panic ( "load_block_bitmap: "
+			    "block_group >= groups_count - "
+			    "block_group = %d, groups_count = %lu",
+			    block_group, sb->s_groups_count);
+
+	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
+		if (sb->s_block_bitmap[block_group]) {
+			if (sb->s_block_bitmap_number[block_group] !=
+			    block_group)
+				panic ( "load_block_bitmap: "
+					    "block_group != block_bitmap_number");
+			else
+				return block_group;
+		} else {
+			read_block_bitmap (mp, block_group, block_group);
+			return block_group;
+		}
+	}
+
+	for (i = 0; i < sb->s_loaded_block_bitmaps &&
+		    sb->s_block_bitmap_number[i] != block_group; i++)
+		;
+	if (i < sb->s_loaded_block_bitmaps &&
+	    sb->s_block_bitmap_number[i] == block_group) {
+		block_bitmap_number = sb->s_block_bitmap_number[i];
+		block_bitmap = sb->s_block_bitmap[i];
+		for (j = i; j > 0; j--) {
+			sb->s_block_bitmap_number[j] =
+				sb->s_block_bitmap_number[j - 1];
+			sb->s_block_bitmap[j] =
+				sb->s_block_bitmap[j - 1];
+		}
+		sb->s_block_bitmap_number[0] = block_bitmap_number;
+		sb->s_block_bitmap[0] = block_bitmap;
+	} else {
+		if (sb->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
+			sb->s_loaded_block_bitmaps++;
+		else
+			ULCK_BUF(sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1])
+
+		for (j = sb->s_loaded_block_bitmaps - 1; j > 0;  j--) {
+			sb->s_block_bitmap_number[j] =
+				sb->s_block_bitmap_number[j - 1];
+			sb->s_block_bitmap[j] =
+				sb->s_block_bitmap[j - 1];
+		}
+		read_block_bitmap (mp, block_group, 0);
+	}
+	return 0;
+}
+
+static __inline int
+load_block_bitmap(struct mount * mp, unsigned int block_group)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	if (sb->s_loaded_block_bitmaps > 0 &&
+	    sb->s_block_bitmap_number[0] == block_group)
+		return 0;
+
+	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED &&
+	    sb->s_block_bitmap_number[block_group] == block_group &&
+	    sb->s_block_bitmap[block_group])
+		return block_group;
+
+	return load__block_bitmap (mp, block_group);
+}
+
+void
+ext2_free_blocks(struct mount * mp, unsigned long block,
+		 unsigned long count)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct buffer_head * bh;
+	struct buffer_head * bh2;
+	unsigned long block_group;
+	unsigned long bit;
+	unsigned long i;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	struct ext2_super_block * es = sb->s_es;
+
+	if (!sb) {
+		kprintf ("ext2_free_blocks: nonexistent device");
+		return;
+	}
+	lock_super (VFSTOEXT2(mp)->um_devvp);
+	if (block < es->s_first_data_block ||
+	    (block + count) > es->s_blocks_count) {
+		kprintf ( "ext2_free_blocks: "
+			    "Freeing blocks not in datazone - "
+			    "block = %lu, count = %lu", block, count);
+		unlock_super (VFSTOEXT2(mp)->um_devvp);
+		return;
+	}
+
+	ext2_debug ("freeing blocks %lu to %lu\n", block, block+count-1);
+
+	block_group = (block - es->s_first_data_block) /
+		      EXT2_BLOCKS_PER_GROUP(sb);
+	bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb);
+	if (bit + count > EXT2_BLOCKS_PER_GROUP(sb))
+		panic ( "ext2_free_blocks: "
+			    "Freeing blocks across group boundary - "
+			    "Block = %lu, count = %lu",
+			    block, count);
+	bitmap_nr = load_block_bitmap (mp, block_group);
+	bh = sb->s_block_bitmap[bitmap_nr];
+	gdp = get_group_desc (mp, block_group, &bh2);
+
+	if (/* test_opt (sb, CHECK_STRICT) && 	assume always strict ! */
+	    (in_range (gdp->bg_block_bitmap, block, count) ||
+	     in_range (gdp->bg_inode_bitmap, block, count) ||
+	     in_range (block, gdp->bg_inode_table,
+		       sb->s_itb_per_group) ||
+	     in_range (block + count - 1, gdp->bg_inode_table,
+		       sb->s_itb_per_group)))
+		panic ( "ext2_free_blocks: "
+			    "Freeing blocks in system zones - "
+			    "Block = %lu, count = %lu",
+			    block, count);
+
+	for (i = 0; i < count; i++) {
+		if (!clear_bit (bit + i, bh->b_data))
+			kprintf ("ext2_free_blocks: "
+				      "bit already cleared for block %lu",
+				      block);
+		else {
+			gdp->bg_free_blocks_count++;
+			es->s_free_blocks_count++;
+		}
+	}
+
+	mark_buffer_dirty(bh2);
+	mark_buffer_dirty(bh);
+/****
+	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ll_rw_block (WRITE, 1, &bh);
+		wait_on_buffer (bh);
+	}
+****/
+	sb->s_dirt = 1;
+	unlock_super (VFSTOEXT2(mp)->um_devvp);
+	return;
+}
+
+/*
+ * ext2_new_block uses a goal block to assist allocation.  If the goal is
+ * free, or there is a free block within 32 blocks of the goal, that block
+ * is allocated.  Otherwise a forward search is made for a free block; within
+ * each block group the search first looks for an entire free byte in the block
+ * bitmap, and then for any free bit if that fails.
+ */
+int
+ext2_new_block(struct mount * mp, unsigned long goal,
+	       u_int32_t * prealloc_count,
+	       u_int32_t * prealloc_block)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct buffer_head * bh;
+	struct buffer_head * bh2;
+	char * p, * r;
+	int i, j, k, tmp;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	struct ext2_super_block * es = sb->s_es;
+
+#ifdef EXT2FS_DEBUG
+	static int goal_hits = 0, goal_attempts = 0;
+#endif
+	if (!sb) {
+		kprintf ("ext2_new_block: nonexistent device");
+		return 0;
+	}
+	lock_super (VFSTOEXT2(mp)->um_devvp);
+
+        ext2_debug ("goal=%lu.\n", goal);
+
+repeat:
+	/*
+	 * First, test whether the goal block is free.
+	 */
+	if (goal < es->s_first_data_block || goal >= es->s_blocks_count)
+		goal = es->s_first_data_block;
+	i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb);
+	gdp = get_group_desc (mp, i, &bh2);
+	if (gdp->bg_free_blocks_count > 0) {
+		j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
+#ifdef EXT2FS_DEBUG
+		if (j)
+			goal_attempts++;
+#endif
+		bitmap_nr = load_block_bitmap (mp, i);
+		bh = sb->s_block_bitmap[bitmap_nr];
+
+		ext2_debug ("goal is at %d:%d.\n", i, j);
+
+		if (!test_bit(j, bh->b_data)) {
+#ifdef EXT2FS_DEBUG
+			goal_hits++;
+			ext2_debug ("goal bit allocated.\n");
+#endif
+			goto got_block;
+		}
+		if (j) {
+			/*
+			 * The goal was occupied; search forward for a free
+			 * block within the next XX blocks.
+			 *
+			 * end_goal is more or less random, but it has to be
+			 * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
+			 * next 64-bit boundary is simple..
+			 */
+			int end_goal = (j + 63) & ~63;
+			j = find_next_zero_bit(bh->b_data, end_goal, j);
+			if (j < end_goal)
+				goto got_block;
+		}
+
+		ext2_debug ("Bit not found near goal\n");
+
+		/*
+		 * There has been no free block found in the near vicinity
+		 * of the goal: do a search forward through the block groups,
+		 * searching in each group first for an entire free byte in
+		 * the bitmap and then for any free bit.
+		 *
+		 * Search first in the remainder of the current group; then,
+		 * cyclicly search through the rest of the groups.
+		 */
+		p = ((char *) bh->b_data) + (j >> 3);
+		r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
+		k = (r - ((char *) bh->b_data)) << 3;
+		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
+			j = k;
+			goto search_back;
+		}
+		k = find_next_zero_bit ((unsigned long *) bh->b_data,
+					EXT2_BLOCKS_PER_GROUP(sb),
+					j);
+		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
+			j = k;
+			goto got_block;
+		}
+	}
+
+	ext2_debug ("Bit not found in block group %d.\n", i);
+
+	/*
+	 * Now search the rest of the groups.  We assume that
+	 * i and gdp correctly point to the last group visited.
+	 */
+	for (k = 0; k < sb->s_groups_count; k++) {
+		i++;
+		if (i >= sb->s_groups_count)
+			i = 0;
+		gdp = get_group_desc (mp, i, &bh2);
+		if (gdp->bg_free_blocks_count > 0)
+			break;
+	}
+	if (k >= sb->s_groups_count) {
+		unlock_super (VFSTOEXT2(mp)->um_devvp);
+		return 0;
+	}
+	bitmap_nr = load_block_bitmap (mp, i);
+	bh = sb->s_block_bitmap[bitmap_nr];
+	r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3);
+	j = (r - bh->b_data) << 3;
+
+	if (j < EXT2_BLOCKS_PER_GROUP(sb))
+		goto search_back;
+	else
+		j = find_first_zero_bit ((unsigned long *) bh->b_data,
+					 EXT2_BLOCKS_PER_GROUP(sb));
+	if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
+		kprintf ( "ext2_new_block: "
+			 "Free blocks count corrupted for block group %d", i);
+		unlock_super (VFSTOEXT2(mp)->um_devvp);
+		return 0;
+	}
+
+search_back:
+	/*
+	 * We have succeeded in finding a free byte in the block
+	 * bitmap.  Now search backwards up to 7 bits to find the
+	 * start of this group of free blocks.
+	 */
+	for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--);
+
+got_block:
+
+	ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
+
+	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;
+
+	if (/* test_opt (sb, CHECK_STRICT) && we are always strict. */
+	    (tmp == gdp->bg_block_bitmap ||
+	     tmp == gdp->bg_inode_bitmap ||
+	     in_range (tmp, gdp->bg_inode_table, sb->s_itb_per_group)))
+		panic ( "ext2_new_block: "
+			    "Allocating block in system zone - "
+			    "%dth block = %u in group %u", j, tmp, i);
+
+	if (set_bit (j, bh->b_data)) {
+		kprintf ( "ext2_new_block: "
+			 "bit already set for block %d", j);
+		goto repeat;
+	}
+
+	ext2_debug ("found bit %d\n", j);
+
+	/*
+	 * Do block preallocation now if required.
+	 */
+#ifdef EXT2_PREALLOCATE
+	if (prealloc_block) {
+		*prealloc_count = 0;
+		*prealloc_block = tmp + 1;
+		for (k = 1;
+		     k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
+			if (set_bit (j + k, bh->b_data))
+				break;
+			(*prealloc_count)++;
+		}
+		gdp->bg_free_blocks_count -= *prealloc_count;
+		es->s_free_blocks_count -= *prealloc_count;
+		ext2_debug ("Preallocated a further %lu bits.\n",
+			    *prealloc_count);
+	}
+#endif
+
+	j = tmp;
+
+	mark_buffer_dirty(bh);
+/****
+	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ll_rw_block (WRITE, 1, &bh);
+		wait_on_buffer (bh);
+	}
+****/
+	if (j >= es->s_blocks_count) {
+		kprintf ( "ext2_new_block: "
+			    "block >= blocks count - "
+			    "block_group = %d, block=%d", i, j);
+		unlock_super (VFSTOEXT2(mp)->um_devvp);
+		return 0;
+	}
+
+	ext2_debug ("allocating block %d. "
+		    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
+
+	gdp->bg_free_blocks_count--;
+	mark_buffer_dirty(bh2);
+	es->s_free_blocks_count--;
+	sb->s_dirt = 1;
+	unlock_super (VFSTOEXT2(mp)->um_devvp);
+	return j;
+}
+
+#ifdef unused
+static unsigned long
+ext2_count_free_blocks(struct mount * mp)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+#ifdef EXT2FS_DEBUG
+	struct ext2_super_block * es;
+	unsigned long desc_count, bitmap_count, x;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	int i;
+
+	lock_super (VFSTOEXT2(mp)->um_devvp);
+	es = sb->s_es;
+	desc_count = 0;
+	bitmap_count = 0;
+	gdp = NULL;
+	for (i = 0; i < sb->s_groups_count; i++) {
+		gdp = get_group_desc (mp, i, NULL);
+		desc_count += gdp->bg_free_blocks_count;
+		bitmap_nr = load_block_bitmap (mp, i);
+		x = ext2_count_free (sb->s_block_bitmap[bitmap_nr],
+				     sb->s_blocksize);
+		ext2_debug ("group %d: stored = %d, counted = %lu\n",
+			i, gdp->bg_free_blocks_count, x);
+		bitmap_count += x;
+	}
+	ext2_debug( "stored = %lu, computed = %lu, %lu\n",
+	       es->s_free_blocks_count, desc_count, bitmap_count);
+	unlock_super (VFSTOEXT2(mp)->um_devvp);
+	return bitmap_count;
+#else
+	return sb->s_es->s_free_blocks_count;
+#endif
+}
+#endif /* unused */
+
+static __inline int
+block_in_use (unsigned long block, struct ext2_sb_info *sb,
+	      unsigned char * map)
+{
+	return test_bit ((block - sb->s_es->s_first_data_block) %
+			 EXT2_BLOCKS_PER_GROUP(sb), map);
+}
+
+static int
+test_root(int a, int b)
+{
+	if (a == 0)
+		return 1;
+	while (1) {
+		if (a == 1)
+			return 1;
+		if (a % b)
+			return 0;
+		a = a / b;
+	}
+}
+
+int
+ext2_group_sparse(int group)
+{
+	return (test_root(group, 3) || test_root(group, 5) ||
+		test_root(group, 7));
+}
+
+#ifdef unused
+static void
+ext2_check_blocks_bitmap(struct mount * mp)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct buffer_head * bh;
+	struct ext2_super_block * es;
+	unsigned long desc_count, bitmap_count, x;
+	unsigned long desc_blocks;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	int i, j;
+
+	lock_super (VFSTOEXT2(mp)->um_devvp);
+	es = sb->s_es;
+	desc_count = 0;
+	bitmap_count = 0;
+	gdp = NULL;
+	desc_blocks = (sb->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+		      EXT2_DESC_PER_BLOCK(sb);
+	for (i = 0; i < sb->s_groups_count; i++) {
+		gdp = get_group_desc (mp, i, NULL);
+		desc_count += gdp->bg_free_blocks_count;
+		bitmap_nr = load_block_bitmap (mp, i);
+		bh = sb->s_block_bitmap[bitmap_nr];
+
+		if (!(es->s_feature_ro_compat &
+		     EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
+		    ext2_group_sparse(i)) {
+			if (!test_bit (0, bh->b_data))
+				kprintf ("ext2_check_blocks_bitmap: "
+					    "Superblock in group %d "
+					    "is marked free", i);
+
+			for (j = 0; j < desc_blocks; j++)
+				if (!test_bit (j + 1, bh->b_data))
+					kprintf ("ext2_check_blocks_bitmap: "
+					    "Descriptor block #%d in group "
+					    "%d is marked free", j, i);
+		}
+
+		if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
+			kprintf ("ext2_check_blocks_bitmap: "
+				    "Block bitmap for group %d is marked free",
+				    i);
+
+		if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data))
+			kprintf ("ext2_check_blocks_bitmap: "
+				    "Inode bitmap for group %d is marked free",
+				    i);
+
+		for (j = 0; j < sb->s_itb_per_group; j++)
+			if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data))
+				kprintf ("ext2_check_blocks_bitmap: "
+					    "Block #%d of the inode table in "
+					    "group %d is marked free", j, i);
+
+		x = ext2_count_free (bh, sb->s_blocksize);
+		if (gdp->bg_free_blocks_count != x)
+			kprintf ("ext2_check_blocks_bitmap: "
+				    "Wrong free blocks count for group %d, "
+				    "stored = %d, counted = %lu", i,
+				    gdp->bg_free_blocks_count, x);
+		bitmap_count += x;
+	}
+	if (es->s_free_blocks_count != bitmap_count)
+		kprintf ("ext2_check_blocks_bitmap: "
+			    "Wrong free blocks count in super block, "
+			    "stored = %lu, counted = %lu",
+			    (unsigned long) es->s_free_blocks_count, bitmap_count);
+	unlock_super (VFSTOEXT2(mp)->um_devvp);
+}
+#endif /* unused */
+
+/*
+ *  this function is taken from
+ *  linux/fs/ext2/bitmap.c
+ */
+
+static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+
+unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
+{
+        unsigned int i;
+        unsigned long sum = 0;
+
+        if (!map)
+                return (0);
+        for (i = 0; i < numchars; i++)
+                sum += nibblemap[map->b_data[i] & 0xf] +
+                        nibblemap[(map->b_data[i] >> 4) & 0xf];
+        return (sum);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_linux_ialloc.c b/sys/gnu/vfs/ext2fs/ext2_linux_ialloc.c
new file mode 100644
index 0000000..50a32d1
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_linux_ialloc.c
@@ -0,0 +1,516 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ *
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_linux_ialloc.c,v 1.13.2.2 2001/08/14 18:03:19 gallatin Exp $
+ */
+/*
+ *  linux/fs/ext2/ialloc.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  BSD ufs-inspired inode and directory allocation by
+ *  Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
+ */
+
+/*
+ * The free inodes are managed by bitmaps.  A file system contains several
+ * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
+ * block for inodes, N blocks for the inode table and data blocks.
+ *
+ * The file system contains group descriptors which are located after the
+ * super block.  Each descriptor contains the number of the bitmap block and
+ * the free blocks count in the block.  The descriptors are loaded in memory
+ * when a file system is mounted (see ext2_read_super).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+#include <sys/stat.h>
+#include <sys/buf2.h>
+#include <sys/thread2.h>
+
+#ifdef __i386__
+#include "i386-bitops.h"
+#else
+#include "ext2_bitops.h"
+#endif
+
+/* this is supposed to mark a buffer dirty on ready for delayed writing
+ */
+void
+mark_buffer_dirty(struct buf *bh)
+{
+	crit_enter();
+	bh->b_flags |= B_DIRTY;
+	crit_exit();
+}
+
+struct ext2_group_desc *
+get_group_desc(struct mount * mp, unsigned int block_group,
+	       struct buffer_head **bh)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	unsigned long group_desc;
+	unsigned long desc;
+	struct ext2_group_desc * gdp;
+
+	if (block_group >= sb->s_groups_count)
+		panic ("get_group_desc: "
+			    "block_group >= groups_count - "
+			    "block_group = %d, groups_count = %lu",
+			    block_group, sb->s_groups_count);
+
+	group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
+	desc = block_group % EXT2_DESC_PER_BLOCK(sb);
+	if (!sb->s_group_desc[group_desc])
+		panic ( "get_group_desc:"
+			    "Group descriptor not loaded - "
+			    "block_group = %d, group_desc = %lu, desc = %lu",
+			     block_group, group_desc, desc);
+	gdp = (struct ext2_group_desc *)
+		sb->s_group_desc[group_desc]->b_data;
+	if (bh)
+		*bh = sb->s_group_desc[group_desc];
+	return gdp + desc;
+}
+
+static void
+read_inode_bitmap(struct mount *mp, unsigned long block_group,
+		  unsigned int bitmap_nr)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct ext2_group_desc * gdp;
+	struct buffer_head * bh;
+	int	error;
+
+	gdp = get_group_desc (mp, block_group, NULL);
+	if ((error = bread (VFSTOEXT2(mp)->um_devvp,
+			    fsbtodoff(sb, gdp->bg_inode_bitmap),
+			    sb->s_blocksize, &bh)) != 0)
+		panic ( "read_inode_bitmap:"
+			    "Cannot read inode bitmap - "
+			    "block_group = %lu, inode_bitmap = %lu",
+			    block_group, (unsigned long) gdp->bg_inode_bitmap);
+	sb->s_inode_bitmap_number[bitmap_nr] = block_group;
+	sb->s_inode_bitmap[bitmap_nr] = bh;
+	LCK_BUF(bh)
+}
+
+/*
+ * load_inode_bitmap loads the inode bitmap for a blocks group
+ *
+ * It maintains a cache for the last bitmaps loaded.  This cache is managed
+ * with a LRU algorithm.
+ *
+ * Notes:
+ * 1/ There is one cache per mounted file system.
+ * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
+ *    this function reads the bitmap without maintaining a LRU cache.
+ */
+static int
+load_inode_bitmap(struct mount *mp, unsigned int block_group)
+{
+	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	int i, j;
+	unsigned long inode_bitmap_number;
+	struct buffer_head * inode_bitmap;
+
+	if (block_group >= sb->s_groups_count)
+		panic ("load_inode_bitmap:"
+			    "block_group >= groups_count - "
+			    "block_group = %d, groups_count = %lu",
+			     block_group, sb->s_groups_count);
+	if (sb->s_loaded_inode_bitmaps > 0 &&
+	    sb->s_inode_bitmap_number[0] == block_group)
+		return 0;
+	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
+		if (sb->s_inode_bitmap[block_group]) {
+			if (sb->s_inode_bitmap_number[block_group] !=
+				block_group)
+				panic ( "load_inode_bitmap:"
+				    "block_group != inode_bitmap_number");
+			else
+				return block_group;
+		} else {
+			read_inode_bitmap (mp, block_group, block_group);
+			return block_group;
+		}
+	}
+
+	for (i = 0; i < sb->s_loaded_inode_bitmaps &&
+		    sb->s_inode_bitmap_number[i] != block_group;
+	     i++)
+		;
+	if (i < sb->s_loaded_inode_bitmaps &&
+	    sb->s_inode_bitmap_number[i] == block_group) {
+		inode_bitmap_number = sb->s_inode_bitmap_number[i];
+		inode_bitmap = sb->s_inode_bitmap[i];
+		for (j = i; j > 0; j--) {
+			sb->s_inode_bitmap_number[j] =
+				sb->s_inode_bitmap_number[j - 1];
+			sb->s_inode_bitmap[j] =
+				sb->s_inode_bitmap[j - 1];
+		}
+		sb->s_inode_bitmap_number[0] = inode_bitmap_number;
+		sb->s_inode_bitmap[0] = inode_bitmap;
+	} else {
+		if (sb->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
+			sb->s_loaded_inode_bitmaps++;
+		else
+			ULCK_BUF(sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1])
+		for (j = sb->s_loaded_inode_bitmaps - 1; j > 0; j--) {
+			sb->s_inode_bitmap_number[j] =
+				sb->s_inode_bitmap_number[j - 1];
+			sb->s_inode_bitmap[j] =
+				sb->s_inode_bitmap[j - 1];
+		}
+		read_inode_bitmap (mp, block_group, 0);
+	}
+	return 0;
+}
+
+
+void
+ext2_free_inode(struct inode *inode)
+{
+	struct ext2_sb_info * sb;
+	struct buffer_head * bh;
+	struct buffer_head * bh2;
+	unsigned long block_group;
+	unsigned long bit;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	struct ext2_super_block * es;
+
+	if (!inode)
+		return;
+
+	if (inode->i_nlink) {
+		kprintf ("ext2_free_inode: inode has nlink=%d\n",
+			inode->i_nlink);
+		return;
+	}
+
+	ext2_debug ("freeing inode %lu\n", inode->i_number);
+
+	sb = inode->i_e2fs;
+	lock_super (DEVVP(inode));
+	if (inode->i_number < EXT2_FIRST_INO(sb) ||
+	    inode->i_number > sb->s_es->s_inodes_count) {
+		kprintf ("free_inode reserved inode or nonexistent inode");
+		unlock_super (DEVVP(inode));
+		return;
+	}
+	es = sb->s_es;
+	block_group = (inode->i_number - 1) / EXT2_INODES_PER_GROUP(sb);
+	bit = (inode->i_number - 1) % EXT2_INODES_PER_GROUP(sb);
+	bitmap_nr = load_inode_bitmap (ITOV(inode)->v_mount, block_group);
+	bh = sb->s_inode_bitmap[bitmap_nr];
+	if (!clear_bit (bit, bh->b_data))
+		kprintf ( "ext2_free_inode:"
+		      "bit already cleared for inode %lu",
+		      (unsigned long)inode->i_number);
+	else {
+		gdp = get_group_desc (ITOV(inode)->v_mount, block_group, &bh2);
+		gdp->bg_free_inodes_count++;
+		if (S_ISDIR(inode->i_mode))
+			gdp->bg_used_dirs_count--;
+		mark_buffer_dirty(bh2);
+		es->s_free_inodes_count++;
+	}
+	mark_buffer_dirty(bh);
+/*** XXX
+	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ll_rw_block (WRITE, 1, &bh);
+		wait_on_buffer (bh);
+	}
+***/
+	sb->s_dirt = 1;
+	unlock_super (DEVVP(inode));
+}
+
+#if linux
+/*
+ * This function increments the inode version number
+ *
+ * This may be used one day by the NFS server
+ */
+static void
+inc_inode_version(struct inode *inode, struct ext2_group_desc *gdp, int mode)
+{
+	unsigned long inode_block;
+	struct buffer_head * bh;
+	struct ext2_inode * raw_inode;
+
+	inode_block = gdp->bg_inode_table + (((inode->i_number - 1) %
+			EXT2_INODES_PER_GROUP(inode->i_sb)) /
+			EXT2_INODES_PER_BLOCK(inode->i_sb));
+	bh = bread (inode->i_sb->s_dev, dbtob(inode_block), inode->i_sb->s_blocksize);
+	if (!bh) {
+		kprintf ("inc_inode_version Cannot load inode table block - "
+			    "inode=%lu, inode_block=%lu\n",
+			    inode->i_number, inode_block);
+		inode->u.ext2_i.i_version = 1;
+		return;
+	}
+	raw_inode = ((struct ext2_inode *) bh->b_data) +
+			(((inode->i_number - 1) %
+			EXT2_INODES_PER_GROUP(inode->i_sb)) %
+			EXT2_INODES_PER_BLOCK(inode->i_sb));
+	raw_inode->i_version++;
+	inode->u.ext2_i.i_version = raw_inode->i_version;
+	bdwrite (bh);
+}
+
+#endif /* linux */
+
+/*
+ * There are two policies for allocating an inode.  If the new inode is
+ * a directory, then a forward search is made for a block group with both
+ * free space and a low directory-to-inode ratio; if that fails, then of
+ * the groups with above-average free space, that group with the fewest
+ * directories already is chosen.
+ *
+ * For other inodes, search forward from the parent directory\'s block
+ * group to find a free inode.
+ */
+/*
+ * this functino has been reduced to the actual 'find the inode number' part
+ */
+ino_t
+ext2_new_inode(const struct inode *dir, int mode)
+{
+	struct ext2_sb_info * sb;
+	struct buffer_head * bh;
+	struct buffer_head * bh2;
+	int i, j, avefreei;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	struct ext2_group_desc * tmp;
+	struct ext2_super_block * es;
+
+	if (!dir)
+		return 0;
+	sb = dir->i_e2fs;
+
+        lock_super (DEVVP(dir));
+        es = sb->s_es;
+repeat:
+        gdp = NULL; i=0;
+
+        if (S_ISDIR(mode)) {
+		avefreei = es->s_free_inodes_count /
+			sb->s_groups_count;
+/* I am not yet convinced that this next bit is necessary.
+		i = dir->u.ext2_i.i_block_group;
+		for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {
+			tmp = get_group_desc (sb, i, &bh2);
+			if ((tmp->bg_used_dirs_count << 8) <
+			    tmp->bg_free_inodes_count) {
+				gdp = tmp;
+				break;
+			}
+			else
+			i = ++i % sb->u.ext2_sb.s_groups_count;
+		}
+*/
+		if (!gdp) {
+			for (j = 0; j < sb->s_groups_count; j++) {
+				tmp = get_group_desc(ITOV(dir)->v_mount,j,&bh2);
+				if (tmp->bg_free_inodes_count &&
+					tmp->bg_free_inodes_count >= avefreei) {
+					if (!gdp ||
+					    (tmp->bg_free_blocks_count >
+					     gdp->bg_free_blocks_count)) {
+						i = j;
+						gdp = tmp;
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		/*
+		 * Try to place the inode in its parent directory
+		 */
+		i = dir->i_block_group;
+		tmp = get_group_desc (ITOV(dir)->v_mount, i, &bh2);
+		if (tmp->bg_free_inodes_count)
+			gdp = tmp;
+		else
+		{
+			/*
+			 * Use a quadratic hash to find a group with a
+			 * free inode
+			 */
+			for (j = 1; j < sb->s_groups_count; j <<= 1) {
+				i += j;
+				if (i >= sb->s_groups_count)
+					i -= sb->s_groups_count;
+				tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2);
+				if (tmp->bg_free_inodes_count) {
+					gdp = tmp;
+					break;
+				}
+			}
+		}
+		if (!gdp) {
+			/*
+			 * That failed: try linear search for a free inode
+			 */
+			i = dir->i_block_group + 1;
+			for (j = 2; j < sb->s_groups_count; j++) {
+				if (++i >= sb->s_groups_count)
+					i = 0;
+				tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2);
+				if (tmp->bg_free_inodes_count) {
+					gdp = tmp;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!gdp) {
+		unlock_super (DEVVP(dir));
+		return 0;
+	}
+	bitmap_nr = load_inode_bitmap (ITOV(dir)->v_mount, i);
+	bh = sb->s_inode_bitmap[bitmap_nr];
+	if ((j = find_first_zero_bit ((unsigned long *) bh->b_data,
+				      EXT2_INODES_PER_GROUP(sb))) <
+	    EXT2_INODES_PER_GROUP(sb)) {
+		if (set_bit (j, bh->b_data)) {
+			kprintf ( "ext2_new_inode:"
+				      "bit already set for inode %d", j);
+			goto repeat;
+		}
+/* Linux now does the following:
+		mark_buffer_dirty(bh);
+		if (sb->s_flags & MS_SYNCHRONOUS) {
+			ll_rw_block (WRITE, 1, &bh);
+			wait_on_buffer (bh);
+		}
+*/
+		mark_buffer_dirty(bh);
+	} else {
+		if (gdp->bg_free_inodes_count != 0) {
+			kprintf ( "ext2_new_inode:"
+				    "Free inodes count corrupted in group %d",
+				    i);
+			unlock_super (DEVVP(dir));
+			return 0;
+		}
+		goto repeat;
+	}
+	j += i * EXT2_INODES_PER_GROUP(sb) + 1;
+	if (j < EXT2_FIRST_INO(sb) || j > es->s_inodes_count) {
+		kprintf ( "ext2_new_inode:"
+			    "reserved inode or inode > inodes count - "
+			    "block_group = %d,inode=%d", i, j);
+		unlock_super (DEVVP(dir));
+		return 0;
+	}
+	gdp->bg_free_inodes_count--;
+	if (S_ISDIR(mode))
+		gdp->bg_used_dirs_count++;
+	mark_buffer_dirty(bh2);
+	es->s_free_inodes_count--;
+	/* mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); */
+	sb->s_dirt = 1;
+	unlock_super (DEVVP(dir));
+	return j;
+}
+
+#ifdef unused
+static unsigned long
+ext2_count_free_inodes(struct mount *mp)
+{
+#ifdef EXT2FS_DEBUG
+        struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
+	struct ext2_super_block * es;
+	unsigned long desc_count, bitmap_count, x;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	int i;
+
+	lock_super (VFSTOEXT2(mp)->um_devvp);
+	es = sb->s_es;
+	desc_count = 0;
+	bitmap_count = 0;
+	gdp = NULL;
+	for (i = 0; i < sb->s_groups_count; i++) {
+		gdp = get_group_desc (mp, i, NULL);
+		desc_count += gdp->bg_free_inodes_count;
+		bitmap_nr = load_inode_bitmap (mp, i);
+		x = ext2_count_free (sb->s_inode_bitmap[bitmap_nr],
+				     EXT2_INODES_PER_GROUP(sb) / 8);
+		ext2_debug ("group %d: stored = %d, counted = %lu\n",
+			i, gdp->bg_free_inodes_count, x);
+		bitmap_count += x;
+	}
+	ext2_debug("stored = %lu, computed = %lu, %lu\n",
+		es->s_free_inodes_count, desc_count, bitmap_count);
+	unlock_super (VFSTOEXT2(mp)->um_devvp);
+	return desc_count;
+#else
+	return VFSTOEXT2(mp)->um_e2fsb->s_free_inodes_count;
+#endif
+}
+#endif /* unused */
+
+#ifdef LATER
+void
+ext2_check_inodes_bitmap(struct mount *mp)
+{
+	struct ext2_super_block * es;
+	unsigned long desc_count, bitmap_count, x;
+	int bitmap_nr;
+	struct ext2_group_desc * gdp;
+	int i;
+
+	lock_super (sb);
+	es = sb->u.ext2_sb.s_es;
+	desc_count = 0;
+	bitmap_count = 0;
+	gdp = NULL;
+	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
+		gdp = get_group_desc (sb, i, NULL);
+		desc_count += gdp->bg_free_inodes_count;
+		bitmap_nr = load_inode_bitmap (sb, i);
+		x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr],
+				     EXT2_INODES_PER_GROUP(sb) / 8);
+		if (gdp->bg_free_inodes_count != x)
+			kprintf ( "ext2_check_inodes_bitmap:"
+				    "Wrong free inodes count in group %d, "
+				    "stored = %d, counted = %lu", i,
+				    gdp->bg_free_inodes_count, x);
+		bitmap_count += x;
+	}
+	if (es->s_free_inodes_count != bitmap_count)
+		kprintf ( "ext2_check_inodes_bitmap:"
+			    "Wrong free inodes count in super block, "
+			    "stored = %lu, counted = %lu",
+			    (unsigned long) es->s_free_inodes_count, bitmap_count);
+	unlock_super (sb);
+}
+#endif
diff --git a/sys/gnu/vfs/ext2fs/ext2_lookup.c b/sys/gnu/vfs/ext2fs/ext2_lookup.c
new file mode 100644
index 0000000..92cd4b8
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_lookup.c
@@ -0,0 +1,1042 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ *
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_lookup.c,v 1.21.2.3 2002/11/17 02:02:42 bde Exp $
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ufs_lookup.c	8.6 (Berkeley) 4/1/94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/buf.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/dirent.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "dir.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+
+/*
+   DIRBLKSIZE in ffs is DEV_BSIZE (in most cases 512)
+   while it is the native blocksize in ext2fs - thus, a #define
+   is no longer appropriate
+*/
+#undef  DIRBLKSIZ
+
+extern	int dirchk;
+
+static u_char ext2_ft_to_dt[] = {
+	DT_UNKNOWN,		/* EXT2_FT_UNKNOWN */
+	DT_REG,			/* EXT2_FT_REG_FILE */
+	DT_DIR,			/* EXT2_FT_DIR */
+	DT_CHR,			/* EXT2_FT_CHRDEV */
+	DT_BLK,			/* EXT2_FT_BLKDEV */
+	DT_FIFO,		/* EXT2_FT_FIFO */
+	DT_SOCK,		/* EXT2_FT_SOCK */
+	DT_LNK,			/* EXT2_FT_SYMLINK */
+};
+#define	FTTODT(ft)						\
+    ((ft) > NELEM(ext2_ft_to_dt) ?	\
+    DT_UNKNOWN : ext2_ft_to_dt[(ft)])
+
+static u_char dt_to_ext2_ft[] = {
+	EXT2_FT_UNKNOWN,	/* DT_UNKNOWN */
+	EXT2_FT_FIFO,		/* DT_FIFO */
+	EXT2_FT_CHRDEV,		/* DT_CHR */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_DIR,		/* DT_DIR */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_BLKDEV,		/* DT_BLK */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_REG_FILE,	/* DT_REG */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_SYMLINK,	/* DT_LNK */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_SOCK,		/* DT_SOCK */
+	EXT2_FT_UNKNOWN,	/* unused */
+	EXT2_FT_UNKNOWN,	/* DT_WHT */
+};
+#define	DTTOFT(dt)						\
+    ((dt) > NELEM(dt_to_ext2_ft) ?	\
+    EXT2_FT_UNKNOWN : dt_to_ext2_ft[(dt)])
+
+static int	ext2_dirbadentry (struct vnode *dp,
+				      struct ext2_dir_entry_2 *de,
+				      int entryoffsetinblock);
+
+/*
+ * Vnode op for reading directories.
+ *
+ * The routine below assumes that the on-disk format of a directory
+ * is the same as that defined by <sys/dirent.h>. If the on-disk
+ * format changes, then it will be necessary to do a conversion
+ * from the on-disk format that read returns to the format defined
+ * by <sys/dirent.h>.
+ */
+/*
+ * this is exactly what we do here - the problem is that the conversion
+ * will blow up some entries by four bytes, so it can't be done in place.
+ * This is too bad. Right now the conversion is done entry by entry, the
+ * converted entry is sent via uiomove.
+ *
+ * XXX allocate a buffer, convert as many entries as possible, then send
+ * the whole buffer to uiomove
+ *
+ * ext2_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
+ */
+int
+ext2_readdir(struct vop_readdir_args *ap)
+{
+        struct uio *uio = ap->a_uio;
+        int count, error;
+	struct ext2_dir_entry_2 *edp, *dp;
+	int ncookies;
+	struct uio auio;
+	struct iovec aiov;
+	caddr_t dirbuf;
+	int DIRBLKSIZ = VTOI(ap->a_vp)->i_e2fs->s_blocksize;
+	int readcnt, retval;
+	off_t startoffset = uio->uio_offset;
+
+	if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
+		return(error);
+
+	count = uio->uio_resid;
+	/*
+	 * Avoid complications for partial directory entries by adjusting
+	 * the i/o to end at a block boundary.  Don't give up (like ufs
+	 * does) if the initial adjustment gives a negative count, since
+	 * many callers don't supply a large enough buffer.  The correct
+	 * size is a little larger than DIRBLKSIZ to allow for expansion
+	 * of directory entries, but some callers just use 512.
+	 */
+	count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
+	if (count <= 0)
+		count += DIRBLKSIZ;
+	if (count > MAXBSIZE)		/* limit to a reasonable size */
+		count = MAXBSIZE;
+
+#ifdef EXT2FS_DEBUG
+	kprintf("ext2_readdir: uio_offset = %lld, uio_resid = %d, count = %d\n",
+	    uio->uio_offset, uio->uio_resid, count);
+#endif
+
+	auio = *uio;
+	auio.uio_iov = &aiov;
+	auio.uio_iovcnt = 1;
+	auio.uio_resid = count;
+	auio.uio_segflg = UIO_SYSSPACE;
+	aiov.iov_len = count;
+	MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
+	aiov.iov_base = dirbuf;
+	error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
+	if (error == 0) {
+		readcnt = count - auio.uio_resid;
+		edp = (struct ext2_dir_entry_2 *)&dirbuf[readcnt];
+		ncookies = 0;
+		for (dp = (struct ext2_dir_entry_2 *)dirbuf;
+		    !error && uio->uio_resid > 0 && dp < edp; ) {
+			/*-
+			 * "New" ext2fs directory entries differ in 3 ways
+			 * from ufs on-disk ones:
+			 * - the name is not necessarily NUL-terminated.
+			 * - the file type field always exists and always
+			 * follows the name length field.
+			 * - the file type is encoded in a different way.
+			 *
+			 * "Old" ext2fs directory entries need no special
+			 * conversions, since they binary compatible with
+			 * "new" entries having a file type of 0 (i.e.,
+			 * EXT2_FT_UNKNOWN).  Splitting the old name length
+			 * field didn't make a mess like it did in ufs,
+			 * because ext2fs uses a machine-dependent disk
+			 * layout.
+			 */
+			if (dp->rec_len <= 0) {
+				error = EIO;
+				break;
+			}
+			retval = vop_write_dirent(&error, uio, dp->inode,
+			    FTTODT(dp->file_type), dp->name_len, dp->name);
+
+			if (retval)
+				break;
+			/* advance dp */
+			dp = (struct ext2_dir_entry_2 *)((char *)dp + dp->rec_len);
+			if (!error)
+				ncookies++;
+		}
+		/* we need to correct uio_offset */
+		uio->uio_offset = startoffset + (caddr_t)dp - dirbuf;
+
+		if (!error && ap->a_ncookies != NULL) {
+			off_t *cookiep, *cookies, *ecookies;
+			off_t off;
+
+			if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
+				panic("ext2fs_readdir: unexpected uio from NFS server");
+			if (ncookies) {
+				MALLOC(cookies, off_t *,
+				       ncookies * sizeof(off_t),
+				       M_TEMP, M_WAITOK);
+			} else {
+				MALLOC(cookies, off_t *,
+				       sizeof(off_t), M_TEMP, M_WAITOK);
+			}
+			off = startoffset;
+			for (dp = (struct ext2_dir_entry_2 *)dirbuf,
+			     cookiep = cookies, ecookies = cookies + ncookies;
+			     cookiep < ecookies;
+			     dp = (struct ext2_dir_entry_2 *)((caddr_t) dp + dp->rec_len)) {
+				off += dp->rec_len;
+				*cookiep++ = off;
+			}
+			*ap->a_ncookies = ncookies;
+			*ap->a_cookies = cookies;
+		}
+	}
+	FREE(dirbuf, M_TEMP);
+	if (ap->a_eofflag)
+		*ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
+	vn_unlock(ap->a_vp);
+        return (error);
+}
+
+/*
+ * Convert a component of a pathname into a pointer to a locked inode.
+ * This is a very central and rather complicated routine.
+ * If the file system is not maintained in a strict tree hierarchy,
+ * this can result in a deadlock situation (see comments in code below).
+ *
+ * The cnp->cn_nameiop argument is LOOKUP, CREATE, RENAME, or DELETE depending
+ * on whether the name is to be looked up, created, renamed, or deleted.
+ * When CREATE, RENAME, or DELETE is specified, information usable in
+ * creating, renaming, or deleting a directory entry may be calculated.
+ * If flag has LOCKPARENT or'ed into it and the target of the pathname
+ * exists, lookup returns both the target and its parent directory locked.
+ * When creating or renaming and LOCKPARENT is specified, the target may
+ * not be ".".  When deleting and LOCKPARENT is specified, the target may
+ * be "."., but the caller must check to ensure it does an vrele and vput
+ * instead of two vputs.
+ *
+ * Overall outline of ufs_lookup:
+ *
+ *	search for name in directory, to found or notfound
+ * notfound:
+ *	if creating, return locked directory, leaving info on available slots
+ *	else return error
+ * found:
+ *	if at end of path and deleting, return information to allow delete
+ *	if at end of path and rewriting (RENAME and LOCKPARENT), lock target
+ *	  inode and return info to allow rewrite
+ *	if not at end, add name to cache; if at end and neither creating
+ *	  nor deleting, add name to cache
+ *
+ * ext2_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
+ *	       struct componentname *a_cnp)
+ */
+int
+ext2_lookup(struct vop_old_lookup_args *ap)
+{
+	struct vnode *vdp;	/* vnode for directory being searched */
+	struct inode *dp;	/* inode for directory being searched */
+	struct buf *bp;			/* a buffer of directory entries */
+	struct ext2_dir_entry_2 *ep; /* the current directory entry */
+	int entryoffsetinblock;		/* offset of ep in bp's buffer */
+	enum {NONE, COMPACT, FOUND} slotstatus;
+	doff_t slotoffset;		/* offset of area with free space */
+	int slotsize;			/* size of area at slotoffset */
+	int slotfreespace;		/* amount of space free in slot */
+	int slotneeded;			/* size of the entry we're seeking */
+	int numdirpasses;		/* strategy for directory search */
+	doff_t endsearch;		/* offset to end directory search */
+	doff_t prevoff;			/* prev entry dp->i_offset */
+	struct vnode *pdp;		/* saved dp during symlink work */
+	struct vnode *tdp;		/* returned by VFS_VGET */
+	doff_t enduseful;		/* pointer past last used dir slot */
+	u_long bmask;			/* block offset mask */
+	int lockparent;			/* 1 => lockparent flag is set */
+	int wantparent;			/* 1 => wantparent or lockparent flag */
+	int namlen, error;
+	struct vnode **vpp = ap->a_vpp;
+	struct componentname *cnp = ap->a_cnp;
+	struct ucred *cred = cnp->cn_cred;
+	int flags = cnp->cn_flags;
+	int nameiop = cnp->cn_nameiop;
+
+	int	DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize;
+
+	bp = NULL;
+	slotoffset = -1;
+	*vpp = NULL;
+	vdp = ap->a_dvp;
+	dp = VTOI(vdp);
+	lockparent = flags & CNP_LOCKPARENT;
+	wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT);
+
+	/*
+	 * We now have a segment name to search for, and a directory to search.
+	 */
+
+	/*
+	 * Suppress search for slots unless creating
+	 * file and at end of pathname, in which case
+	 * we watch for a place to put the new file in
+	 * case it doesn't already exist.
+	 */
+	slotstatus = FOUND;
+	slotfreespace = slotsize = slotneeded = 0;
+	if (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) {
+		slotstatus = NONE;
+		slotneeded = EXT2_DIR_REC_LEN(cnp->cn_namelen);
+		/* was
+		slotneeded = (sizeof(struct direct) - MAXNAMLEN +
+			cnp->cn_namelen + 3) &~ 3; */
+	}
+
+	/*
+	 * If there is cached information on a previous search of
+	 * this directory, pick up where we last left off.
+	 * We cache only lookups as these are the most common
+	 * and have the greatest payoff. Caching CREATE has little
+	 * benefit as it usually must search the entire directory
+	 * to determine that the entry does not exist. Caching the
+	 * location of the last DELETE or RENAME has not reduced
+	 * profiling time and hence has been removed in the interest
+	 * of simplicity.
+	 */
+	bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
+	if (nameiop != NAMEI_LOOKUP || dp->i_diroff == 0 ||
+	    dp->i_diroff > dp->i_size) {
+		entryoffsetinblock = 0;
+		dp->i_offset = 0;
+		numdirpasses = 1;
+	} else {
+		dp->i_offset = dp->i_diroff;
+		if ((entryoffsetinblock = dp->i_offset & bmask) &&
+		    (error = EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
+			return (error);
+		numdirpasses = 2;
+	}
+	prevoff = dp->i_offset;
+	endsearch = roundup(dp->i_size, DIRBLKSIZ);
+	enduseful = 0;
+
+searchloop:
+	while (dp->i_offset < endsearch) {
+		/*
+		 * If necessary, get the next directory block.
+		 */
+		if ((dp->i_offset & bmask) == 0) {
+			if (bp != NULL)
+				brelse(bp);
+			if ((error =
+			    EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
+				return (error);
+			entryoffsetinblock = 0;
+		}
+		/*
+		 * If still looking for a slot, and at a DIRBLKSIZE
+		 * boundary, have to start looking for free space again.
+		 */
+		if (slotstatus == NONE &&
+		    (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) {
+			slotoffset = -1;
+			slotfreespace = 0;
+		}
+		/*
+		 * Get pointer to next entry.
+		 * Full validation checks are slow, so we only check
+		 * enough to insure forward progress through the
+		 * directory. Complete checks can be run by patching
+		 * "dirchk" to be true.
+		 */
+		ep = (struct ext2_dir_entry_2 *)
+			((char *)bp->b_data + entryoffsetinblock);
+		if (ep->rec_len == 0 ||
+		    (dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock))) {
+			int i;
+			ext2_dirbad(dp, dp->i_offset, "mangled entry");
+			i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
+			dp->i_offset += i;
+			entryoffsetinblock += i;
+			continue;
+		}
+
+		/*
+		 * If an appropriate sized slot has not yet been found,
+		 * check to see if one is available. Also accumulate space
+		 * in the current block so that we can determine if
+		 * compaction is viable.
+		 */
+		if (slotstatus != FOUND) {
+			int size = ep->rec_len;
+
+			if (ep->inode != 0)
+				size -= EXT2_DIR_REC_LEN(ep->name_len);
+			if (size > 0) {
+				if (size >= slotneeded) {
+					slotstatus = FOUND;
+					slotoffset = dp->i_offset;
+					slotsize = ep->rec_len;
+				} else if (slotstatus == NONE) {
+					slotfreespace += size;
+					if (slotoffset == -1)
+						slotoffset = dp->i_offset;
+					if (slotfreespace >= slotneeded) {
+						slotstatus = COMPACT;
+						slotsize = dp->i_offset +
+						      ep->rec_len - slotoffset;
+					}
+				}
+			}
+		}
+
+		/*
+		 * Check for a name match.
+		 */
+		if (ep->inode) {
+			namlen = ep->name_len;
+			if (namlen == cnp->cn_namelen &&
+			    !bcmp(cnp->cn_nameptr, ep->name,
+				(unsigned)namlen)) {
+				/*
+				 * Save directory entry's inode number and
+				 * reclen in ndp->ni_ufs area, and release
+				 * directory buffer.
+				 */
+				dp->i_ino = ep->inode;
+				dp->i_reclen = ep->rec_len;
+				goto found;
+			}
+		}
+		prevoff = dp->i_offset;
+		dp->i_offset += ep->rec_len;
+		entryoffsetinblock += ep->rec_len;
+		if (ep->inode)
+			enduseful = dp->i_offset;
+	}
+/* notfound: */
+	/*
+	 * If we started in the middle of the directory and failed
+	 * to find our target, we must check the beginning as well.
+	 */
+	if (numdirpasses == 2) {
+		numdirpasses--;
+		dp->i_offset = 0;
+		endsearch = dp->i_diroff;
+		goto searchloop;
+	}
+	if (bp != NULL)
+		brelse(bp);
+	/*
+	 * If creating, and at end of pathname and current
+	 * directory has not been removed, then can consider
+	 * allowing file to be created.
+	 */
+	if ((nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) &&
+	    dp->i_nlink != 0) {
+		/*
+		 * Access for write is interpreted as allowing
+		 * creation of files in the directory.
+		 */
+		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
+			return (error);
+		/*
+		 * Return an indication of where the new directory
+		 * entry should be put.  If we didn't find a slot,
+		 * then set dp->i_count to 0 indicating
+		 * that the new slot belongs at the end of the
+		 * directory. If we found a slot, then the new entry
+		 * can be put in the range from dp->i_offset to
+		 * dp->i_offset + dp->i_count.
+		 */
+		if (slotstatus == NONE) {
+			dp->i_offset = roundup(dp->i_size, DIRBLKSIZ);
+			dp->i_count = 0;
+			enduseful = dp->i_offset;
+		} else {
+			dp->i_offset = slotoffset;
+			dp->i_count = slotsize;
+			if (enduseful < slotoffset + slotsize)
+				enduseful = slotoffset + slotsize;
+		}
+		dp->i_endoff = roundup(enduseful, DIRBLKSIZ);
+		dp->i_flag |= IN_CHANGE | IN_UPDATE;
+		/*
+		 * We return with the directory locked, so that
+		 * the parameters we set up above will still be
+		 * valid if we actually decide to do a direnter().
+		 * We return ni_vp == NULL to indicate that the entry
+		 * does not currently exist; we leave a pointer to
+		 * the (locked) directory inode in ndp->ni_dvp.
+		 * The pathname buffer is saved so that the name
+		 * can be obtained later.
+		 *
+		 * NB - if the directory is unlocked, then this
+		 * information cannot be used.
+		 */
+		if (!lockparent)
+			vn_unlock(vdp);
+		return (EJUSTRETURN);
+	}
+	return (ENOENT);
+
+found:
+	/*
+	 * Check that directory length properly reflects presence
+	 * of this entry.
+	 */
+	if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len)
+		> dp->i_size) {
+		ext2_dirbad(dp, dp->i_offset, "i_size too small");
+		dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len);
+		dp->i_flag |= IN_CHANGE | IN_UPDATE;
+	}
+	brelse(bp);
+
+	/*
+	 * Found component in pathname.
+	 * If the final component of path name, save information
+	 * in the cache as to where the entry was found.
+	 */
+	if (nameiop == NAMEI_LOOKUP)
+		dp->i_diroff = dp->i_offset &~ (DIRBLKSIZ - 1);
+
+	/*
+	 * If deleting, and at end of pathname, return
+	 * parameters which can be used to remove file.
+	 * If the wantparent flag isn't set, we return only
+	 * the directory (in ndp->ni_dvp), otherwise we go
+	 * on and lock the inode, being careful with ".".
+	 */
+	if (nameiop == NAMEI_DELETE) {
+		/*
+		 * Write access to directory required to delete files.
+		 */
+		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
+			return (error);
+		/*
+		 * Return pointer to current entry in dp->i_offset,
+		 * and distance past previous entry (if there
+		 * is a previous entry in this block) in dp->i_count.
+		 * Save directory inode pointer in ndp->ni_dvp for dirremove().
+		 */
+		if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
+			dp->i_count = 0;
+		else
+			dp->i_count = dp->i_offset - prevoff;
+		if (dp->i_number == dp->i_ino) {
+			vref(vdp);
+			*vpp = vdp;
+			return (0);
+		}
+		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
+			return (error);
+		/*
+		 * If directory is "sticky", then user must own
+		 * the directory, or the file in it, else she
+		 * may not delete it (unless she's root). This
+		 * implements append-only directories.
+		 */
+		if ((dp->i_mode & ISVTX) &&
+		    cred->cr_uid != 0 &&
+		    cred->cr_uid != dp->i_uid &&
+		    VTOI(tdp)->i_uid != cred->cr_uid) {
+			vput(tdp);
+			return (EPERM);
+		}
+		*vpp = tdp;
+		if (!lockparent)
+			vn_unlock(vdp);
+		return (0);
+	}
+
+	/*
+	 * If rewriting (RENAME), return the inode and the
+	 * information required to rewrite the present directory
+	 * Must get inode of directory entry to verify it's a
+	 * regular file, or empty directory.
+	 */
+	if (nameiop == NAMEI_RENAME && wantparent) {
+		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
+			return (error);
+		/*
+		 * Careful about locking second inode.
+		 * This can only occur if the target is ".".
+		 */
+		if (dp->i_number == dp->i_ino)
+			return (EISDIR);
+		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
+			return (error);
+		*vpp = tdp;
+		if (!lockparent)
+			vn_unlock(vdp);
+		return (0);
+	}
+
+	/*
+	 * Step through the translation in the name.  We do not `vput' the
+	 * directory because we may need it again if a symbolic link
+	 * is relative to the current directory.  Instead we save it
+	 * unlocked as "pdp".  We must get the target inode before unlocking
+	 * the directory to insure that the inode will not be removed
+	 * before we get it.  We prevent deadlock by always fetching
+	 * inodes from the root, moving down the directory tree. Thus
+	 * when following backward pointers ".." we must unlock the
+	 * parent directory before getting the requested directory.
+	 * There is a potential race condition here if both the current
+	 * and parent directories are removed before the VFS_VGET for the
+	 * inode associated with ".." returns.  We hope that this occurs
+	 * infrequently since we cannot avoid this race condition without
+	 * implementing a sophisticated deadlock detection algorithm.
+	 * Note also that this simple deadlock detection scheme will not
+	 * work if the file system has any hard links other than ".."
+	 * that point backwards in the directory structure.
+	 */
+	pdp = vdp;
+	if (flags & CNP_ISDOTDOT) {
+		vn_unlock(pdp);	/* race to get the inode */
+		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0) {
+			vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
+			return (error);
+		}
+		if (lockparent && (error = vn_lock(pdp, LK_EXCLUSIVE))) {
+			vput(tdp);
+			return (error);
+		}
+		*vpp = tdp;
+	} else if (dp->i_number == dp->i_ino) {
+		vref(vdp);	/* we want ourself, ie "." */
+		*vpp = vdp;
+	} else {
+		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
+			return (error);
+		if (!lockparent)
+			vn_unlock(pdp);
+		*vpp = tdp;
+	}
+	return (0);
+}
+
+void
+ext2_dirbad(struct inode *ip, doff_t offset, char *how)
+{
+	struct mount *mp;
+
+	mp = ITOV(ip)->v_mount;
+	kprintf("%s: bad dir ino %lu at offset %ld: %s\n",
+	       mp->mnt_stat.f_mntfromname, (u_long)ip->i_number,
+	       (long)offset, how);
+	if ((mp->mnt_flag & MNT_RDONLY) == 0)
+		panic("ufs_dirbad: bad dir");
+}
+
+/*
+ * Do consistency checking on a directory entry:
+ *	record length must be multiple of 4
+ *	entry must fit in rest of its DIRBLKSIZ block
+ *	record must be large enough to contain entry
+ *	name is not longer than MAXNAMLEN
+ *	name must be as long as advertised, and null terminated
+ */
+/*
+ *	changed so that it confirms to ext2_check_dir_entry
+ */
+static int
+ext2_dirbadentry(struct vnode *dp, struct ext2_dir_entry_2 *de,
+		 int entryoffsetinblock)
+{
+	int	DIRBLKSIZ = VTOI(dp)->i_e2fs->s_blocksize;
+
+        char * error_msg = NULL;
+
+        if (de->rec_len < EXT2_DIR_REC_LEN(1))
+                error_msg = "rec_len is smaller than minimal";
+        else if (de->rec_len % 4 != 0)
+                error_msg = "rec_len % 4 != 0";
+        else if (de->rec_len < EXT2_DIR_REC_LEN(de->name_len))
+                error_msg = "reclen is too small for name_len";
+        else if (entryoffsetinblock + de->rec_len > DIRBLKSIZ)
+                error_msg = "directory entry across blocks";
+        /* else LATER
+	     if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count)
+                error_msg = "inode out of bounds";
+	*/
+
+        if (error_msg != NULL) {
+                kprintf("bad directory entry: %s\n", error_msg);
+                kprintf("offset=%d, inode=%lu, rec_len=%u, name_len=%u\n",
+			entryoffsetinblock, (unsigned long)de->inode,
+			de->rec_len, de->name_len);
+        }
+        return error_msg == NULL ? 0 : 1;
+}
+
+/*
+ * Write a directory entry after a call to namei, using the parameters
+ * that it left in the directory inode.  The argument ip is the inode which
+ * the new directory entry will refer to.  Dvp is a pointer to the directory
+ * to be written, which was left locked by namei. Remaining parameters
+ * (dp->i_offset, dp->i_count) indicate how the space for the new
+ * entry is to be obtained.
+ */
+int
+ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp)
+{
+	struct ext2_dir_entry_2 *ep, *nep;
+	struct inode *dp;
+	struct buf *bp;
+	struct ext2_dir_entry_2 newdir;
+	struct iovec aiov;
+	struct uio auio;
+	u_int dsize;
+	int error, loc, newentrysize, spacefree;
+	char *dirbuf;
+	int     DIRBLKSIZ = ip->i_e2fs->s_blocksize;
+
+
+	dp = VTOI(dvp);
+	newdir.inode = ip->i_number;
+	newdir.name_len = cnp->cn_namelen;
+	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+	    EXT2_FEATURE_INCOMPAT_FILETYPE))
+		newdir.file_type = DTTOFT(IFTODT(ip->i_mode));
+	else
+		newdir.file_type = EXT2_FT_UNKNOWN;
+	bcopy(cnp->cn_nameptr, newdir.name, (unsigned)cnp->cn_namelen + 1);
+	newentrysize = EXT2_DIR_REC_LEN(newdir.name_len);
+	if (dp->i_count == 0) {
+		/*
+		 * If dp->i_count is 0, then namei could find no
+		 * space in the directory. Here, dp->i_offset will
+		 * be on a directory block boundary and we will write the
+		 * new entry into a fresh block.
+		 */
+		if (dp->i_offset & (DIRBLKSIZ - 1))
+			panic("ext2_direnter: newblk");
+		auio.uio_offset = dp->i_offset;
+		newdir.rec_len = DIRBLKSIZ;
+		auio.uio_resid = newentrysize;
+		aiov.iov_len = newentrysize;
+		aiov.iov_base = (caddr_t)&newdir;
+		auio.uio_iov = &aiov;
+		auio.uio_iovcnt = 1;
+		auio.uio_rw = UIO_WRITE;
+		auio.uio_segflg = UIO_SYSSPACE;
+		auio.uio_td = NULL;
+		error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred);
+		if (DIRBLKSIZ >
+		    VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
+			/* XXX should grow with balloc() */
+			panic("ext2_direnter: frag size");
+		else if (!error) {
+			dp->i_size = roundup(dp->i_size, DIRBLKSIZ);
+			dp->i_flag |= IN_CHANGE;
+		}
+		return (error);
+	}
+
+	/*
+	 * If dp->i_count is non-zero, then namei found space
+	 * for the new entry in the range dp->i_offset to
+	 * dp->i_offset + dp->i_count in the directory.
+	 * To use this space, we may have to compact the entries located
+	 * there, by copying them together towards the beginning of the
+	 * block, leaving the free space in one usable chunk at the end.
+	 */
+
+	/*
+	 * Increase size of directory if entry eats into new space.
+	 * This should never push the size past a new multiple of
+	 * DIRBLKSIZE.
+	 *
+	 * N.B. - THIS IS AN ARTIFACT OF 4.2 AND SHOULD NEVER HAPPEN.
+	 */
+	if (dp->i_offset + dp->i_count > dp->i_size)
+		dp->i_size = dp->i_offset + dp->i_count;
+	/*
+	 * Get the block containing the space for the new directory entry.
+	 */
+	if ((error = EXT2_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) != 0)
+		return (error);
+	/*
+	 * Find space for the new entry. In the simple case, the entry at
+	 * offset base will have the space. If it does not, then namei
+	 * arranged that compacting the region dp->i_offset to
+	 * dp->i_offset + dp->i_count would yield the
+	 * space.
+	 */
+	ep = (struct ext2_dir_entry_2 *)dirbuf;
+	dsize = EXT2_DIR_REC_LEN(ep->name_len);
+	spacefree = ep->rec_len - dsize;
+	for (loc = ep->rec_len; loc < dp->i_count; ) {
+		nep = (struct ext2_dir_entry_2 *)(dirbuf + loc);
+		if (ep->inode) {
+			/* trim the existing slot */
+			ep->rec_len = dsize;
+			ep = (struct ext2_dir_entry_2 *)((char *)ep + dsize);
+		} else {
+			/* overwrite; nothing there; header is ours */
+			spacefree += dsize;
+		}
+		dsize = EXT2_DIR_REC_LEN(nep->name_len);
+		spacefree += nep->rec_len - dsize;
+		loc += nep->rec_len;
+		bcopy((caddr_t)nep, (caddr_t)ep, dsize);
+	}
+	/*
+	 * Update the pointer fields in the previous entry (if any),
+	 * copy in the new entry, and write out the block.
+	 */
+	if (ep->inode == 0) {
+		if (spacefree + dsize < newentrysize)
+			panic("ext2_direnter: compact1");
+		newdir.rec_len = spacefree + dsize;
+	} else {
+		if (spacefree < newentrysize)
+			panic("ext2_direnter: compact2");
+		newdir.rec_len = spacefree;
+		ep->rec_len = dsize;
+		ep = (struct ext2_dir_entry_2 *)((char *)ep + dsize);
+	}
+	bcopy((caddr_t)&newdir, (caddr_t)ep, (u_int)newentrysize);
+	error = bwrite(bp);
+	dp->i_flag |= IN_CHANGE | IN_UPDATE;
+	if (!error && dp->i_endoff && dp->i_endoff < dp->i_size)
+		error = EXT2_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC,
+				      cnp->cn_cred);
+	return (error);
+}
+
+/*
+ * Remove a directory entry after a call to namei, using
+ * the parameters which it left in the directory inode. The entry
+ * dp->i_offset contains the offset into the directory of the
+ * entry to be eliminated.  The dp->i_count field contains the
+ * size of the previous record in the directory.  If this
+ * is 0, the first entry is being deleted, so we need only
+ * zero the inode number to mark the entry as free.  If the
+ * entry is not the first in the directory, we must reclaim
+ * the space of the now empty record by adding the record size
+ * to the size of the previous entry.
+ */
+int
+ext2_dirremove(struct vnode *dvp, struct componentname *cnp)
+{
+	struct inode *dp;
+	struct ext2_dir_entry_2 *ep;
+	struct buf *bp;
+	int error;
+
+	dp = VTOI(dvp);
+	if (dp->i_count == 0) {
+		/*
+		 * First entry in block: set d_ino to zero.
+		 */
+		if ((error =
+		    EXT2_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
+			return (error);
+		ep->inode = 0;
+		error = bwrite(bp);
+		dp->i_flag |= IN_CHANGE | IN_UPDATE;
+		return (error);
+	}
+	/*
+	 * Collapse new free space into previous entry.
+	 */
+	if ((error = EXT2_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count),
+	    (char **)&ep, &bp)) != 0)
+		return (error);
+	ep->rec_len += dp->i_reclen;
+	error = bwrite(bp);
+	dp->i_flag |= IN_CHANGE | IN_UPDATE;
+	return (error);
+}
+
+/*
+ * Rewrite an existing directory entry to point at the inode
+ * supplied.  The parameters describing the directory entry are
+ * set up by a call to namei.
+ */
+int
+ext2_dirrewrite(struct inode *dp, struct inode *ip, struct componentname *cnp)
+{
+	struct buf *bp;
+	struct ext2_dir_entry_2 *ep;
+	struct vnode *vdp = ITOV(dp);
+	int error;
+
+	if ((error = EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
+		return (error);
+	ep->inode = ip->i_number;
+	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+	    EXT2_FEATURE_INCOMPAT_FILETYPE))
+		ep->file_type = DTTOFT(IFTODT(ip->i_mode));
+	else
+		ep->file_type = EXT2_FT_UNKNOWN;
+	error = bwrite(bp);
+	dp->i_flag |= IN_CHANGE | IN_UPDATE;
+	return (error);
+}
+
+/*
+ * Check if a directory is empty or not.
+ * Inode supplied must be locked.
+ *
+ * Using a struct dirtemplate here is not precisely
+ * what we want, but better than using a struct direct.
+ *
+ * NB: does not handle corrupted directories.
+ */
+int
+ext2_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred)
+{
+	off_t off;
+	struct dirtemplate dbuf;
+	struct ext2_dir_entry_2 *dp = (struct ext2_dir_entry_2 *)&dbuf;
+	int error, count, namlen;
+
+#define	MINDIRSIZ (sizeof (struct dirtemplate) / 2)
+
+	for (off = 0; off < ip->i_size; off += dp->rec_len) {
+		error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off,
+			        UIO_SYSSPACE, IO_NODELOCKED, cred, &count);
+		/*
+		 * Since we read MINDIRSIZ, residual must
+		 * be 0 unless we're at end of file.
+		 */
+		if (error || count != 0)
+			return (0);
+		/* avoid infinite loops */
+		if (dp->rec_len == 0)
+			return (0);
+		/* skip empty entries */
+		if (dp->inode == 0)
+			continue;
+		/* accept only "." and ".." */
+		namlen = dp->name_len;
+		if (namlen > 2)
+			return (0);
+		if (dp->name[0] != '.')
+			return (0);
+		/*
+		 * At this point namlen must be 1 or 2.
+		 * 1 implies ".", 2 implies ".." if second
+		 * char is also "."
+		 */
+		if (namlen == 1)
+			continue;
+		if (dp->name[1] == '.' && dp->inode == parentino)
+			continue;
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * Check if source directory is in the path of the target directory.
+ * Target is supplied locked, source is unlocked.
+ * The target is always vput before returning.
+ */
+int
+ext2_checkpath(struct inode *source, struct inode *target, struct ucred *cred)
+{
+	struct vnode *vp;
+	int error, rootino, namlen;
+	struct dirtemplate dirbuf;
+
+	vp = ITOV(target);
+	if (target->i_number == source->i_number) {
+		error = EEXIST;
+		goto out;
+	}
+	rootino = ROOTINO;
+	error = 0;
+	if (target->i_number == rootino)
+		goto out;
+
+	for (;;) {
+		if (vp->v_type != VDIR) {
+			error = ENOTDIR;
+			break;
+		}
+		error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
+				sizeof (struct dirtemplate), (off_t)0,
+				UIO_SYSSPACE, IO_NODELOCKED, cred, NULL);
+		if (error != 0)
+			break;
+		namlen = dirbuf.dotdot_type;	/* like ufs little-endian */
+		if (namlen != 2 ||
+		    dirbuf.dotdot_name[0] != '.' ||
+		    dirbuf.dotdot_name[1] != '.') {
+			error = ENOTDIR;
+			break;
+		}
+		if (dirbuf.dotdot_ino == source->i_number) {
+			error = EINVAL;
+			break;
+		}
+		if (dirbuf.dotdot_ino == rootino)
+			break;
+		vput(vp);
+		if ((error = VFS_VGET(vp->v_mount, NULL, dirbuf.dotdot_ino, &vp)) != 0) {
+			vp = NULL;
+			break;
+		}
+	}
+
+out:
+	if (error == ENOTDIR)
+		kprintf("checkpath: .. not a directory\n");
+	if (vp != NULL)
+		vput(vp);
+	return (error);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_quota.c b/sys/gnu/vfs/ext2fs/ext2_quota.c
new file mode 100644
index 0000000..eb7c98b
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_quota.c
@@ -0,0 +1,923 @@
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Elz at The University of Melbourne.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ufs_quota.c	8.5 (Berkeley) 5/20/95
+ * $FreeBSD: src/sys/ufs/ufs/ufs_quota.c,v 1.27.2.3 2002/01/15 10:33:32 phk Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/fcntl.h>
+#include <sys/proc.h>
+#include <sys/nlookup.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <vm/vm_zone.h>
+
+#include "quota.h"
+#include "dinode.h"
+#include "inode.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+
+static MALLOC_DEFINE(M_EXT2DQUOT, "EXT2 quota", "EXT2 quota entries");
+
+/*
+ * Quota name to error message mapping.
+ */
+static char *quotatypes[] = INITQFNAMES;
+
+static int ext2_chkdqchg (struct inode *, long, struct ucred *, int);
+static int ext2_chkiqchg (struct inode *, long, struct ucred *, int);
+static int ext2_dqget (struct vnode *,
+		u_long, struct ext2mount *, int, struct ext2_dquot **);
+static int ext2_dqsync (struct vnode *, struct ext2_dquot *);
+static void ext2_dqflush (struct vnode *);
+
+#ifdef DIAGNOSTIC
+static void ext2_dqref (struct ext2_dquot *);
+static void ext2_chkdquot (struct inode *);
+#endif
+
+/*
+ * Set up the quotas for an inode.
+ *
+ * This routine completely defines the semantics of quotas.
+ * If other criterion want to be used to establish quotas, the
+ * MAXQUOTAS value in quotas.h should be increased, and the
+ * additional dquots set up here.
+ */
+int
+ext2_getinoquota(struct inode *ip)
+{
+	struct ext2mount *ump;
+	struct vnode *vp = ITOV(ip);
+	int error;
+
+	ump = VFSTOEXT2(vp->v_mount);
+	/*
+	 * Set up the user quota based on file uid.
+	 * EINVAL means that quotas are not enabled.
+	 */
+	if (ip->i_dquot[USRQUOTA] == NODQUOT &&
+	    (error = ext2_dqget(vp, ip->i_uid, ump, USRQUOTA, &ip->i_dquot[USRQUOTA])) &&
+	    error != EINVAL)
+		return (error);
+	/*
+	 * Set up the group quota based on file gid.
+	 * EINVAL means that quotas are not enabled.
+	 */
+	if (ip->i_dquot[GRPQUOTA] == NODQUOT &&
+	    (error = ext2_dqget(vp, ip->i_gid, ump, GRPQUOTA, &ip->i_dquot[GRPQUOTA])) &&
+	    error != EINVAL)
+		return (error);
+	return (0);
+}
+
+/*
+ * Update disk usage, and take corrective action.
+ */
+int
+ext2_chkdq(struct inode *ip, long change, struct ucred *cred, int flags)
+{
+	struct ext2_dquot *dq;
+	int i;
+	int ncurblocks, error;
+
+#ifdef DIAGNOSTIC
+	if ((flags & CHOWN) == 0)
+		ext2_chkdquot(ip);
+#endif
+	if (change == 0)
+		return (0);
+	if (change < 0) {
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if ((dq = ip->i_dquot[i]) == NODQUOT)
+				continue;
+			while (dq->dq_flags & DQ_LOCK) {
+				dq->dq_flags |= DQ_WANT;
+				(void) tsleep((caddr_t)dq, 0, "chkdq1", 0);
+			}
+			ncurblocks = dq->dq_curblocks + change;
+			if (ncurblocks >= 0)
+				dq->dq_curblocks = ncurblocks;
+			else
+				dq->dq_curblocks = 0;
+			dq->dq_flags &= ~DQ_BLKS;
+			dq->dq_flags |= DQ_MOD;
+		}
+		return (0);
+	}
+	if ((flags & FORCE) == 0 && cred->cr_uid != 0) {
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if ((dq = ip->i_dquot[i]) == NODQUOT)
+				continue;
+			error = ext2_chkdqchg(ip, change, cred, i);
+			if (error)
+				return (error);
+		}
+	}
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if ((dq = ip->i_dquot[i]) == NODQUOT)
+			continue;
+		while (dq->dq_flags & DQ_LOCK) {
+			dq->dq_flags |= DQ_WANT;
+			(void) tsleep((caddr_t)dq, 0, "chkdq2", 0);
+		}
+		/* Reset timer when crossing soft limit */
+		if (dq->dq_curblocks + change >= dq->dq_bsoftlimit &&
+		    dq->dq_curblocks < dq->dq_bsoftlimit)
+			dq->dq_btime = time_second +
+			    VFSTOEXT2(ITOV(ip)->v_mount)->um_btime[i];
+		dq->dq_curblocks += change;
+		dq->dq_flags |= DQ_MOD;
+	}
+	return (0);
+}
+
+/*
+ * Check for a valid change to a users allocation.
+ * Issue an error message if appropriate.
+ */
+static int
+ext2_chkdqchg(struct inode *ip, long change, struct ucred *cred, int type)
+{
+	struct ext2_dquot *dq = ip->i_dquot[type];
+	long ncurblocks = dq->dq_curblocks + change;
+
+	/*
+	 * If user would exceed their hard limit, disallow space allocation.
+	 */
+	if (ncurblocks >= dq->dq_bhardlimit && dq->dq_bhardlimit) {
+		if ((dq->dq_flags & DQ_BLKS) == 0 &&
+		    ip->i_uid == cred->cr_uid) {
+			uprintf("\n%s: write failed, %s disk limit reached\n",
+			    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+			    quotatypes[type]);
+			dq->dq_flags |= DQ_BLKS;
+		}
+		return (EDQUOT);
+	}
+	/*
+	 * If user is over their soft limit for too long, disallow space
+	 * allocation. Reset time limit as they cross their soft limit.
+	 */
+	if (ncurblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) {
+		if (dq->dq_curblocks < dq->dq_bsoftlimit) {
+			dq->dq_btime = time_second +
+			    VFSTOEXT2(ITOV(ip)->v_mount)->um_btime[type];
+			if (ip->i_uid == cred->cr_uid)
+				uprintf("\n%s: warning, %s %s\n",
+				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+				    quotatypes[type], "disk quota exceeded");
+			return (0);
+		}
+		if (time_second > dq->dq_btime) {
+			if ((dq->dq_flags & DQ_BLKS) == 0 &&
+			    ip->i_uid == cred->cr_uid) {
+				uprintf("\n%s: write failed, %s %s\n",
+				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+				    quotatypes[type],
+				    "disk quota exceeded for too long");
+				dq->dq_flags |= DQ_BLKS;
+			}
+			return (EDQUOT);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Check the inode limit, applying corrective action.
+ */
+int
+ext2_chkiq(struct inode *ip, long change, struct ucred *cred, int flags)
+{
+	struct ext2_dquot *dq;
+	int i;
+	int ncurinodes, error;
+
+#ifdef DIAGNOSTIC
+	if ((flags & CHOWN) == 0)
+		ext2_chkdquot(ip);
+#endif
+	if (change == 0)
+		return (0);
+	if (change < 0) {
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if ((dq = ip->i_dquot[i]) == NODQUOT)
+				continue;
+			while (dq->dq_flags & DQ_LOCK) {
+				dq->dq_flags |= DQ_WANT;
+				(void) tsleep((caddr_t)dq, 0, "chkiq1", 0);
+			}
+			ncurinodes = dq->dq_curinodes + change;
+			if (ncurinodes >= 0)
+				dq->dq_curinodes = ncurinodes;
+			else
+				dq->dq_curinodes = 0;
+			dq->dq_flags &= ~DQ_INODS;
+			dq->dq_flags |= DQ_MOD;
+		}
+		return (0);
+	}
+	if ((flags & FORCE) == 0 && cred->cr_uid != 0) {
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if ((dq = ip->i_dquot[i]) == NODQUOT)
+				continue;
+			error = ext2_chkiqchg(ip, change, cred, i);
+			if (error)
+				return (error);
+		}
+	}
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if ((dq = ip->i_dquot[i]) == NODQUOT)
+			continue;
+		while (dq->dq_flags & DQ_LOCK) {
+			dq->dq_flags |= DQ_WANT;
+			(void) tsleep((caddr_t)dq, 0, "chkiq2", 0);
+		}
+		/* Reset timer when crossing soft limit */
+		if (dq->dq_curinodes + change >= dq->dq_isoftlimit &&
+		    dq->dq_curinodes < dq->dq_isoftlimit)
+			dq->dq_itime = time_second +
+			    VFSTOEXT2(ITOV(ip)->v_mount)->um_itime[i];
+		dq->dq_curinodes += change;
+		dq->dq_flags |= DQ_MOD;
+	}
+	return (0);
+}
+
+/*
+ * Check for a valid change to a users allocation.
+ * Issue an error message if appropriate.
+ */
+static int
+ext2_chkiqchg(struct inode *ip, long change, struct ucred *cred, int type)
+{
+	struct ext2_dquot *dq = ip->i_dquot[type];
+	long ncurinodes = dq->dq_curinodes + change;
+
+	/*
+	 * If user would exceed their hard limit, disallow inode allocation.
+	 */
+	if (ncurinodes >= dq->dq_ihardlimit && dq->dq_ihardlimit) {
+		if ((dq->dq_flags & DQ_INODS) == 0 &&
+		    ip->i_uid == cred->cr_uid) {
+			uprintf("\n%s: write failed, %s inode limit reached\n",
+			    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+			    quotatypes[type]);
+			dq->dq_flags |= DQ_INODS;
+		}
+		return (EDQUOT);
+	}
+	/*
+	 * If user is over their soft limit for too long, disallow inode
+	 * allocation. Reset time limit as they cross their soft limit.
+	 */
+	if (ncurinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) {
+		if (dq->dq_curinodes < dq->dq_isoftlimit) {
+			dq->dq_itime = time_second +
+			    VFSTOEXT2(ITOV(ip)->v_mount)->um_itime[type];
+			if (ip->i_uid == cred->cr_uid)
+				uprintf("\n%s: warning, %s %s\n",
+				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+				    quotatypes[type], "inode quota exceeded");
+			return (0);
+		}
+		if (time_second > dq->dq_itime) {
+			if ((dq->dq_flags & DQ_INODS) == 0 &&
+			    ip->i_uid == cred->cr_uid) {
+				uprintf("\n%s: write failed, %s %s\n",
+				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
+				    quotatypes[type],
+				    "inode quota exceeded for too long");
+				dq->dq_flags |= DQ_INODS;
+			}
+			return (EDQUOT);
+		}
+	}
+	return (0);
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * On filesystems with quotas enabled, it is an error for a file to change
+ * size and not to have a dquot structure associated with it.
+ */
+static void
+ext2_chkdquot(struct inode *ip)
+{
+	struct ext2mount *ump = VFSTOEXT2(ITOV(ip)->v_mount);
+	int i;
+
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if (ump->um_quotas[i] == NULLVP ||
+		    (ump->um_qflags[i] & (QTF_OPENING|QTF_CLOSING)))
+			continue;
+		if (ip->i_dquot[i] == NODQUOT) {
+			vprint("chkdquot: missing dquot", ITOV(ip));
+			panic("chkdquot: missing dquot");
+		}
+	}
+}
+#endif
+
+/*
+ * Code to process quotactl commands.
+ */
+
+struct scaninfo {
+	int rescan;
+	int type;
+};
+
+/*
+ * Q_QUOTAON - set up a quota file for a particular filesystem.
+ */
+static int ext2_quotaon_scan(struct mount *mp, struct vnode *vp, void *data);
+
+int
+ext2_quotaon(struct ucred *cred, struct mount *mp, int type, caddr_t fname)
+{
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	struct vnode *vp, **vpp;
+	struct ext2_dquot *dq;
+	int error;
+	struct nlookupdata nd;
+	struct scaninfo scaninfo;
+
+	vpp = &ump->um_quotas[type];
+	error = nlookup_init(&nd, fname, UIO_USERSPACE, NLC_FOLLOW|NLC_LOCKVP);
+	if (error == 0)
+		error = vn_open(&nd, NULL, FREAD|FWRITE, 0);
+	if (error == 0 && nd.nl_open_vp->v_type != VREG)
+		error = EACCES;
+	if (error) {
+		nlookup_done(&nd);
+		return (error);
+	}
+	vp = nd.nl_open_vp;
+	nd.nl_open_vp = NULL;
+	nlookup_done(&nd);
+
+	vn_unlock(vp);
+	if (*vpp != vp)
+		ext2_quotaoff(mp, type);
+	ump->um_qflags[type] |= QTF_OPENING;
+	mp->mnt_flag |= MNT_QUOTA;
+	vsetflags(vp, VSYSTEM);
+	*vpp = vp;
+	/* XXX release duplicate vp if *vpp == vp? */
+	/*
+	 * Save the credential of the process that turned on quotas.
+	 * Set up the time limits for this quota.
+	 */
+	ump->um_cred[type] = crhold(cred);
+	ump->um_btime[type] = MAX_DQ_TIME;
+	ump->um_itime[type] = MAX_IQ_TIME;
+	if (ext2_dqget(NULLVP, 0, ump, type, &dq) == 0) {
+		if (dq->dq_btime > 0)
+			ump->um_btime[type] = dq->dq_btime;
+		if (dq->dq_itime > 0)
+			ump->um_itime[type] = dq->dq_itime;
+		ext2_dqrele(NULLVP, dq);
+	}
+	/*
+	 * Search vnodes associated with this mount point,
+	 * adding references to quota file being opened.
+	 * NB: only need to add dquot's for inodes being modified.
+	 */
+	scaninfo.rescan = 1;
+	while (scaninfo.rescan) {
+		scaninfo.rescan = 0;
+		error = vmntvnodescan(mp, VMSC_GETVP,
+					NULL, ext2_quotaon_scan, &scaninfo);
+		if (error)
+			break;
+	}
+	ump->um_qflags[type] &= ~QTF_OPENING;
+	if (error)
+		ext2_quotaoff(mp, type);
+	return (error);
+}
+
+static int
+ext2_quotaon_scan(struct mount *mp, struct vnode *vp, void *data)
+{
+	int error;
+	/*struct scaninfo *info = data;*/
+
+	if (vp->v_writecount == 0)
+		return(0);
+	error = ext2_getinoquota(VTOI(vp));
+	return(error);
+}
+
+/*
+ * Q_QUOTAOFF - turn off disk quotas for a filesystem.
+ */
+
+static int ext2_quotaoff_scan(struct mount *mp, struct vnode *vp, void *data);
+
+int
+ext2_quotaoff(struct mount *mp, int type)
+{
+	struct vnode *qvp;
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	int error;
+	struct scaninfo scaninfo;
+
+	if ((qvp = ump->um_quotas[type]) == NULLVP)
+		return (0);
+	ump->um_qflags[type] |= QTF_CLOSING;
+
+	/*
+	 * Search vnodes associated with this mount point,
+	 * deleting any references to quota file being closed.
+	 */
+	scaninfo.rescan = 1;
+	scaninfo.type = type;
+	while (scaninfo.rescan) {
+		scaninfo.rescan = 0;
+		vmntvnodescan(mp, VMSC_GETVP, NULL, ext2_quotaoff_scan, &scaninfo);
+	}
+	ext2_dqflush(qvp);
+	vclrflags(qvp, VSYSTEM);
+	error = vn_close(qvp, FREAD|FWRITE);
+	ump->um_quotas[type] = NULLVP;
+	crfree(ump->um_cred[type]);
+	ump->um_cred[type] = NOCRED;
+	ump->um_qflags[type] &= ~QTF_CLOSING;
+	for (type = 0; type < MAXQUOTAS; type++) {
+		if (ump->um_quotas[type] != NULLVP)
+			break;
+	}
+	if (type == MAXQUOTAS)
+		mp->mnt_flag &= ~MNT_QUOTA;
+	return (error);
+}
+
+static int
+ext2_quotaoff_scan(struct mount *mp, struct vnode *vp, void *data)
+{
+	struct scaninfo *info = data;
+	struct ext2_dquot *dq;
+	struct inode *ip;
+
+	if (vp->v_type == VNON) {
+		return(0);
+	}
+	ip = VTOI(vp);
+	dq = ip->i_dquot[info->type];
+	ip->i_dquot[info->type] = NODQUOT;
+	ext2_dqrele(vp, dq);
+	return(0);
+}
+
+/*
+ * Q_GETQUOTA - return current values in a dqblk structure.
+ */
+int
+ext2_getquota(struct mount *mp, u_long id, int type, caddr_t addr)
+{
+	struct ext2_dquot *dq;
+	int error;
+
+	error = ext2_dqget(NULLVP, id, VFSTOEXT2(mp), type, &dq);
+	if (error)
+		return (error);
+	error = copyout((caddr_t)&dq->dq_dqb, addr, sizeof (struct ext2_dqblk));
+	ext2_dqrele(NULLVP, dq);
+	return (error);
+}
+
+/*
+ * Q_SETQUOTA - assign an entire dqblk structure.
+ */
+int
+ext2_setquota(struct mount *mp, u_long id, int type, caddr_t addr)
+{
+	struct ext2_dquot *dq;
+	struct ext2_dquot *ndq;
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	struct ext2_dqblk newlim;
+	int error;
+
+	error = copyin(addr, (caddr_t)&newlim, sizeof (struct ext2_dqblk));
+	if (error)
+		return (error);
+	error = ext2_dqget(NULLVP, id, ump, type, &ndq);
+	if (error)
+		return (error);
+	dq = ndq;
+	while (dq->dq_flags & DQ_LOCK) {
+		dq->dq_flags |= DQ_WANT;
+		(void) tsleep((caddr_t)dq, 0, "setqta", 0);
+	}
+	/*
+	 * Copy all but the current values.
+	 * Reset time limit if previously had no soft limit or were
+	 * under it, but now have a soft limit and are over it.
+	 */
+	newlim.dqb_curblocks = dq->dq_curblocks;
+	newlim.dqb_curinodes = dq->dq_curinodes;
+	if (dq->dq_id != 0) {
+		newlim.dqb_btime = dq->dq_btime;
+		newlim.dqb_itime = dq->dq_itime;
+	}
+	if (newlim.dqb_bsoftlimit &&
+	    dq->dq_curblocks >= newlim.dqb_bsoftlimit &&
+	    (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit))
+		newlim.dqb_btime = time_second + ump->um_btime[type];
+	if (newlim.dqb_isoftlimit &&
+	    dq->dq_curinodes >= newlim.dqb_isoftlimit &&
+	    (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit))
+		newlim.dqb_itime = time_second + ump->um_itime[type];
+	dq->dq_dqb = newlim;
+	if (dq->dq_curblocks < dq->dq_bsoftlimit)
+		dq->dq_flags &= ~DQ_BLKS;
+	if (dq->dq_curinodes < dq->dq_isoftlimit)
+		dq->dq_flags &= ~DQ_INODS;
+	if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
+	    dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
+		dq->dq_flags |= DQ_FAKE;
+	else
+		dq->dq_flags &= ~DQ_FAKE;
+	dq->dq_flags |= DQ_MOD;
+	ext2_dqrele(NULLVP, dq);
+	return (0);
+}
+
+/*
+ * Q_SETUSE - set current inode and block usage.
+ */
+int
+ext2_setuse(struct mount *mp, u_long id, int type, caddr_t addr)
+{
+	struct ext2_dquot *dq;
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	struct ext2_dquot *ndq;
+	struct ext2_dqblk usage;
+	int error;
+
+	error = copyin(addr, (caddr_t)&usage, sizeof (struct ext2_dqblk));
+	if (error)
+		return (error);
+	error = ext2_dqget(NULLVP, id, ump, type, &ndq);
+	if (error)
+		return (error);
+	dq = ndq;
+	while (dq->dq_flags & DQ_LOCK) {
+		dq->dq_flags |= DQ_WANT;
+		(void) tsleep((caddr_t)dq, 0, "setuse", 0);
+	}
+	/*
+	 * Reset time limit if have a soft limit and were
+	 * previously under it, but are now over it.
+	 */
+	if (dq->dq_bsoftlimit && dq->dq_curblocks < dq->dq_bsoftlimit &&
+	    usage.dqb_curblocks >= dq->dq_bsoftlimit)
+		dq->dq_btime = time_second + ump->um_btime[type];
+	if (dq->dq_isoftlimit && dq->dq_curinodes < dq->dq_isoftlimit &&
+	    usage.dqb_curinodes >= dq->dq_isoftlimit)
+		dq->dq_itime = time_second + ump->um_itime[type];
+	dq->dq_curblocks = usage.dqb_curblocks;
+	dq->dq_curinodes = usage.dqb_curinodes;
+	if (dq->dq_curblocks < dq->dq_bsoftlimit)
+		dq->dq_flags &= ~DQ_BLKS;
+	if (dq->dq_curinodes < dq->dq_isoftlimit)
+		dq->dq_flags &= ~DQ_INODS;
+	dq->dq_flags |= DQ_MOD;
+	ext2_dqrele(NULLVP, dq);
+	return (0);
+}
+
+/*
+ * Q_SYNC - sync quota files to disk.
+ */
+
+static int ext2_qsync_scan(struct mount *mp, struct vnode *vp, void *data);
+
+int
+ext2_qsync(struct mount *mp)
+{
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	struct scaninfo scaninfo;
+	int i;
+
+	/*
+	 * Check if the mount point has any quotas.
+	 * If not, simply return.
+	 */
+	for (i = 0; i < MAXQUOTAS; i++)
+		if (ump->um_quotas[i] != NULLVP)
+			break;
+	if (i == MAXQUOTAS)
+		return (0);
+	/*
+	 * Search vnodes associated with this mount point,
+	 * synchronizing any modified ext2_dquot structures.
+	 */
+	scaninfo.rescan = 1;
+	while (scaninfo.rescan) {
+		scaninfo.rescan = 0;
+		vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT,
+				NULL, ext2_qsync_scan, &scaninfo);
+	}
+	return (0);
+}
+
+static int
+ext2_qsync_scan(struct mount *mp, struct vnode *vp, void *data)
+{
+	/*struct scaninfo *info = data;*/
+	struct ext2_dquot *dq;
+	/* int error;*/
+	int i;
+
+	for (i = 0; i < MAXQUOTAS; i++) {
+		dq = VTOI(vp)->i_dquot[i];
+		if (dq != NODQUOT && (dq->dq_flags & DQ_MOD))
+			ext2_dqsync(vp, dq);
+	}
+	return(0);
+}
+
+/*
+ * Code pertaining to management of the in-core dquot data structures.
+ */
+#define DQHASH(dqvp, id) \
+	(&ext2_dqhashtbl[((((intptr_t)(dqvp)) >> 8) + id) & ext2_dqhash])
+static LIST_HEAD(ext2_dqhash, ext2_dquot) *ext2_dqhashtbl;
+static u_long ext2_dqhash;
+
+/*
+ * Dquot free list.
+ */
+#define	DQUOTINC	5	/* minimum free dquots desired */
+static TAILQ_HEAD(ext2_dqfreelist, ext2_dquot) ext2_dqfreelist;
+static long ext2_numdquot, ext2_desireddquot = DQUOTINC;
+
+/*
+ * Initialize the quota system.
+ */
+void
+ext2_dqinit(void)
+{
+	ext2_dqhashtbl = hashinit(desiredvnodes, M_EXT2DQUOT, &ext2_dqhash);
+	TAILQ_INIT(&ext2_dqfreelist);
+}
+
+/*
+ * Obtain a dquot structure for the specified identifier and quota file
+ * reading the information from the file if necessary.
+ */
+static int
+ext2_dqget(struct vnode *vp, u_long id, struct ext2mount *ump, int type,
+      struct ext2_dquot **dqp)
+{
+	struct ext2_dquot *dq;
+	struct ext2_dqhash *dqh;
+	struct vnode *dqvp;
+	struct iovec aiov;
+	struct uio auio;
+	int error;
+
+	dqvp = ump->um_quotas[type];
+	if (dqvp == NULLVP || (ump->um_qflags[type] & QTF_CLOSING)) {
+		*dqp = NODQUOT;
+		return (EINVAL);
+	}
+	/*
+	 * Check the cache first.
+	 */
+	dqh = DQHASH(dqvp, id);
+	for (dq = dqh->lh_first; dq; dq = dq->dq_hash.le_next) {
+		if (dq->dq_id != id ||
+		    dq->dq_ump->um_quotas[dq->dq_type] != dqvp)
+			continue;
+		/*
+		 * Cache hit with no references.  Take
+		 * the structure off the free list.
+		 */
+		if (dq->dq_cnt == 0)
+			TAILQ_REMOVE(&ext2_dqfreelist, dq, dq_freelist);
+		DQREF(dq);
+		*dqp = dq;
+		return (0);
+	}
+	/*
+	 * Not in cache, allocate a new one.
+	 */
+	if (TAILQ_EMPTY(&ext2_dqfreelist) && ext2_numdquot < MAXQUOTAS * desiredvnodes)
+		ext2_desireddquot += DQUOTINC;
+	if (ext2_numdquot < ext2_desireddquot) {
+		dq = (struct ext2_dquot *)kmalloc(sizeof *dq, M_EXT2DQUOT, M_WAITOK | M_ZERO);
+		ext2_numdquot++;
+	} else {
+		if ((dq = TAILQ_FIRST(&ext2_dqfreelist)) == NULL) {
+			tablefull("dquot");
+			*dqp = NODQUOT;
+			return (EUSERS);
+		}
+		if (dq->dq_cnt || (dq->dq_flags & DQ_MOD))
+			panic("dqget: free dquot isn't");
+		TAILQ_REMOVE(&ext2_dqfreelist, dq, dq_freelist);
+		if (dq->dq_ump != NULL)
+			LIST_REMOVE(dq, dq_hash);
+	}
+	/*
+	 * Initialize the contents of the dquot structure.
+	 */
+	if (vp != dqvp)
+		vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY);
+	LIST_INSERT_HEAD(dqh, dq, dq_hash);
+	DQREF(dq);
+	dq->dq_flags = DQ_LOCK;
+	dq->dq_id = id;
+	dq->dq_ump = ump;
+	dq->dq_type = type;
+	auio.uio_iov = &aiov;
+	auio.uio_iovcnt = 1;
+	aiov.iov_base = (caddr_t)&dq->dq_dqb;
+	aiov.iov_len = sizeof (struct ext2_dqblk);
+	auio.uio_resid = sizeof (struct ext2_dqblk);
+	auio.uio_offset = (off_t)(id * sizeof (struct ext2_dqblk));
+	auio.uio_segflg = UIO_SYSSPACE;
+	auio.uio_rw = UIO_READ;
+	auio.uio_td = NULL;
+	error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]);
+	if (auio.uio_resid == sizeof(struct ext2_dqblk) && error == 0)
+		bzero((caddr_t)&dq->dq_dqb, sizeof(struct ext2_dqblk));
+	if (vp != dqvp)
+		vn_unlock(dqvp);
+	if (dq->dq_flags & DQ_WANT)
+		wakeup((caddr_t)dq);
+	dq->dq_flags = 0;
+	/*
+	 * I/O error in reading quota file, release
+	 * quota structure and reflect problem to caller.
+	 */
+	if (error) {
+		LIST_REMOVE(dq, dq_hash);
+		ext2_dqrele(vp, dq);
+		*dqp = NODQUOT;
+		return (error);
+	}
+	/*
+	 * Check for no limit to enforce.
+	 * Initialize time values if necessary.
+	 */
+	if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
+	    dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
+		dq->dq_flags |= DQ_FAKE;
+	if (dq->dq_id != 0) {
+		if (dq->dq_btime == 0)
+			dq->dq_btime = time_second + ump->um_btime[type];
+		if (dq->dq_itime == 0)
+			dq->dq_itime = time_second + ump->um_itime[type];
+	}
+	*dqp = dq;
+	return (0);
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * Obtain a reference to a dquot.
+ */
+static void
+ext2_dqref(struct ext2_dquot *dq)
+{
+	dq->dq_cnt++;
+}
+#endif
+
+/*
+ * Release a reference to a dquot.
+ */
+void
+ext2_dqrele(struct vnode *vp, struct ext2_dquot *dq)
+{
+	if (dq == NODQUOT)
+		return;
+	if (dq->dq_cnt > 1) {
+		dq->dq_cnt--;
+		return;
+	}
+	if (dq->dq_flags & DQ_MOD)
+		(void)ext2_dqsync(vp, dq);
+	if (--dq->dq_cnt > 0)
+		return;
+	TAILQ_INSERT_TAIL(&ext2_dqfreelist, dq, dq_freelist);
+}
+
+/*
+ * Update the disk quota in the quota file.
+ */
+static int
+ext2_dqsync(struct vnode *vp, struct ext2_dquot *dq)
+{
+	struct vnode *dqvp;
+	struct iovec aiov;
+	struct uio auio;
+	int error;
+
+	if (dq == NODQUOT)
+		panic("dqsync: dquot");
+	if ((dq->dq_flags & DQ_MOD) == 0)
+		return (0);
+	if ((dqvp = dq->dq_ump->um_quotas[dq->dq_type]) == NULLVP)
+		panic("dqsync: file");
+	if (vp != dqvp)
+		vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY);
+	while (dq->dq_flags & DQ_LOCK) {
+		dq->dq_flags |= DQ_WANT;
+		(void) tsleep((caddr_t)dq, 0, "dqsync", 0);
+		if ((dq->dq_flags & DQ_MOD) == 0) {
+			if (vp != dqvp)
+				vn_unlock(dqvp);
+			return (0);
+		}
+	}
+	dq->dq_flags |= DQ_LOCK;
+	auio.uio_iov = &aiov;
+	auio.uio_iovcnt = 1;
+	aiov.iov_base = (caddr_t)&dq->dq_dqb;
+	aiov.iov_len = sizeof (struct ext2_dqblk);
+	auio.uio_resid = sizeof (struct ext2_dqblk);
+	auio.uio_offset = (off_t)(dq->dq_id * sizeof (struct ext2_dqblk));
+	auio.uio_segflg = UIO_SYSSPACE;
+	auio.uio_rw = UIO_WRITE;
+	auio.uio_td = NULL;
+	error = VOP_WRITE(dqvp, &auio, 0, dq->dq_ump->um_cred[dq->dq_type]);
+	if (auio.uio_resid && error == 0)
+		error = EIO;
+	if (dq->dq_flags & DQ_WANT)
+		wakeup((caddr_t)dq);
+	dq->dq_flags &= ~(DQ_MOD|DQ_LOCK|DQ_WANT);
+	if (vp != dqvp)
+		vn_unlock(dqvp);
+	return (error);
+}
+
+/*
+ * Flush all entries from the cache for a particular vnode.
+ */
+static void
+ext2_dqflush(struct vnode *vp)
+{
+	struct ext2_dquot *dq, *nextdq;
+	struct ext2_dqhash *dqh;
+
+	/*
+	 * Move all dquot's that used to refer to this quota
+	 * file off their hash chains (they will eventually
+	 * fall off the head of the free list and be re-used).
+	 */
+	for (dqh = &ext2_dqhashtbl[ext2_dqhash]; dqh >= ext2_dqhashtbl; dqh--) {
+		for (dq = dqh->lh_first; dq; dq = nextdq) {
+			nextdq = dq->dq_hash.le_next;
+			if (dq->dq_ump->um_quotas[dq->dq_type] != vp)
+				continue;
+			if (dq->dq_cnt)
+				panic("dqflush: stray dquot");
+			LIST_REMOVE(dq, dq_hash);
+			dq->dq_ump = NULL;
+		}
+	}
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_readwrite.c b/sys/gnu/vfs/ext2fs/ext2_readwrite.c
new file mode 100644
index 0000000..eab450b
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_readwrite.c
@@ -0,0 +1,298 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ufs_readwrite.c	8.7 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_readwrite.c,v 1.18.2.2 2000/12/22 18:44:33 dillon Exp $
+ */
+
+#define	BLKSIZE(a, b, c)	blksize(a, b, c)
+#define	FS			struct ext2_sb_info
+#define	I_FS			i_e2fs
+
+/*
+ * Vnode op for reading.
+ *
+ * ext2_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
+ *	     struct ucred *a_cred)
+ */
+/* ARGSUSED */
+static int
+ext2_read(struct vop_read_args *ap)
+{
+	struct vnode *vp;
+	struct inode *ip;
+	struct uio *uio;
+	FS *fs;
+	struct buf *bp;
+	daddr_t lbn, nextlbn;
+	off_t nextloffset;
+	off_t bytesinfile;
+	long size, xfersize, blkoffset;
+	int error, orig_resid;
+	int seqcount = ap->a_ioflag >> 16;
+
+	vp = ap->a_vp;
+	ip = VTOI(vp);
+	uio = ap->a_uio;
+
+#ifdef DIAGNOSTIC
+	if (uio->uio_rw != UIO_READ)
+		panic("ext2_read: mode");
+
+	if (vp->v_type == VLNK) {
+		if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen)
+			panic("ext2_read: short symlink");
+	} else if (vp->v_type != VREG && vp->v_type != VDIR)
+		panic("ext2_read: type %d", vp->v_type);
+#endif
+	fs = ip->I_FS;
+#if 0
+	if ((u_quad_t)uio->uio_offset > fs->fs_maxfilesize)
+		return (EFBIG);
+#endif
+
+	orig_resid = uio->uio_resid;
+	for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
+		if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
+			break;
+		lbn = lblkno(fs, uio->uio_offset);
+		nextlbn = lbn + 1;
+		nextloffset = lblktodoff(fs, nextlbn);
+		size = BLKSIZE(fs, ip, lbn);
+		blkoffset = blkoff(fs, uio->uio_offset);
+
+		xfersize = fs->s_frag_size - blkoffset;
+		if (uio->uio_resid < xfersize)
+			xfersize = uio->uio_resid;
+		if (bytesinfile < xfersize)
+			xfersize = bytesinfile;
+
+		if (nextloffset >= ip->i_size) {
+			error = bread(vp, lblktodoff(fs, lbn), size, &bp);
+		} else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
+			error = cluster_read(vp, (off_t)ip->i_size,
+					     lblktodoff(fs, lbn), size,
+					     uio->uio_resid,
+					     (ap->a_ioflag >> 16) * BKVASIZE,
+					     &bp);
+		} else if (seqcount > 1) {
+			int nextsize = BLKSIZE(fs, ip, nextlbn);
+			error = breadn(vp, lblktodoff(fs, lbn),
+					size, &nextloffset, &nextsize, 1, &bp);
+		} else {
+			error = bread(vp, lblktodoff(fs, lbn), size, &bp);
+		}
+		if (error) {
+			brelse(bp);
+			bp = NULL;
+			break;
+		}
+
+		/*
+		 * We should only get non-zero b_resid when an I/O error
+		 * has occurred, which should cause us to break above.
+		 * However, if the short read did not cause an error,
+		 * then we want to ensure that we do not uiomove bad
+		 * or uninitialized data.
+		 */
+		size -= bp->b_resid;
+		if (size < xfersize) {
+			if (size == 0)
+				break;
+			xfersize = size;
+		}
+		error = uiomove((char *)bp->b_data + blkoffset,
+				(int)xfersize, uio);
+		if (error)
+			break;
+
+		bqrelse(bp);
+	}
+	if (bp != NULL)
+		bqrelse(bp);
+	if (orig_resid > 0 && (error == 0 || uio->uio_resid != orig_resid) &&
+	    (vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
+		ip->i_flag |= IN_ACCESS;
+	return (error);
+}
+
+/*
+ * Vnode op for writing.
+ *
+ * ext2_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
+ *	      struct ucred *a_cred)
+ */
+static int
+ext2_write(struct vop_write_args *ap)
+{
+	struct vnode *vp;
+	struct uio *uio;
+	struct inode *ip;
+	FS *fs;
+	struct buf *bp;
+	struct thread *td;
+	daddr_t lbn;
+	off_t osize;
+	int seqcount;
+	int blkoffset, error, flags, ioflag, resid, size, xfersize;
+
+	ioflag = ap->a_ioflag;
+	seqcount = ap->a_ioflag >> 16;
+	uio = ap->a_uio;
+	vp = ap->a_vp;
+	ip = VTOI(vp);
+
+#ifdef DIAGNOSTIC
+	if (uio->uio_rw != UIO_WRITE)
+		panic("ext2_write: mode");
+#endif
+
+	switch (vp->v_type) {
+	case VREG:
+		if (ioflag & IO_APPEND)
+			uio->uio_offset = ip->i_size;
+		if ((ip->i_flags & APPEND) && uio->uio_offset != ip->i_size)
+			return (EPERM);
+		/* FALLTHROUGH */
+	case VLNK:
+		break;
+	case VDIR:
+		if ((ioflag & IO_SYNC) == 0)
+			panic("ext2_write: nonsync dir write");
+		break;
+	default:
+		panic("ext2_write: type");
+	}
+
+	fs = ip->I_FS;
+#if 0
+	if (uio->uio_offset < 0 ||
+	    (u_quad_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize)
+		return (EFBIG);
+#endif
+	/*
+	 * Maybe this should be above the vnode op call, but so long as
+	 * file servers have no limits, I don't think it matters.
+	 */
+	td = uio->uio_td;
+	if (vp->v_type == VREG && td && td->td_proc &&
+	    uio->uio_offset + uio->uio_resid >
+	    td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
+		lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ);
+		return (EFBIG);
+	}
+
+	resid = uio->uio_resid;
+	osize = ip->i_size;
+	flags = ioflag & IO_SYNC ? B_SYNC : 0;
+
+	for (error = 0; uio->uio_resid > 0;) {
+		lbn = lblkno(fs, uio->uio_offset);
+		blkoffset = blkoff(fs, uio->uio_offset);
+		xfersize = fs->s_frag_size - blkoffset;
+		if (uio->uio_resid < xfersize)
+			xfersize = uio->uio_resid;
+
+		if (uio->uio_offset + xfersize > ip->i_size)
+			vnode_pager_setsize(vp, uio->uio_offset + xfersize);
+
+		/*
+		 * Avoid a data-consistency race between write() and mmap()
+		 * by ensuring that newly allocated blocks are zerod.  The
+		 * race can occur even in the case where the write covers
+		 * the entire block.
+		 *
+		 * Just set B_CLRBUF unconditionally, even if the write
+		 * covers the whole block.  This also handles the UIO_NOCOPY
+		 * case.  See ffs_write() in ufs for a more sophisticated
+		 * version.
+		 */
+		flags |= B_CLRBUF;
+		error = ext2_balloc(ip, lbn, blkoffset + xfersize,
+				    ap->a_cred, &bp, flags);
+		if (error)
+			break;
+
+		if (uio->uio_offset + xfersize > ip->i_size) {
+			ip->i_size = uio->uio_offset + xfersize;
+		}
+
+		size = BLKSIZE(fs, ip, lbn) - bp->b_resid;
+		if (size < xfersize)
+			xfersize = size;
+
+		error = uiomove((char *)bp->b_data + blkoffset,
+				(int)xfersize, uio);
+		if ((ioflag & IO_VMIO) &&
+		    LIST_FIRST(&bp->b_dep) == NULL) /* in ext2fs? */
+			bp->b_flags |= B_RELBUF;
+
+		if (ioflag & IO_SYNC) {
+			bwrite(bp);
+		} else if (xfersize + blkoffset == fs->s_frag_size) {
+			if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
+				bp->b_flags |= B_CLUSTEROK;
+				cluster_write(bp, (off_t)ip->i_size, vp->v_mount->mnt_stat.f_iosize, seqcount);
+			} else {
+				bawrite(bp);
+			}
+		} else {
+			bp->b_flags |= B_CLUSTEROK;
+			bdwrite(bp);
+		}
+		if (error || xfersize == 0)
+			break;
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	}
+	/*
+	 * If we successfully wrote any data, and we are not the superuser
+	 * we clear the setuid and setgid bits as a precaution against
+	 * tampering.
+	 */
+	if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)
+		ip->i_mode &= ~(ISUID | ISGID);
+	if (error) {
+		if (ioflag & IO_UNIT) {
+			EXT2_TRUNCATE(vp, osize, ioflag & IO_SYNC, ap->a_cred);
+			uio->uio_offset -= resid - uio->uio_resid;
+			uio->uio_resid = resid;
+		}
+	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC))
+		error = EXT2_UPDATE(vp, 1);
+	return (error);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_subr.c b/sys/gnu/vfs/ext2fs/ext2_subr.c
new file mode 100644
index 0000000..7729fe4
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_subr.c
@@ -0,0 +1,87 @@
+/*
+ *  modified for Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ext2_subr.c	8.2 (Berkeley) 9/21/93
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_subr.c,v 1.13.2.2 2000/08/03 18:48:27 peter Exp $
+ */
+
+#include <sys/param.h>
+
+#include <sys/lock.h>
+#include <sys/systm.h>
+#include <sys/ucred.h>
+#include <sys/vnode.h>
+#include <sys/buf.h>
+
+#include "quota.h"
+#include "inode.h"
+#include "ext2_extern.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+
+#include "opt_ddb.h"
+
+/*
+ * Return buffer with the contents of block "offset" from the beginning of
+ * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
+ * remaining space in the directory.
+ */
+int
+ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
+{
+	struct inode *ip;
+	struct ext2_sb_info *fs;
+	struct buf *bp;
+	daddr_t lbn;
+	int bsize, error;
+
+	ip = VTOI(vp);
+	fs = ip->i_e2fs;
+	lbn = lblkno(fs, offset);
+	bsize = blksize(fs, ip, lbn);
+
+	*bpp = NULL;
+	if ((error = bread(vp, lblktodoff(fs, lbn), bsize, &bp)) != 0) {
+		brelse(bp);
+		return (error);
+	}
+	if (res)
+		*res = (char *)bp->b_data + blkoff(fs, offset);
+	*bpp = bp;
+	return (0);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_vfsops.c b/sys/gnu/vfs/ext2fs/ext2_vfsops.c
new file mode 100644
index 0000000..44b95e8
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_vfsops.c
@@ -0,0 +1,1354 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1989, 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ffs_vfsops.c	8.8 (Berkeley) 4/18/94
+ *	$FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $
+ */
+
+#include "opt_quota.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/nlookup.h>
+#include <sys/proc.h>
+#include <sys/priv.h>
+#include <sys/kernel.h>
+#include <sys/vnode.h>
+#include <sys/mount.h>
+#include <sys/buf.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/diskslice.h>
+#include <sys/malloc.h>
+#include <sys/stat.h>
+#include <vm/vm_zone.h>
+
+#include <sys/buf2.h>
+#include <sys/thread2.h>
+
+#include "quota.h"
+#include "dinode.h"
+#include "inode.h"
+#include "ext2mount.h"
+#include "ext2_extern.h"
+
+#include "fs.h"
+#include "ext2_fs.h"
+#include "ext2_fs_sb.h"
+
+extern struct vop_ops ext2_vnode_vops;
+extern struct vop_ops ext2_spec_vops;
+extern struct vop_ops ext2_fifo_vops;
+
+static int ext2_fhtovp (struct mount *, struct vnode *,
+				struct fid *, struct vnode **);
+static int ext2_flushfiles (struct mount *mp, int flags);
+static int ext2_mount (struct mount *, char *, caddr_t, struct ucred *);
+static int ext2_mountfs (struct vnode *, struct mount *, struct ucred *);
+static int ext2_root(struct mount *, struct vnode **);
+static int ext2_reload (struct mount *mountp, struct ucred *cred);
+static int ext2_sbupdate (struct ext2mount *, int);
+static int ext2_statfs (struct mount *, struct statfs *, struct ucred *);
+static int ext2_sync (struct mount *, int);
+static int ext2_unmount (struct mount *, int);
+static int ext2_vget (struct mount *, struct vnode *, ino_t, struct vnode **);
+static int ext2_init(struct vfsconf *);
+static int ext2_vptofh (struct vnode *, struct fid *);
+
+static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
+MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
+
+static struct vfsops ext2fs_vfsops = {
+	.vfs_mount =    	ext2_mount,
+	.vfs_unmount =   	ext2_unmount,
+	.vfs_root =     	ext2_root,	/* root inode via vget */
+	.vfs_quotactl =   	ext2_quotactl,	/* quota operations */
+	.vfs_statfs =     	ext2_statfs,
+	.vfs_sync =     	ext2_sync,
+	.vfs_vget =      	ext2_vget,
+	.vfs_fhtovp =     	ext2_fhtovp,
+	.vfs_checkexp =    	ext2_check_export,
+	.vfs_vptofh =     	ext2_vptofh,
+	.vfs_init =     	ext2_init,
+	.vfs_uninit =    	ext2_uninit
+};
+
+VFS_SET(ext2fs_vfsops, ext2fs, 0);
+#define bsd_malloc kmalloc
+#define bsd_free kfree
+
+static int ext2fs_inode_hash_lock;
+
+static int	ext2_check_sb_compat (struct ext2_super_block *es,
+					  cdev_t dev, int ronly);
+static int	compute_sb_data (struct vnode * devvp,
+				     struct ext2_super_block * es,
+				     struct ext2_sb_info * fs);
+
+static int
+ext2_root(struct mount *mp, struct vnode **vpp)
+{
+	struct vnode *nvp;
+	int error;
+
+	error = VFS_VGET(mp, NULL, (ino_t)ROOTINO, &nvp);
+	if (error)
+		return (error);
+	*vpp = nvp;
+	return (0);
+}
+
+/*
+ * Do operations associated with quotas
+ */
+int
+ext2_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
+	     struct ucred *cred)
+{
+#ifndef QUOTA
+	return (EOPNOTSUPP);
+#else
+	int cmd, type, error;
+
+	type = cmds & SUBCMDMASK;
+	cmd = cmds >> SUBCMDSHIFT;
+
+	if (uid == -1) {
+		switch(type) {
+			case USRQUOTA:
+				uid = cred->cr_ruid;
+				break;
+			case GRPQUOTA:
+				uid = cred->cr_rgid;
+				break;
+			default:
+				return (EINVAL);
+		}
+	}
+
+	/*
+	 * Check permissions.
+	 */
+	switch (cmd) {
+
+	case Q_QUOTAON:
+		error = priv_check_cred(cred, PRIV_UFS_QUOTAON, 0);
+		break;
+
+	case Q_QUOTAOFF:
+		error = priv_check_cred(cred, PRIV_UFS_QUOTAOFF, 0);
+		break;
+
+	case Q_SETQUOTA:
+		error = priv_check_cred(cred, PRIV_VFS_SETQUOTA, 0);
+		break;
+
+	case Q_SETUSE:
+		error = priv_check_cred(cred, PRIV_UFS_SETUSE, 0);
+		break;
+
+	case Q_GETQUOTA:
+		if (uid == cred->cr_ruid)
+			error = 0;
+		else
+			error = priv_check_cred(cred, PRIV_VFS_GETQUOTA, 0);
+		break;
+
+	case Q_SYNC:
+		error = 0;
+		break;
+
+	default:
+		error = EINVAL;
+		break;
+	}
+
+	if (error)
+		return (error);
+
+
+	if ((uint)type >= MAXQUOTAS)
+		return (EINVAL);
+	if (vfs_busy(mp, LK_NOWAIT))
+		return (0);
+
+	switch (cmd) {
+
+	case Q_QUOTAON:
+		error = ext2_quotaon(cred, mp, type, arg);
+		break;
+
+	case Q_QUOTAOFF:
+		error = ext2_quotaoff(mp, type);
+		break;
+
+	case Q_SETQUOTA:
+		error = ext2_setquota(mp, uid, type, arg);
+		break;
+
+	case Q_SETUSE:
+		error = ext2_setuse(mp, uid, type, arg);
+		break;
+
+	case Q_GETQUOTA:
+		error = ext2_getquota(mp, uid, type, arg);
+		break;
+
+	case Q_SYNC:
+		error = ext2_qsync(mp);
+		break;
+
+	default:
+		error = EINVAL;
+		break;
+	}
+	vfs_unbusy(mp);
+	return (error);
+#endif
+}
+
+/*
+ * Initial UFS filesystems, done only once.
+ */
+int
+ext2_init(struct vfsconf *vfsp)
+{
+	static int done;
+
+	if (done)
+		return (0);
+	done = 1;
+	ext2_ihashinit();
+#ifdef QUOTA
+	ext2_dqinit();
+#endif
+	return (0);
+}
+
+/*
+ * VFS Operations.
+ *
+ * mount system call
+ *
+ * Parameters:
+ *	data:	this is actually a (struct ext2_args *)
+ */
+static int
+ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
+{
+	struct vnode *devvp;
+	struct ext2_args args;
+	struct ext2mount *ump = 0;
+	struct ext2_sb_info *fs;
+	size_t size;
+	int error, flags;
+	mode_t accessmode;
+	struct nlookupdata nd;
+
+	if ((error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args))) != 0)
+		return (error);
+
+	/*
+	 * If updating, check whether changing from read-only to
+	 * read/write; if there is no device name, that's all we do.
+	 */
+	if (mp->mnt_flag & MNT_UPDATE) {
+		ump = VFSTOEXT2(mp);
+		fs = ump->um_e2fs;
+		devvp = ump->um_devvp;
+		error = 0;
+		if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
+			flags = WRITECLOSE;
+			if (mp->mnt_flag & MNT_FORCE)
+				flags |= FORCECLOSE;
+			if (vfs_busy(mp, LK_NOWAIT))
+				return (EBUSY);
+			error = ext2_flushfiles(mp, flags);
+			vfs_unbusy(mp);
+			if (!error && fs->s_wasvalid) {
+				fs->s_es->s_state |= EXT2_VALID_FS;
+				ext2_sbupdate(ump, MNT_WAIT);
+			}
+			fs->s_rd_only = 1;
+			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+			VOP_OPEN(devvp, FREAD, FSCRED, NULL);
+			VOP_CLOSE(devvp, FREAD|FWRITE);
+			vn_unlock(devvp);
+		}
+		if (!error && (mp->mnt_flag & MNT_RELOAD))
+			error = ext2_reload(mp, cred);
+		if (error)
+			return (error);
+		if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev,
+		    (mp->mnt_kern_flag & MNTK_WANTRDWR) == 0) != 0)
+			return (EPERM);
+		if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
+			/*
+			 * If upgrade to read-write by non-root, then verify
+			 * that user has necessary permissions on the device.
+			 */
+			if (cred->cr_uid != 0) {
+				vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+				error = VOP_EACCESS(devvp, VREAD | VWRITE, cred);
+				if (error) {
+					vn_unlock(devvp);
+					return (error);
+				}
+				vn_unlock(devvp);
+			}
+
+			if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
+			    (fs->s_es->s_state & EXT2_ERROR_FS)) {
+				if (mp->mnt_flag & MNT_FORCE) {
+					kprintf(
+"WARNING: %s was not properly dismounted\n",
+					    fs->fs_fsmnt);
+				} else {
+					kprintf(
+"WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
+					    fs->fs_fsmnt);
+					return (EPERM);
+				}
+			}
+			fs->s_es->s_state &= ~EXT2_VALID_FS;
+			ext2_sbupdate(ump, MNT_WAIT);
+			fs->s_rd_only = 0;
+			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+			VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL);
+			VOP_CLOSE(devvp, FREAD);
+			vn_unlock(devvp);
+		}
+		if (args.fspec == 0) {
+			/*
+			 * Process export requests.
+			 */
+			return (vfs_export(mp, &ump->um_export, &args.export));
+		}
+	}
+	/*
+	 * Not an update, or updating the name: look up the name
+	 * and verify that it refers to a sensible block device.
+	 */
+	devvp = NULL;
+	error = nlookup_init(&nd, args.fspec, UIO_USERSPACE, NLC_FOLLOW);
+	if (error == 0)
+		error = nlookup(&nd);
+	if (error == 0)
+		error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp);
+	nlookup_done(&nd);
+	if (error)
+		return (error);
+
+	if (!vn_isdisk(devvp, &error)) {
+		vrele(devvp);
+		return (error);
+	}
+
+	/*
+	 * If mount by non-root, then verify that user has necessary
+	 * permissions on the device.
+	 */
+	if (cred->cr_uid != 0) {
+		accessmode = VREAD;
+		if ((mp->mnt_flag & MNT_RDONLY) == 0)
+			accessmode |= VWRITE;
+		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+		if ((error = VOP_EACCESS(devvp, accessmode, cred)) != 0) {
+			vput(devvp);
+			return (error);
+		}
+		vn_unlock(devvp);
+	}
+
+	if ((mp->mnt_flag & MNT_UPDATE) == 0) {
+		error = ext2_mountfs(devvp, mp, cred);
+	} else {
+		if (devvp != ump->um_devvp)
+			error = EINVAL;	/* needs translation */
+		else
+			vrele(devvp);
+	}
+	if (error) {
+		vrele(devvp);
+		return (error);
+	}
+	ump = VFSTOEXT2(mp);
+	fs = ump->um_e2fs;
+	copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
+	bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
+	copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
+	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+	ext2_statfs(mp, &mp->mnt_stat, cred);
+	return (0);
+}
+
+/*
+ * checks that the data in the descriptor blocks make sense
+ * this is taken from ext2/super.c
+ */
+static int
+ext2_check_descriptors(struct ext2_sb_info *sb)
+{
+        int i;
+        int desc_block = 0;
+        unsigned long block = sb->s_es->s_first_data_block;
+        struct ext2_group_desc * gdp = NULL;
+
+        /* ext2_debug ("Checking group descriptors"); */
+
+        for (i = 0; i < sb->s_groups_count; i++)
+        {
+		/* examine next descriptor block */
+                if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
+                        gdp = (struct ext2_group_desc *)
+				sb->s_group_desc[desc_block++]->b_data;
+                if (gdp->bg_block_bitmap < block ||
+                    gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
+                {
+                        kprintf ("ext2_check_descriptors: "
+                                    "Block bitmap for group %d"
+                                    " not in group (block %lu)!\n",
+                                    i, (unsigned long) gdp->bg_block_bitmap);
+                        return 0;
+                }
+                if (gdp->bg_inode_bitmap < block ||
+                    gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
+                {
+                        kprintf ("ext2_check_descriptors: "
+                                    "Inode bitmap for group %d"
+                                    " not in group (block %lu)!\n",
+                                    i, (unsigned long) gdp->bg_inode_bitmap);
+                        return 0;
+                }
+                if (gdp->bg_inode_table < block ||
+                    gdp->bg_inode_table + sb->s_itb_per_group >=
+                    block + EXT2_BLOCKS_PER_GROUP(sb))
+                {
+                        kprintf ("ext2_check_descriptors: "
+                                    "Inode table for group %d"
+                                    " not in group (block %lu)!\n",
+                                    i, (unsigned long) gdp->bg_inode_table);
+                        return 0;
+                }
+                block += EXT2_BLOCKS_PER_GROUP(sb);
+                gdp++;
+        }
+        return 1;
+}
+
+static int
+ext2_check_sb_compat(struct ext2_super_block *es, cdev_t dev, int ronly)
+{
+	if (es->s_magic != EXT2_SUPER_MAGIC) {
+		kprintf("ext2fs: %s: wrong magic number %#x (expected %#x)\n",
+		    devtoname(dev), es->s_magic, EXT2_SUPER_MAGIC);
+		return (1);
+	}
+	if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
+		if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
+			kprintf(
+"WARNING: mount of %s denied due to unsupported optional features\n",
+			    devtoname(dev));
+			return (1);
+		}
+		if (!ronly &&
+		    (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
+			kprintf(
+"WARNING: R/W mount of %s denied due to unsupported optional features\n",
+			    devtoname(dev));
+			return (1);
+		}
+	}
+	return (0);
+}
+
+/*
+ * this computes the fields of the  ext2_sb_info structure from the
+ * data in the ext2_super_block structure read in
+ */
+static int
+compute_sb_data(struct vnode *devvp, struct ext2_super_block *es,
+		struct ext2_sb_info *fs)
+{
+    int db_count, error;
+    int i, j;
+    int logic_sb_block = 1;	/* XXX for now */
+
+#if 1
+#define V(v)
+#else
+#define V(v)  kprintf(#v"= %d\n", fs->v);
+#endif
+
+    fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
+    V(s_blocksize)
+    fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
+    V(s_bshift)
+    fs->s_fsbtodb = es->s_log_block_size + 1;
+    V(s_fsbtodb)
+    fs->s_qbmask = fs->s_blocksize - 1;
+    V(s_bmask)
+    fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es);
+    V(s_blocksize_bits)
+    fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
+    V(s_frag_size)
+    if (fs->s_frag_size)
+	fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size;
+    V(s_frags_per_block)
+    fs->s_blocks_per_group = es->s_blocks_per_group;
+    V(s_blocks_per_group)
+    fs->s_frags_per_group = es->s_frags_per_group;
+    V(s_frags_per_group)
+    fs->s_inodes_per_group = es->s_inodes_per_group;
+    V(s_inodes_per_group)
+    if (es->s_rev_level == EXT2_GOOD_OLD_REV) {
+        fs->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
+        fs->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+    } else {
+        fs->s_first_ino = es->s_first_ino;
+        fs->s_inode_size = es->s_inode_size;
+        /*
+         * Simple sanity check for superblock inode size value.
+         */
+        if (fs->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
+            fs->s_inode_size > fs->s_blocksize ||
+            (fs->s_inode_size & (fs->s_inode_size - 1)) != 0) {
+            kprintf("EXT2-fs: invalid inode size %d\n",
+                fs->s_inode_size);
+            return (EIO);
+        }
+    }
+    V(s_first_ino)
+    V(s_inode_size)
+    fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
+    V(s_inodes_per_block)
+    fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
+    V(s_itb_per_group)
+    fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc);
+    V(s_desc_per_block)
+    /* s_resuid / s_resgid ? */
+    fs->s_groups_count = (es->s_blocks_count -
+			  es->s_first_data_block +
+			  EXT2_BLOCKS_PER_GROUP(fs) - 1) /
+			 EXT2_BLOCKS_PER_GROUP(fs);
+    V(s_groups_count)
+    db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
+	EXT2_DESC_PER_BLOCK(fs);
+    fs->s_db_per_group = db_count;
+    V(s_db_per_group)
+
+    fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
+		M_EXT2MNT, M_WAITOK);
+
+    /* adjust logic_sb_block */
+    if(fs->s_blocksize > SBSIZE)
+	/* Godmar thinks: if the blocksize is greater than 1024, then
+	   the superblock is logically part of block zero.
+	 */
+        logic_sb_block = 0;
+
+    for (i = 0; i < db_count; i++) {
+	error = bread(devvp, fsbtodoff(fs, logic_sb_block + i + 1),
+		      fs->s_blocksize, &fs->s_group_desc[i]);
+	if(error) {
+	    for (j = 0; j < i; j++)
+		brelse(fs->s_group_desc[j]);
+	    bsd_free(fs->s_group_desc, M_EXT2MNT);
+	    kprintf("EXT2-fs: unable to read group descriptors (%d)\n", error);
+	    return EIO;
+	}
+	/* Set the B_LOCKED flag on the buffer, then brelse() it */
+	LCK_BUF(fs->s_group_desc[i])
+    }
+    if(!ext2_check_descriptors(fs)) {
+	    for (j = 0; j < db_count; j++)
+		    ULCK_BUF(fs->s_group_desc[j])
+	    bsd_free(fs->s_group_desc, M_EXT2MNT);
+	    kprintf("EXT2-fs: (ext2_check_descriptors failure) "
+		   "unable to read group descriptors\n");
+	    return EIO;
+    }
+
+    for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
+	    fs->s_inode_bitmap_number[i] = 0;
+	    fs->s_inode_bitmap[i] = NULL;
+	    fs->s_block_bitmap_number[i] = 0;
+	    fs->s_block_bitmap[i] = NULL;
+    }
+    fs->s_loaded_inode_bitmaps = 0;
+    fs->s_loaded_block_bitmaps = 0;
+    return 0;
+}
+
+/*
+ * Reload all incore data for a filesystem (used after running fsck on
+ * the root filesystem and finding things to fix). The filesystem must
+ * be mounted read-only.
+ *
+ * Things to do to update the mount:
+ *	1) invalidate all cached meta-data.
+ *	2) re-read superblock from disk.
+ *	3) re-read summary information from disk.
+ *	4) invalidate all inactive vnodes.
+ *	5) invalidate all cached file data.
+ *	6) re-read inode data for all active vnodes.
+ */
+static int ext2_reload_scan1(struct mount *mp, struct vnode *vp, void *rescan);
+static int ext2_reload_scan2(struct mount *mp, struct vnode *vp, void *rescan);
+
+struct scaninfo {
+	int rescan;
+	int allerror;
+	int waitfor;
+	struct vnode *devvp;
+	struct ext2_sb_info *fs;
+};
+
+static int
+ext2_reload(struct mount *mountp, struct ucred *cred)
+{
+	struct vnode *devvp;
+	struct buf *bp;
+	struct ext2_super_block * es;
+	struct ext2_sb_info *fs;
+	int error;
+	struct scaninfo scaninfo;
+
+	if ((mountp->mnt_flag & MNT_RDONLY) == 0)
+		return (EINVAL);
+	/*
+	 * Step 1: invalidate all cached meta-data.
+	 */
+	devvp = VFSTOEXT2(mountp)->um_devvp;
+	if (vinvalbuf(devvp, 0, 0, 0))
+		panic("ext2_reload: dirty1");
+	/*
+	 * Step 2: re-read superblock from disk.
+	 * constants have been adjusted for ext2
+	 */
+	if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
+		return (error);
+	es = (struct ext2_super_block *)bp->b_data;
+	if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) {
+		brelse(bp);
+		return (EIO);		/* XXX needs translation */
+	}
+	fs = VFSTOEXT2(mountp)->um_e2fs;
+	bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
+
+	if((error = compute_sb_data(devvp, es, fs)) != 0) {
+		brelse(bp);
+		return error;
+	}
+#ifdef UNKLAR
+	if (fs->fs_sbsize < SBSIZE)
+		bp->b_flags |= B_INVAL;
+#endif
+	brelse(bp);
+
+	scaninfo.rescan = 1;
+	scaninfo.devvp = devvp;
+	scaninfo.fs = fs;
+	while (error == 0 && scaninfo.rescan) {
+	    scaninfo.rescan = 0;
+	    error = vmntvnodescan(mountp, VMSC_GETVX, ext2_reload_scan1,
+				ext2_reload_scan2, &scaninfo);
+	}
+	return(error);
+}
+
+static int
+ext2_reload_scan1(struct mount *mp, struct vnode *vp, void *data)
+{
+	/*struct scaninfo *info = data;*/
+
+	return(0);
+}
+
+static int
+ext2_reload_scan2(struct mount *mp, struct vnode *vp, void *data)
+{
+	struct scaninfo *info = data;
+	struct inode *ip;
+	struct buf *bp;
+	int error;
+
+	/*
+	 * Try to recycle
+	 */
+	if (vrecycle(vp))
+		return(0);
+
+	/*
+	 * Step 5: invalidate all cached file data.
+	 */
+	if (vinvalbuf(vp, 0, 0, 0))
+		panic("ext2_reload: dirty2");
+	/*
+	 * Step 6: re-read inode data for all active vnodes.
+	 */
+	ip = VTOI(vp);
+	error = bread(info->devvp,
+		      fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)),
+		      (int)info->fs->s_blocksize, &bp);
+	if (error)
+		return (error);
+	ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data +
+	    EXT2_INODE_SIZE(info->fs) * ino_to_fsbo(info->fs, ip->i_number)),
+	    &ip->i_din);
+	brelse(bp);
+	return(0);
+}
+
+/*
+ * Common code for mount and mountroot
+ */
+static int
+ext2_mountfs(struct vnode *devvp, struct mount *mp, struct ucred *cred)
+{
+	struct ext2mount *ump;
+	struct buf *bp;
+	struct ext2_sb_info *fs;
+	struct ext2_super_block * es;
+	cdev_t dev;
+	struct partinfo dpart;
+	int error, i;
+	int ronly;
+
+	/*
+	 * Disallow multiple mounts of the same device.
+	 * Disallow mounting of a device that is currently in use
+	 * (except for root, which might share swap device for miniroot).
+	 * Flush out any old buffers remaining from a previous use.
+	 */
+	if ((error = vfs_mountedon(devvp)) != 0)
+		return (error);
+	if (vcount(devvp) > 0)
+		return (EBUSY);
+	if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)) != 0)
+		return (error);
+#ifdef READONLY
+/* turn on this to force it to be read-only */
+	mp->mnt_flag |= MNT_RDONLY;
+#endif
+
+	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
+	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
+	error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL);
+	vn_unlock(devvp);
+	if (error)
+		return (error);
+	dev = devvp->v_rdev;
+	if (dev->si_iosize_max != 0)
+		mp->mnt_iosize_max = dev->si_iosize_max;
+	if (mp->mnt_iosize_max > MAXPHYS)
+		mp->mnt_iosize_max = MAXPHYS;
+	VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, NULL);
+
+	bp = NULL;
+	ump = NULL;
+	if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
+		goto out;
+	es = (struct ext2_super_block *)bp->b_data;
+	if (ext2_check_sb_compat(es, dev, ronly) != 0) {
+		error = EINVAL;		/* XXX needs translation */
+		goto out;
+	}
+	if ((es->s_state & EXT2_VALID_FS) == 0 ||
+	    (es->s_state & EXT2_ERROR_FS)) {
+		if (ronly || (mp->mnt_flag & MNT_FORCE)) {
+			kprintf(
+"WARNING: Filesystem was not properly dismounted\n");
+		} else {
+			kprintf(
+"WARNING: R/W mount denied.  Filesystem is not clean - run fsck\n");
+			error = EPERM;
+			goto out;
+		}
+	}
+	ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK | M_ZERO);
+	ump->um_malloctype = M_EXT2NODE;
+	ump->um_blkatoff = ext2_blkatoff;
+	ump->um_truncate = ext2_truncate;
+	ump->um_update = ext2_update;
+	ump->um_valloc = ext2_valloc;
+	ump->um_vfree = ext2_vfree;
+	/* I don't know whether this is the right strategy. Note that
+	   we dynamically allocate both a ext2_sb_info and a ext2_super_block
+	   while Linux keeps the super block in a locked buffer
+	 */
+	ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
+		M_EXT2MNT, M_WAITOK);
+	ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
+		M_EXT2MNT, M_WAITOK);
+	bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
+	if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
+		goto out;
+	/*
+	 * We don't free the group descriptors allocated by compute_sb_data()
+	 * until ext2_unmount().  This is OK since the mount will succeed.
+	 */
+	brelse(bp);
+	bp = NULL;
+	fs = ump->um_e2fs;
+	fs->s_rd_only = ronly;	/* ronly is set according to mnt_flags */
+	/* if the fs is not mounted read-only, make sure the super block is
+	   always written back on a sync()
+	 */
+	fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
+	if (ronly == 0) {
+		fs->s_dirt = 1;		/* mark it modified */
+		fs->s_es->s_state &= ~EXT2_VALID_FS;	/* set fs invalid */
+	}
+	mp->mnt_data = (qaddr_t)ump;
+	mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
+	mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
+	mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN;
+	mp->mnt_flag |= MNT_LOCAL;
+	ump->um_mountp = mp;
+	ump->um_dev = dev;
+	ump->um_devvp = devvp;
+	/* setting those two parameters allows us to use
+	   ext2_bmap w/o changse !
+	*/
+	ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
+	ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
+	ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
+	for (i = 0; i < MAXQUOTAS; i++)
+		ump->um_quotas[i] = NULLVP;
+	dev->si_mountpoint = mp;
+
+	vfs_add_vnodeops(mp, &ext2_vnode_vops, &mp->mnt_vn_norm_ops);
+	vfs_add_vnodeops(mp, &ext2_spec_vops, &mp->mnt_vn_spec_ops);
+	vfs_add_vnodeops(mp, &ext2_fifo_vops, &mp->mnt_vn_fifo_ops);
+
+	if (ronly == 0)
+		ext2_sbupdate(ump, MNT_WAIT);
+	return (0);
+out:
+	if (bp)
+		brelse(bp);
+	VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE);
+	if (ump) {
+		bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
+		bsd_free(ump->um_e2fs, M_EXT2MNT);
+		bsd_free(ump, M_EXT2MNT);
+		mp->mnt_data = (qaddr_t)0;
+	}
+	return (error);
+}
+
+/*
+ * unmount system call
+ */
+static int
+ext2_unmount(struct mount *mp, int mntflags)
+{
+	struct ext2mount *ump;
+	struct ext2_sb_info *fs;
+	int error, flags, ronly, i;
+
+	flags = 0;
+	if (mntflags & MNT_FORCE) {
+		if (mp->mnt_flag & MNT_ROOTFS)
+			return (EINVAL);
+		flags |= FORCECLOSE;
+	}
+	if ((error = ext2_flushfiles(mp, flags)) != 0)
+		return (error);
+	ump = VFSTOEXT2(mp);
+	fs = ump->um_e2fs;
+	ronly = fs->s_rd_only;
+	if (ronly == 0) {
+		if (fs->s_wasvalid)
+			fs->s_es->s_state |= EXT2_VALID_FS;
+		ext2_sbupdate(ump, MNT_WAIT);
+	}
+
+	/* release buffers containing group descriptors */
+	for(i = 0; i < fs->s_db_per_group; i++)
+		ULCK_BUF(fs->s_group_desc[i])
+	bsd_free(fs->s_group_desc, M_EXT2MNT);
+
+	/* release cached inode/block bitmaps */
+        for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
+                if (fs->s_inode_bitmap[i])
+			ULCK_BUF(fs->s_inode_bitmap[i])
+
+        for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
+                if (fs->s_block_bitmap[i])
+			ULCK_BUF(fs->s_block_bitmap[i])
+
+	ump->um_devvp->v_rdev->si_mountpoint = NULL;
+	error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE);
+	vrele(ump->um_devvp);
+	bsd_free(fs->s_es, M_EXT2MNT);
+	bsd_free(fs, M_EXT2MNT);
+	bsd_free(ump, M_EXT2MNT);
+	mp->mnt_data = (qaddr_t)0;
+	mp->mnt_flag &= ~MNT_LOCAL;
+	return (error);
+}
+
+/*
+ * Flush out all the files in a filesystem.
+ */
+static int
+ext2_flushfiles(struct mount *mp, int flags)
+{
+	struct ext2mount *ump;
+	int error;
+#if QUOTA
+	int i;
+#endif
+
+	ump = VFSTOEXT2(mp);
+#if QUOTA
+	if (mp->mnt_flag & MNT_QUOTA) {
+		if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
+			return (error);
+		for (i = 0; i < MAXQUOTAS; i++) {
+			if (ump->um_quotas[i] == NULLVP)
+				continue;
+			ext2_quotaoff(mp, i);
+		}
+		/*
+		 * Here we fall through to vflush again to ensure
+		 * that we have gotten rid of all the system vnodes.
+		 */
+	}
+#endif
+	error = vflush(mp, 0, flags);
+	return (error);
+}
+
+/*
+ * Get file system statistics.
+ * taken from ext2/super.c ext2_statfs
+ */
+static int
+ext2_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
+{
+        unsigned long overhead;
+	struct ext2mount *ump;
+	struct ext2_sb_info *fs;
+	struct ext2_super_block *es;
+	int i, nsb;
+
+	ump = VFSTOEXT2(mp);
+	fs = ump->um_e2fs;
+	es = fs->s_es;
+
+	if (es->s_magic != EXT2_SUPER_MAGIC)
+		panic("ext2_statfs - magic number spoiled");
+
+	/*
+	 * Compute the overhead (FS structures)
+	 */
+	if (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) {
+		nsb = 0;
+		for (i = 0 ; i < fs->s_groups_count; i++)
+			if (ext2_group_sparse(i))
+				nsb++;
+	} else
+		nsb = fs->s_groups_count;
+	overhead = es->s_first_data_block +
+	    /* Superblocks and block group descriptors: */
+	    nsb * (1 + fs->s_db_per_group) +
+	    /* Inode bitmap, block bitmap, and inode table: */
+	    fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
+
+	sbp->f_bsize = EXT2_FRAG_SIZE(fs);
+	sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
+	sbp->f_blocks = es->s_blocks_count - overhead;
+	sbp->f_bfree = es->s_free_blocks_count;
+	sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count;
+	sbp->f_files = es->s_inodes_count;
+	sbp->f_ffree = es->s_free_inodes_count;
+	if (sbp != &mp->mnt_stat) {
+		sbp->f_type = mp->mnt_vfc->vfc_typenum;
+		bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
+			(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
+	}
+	return (0);
+}
+
+/*
+ * Go through the disk queues to initiate sandbagged IO;
+ * go through the inodes to write those that have been modified;
+ * initiate the writing of the super block if it has been modified.
+ *
+ * Note: we are always called with the filesystem marked `MPBUSY'.
+ */
+
+static int ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data);
+
+static int
+ext2_sync(struct mount *mp, int waitfor)
+{
+	struct ext2mount *ump = VFSTOEXT2(mp);
+	struct ext2_sb_info *fs;
+	struct scaninfo scaninfo;
+	int error;
+
+	fs = ump->um_e2fs;
+	if (fs->s_dirt != 0 && fs->s_rd_only != 0) {		/* XXX */
+		kprintf("fs = %s\n", fs->fs_fsmnt);
+		panic("ext2_sync: rofs mod");
+	}
+
+	/*
+	 * Write back each (modified) inode.
+	 */
+	scaninfo.allerror = 0;
+	scaninfo.rescan = 1;
+	scaninfo.waitfor = waitfor;
+	while (scaninfo.rescan) {
+		scaninfo.rescan = 0;
+		vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT,
+				NULL, ext2_sync_scan, &scaninfo);
+	}
+
+	/*
+	 * Force stale file system control information to be flushed.
+	 */
+	if ((waitfor & MNT_LAZY) == 0) {
+		vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
+		if ((error = VOP_FSYNC(ump->um_devvp, waitfor, 0)) != 0)
+			scaninfo.allerror = error;
+		vn_unlock(ump->um_devvp);
+	}
+#if QUOTA
+	ext2_qsync(mp);
+#endif
+	/*
+	 * Write back modified superblock.
+	 */
+	if (fs->s_dirt != 0) {
+		fs->s_dirt = 0;
+		fs->s_es->s_wtime = time_second;
+		if ((error = ext2_sbupdate(ump, waitfor)) != 0)
+			scaninfo.allerror = error;
+	}
+	return (scaninfo.allerror);
+}
+
+static int
+ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data)
+{
+	struct scaninfo *info = data;
+	struct inode *ip;
+	int error;
+
+	ip = VTOI(vp);
+	if (vp->v_type == VNON ||
+	    ((ip->i_flag &
+	    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
+	    (RB_EMPTY(&vp->v_rbdirty_tree) || (info->waitfor & MNT_LAZY)))) {
+		return(0);
+	}
+	if ((error = VOP_FSYNC(vp, info->waitfor, 0)) != 0)
+		info->allerror = error;
+	return(0);
+}
+
+/*
+ * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it
+ * in from disk.  If it is in core, wait for the lock bit to clear, then
+ * return the inode locked.  Detection and handling of mount points must be
+ * done by the calling routine.
+ */
+static int
+ext2_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
+{
+	struct ext2_sb_info *fs;
+	struct inode *ip;
+	struct ext2mount *ump;
+	struct buf *bp;
+	struct vnode *vp;
+	cdev_t dev;
+	int i, error;
+	int used_blocks;
+
+	ump = VFSTOEXT2(mp);
+	dev = ump->um_dev;
+restart:
+	if ((*vpp = ext2_ihashget(dev, ino)) != NULL)
+		return (0);
+
+	/*
+	 * Lock out the creation of new entries in the FFS hash table in
+	 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
+	 * may occur!
+	 */
+	if (ext2fs_inode_hash_lock) {
+		while (ext2fs_inode_hash_lock) {
+			ext2fs_inode_hash_lock = -1;
+			tsleep(&ext2fs_inode_hash_lock, 0, "e2vget", 0);
+		}
+		goto restart;
+	}
+	ext2fs_inode_hash_lock = 1;
+
+	/*
+	 * If this MALLOC() is performed after the getnewvnode()
+	 * it might block, leaving a vnode with a NULL v_data to be
+	 * found by ext2_sync() if a sync happens to fire right then,
+	 * which will cause a panic because ext2_sync() blindly
+	 * dereferences vp->v_data (as well it should).
+	 */
+	MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
+
+	/* Allocate a new vnode/inode. */
+	if ((error = getnewvnode(VT_EXT2FS, mp, &vp, 0, LK_CANRECURSE)) != 0) {
+		if (ext2fs_inode_hash_lock < 0)
+			wakeup(&ext2fs_inode_hash_lock);
+		ext2fs_inode_hash_lock = 0;
+		*vpp = NULL;
+		FREE(ip, M_EXT2NODE);
+		return (error);
+	}
+	bzero((caddr_t)ip, sizeof(struct inode));
+	vp->v_data = ip;
+	ip->i_vnode = vp;
+	ip->i_e2fs = fs = ump->um_e2fs;
+	ip->i_dev = dev;
+	ip->i_number = ino;
+#if QUOTA
+	for (i = 0; i < MAXQUOTAS; i++)
+		ip->i_dquot[i] = NODQUOT;
+#endif
+	/*
+	 * Put it onto its hash chain.  Since our vnode is locked, other
+	 * requests for this inode will block if they arrive while we are
+	 * sleeping waiting for old data structures to be purged or for the
+	 * contents of the disk portion of this inode to be read.
+	 */
+	ext2_ihashins(ip);
+
+	if (ext2fs_inode_hash_lock < 0)
+		wakeup(&ext2fs_inode_hash_lock);
+	ext2fs_inode_hash_lock = 0;
+
+	/* Read in the disk contents for the inode, copy into the inode. */
+#if 0
+kprintf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
+#endif
+	error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)),
+		      (int)fs->s_blocksize, &bp);
+	if (error) {
+		/*
+		 * The inode does not contain anything useful, so it would
+		 * be misleading to leave it on its hash chain. With mode
+		 * still zero, it will be unlinked and returned to the free
+		 * list by vput().
+		 */
+		brelse(bp);
+		vx_put(vp);
+		*vpp = NULL;
+		return (error);
+	}
+	/* convert ext2 inode to dinode */
+	ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
+			ino_to_fsbo(fs, ino)), &ip->i_din);
+	ip->i_block_group = ino_to_cg(fs, ino);
+	ip->i_next_alloc_block = 0;
+	ip->i_next_alloc_goal = 0;
+	ip->i_prealloc_count = 0;
+	ip->i_prealloc_block = 0;
+        /* now we want to make sure that block pointers for unused
+           blocks are zeroed out - ext2_balloc depends on this
+	   although for regular files and directories only
+	*/
+	if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
+		used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize;
+		for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
+			ip->i_db[i] = 0;
+	}
+#if 0
+	ext2_print_inode(ip);
+#endif
+	bqrelse(bp);
+
+	/*
+	 * Initialize the vnode from the inode, check for aliases.
+	 * Note that the underlying vnode may have changed.
+	 */
+	if ((error = ext2_vinit(mp, &vp)) != 0) {
+		vx_put(vp);
+		*vpp = NULL;
+		return (error);
+	}
+
+	/*
+	 * Finish inode initialization now that aliasing has been resolved.
+	 */
+	ip->i_devvp = ump->um_devvp;
+	vref(ip->i_devvp);
+	/*
+	 * Set up a generation number for this inode if it does not
+	 * already have one. This should only happen on old filesystems.
+	 */
+	if (ip->i_gen == 0) {
+		ip->i_gen = krandom() / 2 + 1;
+		if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
+			ip->i_flag |= IN_MODIFIED;
+	}
+	/*
+	 * Return the locked and refd vnode.
+	 */
+	*vpp = vp;
+	return (0);
+}
+
+/*
+ * File handle to vnode
+ *
+ * Have to be really careful about stale file handles:
+ * - check that the inode number is valid
+ * - call ext2_vget() to get the locked inode
+ * - check for an unallocated inode (i_mode == 0)
+ * - check that the given client host has export rights and return
+ *   those rights via. exflagsp and credanonp
+ */
+static int
+ext2_fhtovp(struct mount *mp, struct vnode *rootvp,
+	    struct fid *fhp, struct vnode **vpp)
+{
+	struct ufid *ufhp;
+	struct ext2_sb_info *fs;
+	struct inode *ip;
+        struct vnode *nvp;
+        int error;
+
+	ufhp = (struct ufid *)fhp;
+	fs = VFSTOEXT2(mp)->um_e2fs;
+	if (ufhp->ufid_ino < ROOTINO ||
+	    ufhp->ufid_ino > fs->s_groups_count * fs->s_es->s_inodes_per_group)
+		return (ESTALE);
+
+	error = VFS_VGET(mp, rootvp, ufhp->ufid_ino, &nvp);
+	if (error) {
+		*vpp = NULLVP;
+		return (error);
+	}
+	ip = VTOI(nvp);
+	if (ip->i_mode == 0 ||
+	    ip->i_gen != ufhp->ufid_gen ||
+	    (VFSTOEXT2(mp)->um_i_effnlink_valid ? ip->i_effnlink :
+	    ip->i_nlink) <= 0) {
+		vput(nvp);
+		*vpp = NULLVP;
+		return (ESTALE);
+	}
+	*vpp = nvp;
+	return (0);
+}
+
+/*
+ * Vnode pointer to File handle
+ */
+/* ARGSUSED */
+static int
+ext2_vptofh(struct vnode *vp, struct fid *fhp)
+{
+	struct inode *ip;
+	struct ufid *ufhp;
+
+	ip = VTOI(vp);
+	ufhp = (struct ufid *)fhp;
+	ufhp->ufid_len = sizeof(struct ufid);
+	ufhp->ufid_ino = ip->i_number;
+	ufhp->ufid_gen = ip->i_gen;
+	return (0);
+}
+
+/*
+ * This is the generic part of fhtovp called after the underlying
+ * filesystem has validated the file handle.
+ *
+ * Verify that a host should have access to a filesystem.
+ */
+int
+ext2_check_export(struct mount *mp, struct sockaddr *nam, int *exflagsp,
+                 struct ucred **credanonp)
+{
+	struct netcred *np;
+	struct ext2mount *ump;
+
+	ump = VFSTOEXT2(mp);
+	/*
+	 * Get the export permission structure for this <mp, client> tuple.
+	 */
+	np = vfs_export_lookup(mp, &ump->um_export, nam);
+	if (np == NULL)
+		return (EACCES);
+
+	*exflagsp = np->netc_exflags;
+	*credanonp = &np->netc_anon;
+	return (0);
+}
+
+/*
+ * Write a superblock and associated information back to disk.
+ */
+static int
+ext2_sbupdate(struct ext2mount *mp, int waitfor)
+{
+	struct ext2_sb_info *fs = mp->um_e2fs;
+	struct ext2_super_block *es = fs->s_es;
+	struct buf *bp;
+	int error = 0;
+/*
+kprintf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
+*/
+	bp = getblk(mp->um_devvp, SBOFF, SBSIZE, 0, 0);
+	bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block));
+	if (waitfor == MNT_WAIT)
+		error = bwrite(bp);
+	else
+		bawrite(bp);
+
+	/*
+	 * The buffers for group descriptors, inode bitmaps and block bitmaps
+	 * are not busy at this point and are (hopefully) written by the
+	 * usual sync mechanism. No need to write them here
+	 */
+
+	return (error);
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2_vnops.c b/sys/gnu/vfs/ext2fs/ext2_vnops.c
new file mode 100644
index 0000000..74ce07b
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2_vnops.c
@@ -0,0 +1,2113 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
+ *	@(#)ext2_vnops.c	8.7 (Berkeley) 2/3/94
+ * $FreeBSD: src/sys/gnu/ext2fs/ext2_vnops.c,v 1.51.2.2 2003/01/02 17:26:18 bde Exp $
+ */
+
+#include "opt_quota.h"
+#include "opt_suiddir.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/kernel.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/buf.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/priv.h>
+#include <sys/mount.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
+#include <sys/dirent.h>
+#include <sys/lockf.h>
+#include <sys/event.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/jail.h>
+#include <sys/namei.h>
+#include <sys/signalvar.h>
+#include <sys/unistd.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_zone.h>
+#include <vm/vnode_pager.h>
+
+#include <sys/buf2.h>
+#include <sys/thread2.h>
+
+#include <vfs/fifofs/fifo.h>
+
+#include "dir.h"
+#include "quota.h"
+#include "inode.h"
+#include "ext2mount.h"
+#include "ext2_fs_sb.h"
+#include "fs.h"
+#include "ext2_extern.h"
+#include "ext2_fs.h"
+
+static int ext2_access (struct vop_access_args *);
+static int ext2_advlock (struct vop_advlock_args *);
+static int ext2_chmod (struct vnode *, int, struct ucred *);
+static int ext2_chown (struct vnode *, uid_t, gid_t, struct ucred *);
+static int ext2_close (struct vop_close_args *);
+static int ext2_getattr (struct vop_getattr_args *);
+static int ext2_makeinode (int mode, struct vnode *, struct vnode **, struct componentname *);
+static int ext2_mmap (struct vop_mmap_args *);
+static int ext2_open (struct vop_open_args *);
+static int ext2_pathconf (struct vop_pathconf_args *);
+static int ext2_print (struct vop_print_args *);
+static int ext2_readlink (struct vop_readlink_args *);
+static int ext2_setattr (struct vop_setattr_args *);
+static int ext2_strategy (struct vop_strategy_args *);
+static int ext2_whiteout (struct vop_old_whiteout_args *);
+static int filt_ext2read (struct knote *kn, long hint);
+static int filt_ext2write (struct knote *kn, long hint);
+static int filt_ext2vnode (struct knote *kn, long hint);
+static void filt_ext2detach (struct knote *kn);
+static int ext2_kqfilter (struct vop_kqfilter_args *ap);
+static int ext2fifo_close (struct vop_close_args *);
+static int ext2fifo_kqfilter (struct vop_kqfilter_args *);
+static int ext2fifo_read (struct vop_read_args *);
+static int ext2fifo_write (struct vop_write_args *);
+
+static int ext2_fsync (struct vop_fsync_args *);
+static int ext2_read (struct vop_read_args *);
+static int ext2_write (struct vop_write_args *);
+static int ext2_remove (struct vop_old_remove_args *);
+static int ext2_link (struct vop_old_link_args *);
+static int ext2_rename (struct vop_old_rename_args *);
+static int ext2_mkdir (struct vop_old_mkdir_args *);
+static int ext2_rmdir (struct vop_old_rmdir_args *);
+static int ext2_create (struct vop_old_create_args *);
+static int ext2_mknod (struct vop_old_mknod_args *);
+static int ext2_symlink (struct vop_old_symlink_args *);
+
+#include "ext2_readwrite.c"
+
+union _qcvt {
+	int64_t qcvt;
+	int32_t val[2];
+};
+#define SETHIGH(q, h) { \
+	union _qcvt tmp; \
+	tmp.qcvt = (q); \
+	tmp.val[_QUAD_HIGHWORD] = (h); \
+	(q) = tmp.qcvt; \
+}
+#define SETLOW(q, l) { \
+	union _qcvt tmp; \
+	tmp.qcvt = (q); \
+	tmp.val[_QUAD_LOWWORD] = (l); \
+	(q) = tmp.qcvt; \
+}
+#define VN_KNOTE(vp, b) \
+	KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, (b))
+
+#define OFSFMT(vp)		((vp)->v_mount->mnt_maxsymlinklen <= 0)
+
+/*
+ * A virgin directory (no blushing please).
+ * Note that the type and namlen fields are reversed relative to ufs.
+ * Also, we don't use `struct odirtemplate', since it would just cause
+ * endianness problems.
+ */
+static struct dirtemplate ext2_mastertemplate = {
+	0, 12, 1, EXT2_FT_DIR, ".",
+	0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".."
+};
+static struct dirtemplate ext2_omastertemplate = {
+	0, 12, 1, EXT2_FT_UNKNOWN, ".",
+	0, DIRBLKSIZ - 12, 2, EXT2_FT_UNKNOWN, ".."
+};
+
+/*
+ * Create a regular file
+ *
+ * ext2_create(struct vnode *a_dvp, struct vnode **a_vpp,
+ *	       struct componentname *a_cnp, struct vattr *a_vap)
+ */
+static int
+ext2_create(struct vop_old_create_args *ap)
+{
+	int error;
+
+	error =
+	    ext2_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
+	    ap->a_dvp, ap->a_vpp, ap->a_cnp);
+	if (error)
+		return (error);
+	return (0);
+}
+
+/*
+ * Synch an open file.
+ *
+ * ext2_fsync(struct vnode *a_vp, struct ucred *a_cred, int a_waitfor,
+ *	      struct proc *a_p)
+ */
+/* ARGSUSED */
+
+static int ext2_fsync_bp(struct buf *bp, void *data);
+
+struct ext2_fsync_bp_info {
+	struct vnode *vp;
+	int waitfor;
+};
+
+static int
+ext2_fsync(struct vop_fsync_args *ap)
+{
+	struct ext2_fsync_bp_info info;
+	struct vnode *vp = ap->a_vp;
+	int count;
+
+	/*
+	 * XXX why is all this fs specific?
+	 */
+
+	/*
+	 * Flush all dirty buffers associated with a vnode.
+	 */
+	ext2_discard_prealloc(VTOI(vp));
+
+	lwkt_gettoken(&vp->v_token);
+	info.vp = vp;
+loop:
+	info.waitfor = ap->a_waitfor;
+	count = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL,
+			ext2_fsync_bp, &info);
+	if (count)
+		goto loop;
+
+	if (ap->a_waitfor == MNT_WAIT) {
+		bio_track_wait(&vp->v_track_write, 0, 0);
+#if DIAGNOSTIC
+		if (!RB_EMPTY(&vp->v_rbdirty_tree)) {
+			vprint("ext2_fsync: dirty", vp);
+			goto loop;
+		}
+#endif
+	}
+	lwkt_reltoken(&vp->v_token);
+	return (EXT2_UPDATE(ap->a_vp, ap->a_waitfor == MNT_WAIT));
+}
+
+static int
+ext2_fsync_bp(struct buf *bp, void *data)
+{
+	struct ext2_fsync_bp_info *info = data;
+
+	if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
+		return(0);
+	if ((bp->b_flags & B_DELWRI) == 0)
+		panic("ext2_fsync: not dirty");
+	bremfree(bp);
+
+	/*
+	 * Wait for I/O associated with indirect blocks to complete,
+	 * since there is no way to quickly wait for them below.
+	 */
+	if (bp->b_vp == info->vp || (info->waitfor & MNT_NOWAIT))
+		bawrite(bp);
+	else
+		bwrite(bp);
+	return(1);
+}
+
+/*
+ * Mknod vnode call
+ *
+ * ext2_mknod(struct vnode *a_dvp, struct vnode **a_vpp,
+ *	      struct componentname *a_cnp, struct vattr *a_vap)
+ */
+/* ARGSUSED */
+static int
+ext2_mknod(struct vop_old_mknod_args *ap)
+{
+	struct vattr *vap = ap->a_vap;
+	struct vnode **vpp = ap->a_vpp;
+	struct inode *ip;
+	ino_t ino;
+	int error;
+
+	if (vap->va_rmajor != VNOVAL &&
+	    makeudev(vap->va_rmajor, vap->va_rminor) == NOUDEV) {
+		return (EINVAL);
+	}
+
+	error = ext2_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
+	    ap->a_dvp, vpp, ap->a_cnp);
+	if (error)
+		return (error);
+	ip = VTOI(*vpp);
+	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
+	if (vap->va_rmajor != VNOVAL) {
+		/*
+		 * Want to be able to use this to make badblock
+		 * inodes, so don't truncate the dev number.
+		 */
+		ip->i_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
+	}
+	/*
+	 * Remove inode, then reload it through VFS_VGET so it is
+	 * checked to see if it is an alias of an existing entry in
+	 * the inode cache.
+	 */
+	(*vpp)->v_type = VNON;
+	ino = ip->i_number;	/* Save this before vgone() invalidates ip. */
+	vgone_vxlocked(*vpp);
+	vput(*vpp);
+	error = VFS_VGET(ap->a_dvp->v_mount, NULL, ino, vpp);
+	if (error) {
+		*vpp = NULL;
+		return (error);
+	}
+	return (0);
+}
+
+/*
+ * ext2_remove(struct vnode *a_dvp, struct vnode *a_vp,
+ *	       struct componentname *a_cnp)
+ */
+static int
+ext2_remove(struct vop_old_remove_args *ap)
+{
+	struct inode *ip;
+	struct vnode *vp = ap->a_vp;
+	struct vnode *dvp = ap->a_dvp;
+	int error;
+
+	ip = VTOI(vp);
+	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
+	    (VTOI(dvp)->i_flags & APPEND)) {
+		error = EPERM;
+		goto out;
+	}
+	error = ext2_dirremove(dvp, ap->a_cnp);
+	if (error == 0) {
+		ip->i_nlink--;
+		ip->i_flag |= IN_CHANGE;
+	}
+out:
+	return (error);
+}
+
+/*
+ * link vnode call
+ *
+ * ext2_link(struct vnode *a_tdvp, struct vnode *a_vp,
+ *	     struct componentname *a_cnp)
+ */
+static int
+ext2_link(struct vop_old_link_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct vnode *tdvp = ap->a_tdvp;
+	struct componentname *cnp = ap->a_cnp;
+	struct inode *ip;
+	int error;
+
+	if (tdvp->v_mount != vp->v_mount) {
+		error = EXDEV;
+		goto out2;
+	}
+	if (tdvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
+		goto out2;
+	}
+	ip = VTOI(vp);
+	if ((nlink_t)ip->i_nlink >= LINK_MAX) {
+		error = EMLINK;
+		goto out1;
+	}
+	if (ip->i_flags & (IMMUTABLE | APPEND)) {
+		error = EPERM;
+		goto out1;
+	}
+	ip->i_nlink++;
+	ip->i_flag |= IN_CHANGE;
+	error = EXT2_UPDATE(vp, 1);
+	if (!error)
+		error = ext2_direnter(ip, tdvp, cnp);
+	if (error) {
+		ip->i_nlink--;
+		ip->i_flag |= IN_CHANGE;
+	}
+out1:
+	if (tdvp != vp)
+		vn_unlock(vp);
+out2:
+	return (error);
+}
+
+/*
+ * Rename system call.  fdvp, fvp are ref'd.  tvp, tdvp are ref'd and locked.
+ * all vp's are released and must be in an unlocked state on return.
+ *
+ * ext2_rename(struct vnode *a_fdvp, struct vnode *a_fvp,
+ *		struct componentname *a_fcnp, struct vnode *a_tdvp,
+ *		struct vnode *a_tvp, struct componentname *a_tcnp)
+ */
+static int
+ext2_rename(struct vop_old_rename_args *ap)
+{
+	struct vnode *tvp = ap->a_tvp;
+	struct vnode *tdvp = ap->a_tdvp;
+	struct vnode *fvp = ap->a_fvp;
+	struct vnode *fdvp = ap->a_fdvp;
+	struct componentname *tcnp = ap->a_tcnp;
+	struct componentname *fcnp = ap->a_fcnp;
+	struct inode *ip, *xp, *dp;
+	struct dirtemplate dirbuf;
+	int doingdirectory = 0, oldparent = 0, newparent = 0;
+	int error = 0;
+	u_char namlen;
+
+	/*
+	 * Check for cross-device rename.
+	 */
+	if ((fvp->v_mount != tdvp->v_mount) ||
+	    (tvp && (fvp->v_mount != tvp->v_mount)) ||
+	    tvp == tdvp) {
+		error = EXDEV;
+abortit:
+		if (tdvp == tvp)
+			vrele(tdvp);
+		else
+			vput(tdvp);
+		if (tvp)
+			vput(tvp);
+		vrele(fdvp);
+		vrele(fvp);
+		return (error);
+	}
+
+	if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
+	    (VTOI(tdvp)->i_flags & APPEND))) {
+		error = EPERM;
+		goto abortit;
+	}
+
+	/*
+	 * Renaming a file to itself has no effect.  The upper layers should
+	 * not call us in that case.  Temporarily just warn if they do.
+	 */
+	if (fvp == tvp) {
+		error = 0;
+		goto abortit;
+	}
+
+	if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
+		goto abortit;
+
+	/*
+	 * fvp, tvp, tdvp locked.  fdvp not locked but note that fdvp may
+	 * be equal to tdvp.
+	 */
+	dp = VTOI(fdvp);
+	ip = VTOI(fvp);
+	if (ip->i_nlink >= LINK_MAX) {
+		vn_unlock(fvp);
+		error = EMLINK;
+		goto abortit;
+	}
+	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
+	    || (dp->i_flags & APPEND)) {
+		vn_unlock(fvp);
+		error = EPERM;
+		goto abortit;
+	}
+	if ((ip->i_mode & IFMT) == IFDIR) {
+		/*
+		 * Avoid ".", "..", and aliases of "." for obvious reasons.
+		 */
+		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
+		    dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & CNP_ISDOTDOT ||
+		    (ip->i_flag & IN_RENAME)) {
+			vn_unlock(fvp);
+			error = EINVAL;
+			goto abortit;
+		}
+		ip->i_flag |= IN_RENAME;
+		oldparent = dp->i_number;
+		doingdirectory++;
+	}
+
+	/*
+	 * tvp is non-NULL if the target exists.   fvp is still locked but
+	 * we will unlock it soon.  The 'bad' goto target requires dp and
+	 * xp to be correctly assigned.
+	 */
+	dp = VTOI(tdvp);
+	if (tvp)
+		xp = VTOI(tvp);
+	else
+		xp = NULL;
+
+	/*
+	 * 1) Bump link count while we're moving stuff
+	 *    around.  If we crash somewhere before
+	 *    completing our work, the link count
+	 *    may be wrong, but correctable.
+	 */
+	ip->i_nlink++;
+	ip->i_flag |= IN_CHANGE;
+	if ((error = EXT2_UPDATE(fvp, 1)) != 0) {
+		vn_unlock(fvp);
+		goto bad;
+	}
+
+	/*
+	 * If ".." must be changed (ie the directory gets a new
+	 * parent) then the source directory must not be in the
+	 * directory heirarchy above the target, as this would
+	 * orphan everything below the source directory. Also
+	 * the user must have write permission in the source so
+	 * as to be able to change "..". We must repeat the call
+	 * to namei, as the parent directory is unlocked by the
+	 * call to checkpath().
+	 */
+	error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
+	vn_unlock(fvp);
+
+	/*
+	 * tvp (if not NULL) and tdvp are locked.  fvp and fdvp are not.
+	 * dp and xp are set according to tdvp and tvp.
+	 */
+	if (oldparent != dp->i_number)
+		newparent = dp->i_number;
+	if (doingdirectory && newparent) {
+		if (error)	/* write access check above */
+			goto bad;
+
+		/*
+		 * Prepare for relookup, get rid of xp
+		 */
+		if (xp != NULL) {
+			vput(tvp);
+			xp = NULL;
+		}
+
+		/*
+		 * checkpath vput()'s tdvp (VTOI(dp)) on return no matter what,
+		 * get an extra ref so we wind up with just an unlocked, ref'd
+		 * tdvp.  The 'out' target skips xp and tdvp cleanups.  Our
+		 * tdvp is now unlocked so we have to clean it up ourselves.
+		 */
+		vref(tdvp);
+		error = ext2_checkpath(ip, dp, tcnp->cn_cred);
+		tcnp->cn_flags |= CNP_PDIRUNLOCK;
+		if (error) {
+			vrele(tdvp);
+			goto out;
+		}
+		/*
+		 * relookup no longer messes with the ref count.  An unlocked
+		 * tdvp must be passed and if no error occurs a locked tdvp
+		 * will be returned.  We have to use the out target again.
+		 */
+		error = relookup(tdvp, &tvp, tcnp);
+		if (error) {
+			if (tcnp->cn_flags & CNP_PDIRUNLOCK)
+				vrele(tdvp);
+			else
+				vput(tdvp);
+			goto out;
+		}
+
+		/*
+		 * tdvp is locked at this point.  in the RENAME case tvp may
+		 * be NULL without an error, assign xp accordingly.  The
+		 * 'bad' target can be used again after this.
+		 */
+		dp = VTOI(tdvp);
+		if (tvp)
+			xp = VTOI(tvp);
+	}
+	/*
+	 * 2) If target doesn't exist, link the target
+	 *    to the source and unlink the source.
+	 *    Otherwise, rewrite the target directory
+	 *    entry to reference the source inode and
+	 *    expunge the original entry's existence.
+	 *
+	 * tdvp and tvp are cleaned up by this code.  tvp is only good if
+	 * xp is not NULL.
+	 */
+	if (xp == NULL) {
+		if (dp->i_dev != ip->i_dev)
+			panic("ext2_rename: EXDEV");
+		/*
+		 * Account for ".." in new directory.
+		 * When source and destination have the same
+		 * parent we don't fool with the link count.
+		 */
+		if (doingdirectory && newparent) {
+			if ((nlink_t)dp->i_nlink >= LINK_MAX) {
+				error = EMLINK;
+				goto bad;
+			}
+			dp->i_nlink++;
+			dp->i_flag |= IN_CHANGE;
+			error = EXT2_UPDATE(tdvp, 1);
+			if (error)
+				goto bad;
+		}
+		error = ext2_direnter(ip, tdvp, tcnp);
+		if (error) {
+			if (doingdirectory && newparent) {
+				dp->i_nlink--;
+				dp->i_flag |= IN_CHANGE;
+				EXT2_UPDATE(tdvp, 1);
+			}
+			goto bad;
+		}
+
+		/*
+		 * manual cleanup, we can't use the bad or out target after
+		 * this.
+		 */
+		vput(tdvp);
+	} else {
+		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
+			panic("ext2_rename: EXDEV");
+		/*
+		 * Short circuit rename(foo, foo).
+		 */
+		if (xp->i_number == ip->i_number)
+			panic("ext2_rename: same file");
+		/*
+		 * If the parent directory is "sticky", then the user must
+		 * own the parent directory, or the destination of the rename,
+		 * otherwise the destination may not be changed (except by
+		 * root). This implements append-only directories.
+		 */
+		if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
+		    tcnp->cn_cred->cr_uid != dp->i_uid &&
+		    xp->i_uid != tcnp->cn_cred->cr_uid) {
+			error = EPERM;
+			goto bad;
+		}
+		/*
+		 * Target must be empty if a directory and have no links
+		 * to it. Also, ensure source and target are compatible
+		 * (both directories, or both not directories).
+		 */
+		if ((xp->i_mode&IFMT) == IFDIR) {
+			if (! ext2_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
+			    xp->i_nlink > 2) {
+				error = ENOTEMPTY;
+				goto bad;
+			}
+			if (!doingdirectory) {
+				error = ENOTDIR;
+				goto bad;
+			}
+		} else if (doingdirectory) {
+			error = EISDIR;
+			goto bad;
+		}
+		error = ext2_dirrewrite(dp, ip, tcnp);
+		if (error)
+			goto bad;
+		/*
+		 * If the target directory is in the same
+		 * directory as the source directory,
+		 * decrement the link count on the parent
+		 * of the target directory.
+		 */
+		 if (doingdirectory && !newparent) {
+			dp->i_nlink--;
+			dp->i_flag |= IN_CHANGE;
+		}
+
+		/*
+		 * manual cleanup, we can't use the bad or out target after
+		 * this.
+		 */
+		vput(tdvp);
+
+		/*
+		 * Adjust the link count of the target to
+		 * reflect the dirrewrite above.  If this is
+		 * a directory it is empty and there are
+		 * no links to it, so we can squash the inode and
+		 * any space associated with it.  We disallowed
+		 * renaming over top of a directory with links to
+		 * it above, as the remaining link would point to
+		 * a directory without "." or ".." entries.
+		 */
+		xp->i_nlink--;
+		if (doingdirectory) {
+			if (--xp->i_nlink != 0)
+				panic("ext2_rename: linked directory");
+			error = EXT2_TRUNCATE(tvp, (off_t)0, IO_SYNC,
+					      tcnp->cn_cred);
+		}
+		xp->i_flag |= IN_CHANGE;
+		vput(tvp);
+		xp = NULL;
+	}
+
+	/*
+	 * tvp and tdvp have been cleaned up.  The bad and out targets may
+	 * not be used.  fvp and fdvp are ref'd but not locked.  ip
+	 * still represents the old fvp and ip->i_flag may still have IN_RENAME
+	 * set (if doingdirectory).
+	 */
+
+	/*
+	 * 3) Unlink the source.
+	 *
+	 * fdvp is locked and ref'd. ap->a_fvp holds the old lookup unlocked
+	 * and ref'd, fvp will hold the new lookup locked and ref'd.
+	 *
+	 * After the relookup ap->a_fvp must be released as part of our
+	 * cleanup, not just fdvp and fvp.  And, on success, fdvp and
+	 * fvp will be locked so the bad and out targets cannot be used.
+	 */
+	fcnp->cn_flags &= ~CNP_MODMASK;
+	fcnp->cn_flags |= CNP_LOCKPARENT;
+	KKASSERT(fcnp->cn_flags & CNP_PDIRUNLOCK);
+	error = relookup(fdvp, &fvp, fcnp);
+	if (error) {
+		/*
+		 * From name has disappeared.
+		 */
+		if (doingdirectory)
+			panic("ext2_rename: lost dir entry");
+		/* ip->i_flag only sets IN_RENAME if doingdirectory */
+		vrele(ap->a_fvp);
+		if (fcnp->cn_flags & CNP_PDIRUNLOCK)
+			vrele(fdvp);
+		else
+			vput(fdvp);
+		return (0);
+	}
+	KKASSERT((fcnp->cn_flags & CNP_PDIRUNLOCK) == 0);
+
+	/*
+	 * This case shouldn't occur
+	 */
+	if (fvp == NULL) {
+		/*
+		 * From name has disappeared.
+		 */
+		if (doingdirectory)
+			panic("ext2_rename: lost dir entry");
+		/* ip->i_flag only sets IN_RENAME if doingdirectory */
+		vrele(ap->a_fvp);
+		vput(fvp);
+		vput(fdvp);
+		return (0);
+	}
+
+	/*
+	 * fvp and fdvp are both ref'd and locked.
+	 */
+	xp = VTOI(fvp);
+	dp = VTOI(fdvp);
+
+	/*
+	 * Ensure that the directory entry still exists and has not
+	 * changed while the new name has been entered. If the source is
+	 * a file then the entry may have been unlinked or renamed. In
+	 * either case there is no further work to be done. If the source
+	 * is a directory then it cannot have been rmdir'ed; its link
+	 * count of three would cause a rmdir to fail with ENOTEMPTY.
+	 * The IN_RENAME flag ensures that it cannot be moved by another
+	 * rename.
+	 */
+	if (xp != ip) {
+		if (doingdirectory)
+			panic("ext2_rename: lost dir entry");
+		/* ip->i_flag only sets IN_RENAME if doingdirectory */
+	} else {
+		/*
+		 * If the source is a directory with a
+		 * new parent, the link count of the old
+		 * parent directory must be decremented
+		 * and ".." set to point to the new parent.
+		 */
+		if (doingdirectory && newparent) {
+			dp->i_nlink--;
+			dp->i_flag |= IN_CHANGE;
+			error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
+					sizeof (struct dirtemplate), (off_t)0,
+					UIO_SYSSPACE, IO_NODELOCKED,
+					tcnp->cn_cred, NULL);
+			if (error == 0) {
+				/* Like ext2 little-endian: */
+				namlen = dirbuf.dotdot_type;
+				if (namlen != 2 ||
+				    dirbuf.dotdot_name[0] != '.' ||
+				    dirbuf.dotdot_name[1] != '.') {
+					ext2_dirbad(xp, (doff_t)12,
+					    "rename: mangled dir");
+				} else {
+					dirbuf.dotdot_ino = newparent;
+					vn_rdwr(UIO_WRITE, fvp,
+						(caddr_t)&dirbuf,
+						sizeof (struct dirtemplate),
+						(off_t)0, UIO_SYSSPACE,
+						IO_NODELOCKED|IO_SYNC,
+						tcnp->cn_cred, NULL);
+				}
+			}
+		}
+		error = ext2_dirremove(fdvp, fcnp);
+		if (!error) {
+			xp->i_nlink--;
+			xp->i_flag |= IN_CHANGE;
+		}
+		xp->i_flag &= ~IN_RENAME;
+	}
+	vput(fdvp);
+	vput(fvp);
+	vrele(ap->a_fvp);
+	return (error);
+
+bad:
+	if (xp)
+		vput(ITOV(xp));
+	if (dp)
+		vput(ITOV(dp));
+out:
+	if (doingdirectory)
+		ip->i_flag &= ~IN_RENAME;
+	if (vn_lock(fvp, LK_EXCLUSIVE) == 0) {
+		ip->i_nlink--;
+		ip->i_flag |= IN_CHANGE;
+		ip->i_flag &= ~IN_RENAME;
+		vput(fvp);
+	} else {
+		vrele(fvp);
+	}
+	return (error);
+}
+
+/*
+ * Mkdir system call
+ *
+ * ext2_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
+ *	      struct componentname *a_cnp, struct vattr *a_vap)
+ */
+static int
+ext2_mkdir(struct vop_old_mkdir_args *ap)
+{
+	struct vnode *dvp = ap->a_dvp;
+	struct vattr *vap = ap->a_vap;
+	struct componentname *cnp = ap->a_cnp;
+	struct inode *ip, *dp;
+	struct vnode *tvp;
+	struct dirtemplate dirtemplate, *dtp;
+	int error, dmode;
+
+	dp = VTOI(dvp);
+	if ((nlink_t)dp->i_nlink >= LINK_MAX) {
+		error = EMLINK;
+		goto out;
+	}
+	dmode = vap->va_mode & 0777;
+	dmode |= IFDIR;
+	/*
+	 * Must simulate part of ext2_makeinode here to acquire the inode,
+	 * but not have it entered in the parent directory. The entry is
+	 * made later after writing "." and ".." entries.
+	 */
+	error = EXT2_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
+	if (error)
+		goto out;
+	ip = VTOI(tvp);
+	ip->i_gid = dp->i_gid;
+#ifdef SUIDDIR
+	{
+#ifdef QUOTA
+		struct ucred ucred, *ucp;
+		ucp = cnp->cn_cred;
+#endif
+		/*
+		 * if we are hacking owners here, (only do this where told to)
+		 * and we are not giving it TOO root, (would subvert quotas)
+		 * then go ahead and give it to the other user.
+		 * The new directory also inherits the SUID bit.
+		 * If user's UID and dir UID are the same,
+		 * 'give it away' so that the SUID is still forced on.
+		 */
+		if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
+		   (dp->i_mode & ISUID) && dp->i_uid) {
+			dmode |= ISUID;
+			ip->i_uid = dp->i_uid;
+#ifdef QUOTA
+			if (dp->i_uid != cnp->cn_cred->cr_uid) {
+				/*
+				 * make sure the correct user gets charged
+				 * for the space.
+				 * Make a dummy credential for the victim.
+				 * XXX This seems to never be accessed out of
+				 * our context so a stack variable is ok.
+				 */
+				ucred.cr_ref = 1;
+				ucred.cr_uid = ip->i_uid;
+				ucred.cr_ngroups = 1;
+				ucred.cr_groups[0] = dp->i_gid;
+				ucp = &ucred;
+			}
+#endif
+		} else {
+			ip->i_uid = cnp->cn_cred->cr_uid;
+		}
+#ifdef QUOTA
+		if ((error = ext2_getinoquota(ip)) ||
+		(error = ext2_chkiq(ip, 1, ucp, 0))) {
+			EXT2_VFREE(tvp, ip->i_number, dmode);
+			vput(tvp);
+			return (error);
+		}
+#endif
+	}
+#else
+	ip->i_uid = cnp->cn_cred->cr_uid;
+#ifdef QUOTA
+	if ((error = ext2_getinoquota(ip)) ||
+	    (error = ext2_chkiq(ip, 1, cnp->cn_cred, 0))) {
+		EXT2_VFREE(tvp, ip->i_number, dmode);
+		vput(tvp);
+		return (error);
+	}
+#endif
+#endif
+	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
+	ip->i_mode = dmode;
+	tvp->v_type = VDIR;	/* Rest init'd in getnewvnode(). */
+	ip->i_nlink = 2;
+	if (cnp->cn_flags & CNP_ISWHITEOUT)
+		ip->i_flags |= UF_OPAQUE;
+	error = EXT2_UPDATE(tvp, 1);
+
+	/*
+	 * The vnode must have a VM object in order to issue buffer cache
+	 * ops on it.
+	 */
+	vinitvmio(tvp, 0, PAGE_SIZE, -1);
+
+	/*
+	 * Bump link count in parent directory
+	 * to reflect work done below.  Should
+	 * be done before reference is created
+	 * so reparation is possible if we crash.
+	 */
+	dp->i_nlink++;
+	dp->i_flag |= IN_CHANGE;
+	error = EXT2_UPDATE(dvp, 1);
+	if (error)
+		goto bad;
+
+	/* Initialize directory with "." and ".." from static template. */
+	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
+	    EXT2_FEATURE_INCOMPAT_FILETYPE))
+		dtp = &ext2_mastertemplate;
+	else
+		dtp = &ext2_omastertemplate;
+	dirtemplate = *dtp;
+	dirtemplate.dot_ino = ip->i_number;
+	dirtemplate.dotdot_ino = dp->i_number;
+	/* note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE
+	 * so let's just redefine it - for this function only
+	 */
+#undef  DIRBLKSIZ
+#define DIRBLKSIZ  VTOI(dvp)->i_e2fs->s_blocksize
+	dirtemplate.dotdot_reclen = DIRBLKSIZ - 12;
+	error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
+			sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
+			IO_NODELOCKED|IO_SYNC, cnp->cn_cred, NULL);
+	if (error) {
+		dp->i_nlink--;
+		dp->i_flag |= IN_CHANGE;
+		goto bad;
+	}
+	if (DIRBLKSIZ > VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
+		panic("ext2_mkdir: blksize"); /* XXX should grow with balloc() */
+	else {
+		ip->i_size = DIRBLKSIZ;
+		ip->i_flag |= IN_CHANGE;
+	}
+
+	/* Directory set up, now install its entry in the parent directory. */
+	error = ext2_direnter(ip, dvp, cnp);
+	if (error) {
+		dp->i_nlink--;
+		dp->i_flag |= IN_CHANGE;
+	}
+bad:
+	/*
+	 * No need to do an explicit VOP_TRUNCATE here, vrele will do this
+	 * for us because we set the link count to 0.
+	 */
+	if (error) {
+		ip->i_nlink = 0;
+		ip->i_flag |= IN_CHANGE;
+		vput(tvp);
+	} else
+		*ap->a_vpp = tvp;
+out:
+	return (error);
+#undef  DIRBLKSIZ
+#define DIRBLKSIZ  DEV_BSIZE
+}
+
+/*
+ * Rmdir system call.
+ *
+ * ext2_rmdir(struct vnode *a_dvp, struct vnode *a_vp,
+ *	      struct componentname *a_cnp)
+ */
+static int
+ext2_rmdir(struct vop_old_rmdir_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct vnode *dvp = ap->a_dvp;
+	struct componentname *cnp = ap->a_cnp;
+	struct inode *ip, *dp;
+	int error;
+
+	ip = VTOI(vp);
+	dp = VTOI(dvp);
+
+	/*
+	 * Verify the directory is empty (and valid).
+	 * (Rmdir ".." won't be valid since
+	 *  ".." will contain a reference to
+	 *  the current directory and thus be
+	 *  non-empty.)
+	 */
+	error = 0;
+	if (ip->i_nlink != 2 || !ext2_dirempty(ip, dp->i_number, cnp->cn_cred)) {
+		error = ENOTEMPTY;
+		goto out;
+	}
+	if ((dp->i_flags & APPEND)
+	    || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
+		error = EPERM;
+		goto out;
+	}
+	/*
+	 * Delete reference to directory before purging
+	 * inode.  If we crash in between, the directory
+	 * will be reattached to lost+found,
+	 */
+	error = ext2_dirremove(dvp, cnp);
+	if (error)
+		goto out;
+	dp->i_nlink--;
+	dp->i_flag |= IN_CHANGE;
+	vn_unlock(dvp);
+	/*
+	 * Truncate inode.  The only stuff left
+	 * in the directory is "." and "..".  The
+	 * "." reference is inconsequential since
+	 * we're quashing it.  The ".." reference
+	 * has already been adjusted above.  We've
+	 * removed the "." reference and the reference
+	 * in the parent directory, but there may be
+	 * other hard links so decrement by 2 and
+	 * worry about them later.
+	 */
+	ip->i_nlink -= 2;
+	error = EXT2_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred);
+	vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+out:
+	return (error);
+}
+
+/*
+ * symlink -- make a symbolic link
+ *
+ * ext2_symlink(struct vnode *a_dvp, struct vnode **a_vpp,
+ *		struct componentname *a_cnp, struct vattr *a_vap,
+ *		char *a_target)
+ */
+static int
+ext2_symlink(struct vop_old_symlink_args *ap)
+{
+	struct vnode *vp, **vpp = ap->a_vpp;
+	struct inode *ip;
+	int len, error;
+
+	error = ext2_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
+	    vpp, ap->a_cnp);
+	if (error)
+		return (error);
+	vp = *vpp;
+	len = strlen(ap->a_target);
+	if (len < vp->v_mount->mnt_maxsymlinklen) {
+		ip = VTOI(vp);
+		bcopy(ap->a_target, (char *)ip->i_shortlink, len);
+		ip->i_size = len;
+		ip->i_flag |= IN_CHANGE | IN_UPDATE;
+	} else {
+		/*
+		 * Make sure we have a VM object in order to use
+		 * the buffer cache.
+		 */
+		if (vp->v_object == NULL)
+			vinitvmio(vp, 0, PAGE_SIZE, -1);
+
+		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
+				UIO_SYSSPACE, IO_NODELOCKED,
+				ap->a_cnp->cn_cred, NULL);
+
+		if (error)
+			vput(vp);
+	}
+
+	return (error);
+}
+
+/*
+ * Allocate a new inode.
+ */
+static int
+ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
+	       struct componentname *cnp)
+{
+	struct inode *ip, *pdir;
+	struct vnode *tvp;
+	int error;
+
+	pdir = VTOI(dvp);
+	*vpp = NULL;
+	if ((mode & IFMT) == 0)
+		mode |= IFREG;
+
+	error = EXT2_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
+	if (error) {
+		return (error);
+	}
+	ip = VTOI(tvp);
+	ip->i_gid = pdir->i_gid;
+#ifdef SUIDDIR
+	{
+#ifdef QUOTA
+		struct ucred ucred, *ucp;
+		ucp = cnp->cn_cred;
+#endif
+		/*
+		 * if we are
+		 * not the owner of the directory,
+		 * and we are hacking owners here, (only do this where told to)
+		 * and we are not giving it TOO root, (would subvert quotas)
+		 * then go ahead and give it to the other user.
+		 * Note that this drops off the execute bits for security.
+		 */
+		if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
+		     (pdir->i_mode & ISUID) &&
+		     (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
+			ip->i_uid = pdir->i_uid;
+			mode &= ~07111;
+#ifdef QUOTA
+			/*
+			 * make sure the correct user gets charged
+			 * for the space.
+			 * Quickly knock up a dummy credential for the victim.
+			 * XXX This seems to never be accessed out of our
+			 * context so a stack variable is ok.
+			 */
+			ucred.cr_ref = 1;
+			ucred.cr_uid = ip->i_uid;
+			ucred.cr_ngroups = 1;
+			ucred.cr_groups[0] = pdir->i_gid;
+			ucp = &ucred;
+#endif
+		} else {
+			ip->i_uid = cnp->cn_cred->cr_uid;
+		}
+
+#ifdef QUOTA
+		if ((error = ext2_getinoquota(ip)) ||
+		(error = ext2_chkiq(ip, 1, ucp, 0))) {
+			EXT2_VFREE(tvp, ip->i_number, mode);
+			vput(tvp);
+			return (error);
+		}
+#endif
+	}
+#else
+	ip->i_uid = cnp->cn_cred->cr_uid;
+#ifdef QUOTA
+	if ((error = ext2_getinoquota(ip)) ||
+	    (error = ext2_chkiq(ip, 1, cnp->cn_cred, 0))) {
+		EXT2_VFREE(tvp, ip->i_number, mode);
+		vput(tvp);
+		return (error);
+	}
+#endif
+#endif
+	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
+	ip->i_mode = mode;
+	tvp->v_type = IFTOVT(mode);	/* Rest init'd in getnewvnode(). */
+	ip->i_nlink = 1;
+	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
+	    priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, 0))
+		ip->i_mode &= ~ISGID;
+
+	if (cnp->cn_flags & CNP_ISWHITEOUT)
+		ip->i_flags |= UF_OPAQUE;
+
+	/*
+	 * Regular files and directories need VM objects.  Softlinks do
+	 * not (not immediately anyway).
+	 */
+	if (tvp->v_type == VREG || tvp->v_type == VDIR)
+		vinitvmio(tvp, 0, PAGE_SIZE, -1);
+
+	/*
+	 * Make sure inode goes to disk before directory entry.
+	 */
+	error = EXT2_UPDATE(tvp, 1);
+	if (error)
+		goto bad;
+	error = ext2_direnter(ip, dvp, cnp);
+	if (error)
+		goto bad;
+
+	*vpp = tvp;
+	return (0);
+
+bad:
+	/*
+	 * Write error occurred trying to update the inode
+	 * or the directory so must deallocate the inode.
+	 */
+	ip->i_nlink = 0;
+	ip->i_flag |= IN_CHANGE;
+	vput(tvp);
+	return (error);
+}
+
+void
+ext2_itimes(struct vnode *vp)
+{
+	struct inode *ip;
+	struct timespec ts;
+
+	ip = VTOI(vp);
+	if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
+		return;
+	if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
+		ip->i_flag |= IN_LAZYMOD;
+	else
+		ip->i_flag |= IN_MODIFIED;
+	if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+		vfs_timestamp(&ts);
+		if (ip->i_flag & IN_ACCESS) {
+			ip->i_atime = ts.tv_sec;
+			ip->i_atimensec = ts.tv_nsec;
+		}
+		if (ip->i_flag & IN_UPDATE) {
+			ip->i_mtime = ts.tv_sec;
+			ip->i_mtimensec = ts.tv_nsec;
+			ip->i_modrev++;
+		}
+		if (ip->i_flag & IN_CHANGE) {
+			ip->i_ctime = ts.tv_sec;
+			ip->i_ctimensec = ts.tv_nsec;
+		}
+	}
+	ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
+}
+
+/*
+ * Open called.
+ *
+ * Nothing to do.
+ *
+ * ext2_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
+ *	     struct file *a_fp)
+ */
+/* ARGSUSED */
+static
+int
+ext2_open(struct vop_open_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+
+	/*
+	 * Files marked append-only must be opened for appending.
+	 */
+	if ((VTOI(vp)->i_flags & APPEND) &&
+	    (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) {
+		return (EPERM);
+	}
+	return (vop_stdopen(ap));
+}
+
+/*
+ * Close called.
+ *
+ * Update the times on the inode.
+ *
+ * ext2_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
+ */
+/* ARGSUSED */
+static
+int
+ext2_close(struct vop_close_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+
+	if (vp->v_sysref.refcnt > 1)
+		ext2_itimes(vp);
+	return (vop_stdclose(ap));
+}
+
+/*
+ * ext2_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
+ */
+static
+int
+ext2_access(struct vop_access_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	int error;
+
+#ifdef QUOTA
+	if (ap->a_mode & VWRITE) {
+		switch (vp->v_type) {
+		case VDIR:
+		case VLNK:
+		case VREG:
+			if ((error = ext2_getinoquota(ip)) != 0)
+				return (error);
+			break;
+		default:
+			break;
+		}
+	}
+#endif
+
+	error = vop_helper_access(ap, ip->i_uid, ip->i_gid, ip->i_mode,
+				  ip->i_flags);
+	return (error);
+}
+
+/*
+ * ext2_getattr(struct vnode *a_vp, struct vattr *a_vap)
+ */
+/* ARGSUSED */
+static
+int
+ext2_getattr(struct vop_getattr_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	struct vattr *vap = ap->a_vap;
+
+	ext2_itimes(vp);
+	/*
+	 * Copy from inode table
+	 */
+	vap->va_fsid = dev2udev(ip->i_dev);
+	vap->va_fileid = ip->i_number;
+	vap->va_mode = ip->i_mode & ~IFMT;
+	vap->va_nlink = VFSTOEXT2(vp->v_mount)->um_i_effnlink_valid ?
+	    ip->i_effnlink : ip->i_nlink;
+	vap->va_uid = ip->i_uid;
+	vap->va_gid = ip->i_gid;
+	vap->va_rmajor = umajor(ip->i_rdev);
+	vap->va_rminor = uminor(ip->i_rdev);
+	vap->va_size = ip->i_din.di_size;
+	vap->va_atime.tv_sec = ip->i_atime;
+	vap->va_atime.tv_nsec = ip->i_atimensec;
+	vap->va_mtime.tv_sec = ip->i_mtime;
+	vap->va_mtime.tv_nsec = ip->i_mtimensec;
+	vap->va_ctime.tv_sec = ip->i_ctime;
+	vap->va_ctime.tv_nsec = ip->i_ctimensec;
+	vap->va_flags = ip->i_flags;
+	vap->va_gen = ip->i_gen;
+	vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
+	vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
+	vap->va_type = IFTOVT(ip->i_mode);
+	vap->va_filerev = ip->i_modrev;
+	return (0);
+}
+
+/*
+ * Set attribute vnode op. called from several syscalls
+ *
+ * ext2_setattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred)
+ */
+static
+int
+ext2_setattr(struct vop_setattr_args *ap)
+{
+	struct vattr *vap = ap->a_vap;
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	struct ucred *cred = ap->a_cred;
+	int error;
+
+	/*
+	 * Check for unsettable attributes.
+	 */
+	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
+	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
+	    (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
+	    ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
+		return (EINVAL);
+	}
+	if (vap->va_flags != VNOVAL) {
+		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+			return (EROFS);
+		if (cred->cr_uid != ip->i_uid &&
+		    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)))
+			return (error);
+		/*
+		 * Note that a root chflags becomes a user chflags when
+		 * we are jailed, unless the jail.chflags_allowed sysctl
+		 * is set.
+		 */
+		if (cred->cr_uid == 0 &&
+		    (!jailed(cred) || jail_chflags_allowed)) {
+			if ((ip->i_flags
+			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
+			    securelevel > 0)
+				return (EPERM);
+			ip->i_flags = vap->va_flags;
+		} else {
+			if (ip->i_flags
+			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
+			    (vap->va_flags & UF_SETTABLE) != vap->va_flags)
+				return (EPERM);
+			ip->i_flags &= SF_SETTABLE;
+			ip->i_flags |= (vap->va_flags & UF_SETTABLE);
+		}
+		ip->i_flag |= IN_CHANGE;
+		if (vap->va_flags & (IMMUTABLE | APPEND))
+			return (0);
+	}
+	if (ip->i_flags & (IMMUTABLE | APPEND))
+		return (EPERM);
+	/*
+	 * Go through the fields and update iff not VNOVAL.
+	 */
+	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
+		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+			return (EROFS);
+		if ((error = ext2_chown(vp, vap->va_uid, vap->va_gid, cred)) != 0)
+			return (error);
+	}
+	if (vap->va_size != VNOVAL) {
+		/*
+		 * Disallow write attempts on read-only filesystems;
+		 * unless the file is a socket, fifo, or a block or
+		 * character device resident on the filesystem.
+		 */
+		switch (vp->v_type) {
+		case VDIR:
+			return (EISDIR);
+		case VLNK:
+		case VREG:
+			if (vp->v_mount->mnt_flag & MNT_RDONLY)
+				return (EROFS);
+			break;
+		default:
+			break;
+		}
+		if ((error = EXT2_TRUNCATE(vp, vap->va_size, 0, cred)) != 0)
+			return (error);
+	}
+	ip = VTOI(vp);
+	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
+		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+			return (EROFS);
+		if (cred->cr_uid != ip->i_uid &&
+		    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
+		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
+		    (error = VOP_EACCESS(vp, VWRITE, cred))))
+			return (error);
+		if (vap->va_atime.tv_sec != VNOVAL)
+			ip->i_flag |= IN_ACCESS;
+		if (vap->va_mtime.tv_sec != VNOVAL)
+			ip->i_flag |= IN_CHANGE | IN_UPDATE;
+		ext2_itimes(vp);
+		if (vap->va_atime.tv_sec != VNOVAL) {
+			ip->i_atime = vap->va_atime.tv_sec;
+			ip->i_atimensec = vap->va_atime.tv_nsec;
+		}
+		if (vap->va_mtime.tv_sec != VNOVAL) {
+			ip->i_mtime = vap->va_mtime.tv_sec;
+			ip->i_mtimensec = vap->va_mtime.tv_nsec;
+		}
+		error = EXT2_UPDATE(vp, 0);
+		if (error)
+			return (error);
+	}
+	error = 0;
+	if (vap->va_mode != (mode_t)VNOVAL) {
+		if (vp->v_mount->mnt_flag & MNT_RDONLY)
+			return (EROFS);
+		error = ext2_chmod(vp, (int)vap->va_mode, cred);
+	}
+	VN_KNOTE(vp, NOTE_ATTRIB);
+	return (error);
+}
+
+/*
+ * Change the mode on a file.
+ * Inode must be locked before calling.
+ */
+static int
+ext2_chmod(struct vnode *vp, int mode, struct ucred *cred)
+{
+	struct inode *ip = VTOI(vp);
+	int error;
+
+	if (cred->cr_uid != ip->i_uid) {
+	    error = priv_check_cred(cred, PRIV_VFS_CHMOD, 0);
+	    if (error)
+		return (error);
+	}
+	if (cred->cr_uid) {
+		if (vp->v_type != VDIR && (mode & S_ISTXT))
+			return (EFTYPE);
+		if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
+			return (EPERM);
+	}
+	ip->i_mode &= ~ALLPERMS;
+	ip->i_mode |= (mode & ALLPERMS);
+	ip->i_flag |= IN_CHANGE;
+	return (0);
+}
+
+/*
+ * Perform chown operation on inode ip;
+ * inode must be locked prior to call.
+ */
+static int
+ext2_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred)
+{
+	struct inode *ip = VTOI(vp);
+	uid_t ouid;
+	gid_t ogid;
+	int error = 0;
+#ifdef QUOTA
+	int i;
+	long change;
+#endif
+
+	if (uid == (uid_t)VNOVAL)
+		uid = ip->i_uid;
+	if (gid == (gid_t)VNOVAL)
+		gid = ip->i_gid;
+	/*
+	 * If we don't own the file, are trying to change the owner
+	 * of the file, or are not a member of the target group,
+	 * the caller must be superuser or the call fails.
+	 */
+	if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
+	    (gid != ip->i_gid && !(cred->cr_gid == gid ||
+	    groupmember((gid_t)gid, cred)))) &&
+	    (error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0)))
+		return (error);
+	ogid = ip->i_gid;
+	ouid = ip->i_uid;
+#ifdef QUOTA
+	if ((error = ext2_getinoquota(ip)) != 0)
+		return (error);
+	if (ouid == uid) {
+		ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
+		ip->i_dquot[USRQUOTA] = NODQUOT;
+	}
+	if (ogid == gid) {
+		ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
+		ip->i_dquot[GRPQUOTA] = NODQUOT;
+	}
+	change = ip->i_blocks;
+	(void) ext2_chkdq(ip, -change, cred, CHOWN);
+	(void) ext2_chkiq(ip, -1, cred, CHOWN);
+	for (i = 0; i < MAXQUOTAS; i++) {
+		ext2_dqrele(vp, ip->i_dquot[i]);
+		ip->i_dquot[i] = NODQUOT;
+	}
+#endif
+	ip->i_gid = gid;
+	ip->i_uid = uid;
+#ifdef QUOTA
+	if ((error = ext2_getinoquota(ip)) == 0) {
+		if (ouid == uid) {
+			ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
+			ip->i_dquot[USRQUOTA] = NODQUOT;
+		}
+		if (ogid == gid) {
+			ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
+			ip->i_dquot[GRPQUOTA] = NODQUOT;
+		}
+		if ((error = ext2_chkdq(ip, change, cred, CHOWN)) == 0) {
+			if ((error = ext2_chkiq(ip, 1, cred, CHOWN)) == 0)
+				goto good;
+			else
+				(void)ext2_chkdq(ip, -change, cred, CHOWN|FORCE);
+		}
+		for (i = 0; i < MAXQUOTAS; i++) {
+			ext2_dqrele(vp, ip->i_dquot[i]);
+			ip->i_dquot[i] = NODQUOT;
+		}
+	}
+	ip->i_gid = ogid;
+	ip->i_uid = ouid;
+	if (ext2_getinoquota(ip) == 0) {
+		if (ouid == uid) {
+			ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
+			ip->i_dquot[USRQUOTA] = NODQUOT;
+		}
+		if (ogid == gid) {
+			ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
+			ip->i_dquot[GRPQUOTA] = NODQUOT;
+		}
+		(void) ext2_chkdq(ip, change, cred, FORCE|CHOWN);
+		(void) ext2_chkiq(ip, 1, cred, FORCE|CHOWN);
+		(void) ext2_getinoquota(ip);
+	}
+	return (error);
+good:
+	if (ext2_getinoquota(ip))
+		panic("ext2_chown: lost quota");
+#endif /* QUOTA */
+	ip->i_flag |= IN_CHANGE;
+	if (cred->cr_uid != 0 && (ouid != uid || ogid != gid))
+		ip->i_mode &= ~(ISUID | ISGID);
+	return (0);
+}
+
+/*
+ * Mmap a file
+ *
+ * NB Currently unsupported.
+ *
+ * ext2_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred)
+ */
+/* ARGSUSED */
+static
+int
+ext2_mmap(struct vop_mmap_args *ap)
+{
+	return (EINVAL);
+}
+
+/*
+ * whiteout vnode call
+ *
+ * ext2_whiteout(struct vnode *a_dvp, struct componentname *a_cnp, int a_flags)
+ */
+static
+int
+ext2_whiteout(struct vop_old_whiteout_args *ap)
+{
+	return (EOPNOTSUPP);
+}
+
+/*
+ * Return target name of a symbolic link
+ *
+ * ext2_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
+ */
+static
+int
+ext2_readlink(struct vop_readlink_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+	int isize;
+
+	isize = ip->i_size;
+	if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
+	    (ip->i_din.di_blocks == 0)) {   /* XXX - for old fastlink support */
+		uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
+		return (0);
+	}
+	return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
+}
+
+/*
+ * Calculate the logical to physical mapping if not done already,
+ * then call the device strategy routine.
+ *
+ * In order to be able to swap to a file, the VOP_BMAP operation may not
+ * deadlock on memory.  See ext2_bmap() for details.
+ *
+ * ext2_strategy(struct vnode *a_vp, struct bio *a_bio)
+ */
+static
+int
+ext2_strategy(struct vop_strategy_args *ap)
+{
+	struct bio *bio = ap->a_bio;
+	struct bio *nbio;
+	struct buf *bp = bio->bio_buf;
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip;
+	int error;
+
+	ip = VTOI(vp);
+	if (vp->v_type == VBLK || vp->v_type == VCHR)
+		panic("ext2_strategy: spec");
+	nbio = push_bio(bio);
+	if (nbio->bio_offset == NOOFFSET) {
+		error = VOP_BMAP(vp, bio->bio_offset, &nbio->bio_offset,
+				 NULL, NULL, bp->b_cmd);
+		if (error) {
+			bp->b_error = error;
+			bp->b_flags |= B_ERROR;
+			/* I/O was never started on nbio, must biodone(bio) */
+			biodone(bio);
+			return (error);
+		}
+		if (nbio->bio_offset == NOOFFSET)
+			vfs_bio_clrbuf(bp);
+	}
+	if (nbio->bio_offset == NOOFFSET) {
+		/* I/O was never started on nbio, must biodone(bio) */
+		biodone(bio);
+		return (0);
+	}
+	vn_strategy(ip->i_devvp, nbio);
+	return (0);
+}
+
+/*
+ * Print out the contents of an inode.
+ *
+ * ext2_print(struct vnode *a_vp)
+ */
+static
+int
+ext2_print(struct vop_print_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct inode *ip = VTOI(vp);
+
+	kprintf("tag VT_EXT2FS, ino %lu, on dev %s (%d, %d)",
+	    (u_long)ip->i_number, devtoname(ip->i_dev), major(ip->i_dev),
+	    minor(ip->i_dev));
+	if (vp->v_type == VFIFO)
+		fifo_printinfo(vp);
+	lockmgr_printinfo(&vp->v_lock);
+	kprintf("\n");
+	return (0);
+}
+
+/*
+ * Read wrapper for fifos.
+ *
+ * ext2fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
+ *		struct ucred *a_cred)
+ */
+static
+int
+ext2fifo_read(struct vop_read_args *ap)
+{
+	int error, resid;
+	struct inode *ip;
+	struct uio *uio;
+
+	uio = ap->a_uio;
+	resid = uio->uio_resid;
+	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
+	ip = VTOI(ap->a_vp);
+	if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
+	    (uio->uio_resid != resid || (error == 0 && resid != 0)))
+		VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
+	return (error);
+}
+
+/*
+ * Write wrapper for fifos.
+ *
+ * ext2fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
+ *		 struct ucred *a_cred)
+ */
+static
+int
+ext2fifo_write(struct vop_write_args *ap)
+{
+	int error, resid;
+	struct inode *ip;
+	struct uio *uio;
+
+	uio = ap->a_uio;
+	resid = uio->uio_resid;
+	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
+	ip = VTOI(ap->a_vp);
+	if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
+		VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
+	return (error);
+}
+
+/*
+ * Close wrapper for fifos.
+ *
+ * Update the times on the inode then do device close.
+ *
+ * ext2fifo_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
+ */
+static
+int
+ext2fifo_close(struct vop_close_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+
+	if (vp->v_sysref.refcnt > 1)
+		ext2_itimes(vp);
+	return (VOCALL(&fifo_vnode_vops, &ap->a_head));
+}
+
+/*
+ * Kqfilter wrapper for fifos.
+ *
+ * Fall through to ext2 kqfilter routines if needed
+ */
+static
+int
+ext2fifo_kqfilter(struct vop_kqfilter_args *ap)
+{
+	int error;
+
+	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
+	if (error)
+		error = ext2_kqfilter(ap);
+	return (error);
+}
+
+/*
+ * Return POSIX pathconf information applicable to ext2 filesystems.
+ *
+ * ext2_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
+ */
+static
+int
+ext2_pathconf(struct vop_pathconf_args *ap)
+{
+	switch (ap->a_name) {
+	case _PC_LINK_MAX:
+		*ap->a_retval = LINK_MAX;
+		return (0);
+	case _PC_NAME_MAX:
+		*ap->a_retval = NAME_MAX;
+		return (0);
+	case _PC_PATH_MAX:
+		*ap->a_retval = PATH_MAX;
+		return (0);
+	case _PC_PIPE_BUF:
+		*ap->a_retval = PIPE_BUF;
+		return (0);
+	case _PC_CHOWN_RESTRICTED:
+		*ap->a_retval = 1;
+		return (0);
+	case _PC_NO_TRUNC:
+		*ap->a_retval = 1;
+		return (0);
+	default:
+		return (EINVAL);
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * Advisory record locking support
+ *
+ * ext2_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
+ *	       int a_flags)
+ */
+static
+int
+ext2_advlock(struct vop_advlock_args *ap)
+{
+	struct inode *ip = VTOI(ap->a_vp);
+
+	return (lf_advlock(ap, &(ip->i_lockf), ip->i_size));
+}
+
+/*
+ * Initialize the vnode associated with a new inode, handle aliased
+ * vnodes.
+ */
+int
+ext2_vinit(struct mount *mntp, struct vnode **vpp)
+{
+	struct inode *ip;
+	struct vnode *vp;
+	struct timeval tv;
+
+	vp = *vpp;
+	ip = VTOI(vp);
+
+	switch(vp->v_type = IFTOVT(ip->i_mode)) {
+	case VCHR:
+	case VBLK:
+		vp->v_ops = &mntp->mnt_vn_spec_ops;
+		addaliasu(vp, umajor(ip->i_rdev), uminor(ip->i_rdev));
+		break;
+	case VFIFO:
+		vp->v_ops = &mntp->mnt_vn_fifo_ops;
+		break;
+	case VDIR:
+	case VREG:
+		vinitvmio(vp, ip->i_size, PAGE_SIZE, -1); /* XXX */
+		break;
+	case VLNK:
+		if ((ip->i_size >= vp->v_mount->mnt_maxsymlinklen) &&
+		    ip->i_din.di_blocks != 0
+		) {
+			vinitvmio(vp, ip->i_size, PAGE_SIZE, -1);
+		}
+		break;
+	default:
+		break;
+
+	}
+
+	if (ip->i_number == ROOTINO)
+		vp->v_flag |= VROOT;
+	/*
+	 * Initialize modrev times
+	 */
+	getmicrouptime(&tv);
+	SETHIGH(ip->i_modrev, tv.tv_sec);
+	SETLOW(ip->i_modrev, tv.tv_usec * 4294);
+	*vpp = vp;
+	return (0);
+}
+
+static struct filterops ext2read_filtops =
+	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2read };
+static struct filterops ext2write_filtops =
+	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2write };
+static struct filterops ext2vnode_filtops =
+	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2vnode };
+
+/*
+ * ext2_kqfilter(struct vnode *a_vp, struct knote *a_kn)
+ */
+static int
+ext2_kqfilter(struct vop_kqfilter_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	struct knote *kn = ap->a_kn;
+
+	switch (kn->kn_filter) {
+	case EVFILT_READ:
+		kn->kn_fop = &ext2read_filtops;
+		break;
+	case EVFILT_WRITE:
+		kn->kn_fop = &ext2write_filtops;
+		break;
+	case EVFILT_VNODE:
+		kn->kn_fop = &ext2vnode_filtops;
+		break;
+	default:
+		return (EOPNOTSUPP);
+	}
+
+	kn->kn_hook = (caddr_t)vp;
+
+	/* XXX: kq token actually protects the list */
+	lwkt_gettoken(&vp->v_token);
+	knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
+	lwkt_reltoken(&vp->v_token);
+
+	return (0);
+}
+
+static void
+filt_ext2detach(struct knote *kn)
+{
+	struct vnode *vp = (struct vnode *)kn->kn_hook;
+
+	lwkt_gettoken(&vp->v_token);
+	knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
+	lwkt_reltoken(&vp->v_token);
+}
+
+/*ARGSUSED*/
+static int
+filt_ext2read(struct knote *kn, long hint)
+{
+	struct vnode *vp = (struct vnode *)kn->kn_hook;
+	struct inode *ip = VTOI(vp);
+	off_t off;
+
+	/*
+	 * filesystem is gone, so set the EOF flag and schedule
+	 * the knote for deletion.
+	 */
+	if (hint == NOTE_REVOKE) {
+		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
+		return (1);
+	}
+        off = ip->i_size - kn->kn_fp->f_offset;
+	kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX;
+	if (kn->kn_sfflags & NOTE_OLDAPI)
+		return(1);
+        return (kn->kn_data != 0);
+}
+
+/*ARGSUSED*/
+static int
+filt_ext2write(struct knote *kn, long hint)
+{
+	/*
+	 * filesystem is gone, so set the EOF flag and schedule
+	 * the knote for deletion.
+	 */
+	if (hint == NOTE_REVOKE)
+		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
+
+        kn->kn_data = 0;
+        return (1);
+}
+
+static int
+filt_ext2vnode(struct knote *kn, long hint)
+{
+	if (kn->kn_sfflags & hint)
+		kn->kn_fflags |= hint;
+	if (hint == NOTE_REVOKE) {
+		kn->kn_flags |= (EV_EOF | EV_NODATA);
+		return (1);
+	}
+	return (kn->kn_fflags != 0);
+}
+
+struct vop_ops ext2_vnode_vops = {
+	.vop_default =		vop_defaultop,
+	.vop_fsync =		ext2_fsync,
+	.vop_read =		ext2_read,
+	.vop_reallocblks =	ext2_reallocblks,
+	.vop_write =		ext2_write,
+	.vop_access =		ext2_access,
+	.vop_advlock =		ext2_advlock,
+	.vop_bmap =		ext2_bmap,
+	.vop_old_lookup =	ext2_lookup,
+	.vop_close =		ext2_close,
+	.vop_old_create =	ext2_create,
+	.vop_getattr =		ext2_getattr,
+	.vop_inactive =		ext2_inactive,
+	.vop_old_link =		ext2_link,
+	.vop_old_mkdir =	ext2_mkdir,
+	.vop_old_mknod =	ext2_mknod,
+	.vop_mmap =		ext2_mmap,
+	.vop_open =		ext2_open,
+	.vop_pathconf =		ext2_pathconf,
+	.vop_kqfilter =		ext2_kqfilter,
+	.vop_print =		ext2_print,
+	.vop_readdir =		ext2_readdir,
+	.vop_readlink =		ext2_readlink,
+	.vop_reclaim =		ext2_reclaim,
+	.vop_old_remove =	ext2_remove,
+	.vop_old_rename =	ext2_rename,
+	.vop_old_rmdir =	ext2_rmdir,
+	.vop_setattr =		ext2_setattr,
+	.vop_strategy =		ext2_strategy,
+	.vop_old_symlink =	ext2_symlink,
+	.vop_old_whiteout =	ext2_whiteout,
+	.vop_getpages =		vop_stdgetpages,
+	.vop_putpages =		vop_stdputpages
+};
+
+struct vop_ops ext2_spec_vops = {
+	.vop_default =		vop_defaultop,
+	.vop_fsync =		ext2_fsync,
+	.vop_access =		ext2_access,
+	.vop_close =		ext2_close,
+	.vop_getattr =		ext2_getattr,
+	.vop_inactive =		ext2_inactive,
+	.vop_print =		ext2_print,
+	.vop_read =		vop_stdnoread,
+	.vop_reclaim =		ext2_reclaim,
+	.vop_setattr =		ext2_setattr,
+	.vop_write =		vop_stdnowrite
+};
+
+struct vop_ops ext2_fifo_vops = {
+	.vop_default =		ext2_vnoperatefifo,
+	.vop_fsync =		ext2_fsync,
+	.vop_access =		ext2_access,
+	.vop_close =		ext2fifo_close,
+	.vop_getattr =		ext2_getattr,
+	.vop_inactive =		ext2_inactive,
+	.vop_kqfilter =		ext2fifo_kqfilter,
+	.vop_print =		ext2_print,
+	.vop_read =		ext2fifo_read,
+	.vop_reclaim =		ext2_reclaim,
+	.vop_setattr =		ext2_setattr,
+	.vop_write =		ext2fifo_write
+};
+
+VNODEOP_SET(ext2_vnode_vops);
+VNODEOP_SET(ext2_spec_vops);
+VNODEOP_SET(ext2_fifo_vops);
+
+/*
+ * ext2_vnoperate()
+ */
+int
+ext2_vnoperate(struct vop_generic_args *ap)
+{
+	return (VOCALL(&ext2_vnode_vops, ap));
+}
+
+/*
+ * ext2_vnoperatefifo()
+ */
+int
+ext2_vnoperatefifo(struct vop_generic_args *ap)
+{
+	return (VOCALL(&ext2_fifo_vops, ap));
+}
diff --git a/sys/gnu/vfs/ext2fs/ext2mount.h b/sys/gnu/vfs/ext2fs/ext2mount.h
new file mode 100644
index 0000000..74ac845
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/ext2mount.h
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ufsmount.h	8.6 (Berkeley) 3/30/95
+ * $FreeBSD: src/sys/ufs/ufs/ufsmount.h,v 1.17 1999/12/29 04:55:06 peter Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_EXT2MOUNT_H_
+#define _VFS_GNU_EXT2FS_EXT2MOUNT_H_
+
+/*
+ * Arguments to mount UFS-based filesystems
+ */
+struct ext2_args {
+	char	*fspec;			/* block special device to mount */
+	struct	export_args export;	/* network export information */
+};
+
+/*
+ * Arguments to mount MFS
+ */
+struct mfs_args {
+	char	*fspec;			/* name to export for statfs */
+	struct	export_args export;	/* if exported MFSes are supported */
+	caddr_t	base;			/* base of filesystem in memory */
+	u_long	size;			/* size of filesystem */
+};
+
+#ifdef _KERNEL
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_EXT2MNT);
+#endif
+
+struct buf;
+struct inode;
+struct timeval;
+struct ucred;
+struct uio;
+struct vnode;
+struct netexport;
+
+/* This structure describes the UFS specific mount structure data. */
+struct ext2mount {
+	struct	mount *um_mountp;		/* filesystem vfs structure */
+	cdev_t	um_dev;				/* device mounted */
+	struct	vnode *um_devvp;		/* block device mounted vnode */
+
+	struct	ext2_sb_info *um_e2fs;
+	struct	vnode *um_quotas[MAXQUOTAS];	/* pointer to quota files */
+	struct	ucred *um_cred[MAXQUOTAS];	/* quota file access cred */
+	u_long	um_nindir;			/* indirect ptrs per block */
+	u_long	um_bptrtodb;			/* indir ptr to disk block */
+	u_long	um_seqinc;			/* inc between seq blocks */
+	time_t	um_btime[MAXQUOTAS];		/* block quota time limit */
+	time_t	um_itime[MAXQUOTAS];		/* inode quota time limit */
+	char	um_qflags[MAXQUOTAS];		/* quota specific flags */
+	struct	netexport um_export;		/* export information */
+	int64_t	um_savedmaxfilesize;		/* XXX - limit maxfilesize */
+	struct malloc_type *um_malloctype;	/* The inodes malloctype */
+	int	um_i_effnlink_valid;		/* i_effnlink valid? */
+	int	(*um_blkatoff) (struct vnode *, off_t, char **, struct buf **);
+	int	(*um_truncate) (struct vnode *, off_t, int, struct ucred *);
+	int	(*um_update) (struct vnode *, int);
+	int	(*um_valloc) (struct vnode *, int, struct ucred *, struct vnode **);
+	int	(*um_vfree) (struct vnode *, ino_t, int);
+};
+
+#define	um_e2fsb um_e2fs->s_es
+
+#define EXT2_BLKATOFF(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_blkatoff(aa, bb, cc, dd)
+#define EXT2_TRUNCATE(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_truncate(aa, bb, cc, dd)
+#define EXT2_UPDATE(aa, bb) VFSTOEXT2((aa)->v_mount)->um_update(aa, bb)
+#define EXT2_VALLOC(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_valloc(aa, bb, cc, dd)
+#define EXT2_VFREE(aa, bb, cc) VFSTOEXT2((aa)->v_mount)->um_vfree(aa, bb, cc)
+
+/*
+ * Flags describing the state of quotas.
+ */
+#define	QTF_OPENING	0x01			/* Q_QUOTAON in progress */
+#define	QTF_CLOSING	0x02			/* Q_QUOTAOFF in progress */
+
+/* Convert mount ptr to ext2mount ptr. */
+#define VFSTOEXT2(mp)	((struct ext2mount *)((mp)->mnt_data))
+
+/*
+ * Macros to access filesystem parameters in the ext2mount structure.
+ * Used by ext2_bmap.
+ */
+#define MNINDIR(ump)			((ump)->um_nindir)
+#define	blkptrtodb(ump, b)		((b) << (ump)->um_bptrtodb)
+#define	is_sequential(ump, a, b)	((b) == (a) + ump->um_seqinc)
+#endif /* _KERNEL */
+
+#endif /* !_VFS_GNU_EXT2FS_EXT2MOUNT_H_ */
diff --git a/sys/gnu/vfs/ext2fs/fs.h b/sys/gnu/vfs/ext2fs/fs.h
new file mode 100644
index 0000000..52f2fec
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/fs.h
@@ -0,0 +1,195 @@
+/*
+ *  modified for EXT2FS support in Lites 1.1
+ *
+ *  Aug 1995, Godmar Back (gback@cs.utah.edu)
+ *  University of Utah, Department of Computer Science
+ */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)fs.h	8.7 (Berkeley) 4/19/94
+ * $FreeBSD: src/sys/gnu/ext2fs/fs.h,v 1.5.2.1 2000/11/11 13:12:45 bde Exp $
+ */
+
+/*
+ * Each disk drive contains some number of file systems.
+ * A file system consists of a number of cylinder groups.
+ * Each cylinder group has inodes and data.
+ *
+ * A file system is described by its super-block, which in turn
+ * describes the cylinder groups.  The super-block is critical
+ * data and is replicated in each cylinder group to protect against
+ * catastrophic loss.  This is done at `newfs' time and the critical
+ * super-block data does not change, so the copies need not be
+ * referenced further unless disaster strikes.
+ *
+ * The first boot and super blocks are given in absolute disk addresses.
+ * The byte-offset forms are preferred, as they don't imply a sector size.
+ */
+#define BBSIZE		1024
+#define SBSIZE		1024
+#define	BBOFF		((off_t)(0))
+#define	SBOFF		((off_t)(BBOFF + BBSIZE))
+#define	BBLOCK		((daddr_t)(0))
+#define	SBLOCK		((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
+
+/*
+ * The path name on which the file system is mounted is maintained
+ * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
+ * the super block for this name.
+ */
+#define MAXMNTLEN 512
+
+/*
+ * Macros for access to superblock array structures
+ */
+
+/*
+ * Convert cylinder group to base address of its global summary info.
+ */
+#define fs_cs(fs, cgindx)      (((struct ext2_group_desc *) \
+        (fs->s_group_desc[cgindx / EXT2_DESC_PER_BLOCK(fs)]->b_data)) \
+		[cgindx % EXT2_DESC_PER_BLOCK(fs)])
+
+/*
+ * Turn file system block numbers into disk block addresses.
+ * This maps file system blocks to device size blocks.
+ */
+#define fsbtodb(fs, b)	((b) << ((fs)->s_fsbtodb))
+#define	dbtofsb(fs, b)	((b) >> ((fs)->s_fsbtodb))
+
+/* get group containing inode */
+#define ino_to_cg(fs, x)	(((x) - 1) / EXT2_INODES_PER_GROUP(fs))
+
+/* get block containing inode from its number x */
+#define	ino_to_fsba(fs, x)	(fs_cs(fs, ino_to_cg(fs, x)).bg_inode_table + \
+	(((x)-1) % EXT2_INODES_PER_GROUP(fs))/EXT2_INODES_PER_BLOCK(fs))
+
+/* get offset for inode in block */
+#define	ino_to_fsbo(fs, x)	((x-1) % EXT2_INODES_PER_BLOCK(fs))
+
+/*
+ * Give cylinder group number for a file system block.
+ * Give cylinder group block number for a file system block.
+ */
+#define	dtog(fs, d)	(((d) - fs->s_es->s_first_data_block) / \
+			EXT2_BLOCKS_PER_GROUP(fs))
+#define	dtogd(fs, d)	(((d) - fs->s_es->s_first_data_block) % \
+			EXT2_BLOCKS_PER_GROUP(fs))
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
+	((loc) & (fs)->s_qbmask)
+
+#define lblktosize(fs, blk)	/* calculates (blk * fs->fs_bsize) */ \
+	((blk) << (fs->s_bshift))
+
+/*
+ * Used when converting logical blocks to offsets for getblk, bread,
+ * etc.
+ */
+#define lblktodoff(fs, blk)	/* calculates (blk * fs->fs_bsize) */ \
+	((off_t)(blk) << (fs)->s_bshift)
+#define fsbtodoff(fs, blk)	/* calculates (blk * fs->fs_fsize) */ \
+	((off_t)(blk) * (fs)->s_frag_size)
+#define dofftofsb(fs, blk)	/* calculates blk / fs->fs_fsize */   \
+	((daddr_t)((blk) / (fs)->s_frag_size))
+#define dbtodoff(fs, b)		/* calculates diskblk * sectorsize */ \
+	((off_t)(b) * ((fs)->s_frag_size >> (fs)->s_fsbtodb))
+
+#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
+	((loc) >> (fs->s_bshift))
+
+/* no fragments -> logical block number equal # of frags */
+#define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
+	((loc) >> (fs->s_bshift))
+
+#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
+	roundup(size, fs->s_frag_size)
+	/* was (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) */
+
+/*
+ * Determining the size of a file block in the file system.
+ * easy w/o fragments
+ */
+#define blksize(fs, ip, lbn) ((fs)->s_frag_size)
+
+/*
+ * INOPB is the number of inodes in a secondary storage block.
+ */
+#define	INOPB(fs)	EXT2_INODES_PER_BLOCK(fs)
+
+/*
+ * NINDIR is the number of indirects in a file system block.
+ */
+#define	NINDIR(fs)	(EXT2_ADDR_PER_BLOCK(fs))
+
+extern int inside[], around[];
+extern u_char *fragtbl[];
+
+/* a few remarks about superblock locking/unlocking
+ * Linux provides special routines for doing so
+ * I haven't figured out yet what BSD does
+ * I think I'll try a vn_lock/vn_unlock on the device vnode
+ */
+#define  DEVVP(inode)		(VFSTOEXT2(ITOV(inode)->v_mount)->um_devvp)
+#define  lock_super(devvp)   	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY)
+#define  unlock_super(devvp) 	vn_unlock(devvp)
+
+/*
+ * To lock a buffer, set the B_LOCKED flag and then brelse() it. To unlock,
+ * reset the B_LOCKED flag and brelse() the buffer back on the LRU list
+ */
+#define LCK_BUF(bp) { \
+	crit_enter(); \
+	(bp)->b_flags |= B_LOCKED; \
+	crit_exit(); \
+	brelse(bp); \
+}
+
+#define ULCK_BUF(bp) { \
+	long flags; \
+	crit_enter(); \
+	flags = (bp)->b_flags; \
+	(bp)->b_flags &= ~(B_DIRTY | B_LOCKED); \
+	BUF_LOCK(bp, LK_EXCLUSIVE); \
+	bremfree(bp); \
+	crit_exit(); \
+	if (flags & B_DIRTY) \
+		bwrite(bp); \
+	else \
+		brelse(bp); \
+}
diff --git a/sys/gnu/vfs/ext2fs/i386-bitops.h b/sys/gnu/vfs/ext2fs/i386-bitops.h
new file mode 100644
index 0000000..81b6569
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/i386-bitops.h
@@ -0,0 +1,172 @@
+/*
+ * $FreeBSD: src/sys/gnu/ext2fs/i386-bitops.h,v 1.5 1999/11/15 23:16:06 obrien Exp $
+ */
+/*
+ * this is mixture of i386/bitops.h and asm/string.h
+ * taken from the Linux source tree
+ *
+ * XXX replace with Mach routines or reprogram in C
+ */
+#ifndef _VFS_GNU_EXT2FS_I386_BITOPS_H_
+#define	_VFS_GNU_EXT2FS_I386_BITOPS_H_
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+/*
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy { unsigned long a[100]; };
+#define ADDR (*(struct __dummy *) addr)
+
+static __inline__ int
+set_bit(int nr, void *addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"=m" (ADDR)
+		:"ir" (nr));
+	return oldbit;
+}
+
+static __inline__ int
+clear_bit(int nr, void *addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"=m" (ADDR)
+		:"ir" (nr));
+	return oldbit;
+}
+
+static __inline__ int
+change_bit(int nr, void *addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"=m" (ADDR)
+		:"ir" (nr));
+	return oldbit;
+}
+
+/*
+ * This routine doesn't need to be atomic, but it's faster to code it
+ * this way.
+ */
+static __inline__ int
+test_bit(int nr, void *addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit)
+		:"m" (ADDR),"ir" (nr));
+	return oldbit;
+}
+
+/*
+ * Find-bit routines..
+ */
+static __inline__ int
+find_first_zero_bit(void *addr, unsigned size)
+{
+	int res;
+	int _count = (size + 31) >> 5;
+
+	if (!size)
+		return 0;
+	__asm__("			\n\
+		cld			\n\
+		movl $-1,%%eax		\n\
+		xorl %%edx,%%edx	\n\
+		repe; scasl		\n\
+		je 1f			\n\
+		xorl -4(%%edi),%%eax	\n\
+		subl $4,%%edi		\n\
+		bsfl %%eax,%%edx	\n\
+1:		subl %%ebx,%%edi	\n\
+		shll $3,%%edi		\n\
+		addl %%edi,%%edx"
+		: "=c" (_count), "=D" (addr), "=d" (res)
+		: "0" (_count), "1" (addr), "b" (addr)
+		: "ax");
+	return res;
+}
+
+static __inline__ int
+find_next_zero_bit(void *addr, int size, int offset)
+{
+	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+	int set = 0, bit = offset & 31, res;
+
+	if (bit) {
+		/*
+		 * Look for zero in first byte
+		 */
+		__asm__("			\n\
+			bsfl %1,%0		\n\
+			jne 1f			\n\
+			movl $32, %0		\n\
+1:			"
+			: "=r" (set)
+			: "r" (~(*p >> bit)));
+		if (set < (32 - bit))
+			return set + offset;
+		set = 32 - bit;
+		p++;
+	}
+	/*
+	 * No zero yet, search remaining full bytes for a zero
+	 */
+	res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
+	return (offset + set + res);
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned long
+ffz(unsigned long word)
+{
+	__asm__("bsfl %1,%0"
+		:"=r" (word)
+		:"r" (~word));
+	return word;
+}
+
+/*
+ * memscan() taken from linux asm/string.h
+ */
+/*
+ * find the first occurrence of byte 'c', or 1 past the area if none
+ */
+static __inline__ char *
+memscan(void *addr, unsigned char c, int size)
+{
+        if (!size)
+                return addr;
+        __asm__("			\n\
+		cld			\n\
+                repnz; scasb		\n\
+                jnz 1f			\n\
+                dec %%edi		\n\
+1:              "
+                : "=D" (addr), "=c" (size)
+                : "0" (addr), "1" (size), "a" (c));
+        return addr;
+}
+
+#endif /* _VFS_GNU_EXT2FS_I386_BITOPS_H_ */
diff --git a/sys/gnu/vfs/ext2fs/inode.h b/sys/gnu/vfs/ext2fs/inode.h
new file mode 100644
index 0000000..84c6d9b
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/inode.h
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1982, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)inode.h	8.9 (Berkeley) 5/14/95
+ * $FreeBSD: src/sys/ufs/ufs/inode.h,v 1.28.2.2 2001/09/29 12:52:52 iedowse Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_INODE_H_
+#define	_VFS_GNU_EXT2FS_INODE_H_
+
+#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
+
+#ifndef _SYS_LOCK_H_
+#include <sys/lock.h>
+#endif
+#ifndef _SYS_LOCKF_H
+#include <sys/lockf.h>
+#endif
+
+#endif
+
+#ifndef _SYS_QUEUE_H_
+#include <sys/queue.h>
+#endif
+#include "dinode.h"
+
+/*
+ * The size of a logical block number.
+ */
+typedef long ext2_lbn_t;
+
+/*
+ * This must agree with the definition in "dir.h"
+ */
+#define	doff_t		int32_t
+
+#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
+
+/*
+ * An EXT2FS inode is basically a UFS inode with some spare fields
+ * redefined and a different superblock structure.
+ */
+struct inode {
+	struct inode	*i_next;/* Hash chain */
+	struct	vnode  *i_vnode;/* Vnode associated with this inode. */
+	struct	vnode  *i_devvp;/* Vnode for block I/O. */
+	uint32_t i_flag;	/* flags, see below */
+	cdev_t	  i_dev;	/* Device associated with the inode. */
+	ino_t	  i_number;	/* The identity of the inode. */
+	int	  i_effnlink;	/* i_nlink when I/O completes */
+
+	struct	ext2_sb_info *i_e2fs;	/* EXT2FS */
+	struct	 ext2_dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
+	u_quad_t i_modrev;	/* Revision level for NFS lease. */
+	struct	 lockf i_lockf;/* Head of byte-level lock list. */
+	/*
+	 * Side effects; used during directory lookup.
+	 */
+	int32_t	  i_count;	/* Size of free slot in directory. */
+	doff_t	  i_endoff;	/* End of useful stuff in directory. */
+	doff_t	  i_diroff;	/* Offset in dir, where we found last entry. */
+	doff_t	  i_offset;	/* Offset of free space in directory. */
+	ino_t	  i_ino;	/* Inode number of found directory. */
+	uint32_t i_reclen;	/* Size of found directory entry. */
+	uint32_t i_spare[3];	/* XXX actually non-spare (for ext2fs). */
+
+	struct dirhash *i_dirhash; /* Hashing for large directories */
+	/*
+	 * The on-disk dinode itself (128 bytes)
+	 */
+	struct	ext2_dinode i_din;
+};
+
+#ifndef NO_I_DEFINES
+
+#define	i_atime		i_din.di_atime
+#define	i_atimensec	i_din.di_atimensec
+#define	i_blocks	i_din.di_blocks
+#define	i_ctime		i_din.di_ctime
+#define	i_ctimensec	i_din.di_ctimensec
+#define	i_db		i_din.di_db
+#define	i_flags		i_din.di_flags
+#define	i_gen		i_din.di_gen
+#define	i_gid		i_din.di_gid
+#define	i_ib		i_din.di_ib
+#define	i_mode		i_din.di_mode
+#define	i_mtime		i_din.di_mtime
+#define	i_mtimensec	i_din.di_mtimensec
+#define	i_nlink		i_din.di_nlink
+#define	i_rdev		i_din.di_rdev
+#define	i_shortlink	i_din.di_shortlink
+#define	i_size		i_din.di_size
+#define	i_uid		i_din.di_uid
+
+#endif
+
+#endif
+
+/* These flags are kept in i_flag. */
+#define	IN_ACCESS	0x0001		/* Access time update request. */
+#define	IN_CHANGE	0x0002		/* Inode change time update request. */
+#define	IN_UPDATE	0x0004		/* Modification time update request. */
+#define	IN_MODIFIED	0x0008		/* Inode has been modified. */
+#define	IN_RENAME	0x0010		/* Inode is being renamed. */
+#define	IN_SHLOCK	0x0020		/* File has shared lock. */
+#define	IN_EXLOCK	0x0040		/* File has exclusive lock. */
+#define	IN_HASHED	0x0080		/* Inode is on hash list */
+#define	IN_LAZYMOD	0x0100		/* Modified, but don't write yet. */
+
+#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
+
+/*
+ * Structure used to pass around logical block paths generated by
+ * ext2_getlbns and used by truncate and bmap code.
+ */
+struct indir {
+	ext2_daddr_t in_lbn;		/* Logical block number. */
+	int	in_off;			/* Offset in buffer. */
+	int	in_exists;		/* Flag if the block exists. */
+};
+
+/* Convert between inode pointers and vnode pointers. */
+#define VTOI(vp)	((struct inode *)(vp)->v_data)
+#define ITOV(ip)	((ip)->i_vnode)
+
+/* Determine if soft dependencies are being done */
+#define DOINGSOFTDEP(vp)	((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
+#define DOINGASYNC(vp)		((vp)->v_mount->mnt_flag & MNT_ASYNC)
+
+/* This overlays the fid structure (see mount.h). */
+struct ufid {
+	uint16_t ufid_len;	/* Length of structure. */
+	uint16_t ufid_pad;	/* Force 32-bit alignment. */
+	ino_t	  ufid_ino;	/* File number (ino). */
+	int32_t	  ufid_gen;	/* Generation number. */
+};
+#endif /* _KERNEL || _KERNEL_STRUCTURES */
+
+#endif /* !_VFS_GNU_EXT2FS_INODE_H_ */
diff --git a/sys/gnu/vfs/ext2fs/quota.h b/sys/gnu/vfs/ext2fs/quota.h
new file mode 100644
index 0000000..e31e0fa
--- /dev/null
+++ b/sys/gnu/vfs/ext2fs/quota.h
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Elz at The University of Melbourne.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)quota.h	8.3 (Berkeley) 8/19/94
+ * $FreeBSD: src/sys/ufs/ufs/quota.h,v 1.15.2.1 2003/02/27 12:04:13 das Exp $
+ */
+
+#ifndef _VFS_GNU_EXT2FS_QUOTA_H_
+#define	_VFS_GNU_EXT2FS_QUOTA_H_
+
+/*
+ * Definitions for disk quotas imposed on the average user
+ * (big brother finally hits UNIX).
+ *
+ * The following constants define the amount of time given a user before the
+ * soft limits are treated as hard limits (usually resulting in an allocation
+ * failure). The timer is started when the user crosses their soft limit, it
+ * is reset when they go below their soft limit.
+ */
+#define	MAX_IQ_TIME	(7*24*60*60)	/* seconds in 1 week */
+#define	MAX_DQ_TIME	(7*24*60*60)	/* seconds in 1 week */
+
+/*
+ * The following constants define the usage of the quota file array in the
+ * ext2mount structure and dquot array in the inode structure.  The semantics
+ * of the elements of these arrays are defined in the routine getinoquota;
+ * the remainder of the quota code treats them generically and need not be
+ * inspected when changing the size of the array.
+ */
+#define	MAXQUOTAS	2
+#define	USRQUOTA	0	/* element used for user quotas */
+#define	GRPQUOTA	1	/* element used for group quotas */
+
+/*
+ * Definitions for the default names of the quotas files.
+ */
+#define INITQFNAMES { \
+	"user",		/* USRQUOTA */ \
+	"group",	/* GRPQUOTA */ \
+	"undefined", \
+}
+#define	QUOTAFILENAME	"quota"
+#define	QUOTAGROUP	"operator"
+
+/*
+ * Command definitions for the 'quotactl' system call.  The commands are
+ * broken into a main command defined below and a subcommand that is used
+ * to convey the type of quota that is being manipulated (see above).
+ */
+#define SUBCMDMASK	0x00ff
+#define SUBCMDSHIFT	8
+#define	QCMD(cmd, type)	(((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define	Q_QUOTAON	0x0100	/* enable quotas */
+#define	Q_QUOTAOFF	0x0200	/* disable quotas */
+#define	Q_GETQUOTA	0x0300	/* get limits and usage */
+#define	Q_SETQUOTA	0x0400	/* set limits and usage */
+#define	Q_SETUSE	0x0500	/* set usage */
+#define	Q_SYNC		0x0600	/* sync disk copy of a filesystems quotas */
+
+/*
+ * The following structure defines the format of the disk quota file
+ * (as it appears on disk) - the file is an array of these structures
+ * indexed by user or group number.  The setquota system call establishes
+ * the vnode for each quota file (a pointer is retained in the ext2mount
+ * structure).
+ */
+struct ext2_dqblk {
+	uint32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
+	uint32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
+	uint32_t dqb_curblocks;	/* current block count */
+	uint32_t dqb_ihardlimit;	/* maximum # allocated inodes + 1 */
+	uint32_t dqb_isoftlimit;	/* preferred inode limit */
+	uint32_t dqb_curinodes;	/* current # allocated inodes */
+	time_t	  dqb_btime;		/* time limit for excessive disk use */
+	time_t	  dqb_itime;		/* time limit for excessive files */
+};
+
+#ifdef _KERNEL
+
+#include <sys/queue.h>
+
+/*
+ * The following structure records disk usage for a user or group on a
+ * filesystem. There is one allocated for each quota that exists on any
+ * filesystem for the current user or group. A cache is kept of recently
+ * used entries.
+ */
+struct ext2_dquot {
+	LIST_ENTRY(ext2_dquot) dq_hash;	/* hash list */
+	TAILQ_ENTRY(ext2_dquot) dq_freelist;	/* free list */
+	uint16_t dq_flags;		/* flags, see below */
+	uint16_t dq_type;		/* quota type of this dquot */
+	uint32_t dq_cnt;		/* count of active references */
+	uint32_t dq_id;		/* identifier this applies to */
+	struct	ext2mount *dq_ump;	/* filesystem that this is taken from */
+	struct	ext2_dqblk dq_dqb;	/* actual usage & quotas */
+};
+/*
+ * Flag values.
+ */
+#define	DQ_LOCK		0x01		/* this quota locked (no MODS) */
+#define	DQ_WANT		0x02		/* wakeup on unlock */
+#define	DQ_MOD		0x04		/* this quota modified since read */
+#define	DQ_FAKE		0x08		/* no limits here, just usage */
+#define	DQ_BLKS		0x10		/* has been warned about blk limit */
+#define	DQ_INODS	0x20		/* has been warned about inode limit */
+/*
+ * Shorthand notation.
+ */
+#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
+#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
+#define	dq_curblocks	dq_dqb.dqb_curblocks
+#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
+#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
+#define	dq_curinodes	dq_dqb.dqb_curinodes
+#define	dq_btime	dq_dqb.dqb_btime
+#define	dq_itime	dq_dqb.dqb_itime
+
+/*
+ * If the system has never checked for a quota for this file, then it is
+ * set to NODQUOT.  Once a write attempt is made the inode pointer is set
+ * to reference a dquot structure.
+ */
+#define	NODQUOT		NULL
+
+/*
+ * Flags to ext2_chkdq() and ext2_chkiq()
+ */
+#define	FORCE	0x01	/* force usage changes independent of limits */
+#define	CHOWN	0x02	/* (advisory) change initiated by chown */
+
+/*
+ * Macros to avoid subroutine calls to trivial functions.
+ */
+#ifdef DIAGNOSTIC
+#define	DQREF(dq)	ext2_dqref(dq)
+#else
+#define	DQREF(dq)	(dq)->dq_cnt++
+#endif
+
+struct inode;
+struct mount;
+struct proc;
+struct thread;
+struct ucred;
+struct vnode;
+
+int	ext2_chkdq(struct inode *, long, struct ucred *, int);
+int	ext2_chkiq(struct inode *, long, struct ucred *, int);
+void	ext2_dqinit(void);
+void	ext2_dqrele(struct vnode *, struct ext2_dquot *);
+int	ext2_getinoquota(struct inode *);
+int	ext2_getquota(struct mount *, u_long, int, caddr_t);
+int	ext2_qsync(struct mount *mp);
+int	ext2_quotaoff(struct mount *, int);
+int	ext2_quotaon(struct ucred *, struct mount *, int, caddr_t);
+int	ext2_setquota(struct mount *, u_long, int, caddr_t);
+int	ext2_setuse(struct mount *, u_long, int, caddr_t);
+int	ext2_quotactl(struct mount *, int, uid_t, caddr_t, struct ucred *);
+
+#else /* !_KERNEL */
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int	quotactl(const char *, int, int, void *);
+__END_DECLS
+
+#endif /* _KERNEL */
+
+#endif /* !_VFS_GNU_EXT2FS_QUOTA_H_ */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 4a0c972..f7be114 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -37,7 +37,6 @@
  *
  *	@(#)param.h	8.3 (Berkeley) 4/4/95
  * $FreeBSD: src/sys/sys/param.h,v 1.61.2.38 2003/05/22 17:12:01 fjoe Exp $
- * $DragonFly: src/sys/sys/param.h,v 1.53 2008/11/11 00:55:49 pavalos Exp $
  */
 
 #ifndef _SYS_PARAM_H_
@@ -81,9 +80,10 @@
  * 201100 - 2.11 master
  * 201200 - 2.12 release
  * 201300 - 2.13 master
+ * 201301 - header rename: <vfs/gnu/ext2fs/...> -> <gnu/vfs/ext2fs/...>
  */
 #undef __DragonFly_version
-#define __DragonFly_version 201300	/* propagated to newvers */
+#define __DragonFly_version 201301	/* propagated to newvers */
 
 #include <sys/_null.h>
 
diff --git a/sys/vfs/Makefile b/sys/vfs/Makefile
index 7cd1e26..3fc072d 100644
--- a/sys/vfs/Makefile
+++ b/sys/vfs/Makefile
@@ -1,8 +1,7 @@
 # Makefile for vfs modules
 #
-# $DragonFly: src/sys/vfs/Makefile,v 1.8 2008/07/17 00:16:14 swildner Exp $
 
-SUBDIR=fifofs msdosfs portal gnu nfs procfs \
+SUBDIR=fifofs msdosfs portal nfs procfs \
 	hpfs ntfs smbfs isofs fdesc mfs nwfs udf \
 	nullfs hammer tmpfs
 
diff --git a/sys/vfs/gnu/Makefile b/sys/vfs/gnu/Makefile
deleted file mode 100644
index 8e569a0..0000000
--- a/sys/vfs/gnu/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# $DragonFly: src/sys/vfs/gnu/Makefile,v 1.1 2003/08/15 07:26:15 dillon Exp $
-#
-
-SUBDIR=ext2fs
-
-.include <bsd.subdir.mk>
diff --git a/sys/vfs/gnu/ext2fs/COPYRIGHT.INFO b/sys/vfs/gnu/ext2fs/COPYRIGHT.INFO
deleted file mode 100644
index 1b2be1a..0000000
--- a/sys/vfs/gnu/ext2fs/COPYRIGHT.INFO
+++ /dev/null
@@ -1,57 +0,0 @@
-$FreeBSD: src/sys/gnu/ext2fs/COPYRIGHT.INFO,v 1.3 2000/01/01 11:27:50 bde Exp $
-$DragonFly: src/sys/vfs/gnu/ext2fs/COPYRIGHT.INFO,v 1.3 2006/04/04 17:34:32 dillon Exp $
-
-Most of the files in this directory are written by Godmar Back or modified
-by him using the CSRG sources.  Those files are covered by the Berkeley-style
-copyright.  However the following files are covered by GPL.  Since the policy
-of the FreeBSD project is to keep the files with the more restrictive
-copyright in the gnu tree and it is a good idea to keep the filesystem code
-all together, the EXT2FS in its entirety resides under the gnu tree.  Note
-that only the files below are under the GPL.  In the eventuality that these
-files are redesigned or rewritten, this tree can be moved back into the less
-restrictive FreeBSD tree.
-
-	ext2_bitmap.c		(in the cvs attic)
-	ext2_fs.h
-	ext2_fs_i.h
-	ext2_fs_sb.h
-	ext2_linux_balloc.c
-	ext2_linux_ialloc.c
-	ext2_super.c		(in the cvs attic)
-	ext2_vfsops.c		(has some GPL'ed code from ext2_super.c)
-	i386-bitops.h
-
-PS.
-	THANKS GODMAR!!!
-
-Note that this port has been modified by John Dyson and others on
-the FreeBSD team, and it is best to send the bug reports to the FreeBSD
-team.  If there are any non-FreeBSD specific bugs, fixes will be sent to
-Godmar to help him fix the original code base.  It is also our intention
-to send Godmar any FreeBSD specific porting changes so that he can keep
-control of his code....
-
-John
-dyson@freebsd.org
-
-		-----------------------------------------
-				04 April 2006
-
-    EXT2 has been divorced from UFS.  The following files have been copied
-    from the UFS tree and renamed:
-
-	dinode.h
-	dir.h
-	ext2_bmap.c
-	ext2_ihash.c
-	ext2_quota.c
-	ext2mount.h
-	inode.h
-	quota.h
-
-    In addition, all other UFS procedures that EXT2 used to call,
-    especially in ext2_vnops.c and ext2_vfsops.c, have been copied from
-    the UFS tree into the EXT2 tree and renamed.
-
-				Matthew Dillon <dillon@apollo.backplane.com>
-
diff --git a/sys/vfs/gnu/ext2fs/Makefile b/sys/vfs/gnu/ext2fs/Makefile
deleted file mode 100644
index 4e6f8c2..0000000
--- a/sys/vfs/gnu/ext2fs/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD: src/sys/modules/ext2fs/Makefile,v 1.4.2.1 2002/08/06 14:14:25 mdodd Exp $
-
-KMOD=	ext2fs
-SRCS=	opt_ddb.h opt_quota.h opt_suiddir.h \
-	ext2_alloc.c ext2_balloc.c ext2_inode.c ext2_inode_cnv.c \
-	ext2_linux_balloc.c ext2_linux_ialloc.c ext2_lookup.c \
-	ext2_subr.c ext2_vfsops.c ext2_vnops.c ext2_bmap.c \
-	ext2_ihash.c ext2_quota.c
-
-.include <bsd.kmod.mk>
diff --git a/sys/vfs/gnu/ext2fs/dinode.h b/sys/vfs/gnu/ext2fs/dinode.h
deleted file mode 100644
index e9e04df..0000000
--- a/sys/vfs/gnu/ext2fs/dinode.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * Copyright (c) 1982, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)dinode.h	8.3 (Berkeley) 1/21/94
- * $FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.7 1999/08/28 00:52:27 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/dinode.h,v 1.3 2006/09/10 01:26:40 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_DINODE_H_
-#define _VFS_GNU_EXT2FS_DINODE_H_
-
-typedef __uint32_t	ext2_ino_t;
-
-/*
- * The root inode is the root of the filesystem.  Inode 0 can't be used for
- * normal purposes and historically bad blocks were linked to inode 1, thus
- * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
- * numerous dump tapes make this assumption, so we are stuck with it).
- */
-#define	ROOTINO	((ino_t)2)
-
-/*
- * The Whiteout inode# is a dummy non-zero inode number which will
- * never be allocated to a real file.  It is used as a place holder
- * in the directory entry which has been tagged as a DT_W entry.
- * See the comments about ROOTINO above.
- */
-#define	WINO	((ino_t)1)
-
-/*
- * A dinode contains all the meta-data associated with a EXT2 file.
- * This structure defines the on-disk format of a dinode. Since
- * this structure describes an on-disk structure, all its fields
- * are defined by types with precise widths.
- */
-
-typedef __int32_t       ext2_daddr_t;
-
-#define	NDADDR	12			/* Direct addresses in inode. */
-#define	NIADDR	3			/* Indirect addresses in inode. */
-
-struct ext2_dinode {
-	uint16_t	di_mode;	/*   0: IFMT, permissions; see below. */
-	int16_t		di_nlink;	/*   2: File link count. */
-	union {
-		uint16_t oldids[2];	/*   4: Ffs: old user and group ids. */
-		int32_t	  inumber;	/*   4: Lfs: inode number. */
-	} di_u;
-	uint64_t	di_size;	/*   8: File byte count. */
-	int32_t		di_atime;	/*  16: Last access time. */
-	int32_t		di_atimensec;	/*  20: Last access time. */
-	int32_t		di_mtime;	/*  24: Last modified time. */
-	int32_t		di_mtimensec;	/*  28: Last modified time. */
-	int32_t		di_ctime;	/*  32: Last inode change time. */
-	int32_t		di_ctimensec;	/*  36: Last inode change time. */
-	ext2_daddr_t	di_db[NDADDR];	/*  40: Direct disk blocks. */
-	ext2_daddr_t	di_ib[NIADDR];	/*  88: Indirect disk blocks. */
-	uint32_t	di_flags;	/* 100: Status flags (chflags). */
-	int32_t		di_blocks;	/* 104: Blocks actually held. */
-	int32_t		di_gen;		/* 108: Generation number. */
-	uint32_t	di_uid;		/* 112: File owner. */
-	uint32_t	di_gid;		/* 116: File group. */
-	int32_t		di_spare[2];	/* 120: used by ext2fs */
-};
-
-/*
- * The di_db fields may be overlaid with other information for
- * file types that do not have associated disk storage. Block
- * and character devices overlay the first data block with their
- * cdev_t value. Short symbolic links place their path in the
- * di_db area.
- */
-#define	di_inumber	di_u.inumber
-#define	di_ogid		di_u.oldids[1]
-#define	di_ouid		di_u.oldids[0]
-#define	di_rdev		di_db[0]
-#define	di_shortlink	di_db
-#define	MAXSYMLINKLEN	((NDADDR + NIADDR) * sizeof(ext2_daddr_t))
-
-/* File permissions. */
-#define	IEXEC		0000100		/* Executable. */
-#define	IWRITE		0000200		/* Writeable. */
-#define	IREAD		0000400		/* Readable. */
-#define	ISVTX		0001000		/* Sticky bit. */
-#define	ISGID		0002000		/* Set-gid. */
-#define	ISUID		0004000		/* Set-uid. */
-
-/* File types. */
-#define	IFMT		0170000		/* Mask of file type. */
-#define	IFIFO		0010000		/* Named pipe (fifo). */
-#define	IFCHR		0020000		/* Character device. */
-#define	IFDIR		0040000		/* Directory file. */
-#define	IFBLK		0060000		/* Block device. */
-#define	IFREG		0100000		/* Regular file. */
-#define	IFLNK		0120000		/* Symbolic link. */
-#define	IFSOCK		0140000		/* UNIX domain socket. */
-#define	IFWHT		0160000		/* Whiteout. */
-
-#endif /* !_VFS_GNU_EXT2FS_DINODE_H_ */
diff --git a/sys/vfs/gnu/ext2fs/dir.h b/sys/vfs/gnu/ext2fs/dir.h
deleted file mode 100644
index 09f952e..0000000
--- a/sys/vfs/gnu/ext2fs/dir.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)dir.h	8.2 (Berkeley) 1/21/94
- * $FreeBSD: src/sys/ufs/ufs/dir.h,v 1.9 1999/08/28 00:52:27 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/dir.h,v 1.1 2006/04/04 17:34:32 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_DIR_H_
-#define	_VFS_GNU_EXT2FS_DIR_H_
-
-/*
- * Theoretically, directories can be more than 2Gb in length, however, in
- * practice this seems unlikely. So, we define the type doff_t as a 32-bit
- * quantity to keep down the cost of doing lookup on a 32-bit machine.
- */
-#define	doff_t		int32_t
-#define MAXDIRSIZE	(0x7fffffff)
-
-/*
- * A directory consists of some number of blocks of DIRBLKSIZ
- * bytes, where DIRBLKSIZ is chosen such that it can be transferred
- * to disk in a single atomic operation (e.g. 512 bytes on most machines).
- *
- * Each DIRBLKSIZ byte block contains some number of directory entry
- * structures, which are of variable length.  Each directory entry has
- * a struct direct at the front of it, containing its inode number,
- * the length of the entry, and the length of the name contained in
- * the entry.  These are followed by the name padded to a 4 byte boundary
- * with null bytes.  All names are guaranteed null terminated.
- * The maximum length of a name in a directory is MAXNAMLEN.
- *
- * The macro DIRSIZ(fmt, dp) gives the amount of space required to represent
- * a directory entry.  Free space in a directory is represented by
- * entries which have dp->d_reclen > DIRSIZ(fmt, dp).  All DIRBLKSIZ bytes
- * in a directory block are claimed by the directory entries.  This
- * usually results in the last entry in a directory having a large
- * dp->d_reclen.  When entries are deleted from a directory, the
- * space is returned to the previous entry in the same directory
- * block by increasing its dp->d_reclen.  If the first entry of
- * a directory block is free, then its dp->d_ino is set to 0.
- * Entries other than the first in a directory do not normally have
- * dp->d_ino set to 0.
- */
-#define DIRBLKSIZ	DEV_BSIZE
-#define	MAXNAMLEN	255
-
-struct	direct {
-	uint32_t d_ino;		/* inode number of entry */
-	uint16_t d_reclen;		/* length of this record */
-	uint8_t  d_type; 		/* file type, see below */
-	uint8_t  d_namlen;		/* length of string in d_name */
-	char	  d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
-};
-
-/*
- * File types
- */
-#define	DT_UNKNOWN	 0
-#define	DT_FIFO		 1
-#define	DT_CHR		 2
-#define	DT_DIR		 4
-#define	DT_BLK		 6
-#define	DT_REG		 8
-#define	DT_LNK		10
-#define	DT_SOCK		12
-#define	DT_WHT		14
-
-/*
- * Convert between stat structure types and directory types.
- */
-#define	IFTODT(mode)	(((mode) & 0170000) >> 12)
-#define	DTTOIF(dirtype)	((dirtype) << 12)
-
-/*
- * The DIRSIZ macro gives the minimum record length which will hold
- * the directory entry.  This requires the amount of space in struct direct
- * without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- *
- * 
- */
-#define	DIRECTSIZ(namlen)						\
-	(((int)&((struct direct *)0)->d_name +				\
-	  ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3)
-#if (BYTE_ORDER == LITTLE_ENDIAN)
-#define DIRSIZ(oldfmt, dp) \
-    ((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
-#else
-#define DIRSIZ(oldfmt, dp) \
-    DIRECTSIZ((dp)->d_namlen)
-#endif
-#define OLDDIRFMT	1
-#define NEWDIRFMT	0
-
-/*
- * Template for manipulating directories.  Should use struct direct's,
- * but the name field is MAXNAMLEN - 1, and this just won't do.
- */
-struct dirtemplate {
-	uint32_t	dot_ino;
-	int16_t		dot_reclen;
-	uint8_t	dot_type;
-	uint8_t	dot_namlen;
-	char		dot_name[4];	/* must be multiple of 4 */
-	uint32_t	dotdot_ino;
-	int16_t		dotdot_reclen;
-	uint8_t	dotdot_type;
-	uint8_t	dotdot_namlen;
-	char		dotdot_name[4];	/* ditto */
-};
-
-/*
- * This is the old format of directories, sanz type element.
- */
-struct odirtemplate {
-	uint32_t	dot_ino;
-	int16_t		dot_reclen;
-	uint16_t	dot_namlen;
-	char		dot_name[4];	/* must be multiple of 4 */
-	uint32_t	dotdot_ino;
-	int16_t		dotdot_reclen;
-	uint16_t	dotdot_namlen;
-	char		dotdot_name[4];	/* ditto */
-};
-#endif /* _VFS_GNU_EXT2FS_DIR_H_ */
diff --git a/sys/vfs/gnu/ext2fs/ext2_alloc.c b/sys/vfs/gnu/ext2fs/ext2_alloc.c
deleted file mode 100644
index a8361bc..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_alloc.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ext2_alloc.c	8.8 (Berkeley) 2/21/94
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_alloc.c,v 1.28.2.2 2002/07/01 00:18:51 iedowse Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_alloc.c,v 1.13 2006/12/23 00:41:29 swildner Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/vnode.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <sys/syslog.h>
-
-#include <machine/inttypes.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "ext2mount.h"
-
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-#include "ext2_extern.h"
-
-static void	ext2_fserr (struct ext2_sb_info *, u_int, char *);
-
-/*
- * Linux calls this functions at the following locations:
- * (1) the inode is freed
- * (2) a preallocation miss occurs
- * (3) truncate is called
- * (4) release_file is called and f_mode & 2
- *
- * I call it in ext2_inactive, ext2_truncate, ext2_vfree and in (2)
- * the call in vfree might be redundant
- */
-void
-ext2_discard_prealloc(struct inode *ip)
-{
-#ifdef EXT2_PREALLOCATE
-        if (ip->i_prealloc_count) {
-                int i = ip->i_prealloc_count;
-                ip->i_prealloc_count = 0;
-                ext2_free_blocks (ITOV(ip)->v_mount,
-                                  ip->i_prealloc_block,
-                                  i);
-        }
-#endif
-}
-
-/*
- * Allocate a block in the file system.
- * 
- * this takes the framework from ffs_alloc. To implement the
- * actual allocation, it calls ext2_new_block, the ported version
- * of the same Linux routine.
- *
- * we note that this is always called in connection with ext2_blkpref
- *
- * preallocation is done as Linux does it
- */
-int
-ext2_alloc(struct inode *ip, daddr_t lbn, daddr_t bpref, int size,
-	   struct ucred *cred, daddr_t *bnp)
-{
-	struct ext2_sb_info *fs;
-	daddr_t bno;
-#if QUOTA
-	int error;
-#endif
-	
-	*bnp = 0;
-	fs = ip->i_e2fs;
-#if DIAGNOSTIC
-	if ((u_int)size > fs->s_blocksize || blkoff(fs, size) != 0) {
-		kprintf("dev = %s, bsize = %lu, size = %d, fs = %s\n",
-		    devtoname(ip->i_dev), fs->s_blocksize, size, fs->fs_fsmnt);
-		panic("ext2_alloc: bad size");
-	}
-	if (cred == NOCRED)
-		panic("ext2_alloc: missing credential");
-#endif /* DIAGNOSTIC */
-	if (size == fs->s_blocksize && fs->s_es->s_free_blocks_count == 0)
-		goto nospace;
-	if (cred->cr_uid != 0 && 
-		fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count)
-		goto nospace;
-#if QUOTA
-	if ((error = ext2_chkdq(ip, (long)btodb(size), cred, 0)) != 0)
-		return (error);
-#endif
-	if (bpref >= fs->s_es->s_blocks_count)
-		bpref = 0;
-	/* call the Linux code */
-#ifdef EXT2_PREALLOCATE
-	/* To have a preallocation hit, we must
-	 * - have at least one block preallocated
-	 * - and our preferred block must have that block number or one below
-	 */
-        if (ip->i_prealloc_count &&
-            (bpref == ip->i_prealloc_block ||
-             bpref + 1 == ip->i_prealloc_block))
-        {
-                bno = ip->i_prealloc_block++;
-                ip->i_prealloc_count--;
-                /* ext2_debug ("preallocation hit (%lu/%lu).\n",
-                            ++alloc_hits, ++alloc_attempts); */
-
-		/* Linux gets, clears, and releases the buffer at this
-		   point - we don't have to that; we leave it to the caller
-		 */
-        } else {
-                ext2_discard_prealloc (ip);
-                /* ext2_debug ("preallocation miss (%lu/%lu).\n",
-                            alloc_hits, ++alloc_attempts); */
-                if (S_ISREG(ip->i_mode))
-                        bno = ext2_new_block
-                                (ITOV(ip)->v_mount, bpref,
-                                 &ip->i_prealloc_count,
-                                 &ip->i_prealloc_block);
-                else
-			bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, 
-					bpref, 0, 0);
-        }
-#else
-	bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, bpref, 0, 0);
-#endif
-
-	if (bno > 0) {
-		/* set next_alloc fields as done in block_getblk */
-		ip->i_next_alloc_block = lbn;
-		ip->i_next_alloc_goal = bno;
-
-		ip->i_blocks += btodb(size);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-		*bnp = bno;
-		return (0);
-	}
-#if QUOTA
-	/*
-	 * Restore user's disk quota because allocation failed.
-	 */
-	ext2_chkdq(ip, (long)-btodb(size), cred, FORCE);
-#endif
-nospace:
-	ext2_fserr(fs, cred->cr_uid, "file system full");
-	uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
-	return (ENOSPC);
-}
-
-/*
- * Reallocate a sequence of blocks into a contiguous sequence of blocks.
- *
- * The vnode and an array of buffer pointers for a range of sequential
- * logical blocks to be made contiguous is given. The allocator attempts
- * to find a range of sequential blocks starting as close as possible to
- * an fs_rotdelay offset from the end of the allocation for the logical
- * block immediately preceeding the current range. If successful, the
- * physical block numbers in the buffer pointers and in the inode are
- * changed to reflect the new allocation. If unsuccessful, the allocation
- * is left unchanged. The success in doing the reallocation is returned.
- * Note that the error return is not reflected back to the user. Rather
- * the previous block allocation will be used.
- */
-
-#ifdef FANCY_REALLOC
-#include <sys/sysctl.h>
-static int doasyncfree = 1;
-#ifdef	OPT_DEBUG
-SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
-#endif	/* OPT_DEBUG */
-#endif
-
-/*
- * ext2_reallocblks(struct vnode *a_vp, struct cluster_save *a_buflist)
- */
-int
-ext2_reallocblks(struct vop_reallocblks_args *ap)
-{
-#ifndef FANCY_REALLOC
-/* kprintf("ext2_reallocblks not implemented\n"); */
-return ENOSPC;
-#else
-
-	struct ext2_sb_info *fs;
-	struct inode *ip;
-	struct vnode *vp;
-	struct buf *sbp, *ebp;
-	daddr_t *bap, *sbap, *ebap;
-	struct cluster_save *buflist;
-	daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno;
-	struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
-	int i, len, start_lvl, end_lvl, pref, ssize;
-
-	vp = ap->a_vp;
-	ip = VTOI(vp);
-	fs = ip->i_e2fs;
-#ifdef UNKLAR
-	if (fs->fs_contigsumsize <= 0)
-		return (ENOSPC);
-#endif
-	buflist = ap->a_buflist;
-	len = buflist->bs_nchildren;
-	start_lbn = lblkno(fs, buflist->bs_children[0]->b_loffset);
-	end_lbn = start_lbn + len - 1;
-#if DIAGNOSTIC
-	for (i = 1; i < len; i++) {
-		if (buflist->bs_children[i]->b_loffset != lblktodoff(fs, start_lbn) + lblktodoff(fs, i))
-			panic("ext2_reallocblks: non-cluster");
-	}
-#endif
-	/*
-	 * If the latest allocation is in a new cylinder group, assume that
-	 * the filesystem has decided to move and do not force it back to
-	 * the previous cylinder group.
-	 */
-	if (dtog(fs, dofftofsb(fs, buflist->bs_children[0]->b_bio2.bio_offset)) !=
-	    dtog(fs, dofftofsb(fs, buflist->bs_children[len - 1]->b_bio2.bio_offset)))
-		return (ENOSPC);
-	if (ext2_getlbns(vp, start_lbn, start_ap, &start_lvl) ||
-	    ext2_getlbns(vp, end_lbn, end_ap, &end_lvl))
-		return (ENOSPC);
-	/*
-	 * Get the starting offset and block map for the first block.
-	 */
-	if (start_lvl == 0) {
-		sbap = &ip->i_db[0];
-		soff = start_lbn;
-	} else {
-		idp = &start_ap[start_lvl - 1];
-		if (bread(vp, lblktodoff(fs, idp->in_lbn), (int)fs->s_blocksize, NOCRED, &sbp)) {
-			brelse(sbp);
-			return (ENOSPC);
-		}
-		sbap = (daddr_t *)sbp->b_data;
-		soff = idp->in_off;
-	}
-	/*
-	 * Find the preferred location for the cluster.
-	 */
-	pref = ext2_blkpref(ip, start_lbn, soff, sbap);
-	/*
-	 * If the block range spans two block maps, get the second map.
-	 */
-	if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {
-		ssize = len;
-	} else {
-#if DIAGNOSTIC
-		if (start_ap[start_lvl-1].in_lbn == idp->in_lbn)
-			panic("ext2_reallocblk: start == end");
-#endif
-		ssize = len - (idp->in_off + 1);
-		if (bread(vp, lblktodoff(fs, idp->in_lbn), (int)fs->s_blocksize, NOCRED, &ebp))
-			goto fail;
-		ebap = (daddr_t *)ebp->b_data;
-	}
-	/*
-	 * Search the block map looking for an allocation of the desired size.
-	 */
-	if ((newblk = (daddr_t)ext2_hashalloc(ip, dtog(fs, pref), (long)pref,
-	    len, (u_long (*)())ext2_clusteralloc)) == 0)
-		goto fail;
-	/*
-	 * We have found a new contiguous block.
-	 *
-	 * First we have to replace the old block pointers with the new
-	 * block pointers in the inode and indirect blocks associated
-	 * with the file.
-	 */
-	blkno = newblk;
-	for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
-		if (i == ssize)
-			bap = ebap;
-#if DIAGNOSTIC
-		if (buflist->bs_children[i]->b_bio2.bio_offset != fsbtodoff(fs, *bap))
-			panic("ext2_reallocblks: alloc mismatch");
-#endif
-		*bap++ = blkno;
-	}
-	/*
-	 * Next we must write out the modified inode and indirect blocks.
-	 * For strict correctness, the writes should be synchronous since
-	 * the old block values may have been written to disk. In practise
-	 * they are almost never written, but if we are concerned about 
-	 * strict correctness, the `doasyncfree' flag should be set to zero.
-	 *
-	 * The test on `doasyncfree' should be changed to test a flag
-	 * that shows whether the associated buffers and inodes have
-	 * been written. The flag should be set when the cluster is
-	 * started and cleared whenever the buffer or inode is flushed.
-	 * We can then check below to see if it is set, and do the
-	 * synchronous write only when it has been cleared.
-	 */
-	if (sbap != &ip->i_db[0]) {
-		if (doasyncfree)
-			bdwrite(sbp);
-		else
-			bwrite(sbp);
-	} else {
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-		if (!doasyncfree)
-			EXT2_UPDATE(vp, 1);
-	}
-	if (ssize < len)
-		if (doasyncfree)
-			bdwrite(ebp);
-		else
-			bwrite(ebp);
-	/*
-	 * Last, free the old blocks and assign the new blocks to the buffers.
-	 */
-	for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) {
-		ext2_blkfree(ip, dofftofsb(fs, buflist->bs_children[i]->b_bio2.bio_offset),
-		    fs->s_blocksize);
-		buflist->bs_children[i]->b_bio2.bio_offset = fsbtodoff(fs, blkno);
-	}
-	return (0);
-
-fail:
-	if (ssize < len)
-		brelse(ebp);
-	if (sbap != &ip->i_db[0])
-		brelse(sbp);
-	return (ENOSPC);
-
-#endif /* FANCY_REALLOC */
-}
-
-/*
- * Allocate an inode in the file system.
- * 
- * we leave the actual allocation strategy to the (modified)
- * ext2_new_inode(), to make sure we get the policies right
- */
-int
-ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp)
-{
-	struct inode *pip;
-	struct ext2_sb_info *fs;
-	struct inode *ip;
-	ino_t ino;
-	int i, error;
-	
-	*vpp = NULL;
-	pip = VTOI(pvp);
-	fs = pip->i_e2fs;
-	if (fs->s_es->s_free_inodes_count == 0)
-		goto noinodes;
-
-	/* call the Linux routine - it returns the inode number only */
-	ino = ext2_new_inode(pip, mode);
-
-	if (ino == 0)
-		goto noinodes;
-	error = VFS_VGET(pvp->v_mount, NULL, ino, vpp);
-	if (error) {
-		EXT2_VFREE(pvp, ino, mode);
-		return (error);
-	}
-	ip = VTOI(*vpp);
-
-	/* 
-	  the question is whether using VGET was such good idea at all -
-	  Linux doesn't read the old inode in when it's allocating a
-	  new one. I will set at least i_size & i_blocks the zero. 
-	*/ 
-	ip->i_mode = 0;
-	ip->i_size = 0;
-	ip->i_blocks = 0;
-	ip->i_flags = 0;
-        /* now we want to make sure that the block pointers are zeroed out */
-        for (i = 0; i < NDADDR; i++)
-                ip->i_db[i] = 0;
-        for (i = 0; i < NIADDR; i++)
-                ip->i_ib[i] = 0;
-
-	/*
-	 * Set up a new generation number for this inode.
-	 * XXX check if this makes sense in ext2
-	 */
-	if (ip->i_gen == 0 || ++ip->i_gen == 0)
-		ip->i_gen = krandom() / 2 + 1;
-/*
-kprintf("ext2_valloc: allocated inode %d\n", ino);
-*/
-	return (0);
-noinodes:
-	ext2_fserr(fs, cred->cr_uid, "out of inodes");
-	uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
-	return (ENOSPC);
-}
-
-/*
- * Select the desired position for the next block in a file.  
- *
- * we try to mimic what Remy does in inode_getblk/block_getblk
- *
- * we note: blocknr == 0 means that we're about to allocate either
- * a direct block or a pointer block at the first level of indirection
- * (In other words, stuff that will go in i_db[] or i_ib[])
- *
- * blocknr != 0 means that we're allocating a block that is none
- * of the above. Then, blocknr tells us the number of the block
- * that will hold the pointer
- */
-daddr_t
-ext2_blkpref(struct inode *ip, daddr_t lbn, int indx, daddr_t *bap,
-	     daddr_t blocknr)
-{
-	int	tmp;
-
-	/*
-	 * if the next block is actually what we thought it is,
-	 * then set the goal to what we thought it should be
-	 */
-	if (ip->i_next_alloc_block == lbn && ip->i_next_alloc_goal != 0)
-		return ip->i_next_alloc_goal;
-
-	/* now check whether we were provided with an array that basically
-	   tells us previous blocks to which we want to stay closeby
-	*/
-	if(bap) 
-                for (tmp = indx - 1; tmp >= 0; tmp--) 
-			if (bap[tmp]) 
-				return bap[tmp];
-
-	/*
-	 * else let's fall back to the blocknr, or, if there is none,
-	 * follow the rule that a block should be allocated near its inode
-	 */
-	return blocknr ? blocknr :
-			(daddr_t)(ip->i_block_group * 
-			EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + 
-			ip->i_e2fs->s_es->s_first_data_block;
-}
-
-/*
- * Free a block or fragment.
- *
- * pass on to the Linux code
- */
-void
-ext2_blkfree(struct inode *ip, daddr_t bno, long size)
-{
-	struct ext2_sb_info *fs;
-
-	fs = ip->i_e2fs;
-	/*
-	 *	call Linux code with mount *, block number, count
-	 */
-	ext2_free_blocks(ITOV(ip)->v_mount, bno, size / fs->s_frag_size);
-}
-
-/*
- * Free an inode.
- *
- * the maintenance of the actual bitmaps is again up to the linux code
- */
-int
-ext2_vfree(struct vnode *pvp, ino_t ino, int mode)
-{
-	struct ext2_sb_info *fs;
-	struct inode *pip;
-	mode_t save_i_mode;
-
-	pip = VTOI(pvp);
-	fs = pip->i_e2fs;
-	if ((u_int)ino > fs->s_inodes_per_group * fs->s_groups_count)
-		panic("ext2_vfree: range: dev = (%d, %d), ino = %"PRId64", fs = %s",
-		    major(pip->i_dev), minor(pip->i_dev), ino, fs->fs_fsmnt);
-
-/* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, mode);
- */
-	ext2_discard_prealloc(pip);
-
-	/* we need to make sure that ext2_free_inode can adjust the
-	   used_dir_counts in the group summary information - I'd
-	   really like to know what the rationale behind this
-	   'set i_mode to zero to denote an unused inode' is
-	 */
-	save_i_mode = pip->i_mode;
-	pip->i_mode = mode;
-	ext2_free_inode(pip);	
-	pip->i_mode = save_i_mode;
-	return (0);
-}
-
-/*
- * Fserr prints the name of a file system with an error diagnostic.
- * 
- * The form of the error message is:
- *	fs: error message
- */
-static void
-ext2_fserr(struct ext2_sb_info *fs, u_int uid, char *cp)
-{
-	log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_balloc.c b/sys/vfs/gnu/ext2fs/ext2_balloc.c
deleted file mode 100644
index 66f37a7..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_balloc.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ffs_balloc.c	8.4 (Berkeley) 9/23/93
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_balloc.c,v 1.9.2.1 2000/08/03 00:52:57 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_balloc.c,v 1.10 2006/12/23 00:41:29 swildner Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/lock.h>
-#include <sys/ucred.h>
-#include <sys/vnode.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-#include "ext2_extern.h"
-
-/*
- * Balloc defines the structure of file system storage
- * by allocating the physical blocks on a device given
- * the inode and the logical block number in a file.
- */
-int
-ext2_balloc(struct inode *ip, daddr_t bn, int size, struct ucred *cred,
-	    struct buf **bpp, int flags)
-{
-	struct ext2_sb_info *fs;
-	daddr_t nb;
-	struct buf *bp, *nbp;
-	struct vnode *vp = ITOV(ip);
-	struct indir indirs[NIADDR + 2];
-	daddr_t newb, lbn, *bap, pref;
-	int osize, nsize, num, i, error;
-/*
-ext2_debug("ext2_balloc called (%d, %d, %d)\n", 
-	ip->i_number, (int)bn, (int)size);
-*/
-	*bpp = NULL;
-	if (bn < 0)
-		return (EFBIG);
-	fs = ip->i_e2fs;
-	lbn = bn;
-
-	/*
-	 * check if this is a sequential block allocation. 
-	 * If so, increment next_alloc fields to allow ext2_blkpref 
-	 * to make a good guess
-	 */
-        if (lbn == ip->i_next_alloc_block + 1) {
-		ip->i_next_alloc_block++;
-		ip->i_next_alloc_goal++;
-	}
-
-	/*
-	 * The first NDADDR blocks are direct blocks
-	 */
-	if (bn < NDADDR) {
-		nb = ip->i_db[bn];
-		/* no new block is to be allocated, and no need to expand
-		   the file */
-		if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) {
-			error = bread(vp, lblktodoff(fs, bn), 
-				      fs->s_blocksize, &bp);
-			if (error) {
-				brelse(bp);
-				return (error);
-			}
-			*bpp = bp;
-			return (0);
-		}
-		if (nb != 0) {
-			/*
-			 * Consider need to reallocate a fragment.
-			 */
-			osize = fragroundup(fs, blkoff(fs, ip->i_size));
-			nsize = fragroundup(fs, size);
-			if (nsize <= osize) {
-				error = bread(vp, lblktodoff(fs, bn),
-					      osize, &bp);
-				if (error) {
-					brelse(bp);
-					return (error);
-				}
-			} else {
-			/* Godmar thinks: this shouldn't happen w/o fragments */
-				kprintf("nsize %d(%d) > osize %d(%d) nb %d\n", 
-					(int)nsize, (int)size, (int)osize, 
-					(int)ip->i_size, (int)nb);
-				panic(
-				    "ext2_balloc: Something is terribly wrong");
-/*
- * please note there haven't been any changes from here on -
- * FFS seems to work.
- */
-			}
-		} else {
-			if (ip->i_size < (bn + 1) * fs->s_blocksize)
-				nsize = fragroundup(fs, size);
-			else
-				nsize = fs->s_blocksize;
-			error = ext2_alloc(ip, bn,
-			    ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0),
-			    nsize, cred, &newb);
-			if (error)
-				return (error);
-			bp = getblk(vp, lblktodoff(fs, bn), nsize, 0, 0);
-			bp->b_bio2.bio_offset = fsbtodoff(fs, newb);
-			if (flags & B_CLRBUF)
-				vfs_bio_clrbuf(bp);
-		}
-		ip->i_db[bn] = dofftofsb(fs, bp->b_bio2.bio_offset);
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-		*bpp = bp;
-		return (0);
-	}
-	/*
-	 * Determine the number of levels of indirection.
-	 */
-	pref = 0;
-	if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0)
-		return(error);
-#if DIAGNOSTIC
-	if (num < 1)
-		panic ("ext2_balloc: ext2_bmaparray returned indirect block");
-#endif
-	/*
-	 * Fetch the first indirect block allocating if necessary.
-	 */
-	--num;
-	nb = ip->i_ib[indirs[0].in_off];
-	if (nb == 0) {
-#if 0
-		pref = ext2_blkpref(ip, lbn, 0, NULL, 0);
-#else
-		/* see the comment by ext2_blkpref. What we do here is
-		   to pretend that it'd be good for a block holding indirect
-		   pointers to be allocated near its predecessor in terms 
-		   of indirection, or the last direct block. 
-		   We shamelessly exploit the fact that i_ib immediately
-		   follows i_db. 
-		   Godmar thinks it make sense to allocate i_ib[0] immediately
-		   after i_db[11], but it's not utterly clear whether this also
-		   applies to i_ib[1] and i_ib[0]
-		*/
-
-		pref = ext2_blkpref(ip, lbn, indirs[0].in_off + 
-					     EXT2_NDIR_BLOCKS, &ip->i_db[0], 0);
-#endif
-	        if ((error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize,
-		    cred, &newb)) != 0)
-			return (error);
-		nb = newb;
-		bp = getblk(vp, lblktodoff(fs, indirs[1].in_lbn),
-			    fs->s_blocksize, 0, 0);
-		bp->b_bio2.bio_offset = fsbtodoff(fs, newb);
-		vfs_bio_clrbuf(bp);
-		/*
-		 * Write synchronously so that indirect blocks
-		 * never point at garbage.
-		 */
-		if ((error = bwrite(bp)) != 0) {
-			ext2_blkfree(ip, nb, fs->s_blocksize);
-			return (error);
-		}
-		ip->i_ib[indirs[0].in_off] = newb;
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-	}
-	/*
-	 * Fetch through the indirect blocks, allocating as necessary.
-	 */
-	for (i = 1;;) {
-		error = bread(vp,
-			      lblktodoff(fs, indirs[i].in_lbn), 
-			      (int)fs->s_blocksize, &bp);
-		if (error) {
-			brelse(bp);
-			return (error);
-		}
-		bap = (daddr_t *)bp->b_data;
-		nb = bap[indirs[i].in_off];
-		if (i == num)
-			break;
-		i += 1;
-		if (nb != 0) {
-			brelse(bp);
-			continue;
-		}
-		if (pref == 0) 
-#if 1
-			/* see the comment above and by ext2_blkpref
-			 * I think this implements Linux policy, but
-			 * does it really make sense to allocate to
-			 * block containing pointers together ?
-			 * Also, will it ever succeed ?
-			 */
-			pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap,
-						lblkno(fs, bp->b_loffset));
-#else
-			pref = ext2_blkpref(ip, lbn, 0, NULL, 0);
-#endif
-		if ((error =
-		    ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) {
-			brelse(bp);
-			return (error);
-		}
-		nb = newb;
-		nbp = getblk(vp, lblktodoff(fs, indirs[i].in_lbn),
-			     fs->s_blocksize, 0, 0);
-		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
-		vfs_bio_clrbuf(nbp);
-		/*
-		 * Write synchronously so that indirect blocks
-		 * never point at garbage.
-		 */
-		if ((error = bwrite(nbp)) != 0) {
-			ext2_blkfree(ip, nb, fs->s_blocksize);
-			brelse(bp);
-			return (error);
-		}
-		bap[indirs[i - 1].in_off] = nb;
-		/*
-		 * If required, write synchronously, otherwise use
-		 * delayed write.
-		 */
-		if (flags & B_SYNC) {
-			bwrite(bp);
-		} else {
-			bdwrite(bp);
-		}
-	}
-	/*
-	 * Get the data block, allocating if necessary.
-	 */
-	if (nb == 0) {
-		pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0], 
-				lblkno(fs, bp->b_loffset));
-		if ((error = ext2_alloc(ip,
-		    lbn, pref, (int)fs->s_blocksize, cred, &newb)) != 0) {
-			brelse(bp);
-			return (error);
-		}
-		nb = newb;
-		nbp = getblk(vp, lblktodoff(fs, lbn), fs->s_blocksize, 0, 0);
-		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
-		if (flags & B_CLRBUF)
-			vfs_bio_clrbuf(nbp);
-		bap[indirs[i].in_off] = nb;
-		/*
-		 * If required, write synchronously, otherwise use
-		 * delayed write.
-		 */
-		if (flags & B_SYNC) {
-			bwrite(bp);
-		} else {
-			bdwrite(bp);
-		}
-		*bpp = nbp;
-		return (0);
-	}
-	brelse(bp);
-	if (flags & B_CLRBUF) {
-		error = bread(vp, lblktodoff(fs, lbn),
-			      (int)fs->s_blocksize, &nbp);
-		if (error) {
-			brelse(nbp);
-			return (error);
-		}
-	} else {
-		nbp = getblk(vp, lblktodoff(fs, lbn), fs->s_blocksize, 0, 0);
-		nbp->b_bio2.bio_offset = fsbtodoff(fs, nb);
-	}
-	*bpp = nbp;
-	return (0);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_bitops.h b/sys/vfs/gnu/ext2fs/ext2_bitops.h
deleted file mode 100644
index a11ab6e..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_bitops.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * Copyright (c) 2003 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/gnu/fs/ext2fs/ext2_bitops.h,v 1.3 2006/04/13 19:37:32 cracauer Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_bitops.h,v 1.1 2007/09/23 04:09:55 yanyh Exp $
- */
-
-#ifndef _SYS_GNU_EXT2FS_EXT2_BITOPS_H_
-#define _SYS_GNU_EXT2FS_EXT2_BITOPS_H_
-
-#define	find_first_zero_bit(data, sz)		find_next_zero_bit(data, sz, 0)
-
-static __inline int
-clear_bit(int no, void *data)
-{
-	uint32_t *p;
-	uint32_t mask, new, old;
-
-	p = (uint32_t*)data + (no >> 5);
-	mask = (1U << (no & 31));
-	do {
-		old = *p;
-		new = old & ~mask;
-	} while (!atomic_cmpset_32(p, old, new));
-	return (old & mask);
-}
-
-static __inline int
-set_bit(int no, void *data)
-{
-	uint32_t *p;
-	uint32_t mask, new, old;
-
-	p = (uint32_t*)data + (no >> 5);
-	mask = (1U << (no & 31));
-	do {
-		old = *p;
-		new = old | mask;
-	} while (!atomic_cmpset_32(p, old, new));
-	return (old & mask);
-}
-
-static __inline int
-test_bit(int no, void *data)
-{
-	uint32_t *p;
-	uint32_t mask;
-
-	p = (uint32_t*)data + (no >> 5);
-	mask = (1U << (no & 31));
-	return (*p & mask);
-}
-
-static __inline size_t
-find_next_zero_bit(void *data, size_t sz, size_t ofs)
-{
-	uint32_t *p;
-	uint32_t mask;
-	int bit;
-
-	p = (uint32_t*)data + (ofs >> 5);
-	if (ofs & 31) {
-		mask = ~0U << (ofs & 31);
-		bit = *p | ~mask;
-		if (bit != ~0U)
-			return (ffs(~bit) + ofs - 1);
-		p++;
-		ofs = (ofs + 31U) & ~31U;
-	}
-	while(ofs < sz && *p == ~0U) {
-		p++;
-		ofs += 32;
-	}
-	if (ofs == sz)
-		return (ofs);
-	bit = *p;
-	return (ffs(~bit) + ofs - 1);
-}
-
-static __inline void *
-memscan(void *data, int c, size_t sz)
-{
-	uint8_t *p;
-
-	p = data;
-	while (sz && *p != c) {
-		p++;
-		sz--;
-	}
-	return (p);
-}
-
-#endif /* _SYS_GNU_EXT2FS_EXT2_BITOPS_H_ */
diff --git a/sys/vfs/gnu/ext2fs/ext2_bmap.c b/sys/vfs/gnu/ext2fs/ext2_bmap.c
deleted file mode 100644
index cb98a75..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_bmap.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 1989, 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ufs_bmap.c	8.7 (Berkeley) 3/21/95
- * $FreeBSD: src/sys/ufs/ufs/ufs_bmap.c,v 1.34.2.1 2000/03/17 10:12:14 ps Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_bmap.c,v 1.4 2007/08/13 17:31:56 dillon Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/resourcevar.h>
-#include <sys/conf.h>
-
-#include "quota.h"
-#include "dinode.h"
-#include "inode.h"
-#include "ext2_fs_sb.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-#include "fs.h"
-
-static int ext2_bmaparray(struct vnode *vp, ext2_daddr_t bn,
-			  ext2_daddr_t *bnp, struct indir *ap, int *nump,
-			  int *runp, int *runb);
-
-/*
- * Bmap converts the logical block number of a file to its physical block
- * number on the disk. The conversion is done by using the logical block
- * number to index into the array of block pointers described by the dinode.
- *
- * BMAP must return the contiguous before and after run in bytes, inclusive
- * of the returned block.
- *
- * ext2_bmap(struct vnode *a_vp, off_t a_loffset,
- *	    off_t *a_doffsetp, int *a_runp, int *a_runb)
- */
-int
-ext2_bmap(struct vop_bmap_args *ap)
-{
-	struct ext2_sb_info *fs;
-	ext2_daddr_t lbn;
-	ext2_daddr_t dbn;
-	int error;
-
-	/*
-	 * Check for underlying vnode requests and ensure that logical
-	 * to physical mapping is requested.
-	 */
-	if (ap->a_doffsetp == NULL)
-		return (0);
-
-	fs = VTOI(ap->a_vp)->i_e2fs;
-	KKASSERT(((int)ap->a_loffset & ((1 << fs->s_bshift) - 1)) == 0);
-	lbn = ap->a_loffset >> fs->s_bshift;
-
-	error = ext2_bmaparray(ap->a_vp, lbn, &dbn, NULL, NULL,
-			      ap->a_runp, ap->a_runb);
-
-	if (error || dbn == (ext2_daddr_t)-1) {
-		*ap->a_doffsetp = NOOFFSET;
-	} else {
-		*ap->a_doffsetp = dbtodoff(fs, dbn);
-		if (ap->a_runp)
-			*ap->a_runp = (*ap->a_runp + 1) << fs->s_bshift;
-		if (ap->a_runb)
-			*ap->a_runb = *ap->a_runb << fs->s_bshift;
-	}
-	return (error);
-}
-
-/*
- * Indirect blocks are now on the vnode for the file.  They are given negative
- * logical block numbers.  Indirect blocks are addressed by the negative
- * address of the first data block to which they point.  Double indirect blocks
- * are addressed by one less than the address of the first indirect block to
- * which they point.  Triple indirect blocks are addressed by one less than
- * the address of the first double indirect block to which they point.
- *
- * ext2_bmaparray does the bmap conversion, and if requested returns the
- * array of logical blocks which must be traversed to get to a block.
- * Each entry contains the offset into that block that gets you to the
- * next block and the disk address of the block (if it is assigned).
- */
-static
-int
-ext2_bmaparray(struct vnode *vp, ext2_daddr_t bn, ext2_daddr_t *bnp,
-	      struct indir *ap, int *nump, int *runp, int *runb)
-{
-	struct inode *ip;
-	struct buf *bp;
-	struct ext2mount *ump;
-	struct mount *mp;
-	struct ext2_sb_info *fs;
-	struct indir a[NIADDR+1], *xap;
-	ext2_daddr_t daddr;
-	long metalbn;
-	int error, maxrun, num;
-
-	ip = VTOI(vp);
-	mp = vp->v_mount;
-	ump = VFSTOEXT2(mp);
-	fs = ip->i_e2fs;
-#ifdef DIAGNOSTIC
-	if ((ap != NULL && nump == NULL) || (ap == NULL && nump != NULL))
-		panic("ext2_bmaparray: invalid arguments");
-#endif
-
-	if (runp) {
-		*runp = 0;
-	}
-
-	if (runb) {
-		*runb = 0;
-	}
-
-	maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1;
-
-	xap = ap == NULL ? a : ap;
-	if (!nump)
-		nump = &num;
-	error = ext2_getlbns(vp, bn, xap, nump);
-	if (error)
-		return (error);
-
-	num = *nump;
-	if (num == 0) {
-		*bnp = blkptrtodb(ump, ip->i_db[bn]);
-		if (*bnp == 0)
-			*bnp = -1;
-		else if (runp) {
-			daddr_t bnb = bn;
-			for (++bn; bn < NDADDR && *runp < maxrun &&
-			    is_sequential(ump, ip->i_db[bn - 1], ip->i_db[bn]);
-			    ++bn, ++*runp);
-			bn = bnb;
-			if (runb && (bn > 0)) {
-				for (--bn; (bn >= 0) && (*runb < maxrun) &&
-					is_sequential(ump, ip->i_db[bn],
-						ip->i_db[bn+1]);
-						--bn, ++*runb);
-			}
-		}
-		return (0);
-	}
-
-
-	/* Get disk address out of indirect block array */
-	daddr = ip->i_ib[xap->in_off];
-
-	for (bp = NULL, ++xap; --num; ++xap) {
-		/*
-		 * Exit the loop if there is no disk address assigned yet and
-		 * the indirect block isn't in the cache, or if we were
-		 * looking for an indirect block and we've found it.
-		 */
-
-		metalbn = xap->in_lbn;
-		if ((daddr == 0 &&
-		     !findblk(vp, dbtodoff(fs, metalbn), FINDBLK_TEST)) ||
-		    metalbn == bn) {
-			break;
-		}
-		/*
-		 * If we get here, we've either got the block in the cache
-		 * or we have a disk address for it, go fetch it.
-		 */
-		if (bp)
-			bqrelse(bp);
-
-		xap->in_exists = 1;
-		bp = getblk(vp, lblktodoff(fs, metalbn),
-			    mp->mnt_stat.f_iosize, 0, 0);
-		if ((bp->b_flags & B_CACHE) == 0) {
-#ifdef DIAGNOSTIC
-			if (!daddr)
-				panic("ext2_bmaparray: indirect block not in cache");
-#endif
-			/*
-			 * This runs through ext2_strategy using bio2 to
-			 * cache the disk offset, then comes back through
-			 * bio1.  So we want to wait on bio1
-			 */
-			bp->b_bio1.bio_done = biodone_sync;
-			bp->b_bio1.bio_flags |= BIO_SYNC;
-			bp->b_bio2.bio_offset = fsbtodoff(fs, daddr);
-			bp->b_flags &= ~(B_INVAL|B_ERROR);
-			bp->b_cmd = BUF_CMD_READ;
-			vfs_busy_pages(bp->b_vp, bp);
-			vn_strategy(bp->b_vp, &bp->b_bio1);
-			error = biowait(&bp->b_bio1, "biord");
-			if (error) {
-				brelse(bp);
-				return (error);
-			}
-		}
-
-		daddr = ((ext2_daddr_t *)bp->b_data)[xap->in_off];
-		if (num == 1 && daddr && runp) {
-			for (bn = xap->in_off + 1;
-			    bn < MNINDIR(ump) && *runp < maxrun &&
-			    is_sequential(ump,
-			    ((ext2_daddr_t *)bp->b_data)[bn - 1],
-			    ((ext2_daddr_t *)bp->b_data)[bn]);
-			    ++bn, ++*runp);
-			bn = xap->in_off;
-			if (runb && bn) {
-				for(--bn; bn >= 0 && *runb < maxrun &&
-			    		is_sequential(ump, ((daddr_t *)bp->b_data)[bn],
-					    ((daddr_t *)bp->b_data)[bn+1]);
-			    		--bn, ++*runb);
-			}
-		}
-	}
-	if (bp)
-		bqrelse(bp);
-
-	daddr = blkptrtodb(ump, daddr);
-	*bnp = daddr == 0 ? -1 : daddr;
-	return (0);
-}
-
-/*
- * Create an array of logical block number/offset pairs which represent the
- * path of indirect blocks required to access a data block.  The first "pair"
- * contains the logical block number of the appropriate single, double or
- * triple indirect block and the offset into the inode indirect block array.
- * Note, the logical block number of the inode single/double/triple indirect
- * block appears twice in the array, once with the offset into the i_ib and
- * once with the offset into the page itself.
- */
-int
-ext2_getlbns(struct vnode *vp, ext2_daddr_t bn, struct indir *ap, int *nump)
-{
-	long blockcnt, metalbn, realbn;
-	struct ext2mount *ump;
-	int i, numlevels, off;
-	int64_t qblockcnt;
-
-	ump = VFSTOEXT2(vp->v_mount);
-	if (nump)
-		*nump = 0;
-	numlevels = 0;
-	realbn = bn;
-	if ((long)bn < 0)
-		bn = -(long)bn;
-
-	/* The first NDADDR blocks are direct blocks. */
-	if (bn < NDADDR)
-		return (0);
-
-	/*
-	 * Determine the number of levels of indirection.  After this loop
-	 * is done, blockcnt indicates the number of data blocks possible
-	 * at the previous level of indirection, and NIADDR - i is the number
-	 * of levels of indirection needed to locate the requested block.
-	 */
-	for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) {
-		if (i == 0)
-			return (EFBIG);
-		/*
-		 * Use int64_t's here to avoid overflow for triple indirect
-		 * blocks when longs have 32 bits and the block size is more
-		 * than 4K.
-		 */
-		qblockcnt = (int64_t)blockcnt * MNINDIR(ump);
-		if (bn < qblockcnt)
-			break;
-		blockcnt = qblockcnt;
-	}
-
-	/* Calculate the address of the first meta-block. */
-	if (realbn >= 0)
-		metalbn = -(realbn - bn + NIADDR - i);
-	else
-		metalbn = -(-realbn - bn + NIADDR - i);
-
-	/*
-	 * At each iteration, off is the offset into the bap array which is
-	 * an array of disk addresses at the current level of indirection.
-	 * The logical block number and the offset in that block are stored
-	 * into the argument array.
-	 */
-	ap->in_lbn = metalbn;
-	ap->in_off = off = NIADDR - i;
-	ap->in_exists = 0;
-	ap++;
-	for (++numlevels; i <= NIADDR; i++) {
-		/* If searching for a meta-data block, quit when found. */
-		if (metalbn == realbn)
-			break;
-
-		off = (bn / blockcnt) % MNINDIR(ump);
-
-		++numlevels;
-		ap->in_lbn = metalbn;
-		ap->in_off = off;
-		ap->in_exists = 0;
-		++ap;
-
-		metalbn -= -1 + off * blockcnt;
-		blockcnt /= MNINDIR(ump);
-	}
-	if (nump)
-		*nump = numlevels;
-	return (0);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_extern.h b/sys/vfs/gnu/ext2fs/ext2_extern.h
deleted file mode 100644
index fbc4b2a..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_extern.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*-
- * Copyright (c) 1991, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ffs_extern.h	8.3 (Berkeley) 4/16/94
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_extern.h,v 1.22.6.1 2000/11/05 19:17:40 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_extern.h,v 1.12 2006/09/10 01:26:40 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_EXT2_EXTERN_H_
-#define	_VFS_GNU_EXT2FS_EXT2_EXTERN_H_
-
-struct ext2_dinode;
-struct ext2_inode;
-struct inode;
-struct mount;
-struct vfsconf;
-struct vnode;
-struct indir;
-
-int	ext2_alloc (struct inode *,
-	    daddr_t, daddr_t, int, struct ucred *, daddr_t *);
-int	ext2_balloc (struct inode *,
-	    daddr_t, int, struct ucred *, struct buf **, int);
-int	ext2_blkatoff (struct vnode *, off_t, char **, struct buf **);
-void	ext2_blkfree (struct inode *, daddr_t, long);
-daddr_t	ext2_blkpref (struct inode *, daddr_t, int, daddr_t *, daddr_t);
-int	ext2_bmap (struct vop_bmap_args *);
-int	ext2_reallocblks (struct vop_reallocblks_args *);
-int	ext2_reclaim (struct vop_reclaim_args *);
-void	ext2_setblock (struct ext2_sb_info *, u_char *, daddr_t);
-int	ext2_truncate (struct vnode *, off_t, int, struct ucred *);
-int	ext2_update (struct vnode *, int);
-int	ext2_valloc (struct vnode *, int, struct ucred *, struct vnode **);
-int	ext2_vfree (struct vnode *, ino_t, int);
-int 	ext2_lookup (struct vop_old_lookup_args *);
-int 	ext2_readdir (struct vop_readdir_args *);
-void	ext2_print_dinode (struct ext2_dinode *);
-void	ext2_print_inode (struct inode *);
-int	ext2_direnter (struct inode *, 
-		struct vnode *, struct componentname *);
-int	ext2_dirremove (struct vnode *, struct componentname *);
-int	ext2_dirrewrite (struct inode *,
-		struct inode *, struct componentname *);
-int	ext2_dirempty (struct inode *, ino_t, struct ucred *);
-int	ext2_checkpath (struct inode *, struct inode *, struct ucred *);
-struct  ext2_group_desc * get_group_desc (struct mount * , 
-		unsigned int , struct buf ** );
-int	ext2_group_sparse (int group);
-void	ext2_discard_prealloc (struct inode *);
-int	ext2_inactive (struct vop_inactive_args *);
-int	ext2_new_block (struct mount * mp, unsigned long goal,
-			    u_int32_t * prealloc_count,
-			    u_int32_t * prealloc_block);
-ino_t	ext2_new_inode (const struct inode * dir, int mode);
-unsigned long ext2_count_free (struct buf *map, unsigned int numchars);
-void	ext2_free_blocks (struct mount * mp, unsigned long block,
-			      unsigned long count);
-void	ext2_free_inode (struct inode * inode);
-void	ext2_ei2di (struct ext2_inode *ei, struct ext2_dinode *di);
-void	ext2_di2ei (struct ext2_dinode *di, struct ext2_inode *ei);
-void	mark_buffer_dirty (struct buf *bh);
-
-int	ext2_getlbns(struct vnode *, ext2_daddr_t, struct indir *, int *);
-void	ext2_itimes(struct vnode *vp);
-struct vnode *ext2_ihashget(cdev_t, ino_t);
-int	ext2_ihashins(struct inode *);
-void	ext2_ihashrem(struct inode *);
-void	ext2_dirbad(struct inode *, doff_t, char *);
-int	ext2_check_export(struct mount *, struct sockaddr *, int *,
-			struct ucred **);
-int	ext2_vinit(struct mount *, struct vnode **);
-int	ext2_vnoperate(struct vop_generic_args *);
-int	ext2_vnoperatefifo(struct vop_generic_args *);
-int	ext2_vnoperatespec(struct vop_generic_args *);
-int	ext2_uninit(struct vfsconf *);
-void	ext2_ihashinit(void);
-struct vnode *ext2_ihashlookup(cdev_t dev, ino_t inum);
-int	ext2_ihashcheck(cdev_t dev, ino_t inum);
-
-/*
- * This macro allows the ufs code to distinguish between an EXT2 and a
- * non-ext2(FFS/LFS) vnode.
- */
-#define  IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS)
-
-#endif /* !_VFS_GNU_EXT2FS_EXT2_EXTERN_H_ */
diff --git a/sys/vfs/gnu/ext2fs/ext2_fs.h b/sys/vfs/gnu/ext2fs/ext2_fs.h
deleted file mode 100644
index 2184ba1..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_fs.h
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- *
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_fs.h,v 1.8.2.2 2001/09/29 12:52:47 iedowse Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_fs.h,v 1.6 2006/12/23 00:41:29 swildner Exp $
- */
-/*
- *  linux/include/linux/ext2_fs.h
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- *  from
- *
- *  linux/include/linux/minix_fs.h
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#ifndef _LINUX_EXT2_FS_H
-#define _LINUX_EXT2_FS_H
-
-#include <sys/types.h>
-#include <sys/ioccom.h>
-
-#define __u32 u_int32_t
-#define u32   u_int32_t
-#define __u16 u_int16_t
-#define __u8  u_int8_t
-
-#define __s32 int32_t
-#define __s16 int16_t
-#define __s8  int8_t
-
-#define umode_t mode_t
-#define loff_t  off_t
-
-/* the Linux implementation of EXT2 stores some information about
- * an inode in a ext2_inode_info structure which is part of the incore
- * inode in Linux
- * I decided to use the "spare" fields instead - we'll see how this
- * works out
- */
-
-#define i_block_group		i_spare[0]
-#define i_next_alloc_block	i_spare[1]
-#define i_next_alloc_goal	i_spare[2]
-#define i_prealloc_block	i_din.di_spare[0]
-#define i_prealloc_count	i_din.di_spare[1]
-
-/*
- * The second extended filesystem constants/structures
- */
-
-/*
- * Define EXT2FS_DEBUG to produce debug messages
- */
-#undef EXT2FS_DEBUG
-
-/*
- * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
- */
-#define EXT2_PREALLOCATE
-#define EXT2_DEFAULT_PREALLOC_BLOCKS	8
-
-/*
- * The second extended file system version
- */
-#define EXT2FS_DATE		"95/08/09"
-#define EXT2FS_VERSION		"0.5b"
-
-/*
- * Debug code
- */
-#ifdef EXT2FS_DEBUG
-#	define ext2_debug(f, a...)	{ \
-					kprintf ("EXT2-fs DEBUG (%s, %d): %s:", \
-						__FILE__, __LINE__, __func__); \
-				  	kprintf (f, ## a); \
-					}
-#else
-#	define ext2_debug(f, a...)	/**/
-#endif
-
-/*
- * Special inodes numbers
- */
-#define	EXT2_BAD_INO		 1	/* Bad blocks inode */
-#define EXT2_ROOT_INO		 2	/* Root inode */
-#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
-#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
-#define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
-#define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
-
-/* First non-reserved inode for old ext2 filesystems */
-#define EXT2_GOOD_OLD_FIRST_INO	11
-
-/*
- * The second extended file system magic number
- */
-#define EXT2_SUPER_MAGIC	0xEF53
-
-/*
- * Maximal count of links to a file
- */
-#define EXT2_LINK_MAX		32000
-
-/*
- * Note: under FreeBSD, the "user" versions of the following macros are
- * used (and must be used) in most cases, because ((s)->u.ext2_sb.s_es is
- * not accessible.  This depends on __KERNEL__ not being defined for
- * kernel builds under FreeBSD.
- */
-
-/*
- * Macro-instructions used to manage several block sizes
- */
-#define EXT2_MIN_BLOCK_SIZE		1024
-#define	EXT2_MAX_BLOCK_SIZE		4096
-#define EXT2_MIN_BLOCK_LOG_SIZE		  10
-#if defined(__KERNEL__) || (defined(__DragonFly__) && defined(_KERNEL))
-# define EXT2_BLOCK_SIZE(s)		((s)->s_blocksize)
-#else
-# define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
-#endif
-#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
-#define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
-#ifdef __KERNEL__
-# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
-#else
-# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
-#endif
-#if defined(__KERNEL__) || defined _KERNEL
-#define	EXT2_ADDR_PER_BLOCK_BITS(s)	((s)->s_addr_per_block_bits)
-#define EXT2_INODE_SIZE(s)		((s)->s_inode_size)
-#define EXT2_FIRST_INO(s)		((s)->s_first_ino)
-#else
-#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-				 EXT2_GOOD_OLD_INODE_SIZE : \
-				 (s)->s_inode_size)
-#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-				 EXT2_GOOD_OLD_FIRST_INO : \
-				 (s)->s_first_ino)
-#endif
-#define	EXT2_INODES_PER_BLOCK(s)	((s)->s_inodes_per_block)
-/*
- * Macro-instructions used to manage fragments
- */
-#define EXT2_MIN_FRAG_SIZE		1024
-#define	EXT2_MAX_FRAG_SIZE		4096
-#define EXT2_MIN_FRAG_LOG_SIZE		  10
-#ifdef __KERNEL__
-# define EXT2_FRAG_SIZE(s)		((s)->u.ext2_sb.s_frag_size)
-# define EXT2_FRAGS_PER_BLOCK(s)	((s)->u.ext2_sb.s_frags_per_block)
-#else
-# if defined(_KERNEL) && defined(__DragonFly__)
-# define EXT2_FRAG_SIZE(s)		((s)->s_frag_size)
-# else
-# define EXT2_FRAG_SIZE(s)		(EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# endif
-# define EXT2_FRAGS_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
-#endif
-
-/*
- * ACL structures
- */
-struct ext2_acl_header	/* Header of Access Control Lists */
-{
-	__u32	aclh_size;
-	__u32	aclh_file_count;
-	__u32	aclh_acle_count;
-	__u32	aclh_first_acle;
-};
-
-struct ext2_acl_entry	/* Access Control List Entry */
-{
-	__u32	acle_size;
-	__u16	acle_perms;	/* Access permissions */
-	__u16	acle_type;	/* Type of entry */
-	__u16	acle_tag;	/* User or group identity */
-	__u16	acle_pad1;
-	__u32	acle_next;	/* Pointer on next entry for the */
-					/* same inode or on next free entry */
-};
-
-/*
- * Structure of a blocks group descriptor
- */
-struct ext2_group_desc
-{
-	__u32	bg_block_bitmap;		/* Blocks bitmap block */
-	__u32	bg_inode_bitmap;		/* Inodes bitmap block */
-	__u32	bg_inode_table;		/* Inodes table block */
-	__u16	bg_free_blocks_count;	/* Free blocks count */
-	__u16	bg_free_inodes_count;	/* Free inodes count */
-	__u16	bg_used_dirs_count;	/* Directories count */
-	__u16	bg_pad;
-	__u32	bg_reserved[3];
-};
-
-/*
- * Macro-instructions used to manage group descriptors
- */
-#ifdef __KERNEL__
-# define EXT2_BLOCKS_PER_GROUP(s)	((s)->u.ext2_sb.s_blocks_per_group)
-# define EXT2_DESC_PER_BLOCK(s)		((s)->u.ext2_sb.s_desc_per_block)
-# define EXT2_INODES_PER_GROUP(s)	((s)->u.ext2_sb.s_inodes_per_group)
-# define EXT2_DESC_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_desc_per_block_bits)
-#else
-# define EXT2_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
-# define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
-# define EXT2_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
-#endif
-
-/*
- * Constants relative to the data blocks
- */
-#define	EXT2_NDIR_BLOCKS		12
-#define	EXT2_IND_BLOCK			EXT2_NDIR_BLOCKS
-#define	EXT2_DIND_BLOCK			(EXT2_IND_BLOCK + 1)
-#define	EXT2_TIND_BLOCK			(EXT2_DIND_BLOCK + 1)
-#define	EXT2_N_BLOCKS			(EXT2_TIND_BLOCK + 1)
-#define EXT2_MAXSYMLINKLEN		(EXT2_N_BLOCKS * sizeof (__u32))
-
-/*
- * Inode flags
- */
-#define	EXT2_SECRM_FL			0x00000001 /* Secure deletion */
-#define	EXT2_UNRM_FL			0x00000002 /* Undelete */
-#define	EXT2_COMPR_FL			0x00000004 /* Compress file */
-#define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
-#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
-#define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
-#define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
-#define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
-/* Reserved for compression usage... */
-#define EXT2_DIRTY_FL			0x00000100
-#define EXT2_COMPRBLK_FL		0x00000200 /* One or more compressed clusters */
-#define EXT2_NOCOMP_FL			0x00000400 /* Don't compress */
-#define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
-/* End compression flags --- maybe not all used */	
-#define EXT2_BTREE_FL			0x00001000 /* btree format dir */
-#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
-
-#define EXT2_FL_USER_VISIBLE		0x00001FFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
-
-/*
- * ioctl commands
- */
-#define	EXT2_IOC_GETFLAGS		_IOR('f', 1, long)
-#define	EXT2_IOC_SETFLAGS		_IOW('f', 2, long)
-#define	EXT2_IOC_GETVERSION		_IOR('v', 1, long)
-#define	EXT2_IOC_SETVERSION		_IOW('v', 2, long)
-
-/*
- * Only declare `struct ext2_inode' if <vfs/ufs/inode.h> hasn't made things
- * difficult by #defining i_mode and other struct members.  The details of
- * the struct are only needed in ext2_inode_cnv.c where the ext2fs on-disk
- * inode is converted to a ufs in-core inode.
- */
-#ifndef i_mode
-
-/*
- * Structure of an inode on the disk
- */
-struct ext2_inode {
-	__u16	i_mode;		/* File mode */
-	__u16	i_uid;		/* Owner Uid */
-	__u32	i_size;		/* Size in bytes */
-	__u32	i_atime;	/* Access time */
-	__u32	i_ctime;	/* Creation time */
-	__u32	i_mtime;	/* Modification time */
-	__u32	i_dtime;	/* Deletion Time */
-	__u16	i_gid;		/* Group Id */
-	__u16	i_links_count;	/* Links count */
-	__u32	i_blocks;	/* Blocks count */
-	__u32	i_flags;	/* File flags */
-	union {
-		struct {
-			__u32  l_i_reserved1;
-		} linux1;
-		struct {
-			__u32  h_i_translator;
-		} hurd1;
-		struct {
-			__u32  m_i_reserved1;
-		} masix1;
-	} osd1;				/* OS dependent 1 */
-	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-	__u32	i_generation;	/* File version (for NFS) */
-	__u32	i_file_acl;	/* File ACL */
-	__u32	i_dir_acl;	/* Directory ACL */
-	__u32	i_faddr;	/* Fragment address */
-	union {
-		struct {
-			__u8	l_i_frag;	/* Fragment number */
-			__u8	l_i_fsize;	/* Fragment size */
-			__u16	i_pad1;
-			__u32	l_i_reserved2[2];
-		} linux2;
-		struct {
-			__u8	h_i_frag;	/* Fragment number */
-			__u8	h_i_fsize;	/* Fragment size */
-			__u16	h_i_mode_high;
-			__u16	h_i_uid_high;
-			__u16	h_i_gid_high;
-			__u32	h_i_author;
-		} hurd2;
-		struct {
-			__u8	m_i_frag;	/* Fragment number */
-			__u8	m_i_fsize;	/* Fragment size */
-			__u16	m_pad1;
-			__u32	m_i_reserved2[2];
-		} masix2;
-	} osd2;				/* OS dependent 2 */
-};
-
-#define i_size_high	i_dir_acl
-
-#if defined(__KERNEL__) || defined(__linux__)
-#define i_reserved1	osd1.linux1.l_i_reserved1
-#define i_frag		osd2.linux2.l_i_frag
-#define i_fsize		osd2.linux2.l_i_fsize
-#define i_reserved2	osd2.linux2.l_i_reserved2
-#endif
-
-#ifdef	__hurd__
-#define i_translator	osd1.hurd1.h_i_translator
-#define i_frag		osd2.hurd2.h_i_frag;
-#define i_fsize		osd2.hurd2.h_i_fsize;
-#define i_uid_high	osd2.hurd2.h_i_uid_high
-#define i_gid_high	osd2.hurd2.h_i_gid_high
-#define i_author	osd2.hurd2.h_i_author
-#endif
-
-#ifdef	__masix__
-#define i_reserved1	osd1.masix1.m_i_reserved1
-#define i_frag		osd2.masix2.m_i_frag
-#define i_fsize		osd2.masix2.m_i_fsize
-#define i_reserved2	osd2.masix2.m_i_reserved2
-#endif
-
-#endif /* i_mode */
-
-/*
- * File system states
- */
-#define	EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
-#define	EXT2_ERROR_FS			0x0002	/* Errors detected */
-
-/*
- * Mount flags
- */
-#define EXT2_MOUNT_CHECK_NORMAL		0x0001	/* Do some more checks */
-#define EXT2_MOUNT_CHECK_STRICT		0x0002	/* Do again more checks */
-#define EXT2_MOUNT_CHECK		(EXT2_MOUNT_CHECK_NORMAL | \
-					 EXT2_MOUNT_CHECK_STRICT)
-#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
-#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
-#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
-#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
-#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
-#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
-
-#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
-#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
-#define test_opt(sb, opt)		((sb)->u.ext2_sb.s_mount_opt & \
-					 EXT2_MOUNT_##opt)
-/*
- * Maximal mount counts between two filesystem checks
- */
-#define EXT2_DFL_MAX_MNT_COUNT		20	/* Allow 20 mounts */
-#define EXT2_DFL_CHECKINTERVAL		0	/* Don't use interval check */
-
-/*
- * Behaviour when detecting errors
- */
-#define EXT2_ERRORS_CONTINUE		1	/* Continue execution */
-#define EXT2_ERRORS_RO			2	/* Remount fs read-only */
-#define EXT2_ERRORS_PANIC		3	/* Panic */
-#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE
-
-/*
- * Structure of the super block
- */
-struct ext2_super_block {
-	__u32	s_inodes_count;		/* Inodes count */
-	__u32	s_blocks_count;		/* Blocks count */
-	__u32	s_r_blocks_count;	/* Reserved blocks count */
-	__u32	s_free_blocks_count;	/* Free blocks count */
-	__u32	s_free_inodes_count;	/* Free inodes count */
-	__u32	s_first_data_block;	/* First Data Block */
-	__u32	s_log_block_size;	/* Block size */
-	__s32	s_log_frag_size;	/* Fragment size */
-	__u32	s_blocks_per_group;	/* # Blocks per group */
-	__u32	s_frags_per_group;	/* # Fragments per group */
-	__u32	s_inodes_per_group;	/* # Inodes per group */
-	__u32	s_mtime;		/* Mount time */
-	__u32	s_wtime;		/* Write time */
-	__u16	s_mnt_count;		/* Mount count */
-	__s16	s_max_mnt_count;	/* Maximal mount count */
-	__u16	s_magic;		/* Magic signature */
-	__u16	s_state;		/* File system state */
-	__u16	s_errors;		/* Behaviour when detecting errors */
-	__u16	s_minor_rev_level; 	/* minor revision level */
-	__u32	s_lastcheck;		/* time of last check */
-	__u32	s_checkinterval;	/* max. time between checks */
-	__u32	s_creator_os;		/* OS */
-	__u32	s_rev_level;		/* Revision level */
-	__u16	s_def_resuid;		/* Default uid for reserved blocks */
-	__u16	s_def_resgid;		/* Default gid for reserved blocks */
-	/*
-	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
-	 *
-	 * Note: the difference between the compatible feature set and
-	 * the incompatible feature set is that if there is a bit set
-	 * in the incompatible feature set that the kernel doesn't
-	 * know about, it should refuse to mount the filesystem.
-	 * 
-	 * e2fsck's requirements are more strict; if it doesn't know
-	 * about a feature in either the compatible or incompatible
-	 * feature set, it must abort and not try to meddle with
-	 * things it doesn't understand...
-	 */
-	__u32	s_first_ino; 		/* First non-reserved inode */
-	__u16   s_inode_size; 		/* size of inode structure */
-	__u16	s_block_group_nr; 	/* block group # of this superblock */
-	__u32	s_feature_compat; 	/* compatible feature set */
-	__u32	s_feature_incompat; 	/* incompatible feature set */
-	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
-	__u8	s_uuid[16];		/* 128-bit uuid for volume */
-	char	s_volume_name[16]; 	/* volume name */
-	char	s_last_mounted[64]; 	/* directory where last mounted */
-	__u32	s_algorithm_usage_bitmap; /* For compression */
-	/*
-	 * Performance hints.  Directory preallocation should only
-	 * happen if the EXT2_COMPAT_PREALLOC flag is on.
-	 */
-	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
-	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
-	__u16	s_padding1;
-	__u32	s_reserved[204];	/* Padding to the end of the block */
-};
-
-#ifdef __KERNEL__
-#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
-#else
-/* Assume that user mode programs are passing in an ext2fs superblock, not
- * a kernel struct super_block.  This will allow us to call the feature-test
- * macros from user land. */
-#define EXT2_SB(sb)	(sb)
-#endif
-
-/*
- * Codes for operating systems
- */
-#define EXT2_OS_LINUX		0
-#define EXT2_OS_HURD		1
-#define EXT2_OS_MASIX		2
-#define EXT2_OS_FREEBSD		3
-#define EXT2_OS_LITES		4
-
-/*
- * Revision levels
- */
-#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
-#define EXT2_DYNAMIC_REV	1 	/* V2 format w/ dynamic inode sizes */
-
-#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
-#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
-
-#define EXT2_GOOD_OLD_INODE_SIZE 128
-
-/*
- * Feature set definitions
- */
-
-#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
-	( EXT2_SB(sb)->s_feature_compat & (mask) )
-#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
-	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
-#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
-	( EXT2_SB(sb)->s_feature_incompat & (mask) )
-
-#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
-
-#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
-#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
-#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004
-
-#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
-#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
-
-#define EXT2_FEATURE_COMPAT_SUPP	0
-#define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
-#ifdef notyet
-#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
-#else
-#define EXT2_FEATURE_RO_COMPAT_SUPP	EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
-#endif
-
-/*
- * Default values for user and/or group using reserved blocks
- */
-#define	EXT2_DEF_RESUID		0
-#define	EXT2_DEF_RESGID		0
-
-/*
- * Structure of a directory entry
- */
-#define EXT2_NAME_LEN 255
-
-struct ext2_dir_entry {
-	__u32	inode;			/* Inode number */
-	__u16	rec_len;		/* Directory entry length */
-	__u16	name_len;		/* Name length */
-	char	name[EXT2_NAME_LEN];	/* File name */
-};
-
-/*
- * The new version of the directory entry.  Since EXT2 structures are
- * stored in intel byte order, and the name_len field could never be
- * bigger than 255 chars, it's safe to reclaim the extra byte for the
- * file_type field.
- */
-struct ext2_dir_entry_2 {
-	__u32	inode;			/* Inode number */
-	__u16	rec_len;		/* Directory entry length */
-	__u8	name_len;		/* Name length */
-	__u8	file_type;
-	char	name[EXT2_NAME_LEN];	/* File name */
-};
-
-/*
- * Ext2 directory file types.  Only the low 3 bits are used.  The
- * other bits are reserved for now.
- */
-#define EXT2_FT_UNKNOWN		0
-#define EXT2_FT_REG_FILE	1
-#define EXT2_FT_DIR		2
-#define EXT2_FT_CHRDEV		3
-#define EXT2_FT_BLKDEV 		4
-#define EXT2_FT_FIFO		5
-#define EXT2_FT_SOCK		6
-#define EXT2_FT_SYMLINK		7
-
-#define EXT2_FT_MAX		8
-
-/*
- * EXT2_DIR_PAD defines the directory entries boundaries
- *
- * NOTE: It must be a multiple of 4
- */
-#define EXT2_DIR_PAD		 	4
-#define EXT2_DIR_ROUND 			(EXT2_DIR_PAD - 1)
-#define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
-					 ~EXT2_DIR_ROUND)
-
-#endif	/* _LINUX_EXT2_FS_H */
diff --git a/sys/vfs/gnu/ext2fs/ext2_fs_sb.h b/sys/vfs/gnu/ext2fs/ext2_fs_sb.h
deleted file mode 100644
index a5b9123..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_fs_sb.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- *  linux/include/linux/ext2_fs_sb.h
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- *  from
- *
- *  linux/include/linux/minix_fs_sb.h
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#ifndef _LINUX_EXT2_FS_SB
-#define _LINUX_EXT2_FS_SB
-
-/*
- * The following is not needed anymore since the descriptors buffer
- * heads are now dynamically allocated
- */
-/* #define EXT2_MAX_GROUP_DESC	8 */
-
-#define EXT2_MAX_GROUP_LOADED	8
-
-#define buffer_head buf
-#define MAXMNTLEN	512
-
-/*
- * second extended-fs super-block data in memory
- */
-struct ext2_sb_info {
-	unsigned long s_frag_size;	/* Size of a fragment in bytes */
-	unsigned long s_frags_per_block;/* Number of fragments per block */
-	unsigned long s_inodes_per_block;/* Number of inodes per block */
-	unsigned long s_frags_per_group;/* Number of fragments in a group */
-	unsigned long s_blocks_per_group;/* Number of blocks in a group */
-	unsigned long s_inodes_per_group;/* Number of inodes in a group */
-	unsigned long s_itb_per_group;	/* Number of inode table blocks per group */
-	unsigned long s_db_per_group;	/* Number of descriptor blocks per group */
-	unsigned long s_desc_per_block;	/* Number of group descriptors per block */
-	unsigned long s_groups_count;	/* Number of groups in the fs */
-	struct buffer_head * s_sbh;	/* Buffer containing the super block */
-	struct ext2_super_block * s_es;	/* Pointer to the super block in the buffer */
-	struct buffer_head ** s_group_desc;
-	unsigned short s_loaded_inode_bitmaps;
-	unsigned short s_loaded_block_bitmaps;
-	unsigned long s_inode_bitmap_number[EXT2_MAX_GROUP_LOADED];
-	struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED];
-	unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED];
-	struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED];
-	int s_rename_lock;
-	unsigned long  s_mount_opt;
-#ifdef notyet
-	unsigned short s_resuid;
-	unsigned short s_resgid;
-#endif
-    unsigned short s_inode_size;
-    unsigned int s_first_ino;
-	unsigned short s_mount_state;
-	/* 
-	   stuff that FFS keeps in its super block or that linux
-	   has in its non-ext2 specific super block and which is
-	   generally considered useful 
-	*/
-	unsigned long s_blocksize;
-	unsigned long s_blocksize_bits;
-	unsigned int  s_bshift;			/* = log2(s_blocksize) */
-	quad_t	 s_qbmask;			/* = s_blocksize - 1 */
-	unsigned int  s_fsbtodb;		/* shift to get disk block */
-	char    s_rd_only;                      /* read-only 		*/
-	char    s_dirt;                         /* fs modified flag */
-	char	s_wasvalid;			/* valid at mount time */
-
-	char    fs_fsmnt[MAXMNTLEN];            /* name mounted on */
-};
-
-#endif	/* _LINUX_EXT2_FS_SB */
diff --git a/sys/vfs/gnu/ext2fs/ext2_ihash.c b/sys/vfs/gnu/ext2fs/ext2_ihash.c
deleted file mode 100644
index bc75eee..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_ihash.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ufs_ihash.c	8.7 (Berkeley) 5/17/95
- * $FreeBSD: src/sys/ufs/ufs/ufs_ihash.c,v 1.20 1999/08/28 00:52:29 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_ihash.c,v 1.5 2006/10/14 16:26:38 dillon Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-
-#include "quota.h"
-#include "dinode.h"
-#include "inode.h"
-#include "ext2_extern.h"
-
-static MALLOC_DEFINE(M_EXT2IHASH, "EXT2 ihash", "EXT2 Inode hash tables");
-/*
- * Structures associated with inode cacheing.
- */
-static struct inode **ext2_ihashtbl;
-static u_long	ext2_ihash;		/* size of hash table - 1 */
-static struct lwkt_token ext2_ihash_token;
-
-#define	INOHASH(device, inum)	(&ext2_ihashtbl[(minor(device) + (inum)) & ext2_ihash])
-
-/*
- * Initialize inode hash table.
- */
-void
-ext2_ihashinit(void)
-{
-	ext2_ihash = 16;
-	while (ext2_ihash < desiredvnodes)
-		ext2_ihash <<= 1;
-	ext2_ihashtbl = kmalloc(sizeof(void *) * ext2_ihash, M_EXT2IHASH, M_WAITOK|M_ZERO);
-	--ext2_ihash;
-	lwkt_token_init(&ext2_ihash_token, "ext2ihash");
-}
-
-int
-ext2_uninit(struct vfsconf *vfc)
-{
-    lwkt_gettoken(&ext2_ihash_token);
-    if (ext2_ihashtbl)
-		kfree(ext2_ihashtbl, M_EXT2IHASH);
-    lwkt_reltoken(&ext2_ihash_token);
-
-    return (0);
-}
-/*
- * Use the device/inum pair to find the incore inode, and return a pointer
- * to it. If it is in core, return it, even if it is locked.
- */
-struct vnode *
-ext2_ihashlookup(cdev_t dev, ino_t inum)
-{
-	struct inode *ip;
-
-	lwkt_gettoken(&ext2_ihash_token);
-	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
-		if (inum == ip->i_number && dev == ip->i_dev)
-			break;
-	}
-	lwkt_reltoken(&ext2_ihash_token);
-	if (ip)
-		return (ITOV(ip));
-	return (NULLVP);
-}
-
-/*
- * Use the device/inum pair to find the incore inode, and return a pointer
- * to it. If it is in core, but locked, wait for it.
- *
- * Note that the serializing tokens do not prevent other processes from
- * playing with the data structure being protected while we are blocked.
- * They do protect us from preemptive interrupts which might try to
- * play with the protected data structure.
- */
-struct vnode *
-ext2_ihashget(cdev_t dev, ino_t inum)
-{
-	struct inode *ip;
-	struct vnode *vp;
-
-	lwkt_gettoken(&ext2_ihash_token);
-loop:
-	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
-		if (inum != ip->i_number || dev != ip->i_dev)
-			continue;
-		vp = ITOV(ip);
-		if (vget(vp, LK_EXCLUSIVE))
-			goto loop;
-		/*
-		 * We must check to see if the inode has been ripped
-		 * out from under us after blocking.
-		 */
-		for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
-			if (inum == ip->i_number && dev == ip->i_dev)
-				break;
-		}
-		if (ip == NULL || ITOV(ip) != vp) {
-			vput(vp);
-			goto loop;
-		}
-		lwkt_reltoken(&ext2_ihash_token);
-		return (vp);
-	}
-	lwkt_reltoken(&ext2_ihash_token);
-	return (NULL);
-}
-
-/*
- * Check to see if an inode is in the hash table.  This is used to interlock
- * file free operations to ensure that the vnode is not reused due to a
- * reallocate of its inode number before we have had a chance to recycle it.
- */
-int
-ext2_ihashcheck(cdev_t dev, ino_t inum)
-{
-	struct inode *ip;
-
-	lwkt_gettoken(&ext2_ihash_token);
-	for (ip = *INOHASH(dev, inum); ip; ip = ip->i_next) {
-		if (inum == ip->i_number && dev == ip->i_dev)
-			break;
-	}
-	lwkt_reltoken(&ext2_ihash_token);
-	return(ip ? 1 : 0);
-}
-
-/*
- * Insert the inode into the hash table, and return it locked.
- */
-int
-ext2_ihashins(struct inode *ip)
-{
-	struct inode **ipp;
-	struct inode *iq;
-
-	KKASSERT((ip->i_flag & IN_HASHED) == 0);
-	lwkt_gettoken(&ext2_ihash_token);
-	ipp = INOHASH(ip->i_dev, ip->i_number);
-	while ((iq = *ipp) != NULL) {
-		if (ip->i_dev == iq->i_dev && ip->i_number == iq->i_number) {
-			lwkt_reltoken(&ext2_ihash_token);
-			return(EBUSY);
-		}
-		ipp = &iq->i_next;
-	}
-	ip->i_next = NULL;
-	*ipp = ip;
-	ip->i_flag |= IN_HASHED;
-	lwkt_reltoken(&ext2_ihash_token);
-	return(0);
-}
-
-/*
- * Remove the inode from the hash table.
- */
-void
-ext2_ihashrem(struct inode *ip)
-{
-	struct inode **ipp;
-	struct inode *iq;
-
-	lwkt_gettoken(&ext2_ihash_token);
-	if (ip->i_flag & IN_HASHED) {
-		ipp = INOHASH(ip->i_dev, ip->i_number);
-		while ((iq = *ipp) != NULL) {
-			if (ip == iq)
-				break;
-			ipp = &iq->i_next;
-		}
-		KKASSERT(ip == iq);
-		*ipp = ip->i_next;
-		ip->i_next = NULL;
-		ip->i_flag &= ~IN_HASHED;
-	}
-	lwkt_reltoken(&ext2_ihash_token);
-}
-
diff --git a/sys/vfs/gnu/ext2fs/ext2_inode.c b/sys/vfs/gnu/ext2fs/ext2_inode.c
deleted file mode 100644
index ca84d4c..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_inode.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ext2_inode.c	8.5 (Berkeley) 12/30/93
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode.c,v 1.24.2.1 2000/08/03 00:52:57 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode.c,v 1.21 2007/05/06 19:23:33 dillon Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mount.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "ext2mount.h"
-
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-#include "ext2_extern.h"
-
-static int ext2_indirtrunc (struct inode *, daddr_t, off_t, daddr_t,
-			    int, long *);
-
-/*
- * Update the access, modified, and inode change times as specified by the
- * IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively.  Write the inode
- * to disk if the IN_MODIFIED flag is set (it may be set initially, or by
- * the timestamp update).  The IN_LAZYMOD flag is set to force a write
- * later if not now.  If we write now, then clear both IN_MODIFIED and
- * IN_LAZYMOD to reflect the presumably successful write, and if waitfor is
- * set, then wait for the write to complete.
- */
-int
-ext2_update(struct vnode *vp, int waitfor)
-{
-	struct ext2_sb_info *fs;
-	struct buf *bp;
-	struct inode *ip;
-	int error;
-
-	ext2_itimes(vp);
-	ip = VTOI(vp);
-	if ((ip->i_flag & IN_MODIFIED) == 0)
-		return (0);
-	ip->i_flag &= ~(IN_LAZYMOD | IN_MODIFIED);
-	if (vp->v_mount->mnt_flag & MNT_RDONLY)
-		return (0);
-	fs = ip->i_e2fs;
-	error = bread(ip->i_devvp,
-		      fsbtodoff(fs, ino_to_fsba(fs, ip->i_number)),
-		      (int)fs->s_blocksize, &bp);
-	if (error) {
-		brelse(bp);
-		return (error);
-	}
-	ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
-	    ino_to_fsbo(fs, ip->i_number)));
-/*
-	if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
-		return (bwrite(bp));
-	else {
-*/
-		bdwrite(bp);
-		return (0);
-/*
-	}
-*/
-}
-
-#define	SINGLE	0	/* index of single indirect block */
-#define	DOUBLE	1	/* index of double indirect block */
-#define	TRIPLE	2	/* index of triple indirect block */
-/*
- * Truncate the inode oip to at most length size, freeing the
- * disk blocks.
- */
-int
-ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred)
-{
-	struct vnode *ovp = vp;
-	daddr_t lastblock;
-	struct inode *oip;
-	daddr_t bn, lbn, lastiblock[NIADDR], indir_lbn[NIADDR];
-	daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR];
-	struct ext2_sb_info *fs;
-	struct buf *bp;
-	int offset, size, level;
-	long count, nblocks, blocksreleased = 0;
-	int i;
-	int aflags, error, allerror;
-	off_t osize;
-/*
-kprintf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
-*/	/* 
-	 * negative file sizes will totally break the code below and
-	 * are not meaningful anyways.
-	 */
-	if (length < 0)
-	    return EFBIG;
-
-	oip = VTOI(ovp);
-	if (ovp->v_type == VLNK &&
-	    oip->i_size < ovp->v_mount->mnt_maxsymlinklen) {
-#if DIAGNOSTIC
-		if (length != 0)
-			panic("ext2_truncate: partial truncate of symlink");
-#endif
-		bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
-		oip->i_size = 0;
-		oip->i_flag |= IN_CHANGE | IN_UPDATE;
-		return (EXT2_UPDATE(ovp, 1));
-	}
-	if (oip->i_size == length) {
-		oip->i_flag |= IN_CHANGE | IN_UPDATE;
-		return (EXT2_UPDATE(ovp, 0));
-	}
-#if QUOTA
-	if ((error = ext2_getinoquota(oip)) != 0)
-		return (error);
-#endif
-	fs = oip->i_e2fs;
-	osize = oip->i_size;
-	ext2_discard_prealloc(oip);
-	/*
-	 * Lengthen the size of the file. We must ensure that the
-	 * last byte of the file is allocated. Since the smallest
-	 * value of osize is 0, length will be at least 1.
-	 */
-	if (osize < length) {
-		offset = blkoff(fs, length - 1);
-		lbn = lblkno(fs, length - 1);
-		aflags = B_CLRBUF;
-		if (flags & IO_SYNC)
-			aflags |= B_SYNC;
-		vnode_pager_setsize(ovp, length);
-		error = ext2_balloc(oip, lbn, offset + 1, cred, &bp, aflags);
-		if (error) {
-			vnode_pager_setsize(ovp, osize);
-			return (error);
-		}
-		oip->i_size = length;
-		if (aflags & IO_SYNC)
-			bwrite(bp);
-		else
-			bawrite(bp);
-		oip->i_flag |= IN_CHANGE | IN_UPDATE;
-		return (EXT2_UPDATE(ovp, 1));
-	}
-	/*
-	 * Shorten the size of the file. If the file is not being
-	 * truncated to a block boundry, the contents of the
-	 * partial block following the end of the file must be
-	 * zero'ed in case it ever become accessable again because
-	 * of subsequent file growth.
-	 */
-	/* I don't understand the comment above */
-	offset = blkoff(fs, length);
-	if (offset == 0) {
-		oip->i_size = length;
-	} else {
-		lbn = lblkno(fs, length);
-		aflags = B_CLRBUF;
-		if (flags & IO_SYNC)
-			aflags |= B_SYNC;
-		error = ext2_balloc(oip, lbn, offset, cred, &bp, aflags);
-		if (error)
-			return (error);
-		oip->i_size = length;
-		size = blksize(fs, oip, lbn);
-		bzero((char *)bp->b_data + offset, (u_int)(size - offset));
-		allocbuf(bp, size);
-		if (aflags & IO_SYNC)
-			bwrite(bp);
-		else
-			bawrite(bp);
-	}
-	/*
-	 * Calculate index into inode's block list of
-	 * last direct and indirect blocks (if any)
-	 * which we want to keep.  Lastblock is -1 when
-	 * the file is truncated to 0.
-	 */
-	lastblock = lblkno(fs, length + fs->s_blocksize - 1) - 1;
-	lastiblock[SINGLE] = lastblock - NDADDR;
-	lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
-	lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
-	nblocks = btodb(fs->s_blocksize);
-	/*
-	 * Update file and block pointers on disk before we start freeing
-	 * blocks.  If we crash before free'ing blocks below, the blocks
-	 * will be returned to the free list.  lastiblock values are also
-	 * normalized to -1 for calls to ext2_indirtrunc below.
-	 */
-	bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof oldblks);
-	for (level = TRIPLE; level >= SINGLE; level--)
-		if (lastiblock[level] < 0) {
-			oip->i_ib[level] = 0;
-			lastiblock[level] = -1;
-		}
-	for (i = NDADDR - 1; i > lastblock; i--)
-		oip->i_db[i] = 0;
-	oip->i_flag |= IN_CHANGE | IN_UPDATE;
-	allerror = EXT2_UPDATE(ovp, 1);
-
-	/*
-	 * Having written the new inode to disk, save its new configuration
-	 * and put back the old block pointers long enough to process them.
-	 * Note that we save the new block configuration so we can check it
-	 * when we are done.
-	 */
-	bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof newblks);
-	bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof oldblks);
-	oip->i_size = osize;
-	error = vtruncbuf(ovp, length, (int)fs->s_blocksize);
-	if (error && (allerror == 0))
-		allerror = error;
-
-	/*
-	 * Indirect blocks first.
-	 */
-	indir_lbn[SINGLE] = -NDADDR;
-	indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1;
-	indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1;
-	for (level = TRIPLE; level >= SINGLE; level--) {
-		bn = oip->i_ib[level];
-		if (bn != 0) {
-			error = ext2_indirtrunc(oip, indir_lbn[level],
-			    fsbtodoff(fs, bn), lastiblock[level], level, &count);
-			if (error)
-				allerror = error;
-			blocksreleased += count;
-			if (lastiblock[level] < 0) {
-				oip->i_ib[level] = 0;
-				ext2_blkfree(oip, bn, fs->s_frag_size);
-				blocksreleased += nblocks;
-			}
-		}
-		if (lastiblock[level] >= 0)
-			goto done;
-	}
-
-	/*
-	 * All whole direct blocks or frags.
-	 */
-	for (i = NDADDR - 1; i > lastblock; i--) {
-		long bsize;
-
-		bn = oip->i_db[i];
-		if (bn == 0)
-			continue;
-		oip->i_db[i] = 0;
-		bsize = blksize(fs, oip, i);
-		ext2_blkfree(oip, bn, bsize);
-		blocksreleased += btodb(bsize);
-	}
-	if (lastblock < 0)
-		goto done;
-
-	/*
-	 * Finally, look for a change in size of the
-	 * last direct block; release any frags.
-	 */
-	bn = oip->i_db[lastblock];
-	if (bn != 0) {
-		long oldspace, newspace;
-
-		/*
-		 * Calculate amount of space we're giving
-		 * back as old block size minus new block size.
-		 */
-		oldspace = blksize(fs, oip, lastblock);
-		oip->i_size = length;
-		newspace = blksize(fs, oip, lastblock);
-		if (newspace == 0)
-			panic("itrunc: newspace");
-		if (oldspace - newspace > 0) {
-			/*
-			 * Block number of space to be free'd is
-			 * the old block # plus the number of frags
-			 * required for the storage we're keeping.
-			 */
-			bn += numfrags(fs, newspace);
-			ext2_blkfree(oip, bn, oldspace - newspace);
-			blocksreleased += btodb(oldspace - newspace);
-		}
-	}
-done:
-#if DIAGNOSTIC
-	for (level = SINGLE; level <= TRIPLE; level++)
-		if (newblks[NDADDR + level] != oip->i_ib[level])
-			panic("itrunc1");
-	for (i = 0; i < NDADDR; i++)
-		if (newblks[i] != oip->i_db[i])
-			panic("itrunc2");
-	if (length == 0 && (!RB_EMPTY(&ovp->v_rbdirty_tree) ||
-			    !RB_EMPTY(&ovp->v_rbclean_tree)))
-		panic("itrunc3");
-#endif /* DIAGNOSTIC */
-	/*
-	 * Put back the real size.
-	 */
-	oip->i_size = length;
-	oip->i_blocks -= blocksreleased;
-	if (oip->i_blocks < 0)			/* sanity */
-		oip->i_blocks = 0;
-	oip->i_flag |= IN_CHANGE;
-	vnode_pager_setsize(ovp, length);
-#if QUOTA
-	ext2_chkdq(oip, -blocksreleased, NOCRED, 0);
-#endif
-	return (allerror);
-}
-
-/*
- * Release blocks associated with the inode ip and stored in the indirect
- * block bn.  Blocks are free'd in LIFO order up to (but not including)
- * lastbn.  If level is greater than SINGLE, the block is an indirect block
- * and recursive calls to indirtrunc must be used to cleanse other indirect
- * blocks.
- *
- * NB: triple indirect blocks are untested.
- */
-
-static int
-ext2_indirtrunc(struct inode *ip, daddr_t lbn, off_t doffset, daddr_t lastbn,
-		int level, long *countp)
-{
-	int i;
-	struct buf *bp;
-	struct ext2_sb_info *fs = ip->i_e2fs;
-	daddr_t *bap;
-	struct vnode *vp;
-	daddr_t *copy, nb, nlbn, last;
-	long blkcount, factor;
-	int nblocks, blocksreleased = 0;
-	int error = 0, allerror = 0;
-
-	/*
-	 * Calculate index in current block of last
-	 * block to be kept.  -1 indicates the entire
-	 * block so we need not calculate the index.
-	 */
-	factor = 1;
-	for (i = SINGLE; i < level; i++)
-		factor *= NINDIR(fs);
-	last = lastbn;
-	if (lastbn > 0)
-		last /= factor;
-	nblocks = btodb(fs->s_blocksize);
-	/*
-	 * Get buffer of block pointers, zero those entries corresponding
-	 * to blocks to be free'd, and update on disk copy first.  Since
-	 * double(triple) indirect before single(double) indirect, calls
-	 * to bmap on these blocks will fail.  However, we already have
-	 * the on disk address, so we have to set the bio_offset field
-	 * explicitly instead of letting bread do everything for us.
-	 */
-	vp = ITOV(ip);
-	bp = getblk(vp, lblktodoff(fs, lbn), (int)fs->s_blocksize, 0, 0);
-	if ((bp->b_flags & B_CACHE) == 0) {
-		bp->b_flags &= ~(B_ERROR | B_INVAL);
-		bp->b_cmd = BUF_CMD_READ;
-		if (bp->b_bcount > bp->b_bufsize)
-			panic("ext2_indirtrunc: bad buffer size");
-		bp->b_bio2.bio_offset = doffset;
-		bp->b_bio1.bio_done = biodone_sync;
-		bp->b_bio1.bio_flags |= BIO_SYNC;
-		vfs_busy_pages(bp->b_vp, bp);
-		vn_strategy(vp, &bp->b_bio1);
-		error = biowait(&bp->b_bio1, "biord");
-	}
-	if (error) {
-		brelse(bp);
-		*countp = 0;
-		return (error);
-	}
-
-	bap = (daddr_t *)bp->b_data;
-	MALLOC(copy, daddr_t *, fs->s_blocksize, M_TEMP, M_WAITOK);
-	bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->s_blocksize);
-	bzero((caddr_t)&bap[last + 1],
-	  (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t));
-	if (last == -1)
-		bp->b_flags |= B_INVAL;
-	error = bwrite(bp);
-	if (error)
-		allerror = error;
-	bap = copy;
-
-	/*
-	 * Recursively free totally unused blocks.
-	 */
-	for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last;
-	    i--, nlbn += factor) {
-		nb = bap[i];
-		if (nb == 0)
-			continue;
-		if (level > SINGLE) {
-			if ((error = ext2_indirtrunc(ip, nlbn,
-			    fsbtodoff(fs, nb), (daddr_t)-1, level - 1, &blkcount)) != 0)
-				allerror = error;
-			blocksreleased += blkcount;
-		}
-		ext2_blkfree(ip, nb, fs->s_blocksize);
-		blocksreleased += nblocks;
-	}
-
-	/*
-	 * Recursively free last partial block.
-	 */
-	if (level > SINGLE && lastbn >= 0) {
-		last = lastbn % factor;
-		nb = bap[i];
-		if (nb != 0) {
-			error = ext2_indirtrunc(ip, nlbn, fsbtodoff(fs, nb),
-						last, level - 1, &blkcount);
-			if (error)
-				allerror = error;
-			blocksreleased += blkcount;
-		}
-	}
-	FREE(copy, M_TEMP);
-	*countp = blocksreleased;
-	return (allerror);
-}
-
-/*
- * Last reference to an inode.  If necessary, write or delete it.
- *
- * ext2_inactive(struct vnode *a_vp)
- */
-int
-ext2_inactive(struct vop_inactive_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	int mode, error = 0;
-
-	ext2_discard_prealloc(ip);
-	if (prtactive && vp->v_sysref.refcnt > 1)
-		vprint("ext2_inactive: pushing active", vp);
-
-	/*
-	 * Ignore inodes related to stale file handles.
-	 */
-	if (ip == NULL || ip->i_mode == 0)
-		goto out;
-	if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
-#ifdef QUOTA
-		if (!ext2_getinoquota(ip))
-			(void)ext2_chkiq(ip, -1, NOCRED, FORCE);
-#endif
-		error = EXT2_TRUNCATE(vp, (off_t)0, 0, NOCRED);
-		ip->i_rdev = 0;
-		mode = ip->i_mode;
-		ip->i_mode = 0;
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-		EXT2_VFREE(vp, ip->i_number, mode);
-	}
-	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))
-		EXT2_UPDATE(vp, 0);
-out:
-	/*
-	 * If we are done with the inode, reclaim it
-	 * so that it can be reused immediately.
-	 */
-	if (ip == NULL || ip->i_mode == 0)
-		vrecycle(vp);
-	return (error);
-}
-
-/*
- * Reclaim an inode so that it can be used for other purposes.
- *
- * ext2_reclaim(struct vnode *a_vp)
- */
-int
-ext2_reclaim(struct vop_reclaim_args *ap)
-{
-	struct inode *ip;
-	struct vnode *vp = ap->a_vp;
-#ifdef QUOTA
-	int i;
-#endif
-
-	if (prtactive && vp->v_sysref.refcnt > 1)
-		vprint("ext2_reclaim: pushing active", vp);
-	ip = VTOI(vp);
-
-	/*
-	 * Lazy updates.
-	 */
-	if (ip) {
-		if (ip->i_flag & IN_LAZYMOD) {
-			ip->i_flag |= IN_MODIFIED;
-			EXT2_UPDATE(vp, 0);
-		}
-	}
-#ifdef INVARIANTS
-	if (ip && (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))) {
-		kprintf("WARNING: INODE %ld flags %08x: modified inode being released!\n", (long)ip->i_number, (int)ip->i_flag);
-		ip->i_flag |= IN_MODIFIED;
-		EXT2_UPDATE(vp, 0);
-	}
-#endif
-	/*
-	 * Remove the inode from its hash chain and purge namecache
-	 * data associated with the vnode.
-	 */
-	vp->v_data = NULL;
-	if (ip) {
-		ext2_ihashrem(ip);
-		if (ip->i_devvp) {
-			vrele(ip->i_devvp);
-			ip->i_devvp = 0;
-		}
-#ifdef QUOTA
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if (ip->i_dquot[i] != NODQUOT) {
-				ext2_dqrele(vp, ip->i_dquot[i]);
-				ip->i_dquot[i] = NODQUOT;
-			}
-		}
-#endif
-#ifdef UFS_DIRHASH
-		if (ip->i_dirhash != NULL)
-			ext2dirhash_free(ip);
-#endif
-		kfree(ip, VFSTOEXT2(vp->v_mount)->um_malloctype);
-	}
-	return (0);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_inode_cnv.c b/sys/vfs/gnu/ext2fs/ext2_inode_cnv.c
deleted file mode 100644
index edcc4ee..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_inode_cnv.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 1995 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- *      Utah $Hdr$
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_inode_cnv.c,v 1.11 2000/01/01 17:39:21 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_inode_cnv.c,v 1.7 2006/12/23 00:41:29 swildner Exp $
- */
-
-/*
- * routines to convert on disk ext2 inodes in dinodes and back
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-
-#include <machine/inttypes.h>
-
-#include "quota.h"
-
-#define NO_I_DEFINES
-#include "inode.h"
-#include "ext2_fs.h"
-#include "ext2_extern.h"
-
-void
-ext2_print_dinode(struct ext2_dinode *di)
-{
-	int i;
-	kprintf( /* "Inode: %5d" */
-		" Type: %10s Mode: 0x%o Flags: 0x%x  Version: %d\n",
-		"n/a", di->di_mode, di->di_flags, di->di_gen);
-	kprintf( "User: %5lu Group: %5lu  Size: %lu\n",
-		(unsigned long)di->di_uid, (unsigned long)di->di_gid,
-		(unsigned long)di->di_size);
-	kprintf( "Links: %3d Blockcount: %d\n",
-		di->di_nlink, di->di_blocks);
-	kprintf( "ctime: 0x%x", di->di_ctime); 
-	kprintf( "atime: 0x%x", di->di_atime); 
-	kprintf( "mtime: 0x%x", di->di_mtime); 
-	kprintf( "BLOCKS: ");
-	for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
-		kprintf("%d ", di->di_db[i]);
-	kprintf("\n");
-}
-
-void
-ext2_print_inode(struct inode *in)
-{
-	kprintf( "Inode: %"PRId64, in->i_number);
-	ext2_print_dinode(&in->i_din);
-}
-
-/*
- *	raw ext2 inode to dinode
- */
-void
-ext2_ei2di(struct ext2_inode *ei, struct ext2_dinode *di)
-{
-        int     i;
-
-        di->di_nlink    = ei->i_links_count;
-	/* Godmar thinks - if the link count is zero, then the inode is
-	   unused - according to ext2 standards. Ufs marks this fact
-	   by setting i_mode to zero - why ?
-	   I can see that this might lead to problems in an undelete.
-	*/
-	di->di_mode     = ei->i_links_count ? ei->i_mode : 0;
-        di->di_size     = ei->i_size;
-        di->di_atime	= ei->i_atime;
-        di->di_mtime	= ei->i_mtime;
-        di->di_ctime	= ei->i_ctime;
-        di->di_flags    = 0;
-        di->di_flags    |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
-        di->di_flags    |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
-        di->di_blocks   = ei->i_blocks;
-        di->di_gen      = ei->i_generation;
-        di->di_uid      = ei->i_uid;
-        di->di_gid      = ei->i_gid;
-	/* XXX use memcpy */
-        for(i = 0; i < NDADDR; i++)
-                di->di_db[i] = ei->i_block[i];
-        for(i = 0; i < NIADDR; i++)
-                di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
-}
-
-/*
- *	dinode to raw ext2 inode
- */
-void
-ext2_di2ei(struct ext2_dinode *di, struct ext2_inode *ei)
-{
-        int     i;
-
-        ei->i_mode              = di->di_mode;
-        ei->i_links_count       = di->di_nlink;
-	/* 
-	   Godmar thinks: if dtime is nonzero, ext2 says this inode
-	   has been deleted, this would correspond to a zero link count
-	 */
-        ei->i_dtime             = ei->i_links_count ? 0 : di->di_mtime;
-        ei->i_size              = di->di_size;
-        ei->i_atime             = di->di_atime;
-        ei->i_mtime             = di->di_mtime;
-        ei->i_ctime             = di->di_ctime;
-        ei->i_flags             = di->di_flags;
-        ei->i_flags    		= 0;
-        ei->i_flags    		|= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;
-        ei->i_flags    		|= (di->di_flags & IMMUTABLE) 
-							? EXT2_IMMUTABLE_FL: 0;
-        ei->i_blocks            = di->di_blocks;
-        ei->i_generation        = di->di_gen;
-        ei->i_uid               = di->di_uid;
-        ei->i_gid               = di->di_gid;
-	/* XXX use memcpy */
-        for(i = 0; i < NDADDR; i++)
-                ei->i_block[i] = di->di_db[i];
-        for(i = 0; i < NIADDR; i++)
-                ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i];
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_linux_balloc.c b/sys/vfs/gnu/ext2fs/ext2_linux_balloc.c
deleted file mode 100644
index c5274ff..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_linux_balloc.c
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- *
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_linux_balloc.c,v 1.11.2.3 2001/08/14 18:03:19 gallatin Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_linux_balloc.c,v 1.11 2007/09/23 04:09:55 yanyh Exp $
- */
-/*
- *  linux/fs/ext2/balloc.c
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- *  Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
- */
-
-/*
- * The free blocks are managed by bitmaps.  A file system contains several
- * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
- * block for inodes, N blocks for the inode table and data blocks.
- *
- * The file system contains group descriptors which are located after the
- * super block.  Each descriptor contains the number of the bitmap block and
- * the free blocks count in the block.  The descriptors are loaded in memory
- * when a file system is mounted (see ext2_read_super).
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/buf2.h>
-#include <sys/thread2.h>
-
-#include "quota.h"
-#include "dinode.h"
-#include "inode.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-
-#ifdef __i386__
-#include "i386-bitops.h"
-#else
-#include "ext2_bitops.h"
-#endif
-
-#define in_range(b, first, len)		((b) >= (first) && (b) <= (first) + (len) - 1)
-
-/* got rid of get_group_desc since it can already be found in 
- * ext2_linux_ialloc.c
- */
-
-static void
-read_block_bitmap(struct mount *mp, unsigned int block_group,
-		  unsigned long bitmap_nr)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct ext2_group_desc * gdp;
-	struct buffer_head * bh;
-	int    error;
-	
-	gdp = get_group_desc (mp, block_group, NULL);
-	error = bread(VFSTOEXT2(mp)->um_devvp, 
-		      fsbtodoff(sb, gdp->bg_block_bitmap),
-		      sb->s_blocksize, &bh);
-	if (error) {
-		panic ( "read_block_bitmap: "
-			    "Cannot read block bitmap - "
-			    "block_group = %d, block_bitmap = %lu",
-			    block_group, (unsigned long) gdp->bg_block_bitmap);
-	}
-	sb->s_block_bitmap_number[bitmap_nr] = block_group;
-	sb->s_block_bitmap[bitmap_nr] = bh;
-	LCK_BUF(bh)
-}
-
-/*
- * load_block_bitmap loads the block bitmap for a blocks group
- *
- * It maintains a cache for the last bitmaps loaded.  This cache is managed
- * with a LRU algorithm.
- *
- * Notes:
- * 1/ There is one cache per mounted file system.
- * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
- *    this function reads the bitmap without maintaining a LRU cache.
- */
-static int
-load__block_bitmap(struct mount *mp, unsigned int block_group)
-{
-	int i, j;
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	unsigned long block_bitmap_number;
-	struct buffer_head * block_bitmap;
-
-	if (block_group >= sb->s_groups_count)
-		panic ( "load_block_bitmap: "
-			    "block_group >= groups_count - "
-			    "block_group = %d, groups_count = %lu",
-			    block_group, sb->s_groups_count);
-
-	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
-		if (sb->s_block_bitmap[block_group]) {
-			if (sb->s_block_bitmap_number[block_group] !=
-			    block_group)
-				panic ( "load_block_bitmap: "
-					    "block_group != block_bitmap_number");
-			else
-				return block_group;
-		} else {
-			read_block_bitmap (mp, block_group, block_group);
-			return block_group;
-		}
-	}
-
-	for (i = 0; i < sb->s_loaded_block_bitmaps &&
-		    sb->s_block_bitmap_number[i] != block_group; i++)
-		;
-	if (i < sb->s_loaded_block_bitmaps &&
-  	    sb->s_block_bitmap_number[i] == block_group) {
-		block_bitmap_number = sb->s_block_bitmap_number[i];
-		block_bitmap = sb->s_block_bitmap[i];
-		for (j = i; j > 0; j--) {
-			sb->s_block_bitmap_number[j] =
-				sb->s_block_bitmap_number[j - 1];
-			sb->s_block_bitmap[j] =
-				sb->s_block_bitmap[j - 1];
-		}
-		sb->s_block_bitmap_number[0] = block_bitmap_number;
-		sb->s_block_bitmap[0] = block_bitmap;
-	} else {
-		if (sb->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED)
-			sb->s_loaded_block_bitmaps++;
-		else
-			ULCK_BUF(sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1])
-
-		for (j = sb->s_loaded_block_bitmaps - 1; j > 0;  j--) {
-			sb->s_block_bitmap_number[j] =
-				sb->s_block_bitmap_number[j - 1];
-			sb->s_block_bitmap[j] =
-				sb->s_block_bitmap[j - 1];
-		}
-		read_block_bitmap (mp, block_group, 0);
-	}
-	return 0;
-}
-
-static __inline int
-load_block_bitmap(struct mount * mp, unsigned int block_group)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	if (sb->s_loaded_block_bitmaps > 0 &&
-	    sb->s_block_bitmap_number[0] == block_group)
-		return 0;
-	
-	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED && 
-	    sb->s_block_bitmap_number[block_group] == block_group &&
-	    sb->s_block_bitmap[block_group]) 
-		return block_group;
-
-	return load__block_bitmap (mp, block_group);
-}
-
-void
-ext2_free_blocks(struct mount * mp, unsigned long block,
-		 unsigned long count)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct buffer_head * bh;
-	struct buffer_head * bh2;
-	unsigned long block_group;
-	unsigned long bit;
-	unsigned long i;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	struct ext2_super_block * es = sb->s_es;
-
-	if (!sb) {
-		kprintf ("ext2_free_blocks: nonexistent device");
-		return;
-	}
-	lock_super (VFSTOEXT2(mp)->um_devvp);
-	if (block < es->s_first_data_block || 
-	    (block + count) > es->s_blocks_count) {
-		kprintf ( "ext2_free_blocks: "
-			    "Freeing blocks not in datazone - "
-			    "block = %lu, count = %lu", block, count);
-		unlock_super (VFSTOEXT2(mp)->um_devvp);
-		return;
-	}
-
-	ext2_debug ("freeing blocks %lu to %lu\n", block, block+count-1);
-
-	block_group = (block - es->s_first_data_block) /
-		      EXT2_BLOCKS_PER_GROUP(sb);
-	bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb);
-	if (bit + count > EXT2_BLOCKS_PER_GROUP(sb))
-		panic ( "ext2_free_blocks: "
-			    "Freeing blocks across group boundary - "
-			    "Block = %lu, count = %lu",
-			    block, count);
-	bitmap_nr = load_block_bitmap (mp, block_group);
-	bh = sb->s_block_bitmap[bitmap_nr];
-	gdp = get_group_desc (mp, block_group, &bh2);
-
-	if (/* test_opt (sb, CHECK_STRICT) && 	assume always strict ! */
-	    (in_range (gdp->bg_block_bitmap, block, count) ||
-	     in_range (gdp->bg_inode_bitmap, block, count) ||
-	     in_range (block, gdp->bg_inode_table,
-		       sb->s_itb_per_group) ||
-	     in_range (block + count - 1, gdp->bg_inode_table,
-		       sb->s_itb_per_group)))
-		panic ( "ext2_free_blocks: "
-			    "Freeing blocks in system zones - "
-			    "Block = %lu, count = %lu",
-			    block, count);
-
-	for (i = 0; i < count; i++) {
-		if (!clear_bit (bit + i, bh->b_data))
-			kprintf ("ext2_free_blocks: "
-				      "bit already cleared for block %lu", 
-				      block);
-		else {
-			gdp->bg_free_blocks_count++;
-			es->s_free_blocks_count++;
-		}
-	}
-
-	mark_buffer_dirty(bh2);
-	mark_buffer_dirty(bh);
-/****
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
-****/
-	sb->s_dirt = 1;
-	unlock_super (VFSTOEXT2(mp)->um_devvp);
-	return;
-}
-
-/*
- * ext2_new_block uses a goal block to assist allocation.  If the goal is
- * free, or there is a free block within 32 blocks of the goal, that block
- * is allocated.  Otherwise a forward search is made for a free block; within 
- * each block group the search first looks for an entire free byte in the block
- * bitmap, and then for any free bit if that fails.
- */
-int
-ext2_new_block(struct mount * mp, unsigned long goal,
-	       u_int32_t * prealloc_count,
-	       u_int32_t * prealloc_block)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct buffer_head * bh;
-	struct buffer_head * bh2;
-	char * p, * r;
-	int i, j, k, tmp;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	struct ext2_super_block * es = sb->s_es;
-
-#ifdef EXT2FS_DEBUG
-	static int goal_hits = 0, goal_attempts = 0;
-#endif
-	if (!sb) {
-		kprintf ("ext2_new_block: nonexistent device");
-		return 0;
-	}
-	lock_super (VFSTOEXT2(mp)->um_devvp);
-
-        ext2_debug ("goal=%lu.\n", goal);
-
-repeat:
-	/*
-	 * First, test whether the goal block is free.
-	 */
-	if (goal < es->s_first_data_block || goal >= es->s_blocks_count)
-		goal = es->s_first_data_block;
-	i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb);
-	gdp = get_group_desc (mp, i, &bh2);
-	if (gdp->bg_free_blocks_count > 0) {
-		j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
-#ifdef EXT2FS_DEBUG
-		if (j)
-			goal_attempts++;
-#endif
-		bitmap_nr = load_block_bitmap (mp, i);
-		bh = sb->s_block_bitmap[bitmap_nr];
-
-		ext2_debug ("goal is at %d:%d.\n", i, j); 
-
-		if (!test_bit(j, bh->b_data)) {
-#ifdef EXT2FS_DEBUG
-			goal_hits++;
-			ext2_debug ("goal bit allocated.\n");
-#endif
-			goto got_block;
-		}
-		if (j) {
-			/*
-			 * The goal was occupied; search forward for a free 
-			 * block within the next XX blocks.
-			 *
-			 * end_goal is more or less random, but it has to be
-			 * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
-			 * next 64-bit boundary is simple..
-			 */
-			int end_goal = (j + 63) & ~63;
-			j = find_next_zero_bit(bh->b_data, end_goal, j);
-			if (j < end_goal)
-				goto got_block;
-		}
-	
-		ext2_debug ("Bit not found near goal\n");
-
-		/*
-		 * There has been no free block found in the near vicinity
-		 * of the goal: do a search forward through the block groups,
-		 * searching in each group first for an entire free byte in
-		 * the bitmap and then for any free bit.
-		 * 
-		 * Search first in the remainder of the current group; then,
-		 * cyclicly search through the rest of the groups.
-		 */
-		p = ((char *) bh->b_data) + (j >> 3);
-		r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
-		k = (r - ((char *) bh->b_data)) << 3;
-		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
-			j = k;
-			goto search_back;
-		}
-		k = find_next_zero_bit ((unsigned long *) bh->b_data, 
-					EXT2_BLOCKS_PER_GROUP(sb),
-					j);
-		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
-			j = k;
-			goto got_block;
-		}
-	}
-
-	ext2_debug ("Bit not found in block group %d.\n", i); 
-
-	/*
-	 * Now search the rest of the groups.  We assume that 
-	 * i and gdp correctly point to the last group visited.
-	 */
-	for (k = 0; k < sb->s_groups_count; k++) {
-		i++;
-		if (i >= sb->s_groups_count)
-			i = 0;
-		gdp = get_group_desc (mp, i, &bh2);
-		if (gdp->bg_free_blocks_count > 0)
-			break;
-	}
-	if (k >= sb->s_groups_count) {
-		unlock_super (VFSTOEXT2(mp)->um_devvp);
-		return 0;
-	}
-	bitmap_nr = load_block_bitmap (mp, i);
-	bh = sb->s_block_bitmap[bitmap_nr];
-	r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3);
-	j = (r - bh->b_data) << 3;
-
-	if (j < EXT2_BLOCKS_PER_GROUP(sb))
-		goto search_back;
-	else
-		j = find_first_zero_bit ((unsigned long *) bh->b_data,
-					 EXT2_BLOCKS_PER_GROUP(sb));
-	if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
-		kprintf ( "ext2_new_block: "
-			 "Free blocks count corrupted for block group %d", i);
-		unlock_super (VFSTOEXT2(mp)->um_devvp);
-		return 0;
-	}
-
-search_back:
-	/* 
-	 * We have succeeded in finding a free byte in the block
-	 * bitmap.  Now search backwards up to 7 bits to find the
-	 * start of this group of free blocks.
-	 */
-	for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--);
-	
-got_block:
-
-	ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
-
-	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block;
-
-	if (/* test_opt (sb, CHECK_STRICT) && we are always strict. */
-	    (tmp == gdp->bg_block_bitmap ||
-	     tmp == gdp->bg_inode_bitmap ||
-	     in_range (tmp, gdp->bg_inode_table, sb->s_itb_per_group)))
-		panic ( "ext2_new_block: "
-			    "Allocating block in system zone - "
-			    "%dth block = %u in group %u", j, tmp, i);
-
-	if (set_bit (j, bh->b_data)) {
-		kprintf ( "ext2_new_block: "
-			 "bit already set for block %d", j);
-		goto repeat;
-	}
-
-	ext2_debug ("found bit %d\n", j);
-
-	/*
-	 * Do block preallocation now if required.
-	 */
-#ifdef EXT2_PREALLOCATE
-	if (prealloc_block) {
-		*prealloc_count = 0;
-		*prealloc_block = tmp + 1;
-		for (k = 1;
-		     k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) {
-			if (set_bit (j + k, bh->b_data))
-				break;
-			(*prealloc_count)++;
-		}	
-		gdp->bg_free_blocks_count -= *prealloc_count;
-		es->s_free_blocks_count -= *prealloc_count;
-		ext2_debug ("Preallocated a further %lu bits.\n",
-			    *prealloc_count); 
-	}
-#endif
-
-	j = tmp;
-
-	mark_buffer_dirty(bh);
-/****
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
-****/
-	if (j >= es->s_blocks_count) {
-		kprintf ( "ext2_new_block: "
-			    "block >= blocks count - "
-			    "block_group = %d, block=%d", i, j);
-		unlock_super (VFSTOEXT2(mp)->um_devvp);
-		return 0;
-	}
-
-	ext2_debug ("allocating block %d. "
-		    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
-
-	gdp->bg_free_blocks_count--;
-	mark_buffer_dirty(bh2);
-	es->s_free_blocks_count--;
-	sb->s_dirt = 1;
-	unlock_super (VFSTOEXT2(mp)->um_devvp);
-	return j;
-}
-
-#ifdef unused
-static unsigned long
-ext2_count_free_blocks(struct mount * mp)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-#ifdef EXT2FS_DEBUG
-	struct ext2_super_block * es;
-	unsigned long desc_count, bitmap_count, x;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	int i;
-	
-	lock_super (VFSTOEXT2(mp)->um_devvp);
-	es = sb->s_es;
-	desc_count = 0;
-	bitmap_count = 0;
-	gdp = NULL;
-	for (i = 0; i < sb->s_groups_count; i++) {
-		gdp = get_group_desc (mp, i, NULL);
-		desc_count += gdp->bg_free_blocks_count;
-		bitmap_nr = load_block_bitmap (mp, i);
-		x = ext2_count_free (sb->s_block_bitmap[bitmap_nr],
-				     sb->s_blocksize);
-		ext2_debug ("group %d: stored = %d, counted = %lu\n",
-			i, gdp->bg_free_blocks_count, x);
-		bitmap_count += x;
-	}
-	ext2_debug( "stored = %lu, computed = %lu, %lu\n",
-	       es->s_free_blocks_count, desc_count, bitmap_count);
-	unlock_super (VFSTOEXT2(mp)->um_devvp);
-	return bitmap_count;
-#else
-	return sb->s_es->s_free_blocks_count;
-#endif
-}
-#endif /* unused */
-
-static __inline int
-block_in_use (unsigned long block, struct ext2_sb_info *sb,
-	      unsigned char * map)
-{
-	return test_bit ((block - sb->s_es->s_first_data_block) %
-			 EXT2_BLOCKS_PER_GROUP(sb), map);
-}
-
-static int
-test_root(int a, int b)
-{
-	if (a == 0)
-		return 1;
-	while (1) {
-		if (a == 1)
-			return 1;
-		if (a % b)
-			return 0;
-		a = a / b;
-	}
-}
-
-int
-ext2_group_sparse(int group)
-{
-	return (test_root(group, 3) || test_root(group, 5) ||
-		test_root(group, 7));
-}
-
-#ifdef unused
-static void
-ext2_check_blocks_bitmap(struct mount * mp)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct buffer_head * bh;
-	struct ext2_super_block * es;
-	unsigned long desc_count, bitmap_count, x;
-	unsigned long desc_blocks;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	int i, j;
-
-	lock_super (VFSTOEXT2(mp)->um_devvp);
-	es = sb->s_es;
-	desc_count = 0;
-	bitmap_count = 0;
-	gdp = NULL;
-	desc_blocks = (sb->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
-		      EXT2_DESC_PER_BLOCK(sb);
-	for (i = 0; i < sb->s_groups_count; i++) {
-		gdp = get_group_desc (mp, i, NULL);
-		desc_count += gdp->bg_free_blocks_count;
-		bitmap_nr = load_block_bitmap (mp, i);
-		bh = sb->s_block_bitmap[bitmap_nr];
-
-		if (!(es->s_feature_ro_compat &
-		     EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
-		    ext2_group_sparse(i)) {
-			if (!test_bit (0, bh->b_data))
-				kprintf ("ext2_check_blocks_bitmap: "
-					    "Superblock in group %d "
-					    "is marked free", i);
-
-			for (j = 0; j < desc_blocks; j++)
-				if (!test_bit (j + 1, bh->b_data))
-					kprintf ("ext2_check_blocks_bitmap: "
-					    "Descriptor block #%d in group "
-					    "%d is marked free", j, i);
-		}
-
-		if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
-			kprintf ("ext2_check_blocks_bitmap: "
-				    "Block bitmap for group %d is marked free",
-				    i);
-
-		if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data))
-			kprintf ("ext2_check_blocks_bitmap: "
-				    "Inode bitmap for group %d is marked free",
-				    i);
-
-		for (j = 0; j < sb->s_itb_per_group; j++)
-			if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data))
-				kprintf ("ext2_check_blocks_bitmap: "
-					    "Block #%d of the inode table in "
-					    "group %d is marked free", j, i);
-
-		x = ext2_count_free (bh, sb->s_blocksize);
-		if (gdp->bg_free_blocks_count != x)
-			kprintf ("ext2_check_blocks_bitmap: "
-				    "Wrong free blocks count for group %d, "
-				    "stored = %d, counted = %lu", i,
-				    gdp->bg_free_blocks_count, x);
-		bitmap_count += x;
-	}
-	if (es->s_free_blocks_count != bitmap_count)
-		kprintf ("ext2_check_blocks_bitmap: "
-			    "Wrong free blocks count in super block, "
-			    "stored = %lu, counted = %lu",
-			    (unsigned long) es->s_free_blocks_count, bitmap_count);
-	unlock_super (VFSTOEXT2(mp)->um_devvp);
-}
-#endif /* unused */
-
-/*
- *  this function is taken from 
- *  linux/fs/ext2/bitmap.c
- */
-
-static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
-
-unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
-{
-        unsigned int i;
-        unsigned long sum = 0;
-
-        if (!map)
-                return (0);
-        for (i = 0; i < numchars; i++)
-                sum += nibblemap[map->b_data[i] & 0xf] +
-                        nibblemap[(map->b_data[i] >> 4) & 0xf];
-        return (sum);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c b/sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c
deleted file mode 100644
index db6e78f..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- *
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_linux_ialloc.c,v 1.13.2.2 2001/08/14 18:03:19 gallatin Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_linux_ialloc.c,v 1.12 2007/09/23 04:09:55 yanyh Exp $
- */
-/*
- *  linux/fs/ext2/ialloc.c
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card@masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- *  BSD ufs-inspired inode and directory allocation by 
- *  Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
- */
-
-/*
- * The free inodes are managed by bitmaps.  A file system contains several
- * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
- * block for inodes, N blocks for the inode table and data blocks.
- *
- * The file system contains group descriptors which are located after the
- * super block.  Each descriptor contains the number of the bitmap block and
- * the free blocks count in the block.  The descriptors are loaded in memory
- * when a file system is mounted (see ext2_read_super).
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-#include <sys/stat.h>
-#include <sys/buf2.h>
-#include <sys/thread2.h>
-
-#ifdef __i386__
-#include "i386-bitops.h"
-#else
-#include "ext2_bitops.h"
-#endif
-
-/* this is supposed to mark a buffer dirty on ready for delayed writing
- */
-void
-mark_buffer_dirty(struct buf *bh)
-{
-	crit_enter();
-	bh->b_flags |= B_DIRTY;
-	crit_exit();
-} 
-
-struct ext2_group_desc *
-get_group_desc(struct mount * mp, unsigned int block_group,
-	       struct buffer_head **bh)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	unsigned long group_desc;
-	unsigned long desc;
-	struct ext2_group_desc * gdp;
-
-	if (block_group >= sb->s_groups_count)
-		panic ("get_group_desc: "
-			    "block_group >= groups_count - "
-			    "block_group = %d, groups_count = %lu",
-			    block_group, sb->s_groups_count);
-
-	group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
-	desc = block_group % EXT2_DESC_PER_BLOCK(sb);
-	if (!sb->s_group_desc[group_desc])
-		panic ( "get_group_desc:"
-			    "Group descriptor not loaded - "
-			    "block_group = %d, group_desc = %lu, desc = %lu",
-			     block_group, group_desc, desc);
-	gdp = (struct ext2_group_desc *) 
-		sb->s_group_desc[group_desc]->b_data;
-	if (bh)
-		*bh = sb->s_group_desc[group_desc];
-	return gdp + desc;
-}
-
-static void
-read_inode_bitmap(struct mount *mp, unsigned long block_group,
-		  unsigned int bitmap_nr)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct ext2_group_desc * gdp;
-	struct buffer_head * bh;
-	int	error;
-
-	gdp = get_group_desc (mp, block_group, NULL);
-	if ((error = bread (VFSTOEXT2(mp)->um_devvp, 
-			    fsbtodoff(sb, gdp->bg_inode_bitmap), 
-			    sb->s_blocksize, &bh)) != 0)
-		panic ( "read_inode_bitmap:"
-			    "Cannot read inode bitmap - "
-			    "block_group = %lu, inode_bitmap = %lu",
-			    block_group, (unsigned long) gdp->bg_inode_bitmap);
-	sb->s_inode_bitmap_number[bitmap_nr] = block_group;
-	sb->s_inode_bitmap[bitmap_nr] = bh;
-	LCK_BUF(bh)
-}
-
-/*
- * load_inode_bitmap loads the inode bitmap for a blocks group
- *
- * It maintains a cache for the last bitmaps loaded.  This cache is managed
- * with a LRU algorithm.
- *
- * Notes:
- * 1/ There is one cache per mounted file system.
- * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups,
- *    this function reads the bitmap without maintaining a LRU cache.
- */
-static int
-load_inode_bitmap(struct mount *mp, unsigned int block_group)
-{
-	struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	int i, j;
-	unsigned long inode_bitmap_number;
-	struct buffer_head * inode_bitmap;
-
-	if (block_group >= sb->s_groups_count)
-		panic ("load_inode_bitmap:"
-			    "block_group >= groups_count - "
-			    "block_group = %d, groups_count = %lu",
-			     block_group, sb->s_groups_count);
-	if (sb->s_loaded_inode_bitmaps > 0 &&
-	    sb->s_inode_bitmap_number[0] == block_group)
-		return 0;
-	if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) {
-		if (sb->s_inode_bitmap[block_group]) {
-			if (sb->s_inode_bitmap_number[block_group] != 
-				block_group)
-				panic ( "load_inode_bitmap:"
-				    "block_group != inode_bitmap_number");
-			else
-				return block_group;
-		} else {
-			read_inode_bitmap (mp, block_group, block_group);
-			return block_group;
-		}
-	}
-
-	for (i = 0; i < sb->s_loaded_inode_bitmaps &&
-		    sb->s_inode_bitmap_number[i] != block_group;
-	     i++)
-		;
-	if (i < sb->s_loaded_inode_bitmaps &&
-  	    sb->s_inode_bitmap_number[i] == block_group) {
-		inode_bitmap_number = sb->s_inode_bitmap_number[i];
-		inode_bitmap = sb->s_inode_bitmap[i];
-		for (j = i; j > 0; j--) {
-			sb->s_inode_bitmap_number[j] =
-				sb->s_inode_bitmap_number[j - 1];
-			sb->s_inode_bitmap[j] =
-				sb->s_inode_bitmap[j - 1];
-		}
-		sb->s_inode_bitmap_number[0] = inode_bitmap_number;
-		sb->s_inode_bitmap[0] = inode_bitmap;
-	} else {
-		if (sb->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED)
-			sb->s_loaded_inode_bitmaps++;
-		else
-			ULCK_BUF(sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1])
-		for (j = sb->s_loaded_inode_bitmaps - 1; j > 0; j--) {
-			sb->s_inode_bitmap_number[j] =
-				sb->s_inode_bitmap_number[j - 1];
-			sb->s_inode_bitmap[j] =
-				sb->s_inode_bitmap[j - 1];
-		}
-		read_inode_bitmap (mp, block_group, 0);
-	}
-	return 0;
-}
-
-
-void
-ext2_free_inode(struct inode *inode)
-{
-	struct ext2_sb_info * sb;
-	struct buffer_head * bh;
-	struct buffer_head * bh2;
-	unsigned long block_group;
-	unsigned long bit;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	struct ext2_super_block * es;
-
-	if (!inode)
-		return;
-
-	if (inode->i_nlink) {
-		kprintf ("ext2_free_inode: inode has nlink=%d\n",
-			inode->i_nlink);
-		return;
-	}
-
-	ext2_debug ("freeing inode %lu\n", inode->i_number);
-
-	sb = inode->i_e2fs;
-	lock_super (DEVVP(inode));
-	if (inode->i_number < EXT2_FIRST_INO(sb) ||
-	    inode->i_number > sb->s_es->s_inodes_count) {
-		kprintf ("free_inode reserved inode or nonexistent inode");
-		unlock_super (DEVVP(inode));
-		return;
-	}
-	es = sb->s_es;
-	block_group = (inode->i_number - 1) / EXT2_INODES_PER_GROUP(sb);
-	bit = (inode->i_number - 1) % EXT2_INODES_PER_GROUP(sb);
-	bitmap_nr = load_inode_bitmap (ITOV(inode)->v_mount, block_group);
-	bh = sb->s_inode_bitmap[bitmap_nr];
-	if (!clear_bit (bit, bh->b_data))	
-		kprintf ( "ext2_free_inode:"
-		      "bit already cleared for inode %lu",
-		      (unsigned long)inode->i_number);
-	else {
-		gdp = get_group_desc (ITOV(inode)->v_mount, block_group, &bh2);
-		gdp->bg_free_inodes_count++;
-		if (S_ISDIR(inode->i_mode)) 
-			gdp->bg_used_dirs_count--;
-		mark_buffer_dirty(bh2);
-		es->s_free_inodes_count++;
-	}
-	mark_buffer_dirty(bh);
-/*** XXX
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
-***/
-	sb->s_dirt = 1;
-	unlock_super (DEVVP(inode));
-}
-
-#if linux
-/*
- * This function increments the inode version number
- *
- * This may be used one day by the NFS server
- */
-static void
-inc_inode_version(struct inode *inode, struct ext2_group_desc *gdp, int mode)
-{
-	unsigned long inode_block;
-	struct buffer_head * bh;
-	struct ext2_inode * raw_inode;
-
-	inode_block = gdp->bg_inode_table + (((inode->i_number - 1) %
-			EXT2_INODES_PER_GROUP(inode->i_sb)) /
-			EXT2_INODES_PER_BLOCK(inode->i_sb));
-	bh = bread (inode->i_sb->s_dev, dbtob(inode_block), inode->i_sb->s_blocksize);
-	if (!bh) {
-		kprintf ("inc_inode_version Cannot load inode table block - "
-			    "inode=%lu, inode_block=%lu\n",
-			    inode->i_number, inode_block);
-		inode->u.ext2_i.i_version = 1;
-		return;
-	}
-	raw_inode = ((struct ext2_inode *) bh->b_data) +
-			(((inode->i_number - 1) %
-			EXT2_INODES_PER_GROUP(inode->i_sb)) %
-			EXT2_INODES_PER_BLOCK(inode->i_sb));
-	raw_inode->i_version++;
-	inode->u.ext2_i.i_version = raw_inode->i_version;
-	bdwrite (bh);
-}
-
-#endif /* linux */
-
-/*
- * There are two policies for allocating an inode.  If the new inode is
- * a directory, then a forward search is made for a block group with both
- * free space and a low directory-to-inode ratio; if that fails, then of
- * the groups with above-average free space, that group with the fewest
- * directories already is chosen.
- *
- * For other inodes, search forward from the parent directory\'s block
- * group to find a free inode.
- */
-/*
- * this functino has been reduced to the actual 'find the inode number' part
- */
-ino_t
-ext2_new_inode(const struct inode *dir, int mode)
-{
-	struct ext2_sb_info * sb;
-	struct buffer_head * bh;
-	struct buffer_head * bh2;
-	int i, j, avefreei;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	struct ext2_group_desc * tmp;
-	struct ext2_super_block * es;
-
-	if (!dir)
-		return 0;
-	sb = dir->i_e2fs;
-
-        lock_super (DEVVP(dir));
-        es = sb->s_es;
-repeat:
-        gdp = NULL; i=0;
-
-        if (S_ISDIR(mode)) {
-		avefreei = es->s_free_inodes_count /
-			sb->s_groups_count;
-/* I am not yet convinced that this next bit is necessary.
-		i = dir->u.ext2_i.i_block_group;
-		for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) {
-			tmp = get_group_desc (sb, i, &bh2);
-			if ((tmp->bg_used_dirs_count << 8) < 
-			    tmp->bg_free_inodes_count) {
-				gdp = tmp;
-				break;
-			}
-			else
-			i = ++i % sb->u.ext2_sb.s_groups_count;
-		}
-*/
-		if (!gdp) {
-			for (j = 0; j < sb->s_groups_count; j++) {
-				tmp = get_group_desc(ITOV(dir)->v_mount,j,&bh2);
-				if (tmp->bg_free_inodes_count &&
-					tmp->bg_free_inodes_count >= avefreei) {
-					if (!gdp || 
-					    (tmp->bg_free_blocks_count >
-					     gdp->bg_free_blocks_count)) {
-						i = j;
-						gdp = tmp;
-					}
-				}
-			}
-		}
-	}
-	else 
-	{
-		/*
-		 * Try to place the inode in its parent directory
-		 */
-		i = dir->i_block_group;
-		tmp = get_group_desc (ITOV(dir)->v_mount, i, &bh2);
-		if (tmp->bg_free_inodes_count)
-			gdp = tmp;
-		else
-		{
-			/*
-			 * Use a quadratic hash to find a group with a
-			 * free inode
-			 */
-			for (j = 1; j < sb->s_groups_count; j <<= 1) {
-				i += j;
-				if (i >= sb->s_groups_count)
-					i -= sb->s_groups_count;
-				tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2);
-				if (tmp->bg_free_inodes_count) {
-					gdp = tmp;
-					break;
-				}
-			}
-		}
-		if (!gdp) {
-			/*
-			 * That failed: try linear search for a free inode
-			 */
-			i = dir->i_block_group + 1;
-			for (j = 2; j < sb->s_groups_count; j++) {
-				if (++i >= sb->s_groups_count)
-					i = 0;
-				tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2);
-				if (tmp->bg_free_inodes_count) {
-					gdp = tmp;
-					break;
-				}
-			}
-		}
-	}
-
-	if (!gdp) {
-		unlock_super (DEVVP(dir));
-		return 0;
-	}
-	bitmap_nr = load_inode_bitmap (ITOV(dir)->v_mount, i);
-	bh = sb->s_inode_bitmap[bitmap_nr];
-	if ((j = find_first_zero_bit ((unsigned long *) bh->b_data,
-				      EXT2_INODES_PER_GROUP(sb))) <
-	    EXT2_INODES_PER_GROUP(sb)) {
-		if (set_bit (j, bh->b_data)) {
-			kprintf ( "ext2_new_inode:"
-				      "bit already set for inode %d", j);
-			goto repeat;
-		}
-/* Linux now does the following:
-		mark_buffer_dirty(bh);
-		if (sb->s_flags & MS_SYNCHRONOUS) {
-			ll_rw_block (WRITE, 1, &bh);
-			wait_on_buffer (bh);
-		}
-*/
-		mark_buffer_dirty(bh);
-	} else {
-		if (gdp->bg_free_inodes_count != 0) {
-			kprintf ( "ext2_new_inode:"
-				    "Free inodes count corrupted in group %d",
-				    i);
-			unlock_super (DEVVP(dir));
-			return 0;
-		}
-		goto repeat;
-	}
-	j += i * EXT2_INODES_PER_GROUP(sb) + 1;
-	if (j < EXT2_FIRST_INO(sb) || j > es->s_inodes_count) {
-		kprintf ( "ext2_new_inode:"
-			    "reserved inode or inode > inodes count - "
-			    "block_group = %d,inode=%d", i, j);
-		unlock_super (DEVVP(dir));
-		return 0;
-	}
-	gdp->bg_free_inodes_count--;
-	if (S_ISDIR(mode))
-		gdp->bg_used_dirs_count++;
-	mark_buffer_dirty(bh2);
-	es->s_free_inodes_count--;
-	/* mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); */
-	sb->s_dirt = 1;
-	unlock_super (DEVVP(dir));
-	return j;
-}
-
-#ifdef unused
-static unsigned long
-ext2_count_free_inodes(struct mount *mp)
-{
-#ifdef EXT2FS_DEBUG
-        struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
-	struct ext2_super_block * es;
-	unsigned long desc_count, bitmap_count, x;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	int i;
-
-	lock_super (VFSTOEXT2(mp)->um_devvp);
-	es = sb->s_es;
-	desc_count = 0;
-	bitmap_count = 0;
-	gdp = NULL;
-	for (i = 0; i < sb->s_groups_count; i++) {
-		gdp = get_group_desc (mp, i, NULL);
-		desc_count += gdp->bg_free_inodes_count;
-		bitmap_nr = load_inode_bitmap (mp, i);
-		x = ext2_count_free (sb->s_inode_bitmap[bitmap_nr],
-				     EXT2_INODES_PER_GROUP(sb) / 8);
-		ext2_debug ("group %d: stored = %d, counted = %lu\n",
-			i, gdp->bg_free_inodes_count, x);
-		bitmap_count += x;
-	}
-	ext2_debug("stored = %lu, computed = %lu, %lu\n",
-		es->s_free_inodes_count, desc_count, bitmap_count);
-	unlock_super (VFSTOEXT2(mp)->um_devvp);
-	return desc_count;
-#else
-	return VFSTOEXT2(mp)->um_e2fsb->s_free_inodes_count;
-#endif
-}
-#endif /* unused */
-
-#ifdef LATER
-void
-ext2_check_inodes_bitmap(struct mount *mp)
-{
-	struct ext2_super_block * es;
-	unsigned long desc_count, bitmap_count, x;
-	int bitmap_nr;
-	struct ext2_group_desc * gdp;
-	int i;
-
-	lock_super (sb);
-	es = sb->u.ext2_sb.s_es;
-	desc_count = 0;
-	bitmap_count = 0;
-	gdp = NULL;
-	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
-		gdp = get_group_desc (sb, i, NULL);
-		desc_count += gdp->bg_free_inodes_count;
-		bitmap_nr = load_inode_bitmap (sb, i);
-		x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr],
-				     EXT2_INODES_PER_GROUP(sb) / 8);
-		if (gdp->bg_free_inodes_count != x)
-			kprintf ( "ext2_check_inodes_bitmap:"
-				    "Wrong free inodes count in group %d, "
-				    "stored = %d, counted = %lu", i,
-				    gdp->bg_free_inodes_count, x);
-		bitmap_count += x;
-	}
-	if (es->s_free_inodes_count != bitmap_count)
-		kprintf ( "ext2_check_inodes_bitmap:"
-			    "Wrong free inodes count in super block, "
-			    "stored = %lu, counted = %lu",
-			    (unsigned long) es->s_free_inodes_count, bitmap_count);
-	unlock_super (sb);
-}
-#endif
diff --git a/sys/vfs/gnu/ext2fs/ext2_lookup.c b/sys/vfs/gnu/ext2fs/ext2_lookup.c
deleted file mode 100644
index d575e13..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_lookup.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- *
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_lookup.c,v 1.21.2.3 2002/11/17 02:02:42 bde Exp $
- */
-/*
- * Copyright (c) 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ufs_lookup.c	8.6 (Berkeley) 4/1/94
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/buf.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/dirent.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "dir.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-
-/* 
-   DIRBLKSIZE in ffs is DEV_BSIZE (in most cases 512)
-   while it is the native blocksize in ext2fs - thus, a #define
-   is no longer appropriate
-*/
-#undef  DIRBLKSIZ
-
-extern	int dirchk;
-
-static u_char ext2_ft_to_dt[] = {
-	DT_UNKNOWN,		/* EXT2_FT_UNKNOWN */
-	DT_REG,			/* EXT2_FT_REG_FILE */
-	DT_DIR,			/* EXT2_FT_DIR */
-	DT_CHR,			/* EXT2_FT_CHRDEV */
-	DT_BLK,			/* EXT2_FT_BLKDEV */
-	DT_FIFO,		/* EXT2_FT_FIFO */
-	DT_SOCK,		/* EXT2_FT_SOCK */
-	DT_LNK,			/* EXT2_FT_SYMLINK */
-};
-#define	FTTODT(ft)						\
-    ((ft) > NELEM(ext2_ft_to_dt) ?	\
-    DT_UNKNOWN : ext2_ft_to_dt[(ft)])
-
-static u_char dt_to_ext2_ft[] = {
-	EXT2_FT_UNKNOWN,	/* DT_UNKNOWN */
-	EXT2_FT_FIFO,		/* DT_FIFO */
-	EXT2_FT_CHRDEV,		/* DT_CHR */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_DIR,		/* DT_DIR */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_BLKDEV,		/* DT_BLK */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_REG_FILE,	/* DT_REG */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_SYMLINK,	/* DT_LNK */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_SOCK,		/* DT_SOCK */
-	EXT2_FT_UNKNOWN,	/* unused */
-	EXT2_FT_UNKNOWN,	/* DT_WHT */
-};
-#define	DTTOFT(dt)						\
-    ((dt) > NELEM(dt_to_ext2_ft) ?	\
-    EXT2_FT_UNKNOWN : dt_to_ext2_ft[(dt)])
-
-static int	ext2_dirbadentry (struct vnode *dp,
-				      struct ext2_dir_entry_2 *de,
-				      int entryoffsetinblock);
-
-/*
- * Vnode op for reading directories.
- *
- * The routine below assumes that the on-disk format of a directory
- * is the same as that defined by <sys/dirent.h>. If the on-disk
- * format changes, then it will be necessary to do a conversion
- * from the on-disk format that read returns to the format defined
- * by <sys/dirent.h>.
- */
-/*
- * this is exactly what we do here - the problem is that the conversion
- * will blow up some entries by four bytes, so it can't be done in place.
- * This is too bad. Right now the conversion is done entry by entry, the
- * converted entry is sent via uiomove. 
- *
- * XXX allocate a buffer, convert as many entries as possible, then send
- * the whole buffer to uiomove
- *
- * ext2_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
- */
-int
-ext2_readdir(struct vop_readdir_args *ap)
-{
-        struct uio *uio = ap->a_uio;
-        int count, error;
-	struct ext2_dir_entry_2 *edp, *dp;
-	int ncookies;
-	struct uio auio;
-	struct iovec aiov;
-	caddr_t dirbuf;
-	int DIRBLKSIZ = VTOI(ap->a_vp)->i_e2fs->s_blocksize;
-	int readcnt, retval;
-	off_t startoffset = uio->uio_offset;
-
-	if ((error = vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY)) != 0)
-		return(error);
-
-	count = uio->uio_resid;
-	/*
-	 * Avoid complications for partial directory entries by adjusting
-	 * the i/o to end at a block boundary.  Don't give up (like ufs
-	 * does) if the initial adjustment gives a negative count, since
-	 * many callers don't supply a large enough buffer.  The correct
-	 * size is a little larger than DIRBLKSIZ to allow for expansion
-	 * of directory entries, but some callers just use 512.
-	 */
-	count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
-	if (count <= 0)
-		count += DIRBLKSIZ;
-	if (count > MAXBSIZE)		/* limit to a reasonable size */
-		count = MAXBSIZE;
-
-#ifdef EXT2FS_DEBUG
-	kprintf("ext2_readdir: uio_offset = %lld, uio_resid = %d, count = %d\n", 
-	    uio->uio_offset, uio->uio_resid, count);
-#endif
-
-	auio = *uio;
-	auio.uio_iov = &aiov;
-	auio.uio_iovcnt = 1;
-	auio.uio_resid = count;
-	auio.uio_segflg = UIO_SYSSPACE;
-	aiov.iov_len = count;
-	MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
-	aiov.iov_base = dirbuf;
-	error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
-	if (error == 0) {
-		readcnt = count - auio.uio_resid;
-		edp = (struct ext2_dir_entry_2 *)&dirbuf[readcnt];
-		ncookies = 0;
-		for (dp = (struct ext2_dir_entry_2 *)dirbuf; 
-		    !error && uio->uio_resid > 0 && dp < edp; ) {
-			/*-
-			 * "New" ext2fs directory entries differ in 3 ways
-			 * from ufs on-disk ones:
-			 * - the name is not necessarily NUL-terminated.
-			 * - the file type field always exists and always
-			 * follows the name length field.
-			 * - the file type is encoded in a different way.
-			 *
-			 * "Old" ext2fs directory entries need no special
-			 * conversions, since they binary compatible with
-			 * "new" entries having a file type of 0 (i.e.,
-			 * EXT2_FT_UNKNOWN).  Splitting the old name length
-			 * field didn't make a mess like it did in ufs,
-			 * because ext2fs uses a machine-dependent disk
-			 * layout.
-			 */
-			if (dp->rec_len <= 0) {
-				error = EIO;
-				break;
-			}
-			retval = vop_write_dirent(&error, uio, dp->inode,
-			    FTTODT(dp->file_type), dp->name_len, dp->name);
-
-			if (retval)
-				break;
-			/* advance dp */
-			dp = (struct ext2_dir_entry_2 *)((char *)dp + dp->rec_len); 
-			if (!error)
-				ncookies++;
-		}
-		/* we need to correct uio_offset */
-		uio->uio_offset = startoffset + (caddr_t)dp - dirbuf;
-
-		if (!error && ap->a_ncookies != NULL) {
-			off_t *cookiep, *cookies, *ecookies;
-			off_t off;
-
-			if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
-				panic("ext2fs_readdir: unexpected uio from NFS server");
-			if (ncookies) {
-				MALLOC(cookies, off_t *,
-				       ncookies * sizeof(off_t),
-				       M_TEMP, M_WAITOK);
-			} else {
-				MALLOC(cookies, off_t *,
-				       sizeof(off_t), M_TEMP, M_WAITOK);
-			}
-			off = startoffset;
-			for (dp = (struct ext2_dir_entry_2 *)dirbuf,
-			     cookiep = cookies, ecookies = cookies + ncookies;
-			     cookiep < ecookies;
-			     dp = (struct ext2_dir_entry_2 *)((caddr_t) dp + dp->rec_len)) {
-				off += dp->rec_len;
-				*cookiep++ = off;
-			}
-			*ap->a_ncookies = ncookies;
-			*ap->a_cookies = cookies;
-		}
-	}
-	FREE(dirbuf, M_TEMP);
-	if (ap->a_eofflag)
-		*ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
-	vn_unlock(ap->a_vp);
-        return (error);
-}
-
-/*
- * Convert a component of a pathname into a pointer to a locked inode.
- * This is a very central and rather complicated routine.
- * If the file system is not maintained in a strict tree hierarchy,
- * this can result in a deadlock situation (see comments in code below).
- *
- * The cnp->cn_nameiop argument is LOOKUP, CREATE, RENAME, or DELETE depending
- * on whether the name is to be looked up, created, renamed, or deleted.
- * When CREATE, RENAME, or DELETE is specified, information usable in
- * creating, renaming, or deleting a directory entry may be calculated.
- * If flag has LOCKPARENT or'ed into it and the target of the pathname
- * exists, lookup returns both the target and its parent directory locked.
- * When creating or renaming and LOCKPARENT is specified, the target may
- * not be ".".  When deleting and LOCKPARENT is specified, the target may
- * be "."., but the caller must check to ensure it does an vrele and vput
- * instead of two vputs.
- *
- * Overall outline of ufs_lookup:
- *
- *	search for name in directory, to found or notfound
- * notfound:
- *	if creating, return locked directory, leaving info on available slots
- *	else return error
- * found:
- *	if at end of path and deleting, return information to allow delete
- *	if at end of path and rewriting (RENAME and LOCKPARENT), lock target
- *	  inode and return info to allow rewrite
- *	if not at end, add name to cache; if at end and neither creating
- *	  nor deleting, add name to cache
- *
- * ext2_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
- *	       struct componentname *a_cnp)
- */
-int
-ext2_lookup(struct vop_old_lookup_args *ap)
-{
-	struct vnode *vdp;	/* vnode for directory being searched */
-	struct inode *dp;	/* inode for directory being searched */
-	struct buf *bp;			/* a buffer of directory entries */
-	struct ext2_dir_entry_2 *ep; /* the current directory entry */
-	int entryoffsetinblock;		/* offset of ep in bp's buffer */
-	enum {NONE, COMPACT, FOUND} slotstatus;
-	doff_t slotoffset;		/* offset of area with free space */
-	int slotsize;			/* size of area at slotoffset */
-	int slotfreespace;		/* amount of space free in slot */
-	int slotneeded;			/* size of the entry we're seeking */
-	int numdirpasses;		/* strategy for directory search */
-	doff_t endsearch;		/* offset to end directory search */
-	doff_t prevoff;			/* prev entry dp->i_offset */
-	struct vnode *pdp;		/* saved dp during symlink work */
-	struct vnode *tdp;		/* returned by VFS_VGET */
-	doff_t enduseful;		/* pointer past last used dir slot */
-	u_long bmask;			/* block offset mask */
-	int lockparent;			/* 1 => lockparent flag is set */
-	int wantparent;			/* 1 => wantparent or lockparent flag */
-	int namlen, error;
-	struct vnode **vpp = ap->a_vpp;
-	struct componentname *cnp = ap->a_cnp;
-	struct ucred *cred = cnp->cn_cred;
-	int flags = cnp->cn_flags;
-	int nameiop = cnp->cn_nameiop;
-
-	int	DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize;
-
-	bp = NULL;
-	slotoffset = -1;
-	*vpp = NULL;
-	vdp = ap->a_dvp;
-	dp = VTOI(vdp);
-	lockparent = flags & CNP_LOCKPARENT;
-	wantparent = flags & (CNP_LOCKPARENT|CNP_WANTPARENT);
-
-	/*
-	 * We now have a segment name to search for, and a directory to search.
-	 */
-
-	/*
-	 * Suppress search for slots unless creating
-	 * file and at end of pathname, in which case
-	 * we watch for a place to put the new file in
-	 * case it doesn't already exist.
-	 */
-	slotstatus = FOUND;
-	slotfreespace = slotsize = slotneeded = 0;
-	if (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) {
-		slotstatus = NONE;
-		slotneeded = EXT2_DIR_REC_LEN(cnp->cn_namelen); 
-		/* was
-		slotneeded = (sizeof(struct direct) - MAXNAMLEN +
-			cnp->cn_namelen + 3) &~ 3; */
-	}
-
-	/*
-	 * If there is cached information on a previous search of
-	 * this directory, pick up where we last left off.
-	 * We cache only lookups as these are the most common
-	 * and have the greatest payoff. Caching CREATE has little
-	 * benefit as it usually must search the entire directory
-	 * to determine that the entry does not exist. Caching the
-	 * location of the last DELETE or RENAME has not reduced
-	 * profiling time and hence has been removed in the interest
-	 * of simplicity.
-	 */
-	bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
-	if (nameiop != NAMEI_LOOKUP || dp->i_diroff == 0 ||
-	    dp->i_diroff > dp->i_size) {
-		entryoffsetinblock = 0;
-		dp->i_offset = 0;
-		numdirpasses = 1;
-	} else {
-		dp->i_offset = dp->i_diroff;
-		if ((entryoffsetinblock = dp->i_offset & bmask) &&
-		    (error = EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
-			return (error);
-		numdirpasses = 2;
-	}
-	prevoff = dp->i_offset;
-	endsearch = roundup(dp->i_size, DIRBLKSIZ);
-	enduseful = 0;
-
-searchloop:
-	while (dp->i_offset < endsearch) {
-		/*
-		 * If necessary, get the next directory block.
-		 */
-		if ((dp->i_offset & bmask) == 0) {
-			if (bp != NULL)
-				brelse(bp);
-			if ((error =
-			    EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
-				return (error);
-			entryoffsetinblock = 0;
-		}
-		/*
-		 * If still looking for a slot, and at a DIRBLKSIZE
-		 * boundary, have to start looking for free space again.
-		 */
-		if (slotstatus == NONE &&
-		    (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) {
-			slotoffset = -1;
-			slotfreespace = 0;
-		}
-		/*
-		 * Get pointer to next entry.
-		 * Full validation checks are slow, so we only check
-		 * enough to insure forward progress through the
-		 * directory. Complete checks can be run by patching
-		 * "dirchk" to be true.
-		 */
-		ep = (struct ext2_dir_entry_2 *)
-			((char *)bp->b_data + entryoffsetinblock);
-		if (ep->rec_len == 0 ||
-		    (dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock))) {
-			int i;
-			ext2_dirbad(dp, dp->i_offset, "mangled entry");
-			i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
-			dp->i_offset += i;
-			entryoffsetinblock += i;
-			continue;
-		}
-
-		/*
-		 * If an appropriate sized slot has not yet been found,
-		 * check to see if one is available. Also accumulate space
-		 * in the current block so that we can determine if
-		 * compaction is viable.
-		 */
-		if (slotstatus != FOUND) {
-			int size = ep->rec_len;
-
-			if (ep->inode != 0)
-				size -= EXT2_DIR_REC_LEN(ep->name_len);
-			if (size > 0) {
-				if (size >= slotneeded) {
-					slotstatus = FOUND;
-					slotoffset = dp->i_offset;
-					slotsize = ep->rec_len;
-				} else if (slotstatus == NONE) {
-					slotfreespace += size;
-					if (slotoffset == -1)
-						slotoffset = dp->i_offset;
-					if (slotfreespace >= slotneeded) {
-						slotstatus = COMPACT;
-						slotsize = dp->i_offset +
-						      ep->rec_len - slotoffset;
-					}
-				}
-			}
-		}
-
-		/*
-		 * Check for a name match.
-		 */
-		if (ep->inode) {
-			namlen = ep->name_len;
-			if (namlen == cnp->cn_namelen &&
-			    !bcmp(cnp->cn_nameptr, ep->name,
-				(unsigned)namlen)) {
-				/*
-				 * Save directory entry's inode number and
-				 * reclen in ndp->ni_ufs area, and release
-				 * directory buffer.
-				 */
-				dp->i_ino = ep->inode;
-				dp->i_reclen = ep->rec_len;
-				goto found;
-			}
-		}
-		prevoff = dp->i_offset;
-		dp->i_offset += ep->rec_len;
-		entryoffsetinblock += ep->rec_len;
-		if (ep->inode)
-			enduseful = dp->i_offset;
-	}
-/* notfound: */
-	/*
-	 * If we started in the middle of the directory and failed
-	 * to find our target, we must check the beginning as well.
-	 */
-	if (numdirpasses == 2) {
-		numdirpasses--;
-		dp->i_offset = 0;
-		endsearch = dp->i_diroff;
-		goto searchloop;
-	}
-	if (bp != NULL)
-		brelse(bp);
-	/*
-	 * If creating, and at end of pathname and current
-	 * directory has not been removed, then can consider
-	 * allowing file to be created.
-	 */
-	if ((nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME) &&
-	    dp->i_nlink != 0) {
-		/*
-		 * Access for write is interpreted as allowing
-		 * creation of files in the directory.
-		 */
-		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
-			return (error);
-		/*
-		 * Return an indication of where the new directory
-		 * entry should be put.  If we didn't find a slot,
-		 * then set dp->i_count to 0 indicating
-		 * that the new slot belongs at the end of the
-		 * directory. If we found a slot, then the new entry
-		 * can be put in the range from dp->i_offset to
-		 * dp->i_offset + dp->i_count.
-		 */
-		if (slotstatus == NONE) {
-			dp->i_offset = roundup(dp->i_size, DIRBLKSIZ);
-			dp->i_count = 0;
-			enduseful = dp->i_offset;
-		} else {
-			dp->i_offset = slotoffset;
-			dp->i_count = slotsize;
-			if (enduseful < slotoffset + slotsize)
-				enduseful = slotoffset + slotsize;
-		}
-		dp->i_endoff = roundup(enduseful, DIRBLKSIZ);
-		dp->i_flag |= IN_CHANGE | IN_UPDATE;
-		/*
-		 * We return with the directory locked, so that
-		 * the parameters we set up above will still be
-		 * valid if we actually decide to do a direnter().
-		 * We return ni_vp == NULL to indicate that the entry
-		 * does not currently exist; we leave a pointer to
-		 * the (locked) directory inode in ndp->ni_dvp.
-		 * The pathname buffer is saved so that the name
-		 * can be obtained later.
-		 *
-		 * NB - if the directory is unlocked, then this
-		 * information cannot be used.
-		 */
-		if (!lockparent)
-			vn_unlock(vdp);
-		return (EJUSTRETURN);
-	}
-	return (ENOENT);
-
-found:
-	/*
-	 * Check that directory length properly reflects presence
-	 * of this entry.
-	 */
-	if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len)
-		> dp->i_size) {
-		ext2_dirbad(dp, dp->i_offset, "i_size too small");
-		dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len);
-		dp->i_flag |= IN_CHANGE | IN_UPDATE;
-	}
-	brelse(bp);
-
-	/*
-	 * Found component in pathname.
-	 * If the final component of path name, save information
-	 * in the cache as to where the entry was found.
-	 */
-	if (nameiop == NAMEI_LOOKUP)
-		dp->i_diroff = dp->i_offset &~ (DIRBLKSIZ - 1);
-
-	/*
-	 * If deleting, and at end of pathname, return
-	 * parameters which can be used to remove file.
-	 * If the wantparent flag isn't set, we return only
-	 * the directory (in ndp->ni_dvp), otherwise we go
-	 * on and lock the inode, being careful with ".".
-	 */
-	if (nameiop == NAMEI_DELETE) {
-		/*
-		 * Write access to directory required to delete files.
-		 */
-		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
-			return (error);
-		/*
-		 * Return pointer to current entry in dp->i_offset,
-		 * and distance past previous entry (if there
-		 * is a previous entry in this block) in dp->i_count.
-		 * Save directory inode pointer in ndp->ni_dvp for dirremove().
-		 */
-		if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
-			dp->i_count = 0;
-		else
-			dp->i_count = dp->i_offset - prevoff;
-		if (dp->i_number == dp->i_ino) {
-			vref(vdp);
-			*vpp = vdp;
-			return (0);
-		}
-		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
-			return (error);
-		/*
-		 * If directory is "sticky", then user must own
-		 * the directory, or the file in it, else she
-		 * may not delete it (unless she's root). This
-		 * implements append-only directories.
-		 */
-		if ((dp->i_mode & ISVTX) &&
-		    cred->cr_uid != 0 &&
-		    cred->cr_uid != dp->i_uid &&
-		    VTOI(tdp)->i_uid != cred->cr_uid) {
-			vput(tdp);
-			return (EPERM);
-		}
-		*vpp = tdp;
-		if (!lockparent)
-			vn_unlock(vdp);
-		return (0);
-	}
-
-	/*
-	 * If rewriting (RENAME), return the inode and the
-	 * information required to rewrite the present directory
-	 * Must get inode of directory entry to verify it's a
-	 * regular file, or empty directory.
-	 */
-	if (nameiop == NAMEI_RENAME && wantparent) {
-		if ((error = VOP_EACCESS(vdp, VWRITE, cred)) != 0)
-			return (error);
-		/*
-		 * Careful about locking second inode.
-		 * This can only occur if the target is ".".
-		 */
-		if (dp->i_number == dp->i_ino)
-			return (EISDIR);
-		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
-			return (error);
-		*vpp = tdp;
-		if (!lockparent)
-			vn_unlock(vdp);
-		return (0);
-	}
-
-	/*
-	 * Step through the translation in the name.  We do not `vput' the
-	 * directory because we may need it again if a symbolic link
-	 * is relative to the current directory.  Instead we save it
-	 * unlocked as "pdp".  We must get the target inode before unlocking
-	 * the directory to insure that the inode will not be removed
-	 * before we get it.  We prevent deadlock by always fetching
-	 * inodes from the root, moving down the directory tree. Thus
-	 * when following backward pointers ".." we must unlock the
-	 * parent directory before getting the requested directory.
-	 * There is a potential race condition here if both the current
-	 * and parent directories are removed before the VFS_VGET for the
-	 * inode associated with ".." returns.  We hope that this occurs
-	 * infrequently since we cannot avoid this race condition without
-	 * implementing a sophisticated deadlock detection algorithm.
-	 * Note also that this simple deadlock detection scheme will not
-	 * work if the file system has any hard links other than ".."
-	 * that point backwards in the directory structure.
-	 */
-	pdp = vdp;
-	if (flags & CNP_ISDOTDOT) {
-		vn_unlock(pdp);	/* race to get the inode */
-		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0) {
-			vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
-			return (error);
-		}
-		if (lockparent && (error = vn_lock(pdp, LK_EXCLUSIVE))) {
-			vput(tdp);
-			return (error);
-		}
-		*vpp = tdp;
-	} else if (dp->i_number == dp->i_ino) {
-		vref(vdp);	/* we want ourself, ie "." */
-		*vpp = vdp;
-	} else {
-		if ((error = VFS_VGET(vdp->v_mount, NULL, dp->i_ino, &tdp)) != 0)
-			return (error);
-		if (!lockparent)
-			vn_unlock(pdp);
-		*vpp = tdp;
-	}
-	return (0);
-}
-
-void
-ext2_dirbad(struct inode *ip, doff_t offset, char *how)
-{
-	struct mount *mp;
-
-	mp = ITOV(ip)->v_mount;
-	kprintf("%s: bad dir ino %lu at offset %ld: %s\n",
-	       mp->mnt_stat.f_mntfromname, (u_long)ip->i_number,
-	       (long)offset, how);
-	if ((mp->mnt_flag & MNT_RDONLY) == 0)
-		panic("ufs_dirbad: bad dir");
-}
-
-/*
- * Do consistency checking on a directory entry:
- *	record length must be multiple of 4
- *	entry must fit in rest of its DIRBLKSIZ block
- *	record must be large enough to contain entry
- *	name is not longer than MAXNAMLEN
- *	name must be as long as advertised, and null terminated
- */
-/*
- *	changed so that it confirms to ext2_check_dir_entry
- */
-static int
-ext2_dirbadentry(struct vnode *dp, struct ext2_dir_entry_2 *de,
-		 int entryoffsetinblock)
-{
-	int	DIRBLKSIZ = VTOI(dp)->i_e2fs->s_blocksize;
-
-        char * error_msg = NULL;
-
-        if (de->rec_len < EXT2_DIR_REC_LEN(1))
-                error_msg = "rec_len is smaller than minimal";
-        else if (de->rec_len % 4 != 0)
-                error_msg = "rec_len % 4 != 0";
-        else if (de->rec_len < EXT2_DIR_REC_LEN(de->name_len))
-                error_msg = "reclen is too small for name_len";
-        else if (entryoffsetinblock + de->rec_len > DIRBLKSIZ)
-                error_msg = "directory entry across blocks";
-        /* else LATER
-	     if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count)
-                error_msg = "inode out of bounds";
-	*/
-
-        if (error_msg != NULL) {
-                kprintf("bad directory entry: %s\n", error_msg);
-                kprintf("offset=%d, inode=%lu, rec_len=%u, name_len=%u\n",
-			entryoffsetinblock, (unsigned long)de->inode,
-			de->rec_len, de->name_len);
-        }
-        return error_msg == NULL ? 0 : 1;
-}
-
-/*
- * Write a directory entry after a call to namei, using the parameters
- * that it left in the directory inode.  The argument ip is the inode which
- * the new directory entry will refer to.  Dvp is a pointer to the directory 
- * to be written, which was left locked by namei. Remaining parameters
- * (dp->i_offset, dp->i_count) indicate how the space for the new
- * entry is to be obtained.
- */
-int
-ext2_direnter(struct inode *ip, struct vnode *dvp, struct componentname *cnp)
-{
-	struct ext2_dir_entry_2 *ep, *nep;
-	struct inode *dp;
-	struct buf *bp;
-	struct ext2_dir_entry_2 newdir;
-	struct iovec aiov;
-	struct uio auio;
-	u_int dsize;
-	int error, loc, newentrysize, spacefree;
-	char *dirbuf;
-	int     DIRBLKSIZ = ip->i_e2fs->s_blocksize;
-
-
-	dp = VTOI(dvp);
-	newdir.inode = ip->i_number;
-	newdir.name_len = cnp->cn_namelen;
-	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
-	    EXT2_FEATURE_INCOMPAT_FILETYPE))
-		newdir.file_type = DTTOFT(IFTODT(ip->i_mode));
-	else
-		newdir.file_type = EXT2_FT_UNKNOWN;
-	bcopy(cnp->cn_nameptr, newdir.name, (unsigned)cnp->cn_namelen + 1);
-	newentrysize = EXT2_DIR_REC_LEN(newdir.name_len);
-	if (dp->i_count == 0) {
-		/*
-		 * If dp->i_count is 0, then namei could find no
-		 * space in the directory. Here, dp->i_offset will
-		 * be on a directory block boundary and we will write the
-		 * new entry into a fresh block.
-		 */
-		if (dp->i_offset & (DIRBLKSIZ - 1))
-			panic("ext2_direnter: newblk");
-		auio.uio_offset = dp->i_offset;
-		newdir.rec_len = DIRBLKSIZ;
-		auio.uio_resid = newentrysize;
-		aiov.iov_len = newentrysize;
-		aiov.iov_base = (caddr_t)&newdir;
-		auio.uio_iov = &aiov;
-		auio.uio_iovcnt = 1;
-		auio.uio_rw = UIO_WRITE;
-		auio.uio_segflg = UIO_SYSSPACE;
-		auio.uio_td = NULL;
-		error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred);
-		if (DIRBLKSIZ >
-		    VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
-			/* XXX should grow with balloc() */
-			panic("ext2_direnter: frag size");
-		else if (!error) {
-			dp->i_size = roundup(dp->i_size, DIRBLKSIZ);
-			dp->i_flag |= IN_CHANGE;
-		}
-		return (error);
-	}
-
-	/*
-	 * If dp->i_count is non-zero, then namei found space
-	 * for the new entry in the range dp->i_offset to
-	 * dp->i_offset + dp->i_count in the directory.
-	 * To use this space, we may have to compact the entries located
-	 * there, by copying them together towards the beginning of the
-	 * block, leaving the free space in one usable chunk at the end.
-	 */
-
-	/*
-	 * Increase size of directory if entry eats into new space.
-	 * This should never push the size past a new multiple of
-	 * DIRBLKSIZE.
-	 *
-	 * N.B. - THIS IS AN ARTIFACT OF 4.2 AND SHOULD NEVER HAPPEN.
-	 */
-	if (dp->i_offset + dp->i_count > dp->i_size)
-		dp->i_size = dp->i_offset + dp->i_count;
-	/*
-	 * Get the block containing the space for the new directory entry.
-	 */
-	if ((error = EXT2_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) != 0)
-		return (error);
-	/*
-	 * Find space for the new entry. In the simple case, the entry at
-	 * offset base will have the space. If it does not, then namei
-	 * arranged that compacting the region dp->i_offset to
-	 * dp->i_offset + dp->i_count would yield the
-	 * space.
-	 */
-	ep = (struct ext2_dir_entry_2 *)dirbuf;
-	dsize = EXT2_DIR_REC_LEN(ep->name_len);
-	spacefree = ep->rec_len - dsize;
-	for (loc = ep->rec_len; loc < dp->i_count; ) {
-		nep = (struct ext2_dir_entry_2 *)(dirbuf + loc);
-		if (ep->inode) {
-			/* trim the existing slot */
-			ep->rec_len = dsize;
-			ep = (struct ext2_dir_entry_2 *)((char *)ep + dsize);
-		} else {
-			/* overwrite; nothing there; header is ours */
-			spacefree += dsize;
-		}
-		dsize = EXT2_DIR_REC_LEN(nep->name_len);
-		spacefree += nep->rec_len - dsize;
-		loc += nep->rec_len;
-		bcopy((caddr_t)nep, (caddr_t)ep, dsize);
-	}
-	/*
-	 * Update the pointer fields in the previous entry (if any),
-	 * copy in the new entry, and write out the block.
-	 */
-	if (ep->inode == 0) {
-		if (spacefree + dsize < newentrysize)
-			panic("ext2_direnter: compact1");
-		newdir.rec_len = spacefree + dsize;
-	} else {
-		if (spacefree < newentrysize)
-			panic("ext2_direnter: compact2");
-		newdir.rec_len = spacefree;
-		ep->rec_len = dsize;
-		ep = (struct ext2_dir_entry_2 *)((char *)ep + dsize);
-	}
-	bcopy((caddr_t)&newdir, (caddr_t)ep, (u_int)newentrysize);
-	error = bwrite(bp);
-	dp->i_flag |= IN_CHANGE | IN_UPDATE;
-	if (!error && dp->i_endoff && dp->i_endoff < dp->i_size)
-		error = EXT2_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC,
-				      cnp->cn_cred);
-	return (error);
-}
-
-/*
- * Remove a directory entry after a call to namei, using
- * the parameters which it left in the directory inode. The entry
- * dp->i_offset contains the offset into the directory of the
- * entry to be eliminated.  The dp->i_count field contains the
- * size of the previous record in the directory.  If this
- * is 0, the first entry is being deleted, so we need only
- * zero the inode number to mark the entry as free.  If the
- * entry is not the first in the directory, we must reclaim
- * the space of the now empty record by adding the record size
- * to the size of the previous entry.
- */
-int
-ext2_dirremove(struct vnode *dvp, struct componentname *cnp)
-{
-	struct inode *dp;
-	struct ext2_dir_entry_2 *ep;
-	struct buf *bp;
-	int error;
-	 
-	dp = VTOI(dvp);
-	if (dp->i_count == 0) {
-		/*
-		 * First entry in block: set d_ino to zero.
-		 */
-		if ((error =
-		    EXT2_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
-			return (error);
-		ep->inode = 0;
-		error = bwrite(bp);
-		dp->i_flag |= IN_CHANGE | IN_UPDATE;
-		return (error);
-	}
-	/*
-	 * Collapse new free space into previous entry.
-	 */
-	if ((error = EXT2_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count),
-	    (char **)&ep, &bp)) != 0)
-		return (error);
-	ep->rec_len += dp->i_reclen;
-	error = bwrite(bp);
-	dp->i_flag |= IN_CHANGE | IN_UPDATE;
-	return (error);
-}
-
-/*
- * Rewrite an existing directory entry to point at the inode
- * supplied.  The parameters describing the directory entry are
- * set up by a call to namei.
- */
-int
-ext2_dirrewrite(struct inode *dp, struct inode *ip, struct componentname *cnp)
-{
-	struct buf *bp;
-	struct ext2_dir_entry_2 *ep;
-	struct vnode *vdp = ITOV(dp);
-	int error;
-
-	if ((error = EXT2_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
-		return (error);
-	ep->inode = ip->i_number;
-	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
-	    EXT2_FEATURE_INCOMPAT_FILETYPE))
-		ep->file_type = DTTOFT(IFTODT(ip->i_mode));
-	else
-		ep->file_type = EXT2_FT_UNKNOWN;
-	error = bwrite(bp);
-	dp->i_flag |= IN_CHANGE | IN_UPDATE;
-	return (error);
-}
-
-/*
- * Check if a directory is empty or not.
- * Inode supplied must be locked.
- *
- * Using a struct dirtemplate here is not precisely
- * what we want, but better than using a struct direct.
- *
- * NB: does not handle corrupted directories.
- */
-int
-ext2_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred)
-{
-	off_t off;
-	struct dirtemplate dbuf;
-	struct ext2_dir_entry_2 *dp = (struct ext2_dir_entry_2 *)&dbuf;
-	int error, count, namlen;
-		 
-#define	MINDIRSIZ (sizeof (struct dirtemplate) / 2)
-
-	for (off = 0; off < ip->i_size; off += dp->rec_len) {
-		error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off,
-			        UIO_SYSSPACE, IO_NODELOCKED, cred, &count);
-		/*
-		 * Since we read MINDIRSIZ, residual must
-		 * be 0 unless we're at end of file.
-		 */
-		if (error || count != 0)
-			return (0);
-		/* avoid infinite loops */
-		if (dp->rec_len == 0)
-			return (0);
-		/* skip empty entries */
-		if (dp->inode == 0)
-			continue;
-		/* accept only "." and ".." */
-		namlen = dp->name_len;
-		if (namlen > 2)
-			return (0);
-		if (dp->name[0] != '.')
-			return (0);
-		/*
-		 * At this point namlen must be 1 or 2.
-		 * 1 implies ".", 2 implies ".." if second
-		 * char is also "."
-		 */
-		if (namlen == 1)
-			continue;
-		if (dp->name[1] == '.' && dp->inode == parentino)
-			continue;
-		return (0);
-	}
-	return (1);
-}
-
-/*
- * Check if source directory is in the path of the target directory.
- * Target is supplied locked, source is unlocked.
- * The target is always vput before returning.
- */
-int
-ext2_checkpath(struct inode *source, struct inode *target, struct ucred *cred)
-{
-	struct vnode *vp;
-	int error, rootino, namlen;
-	struct dirtemplate dirbuf;
-
-	vp = ITOV(target);
-	if (target->i_number == source->i_number) {
-		error = EEXIST;
-		goto out;
-	}
-	rootino = ROOTINO;
-	error = 0;
-	if (target->i_number == rootino)
-		goto out;
-
-	for (;;) {
-		if (vp->v_type != VDIR) {
-			error = ENOTDIR;
-			break;
-		}
-		error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
-				sizeof (struct dirtemplate), (off_t)0,
-				UIO_SYSSPACE, IO_NODELOCKED, cred, NULL);
-		if (error != 0)
-			break;
-		namlen = dirbuf.dotdot_type;	/* like ufs little-endian */
-		if (namlen != 2 ||
-		    dirbuf.dotdot_name[0] != '.' ||
-		    dirbuf.dotdot_name[1] != '.') {
-			error = ENOTDIR;
-			break;
-		}
-		if (dirbuf.dotdot_ino == source->i_number) {
-			error = EINVAL;
-			break;
-		}
-		if (dirbuf.dotdot_ino == rootino)
-			break;
-		vput(vp);
-		if ((error = VFS_VGET(vp->v_mount, NULL, dirbuf.dotdot_ino, &vp)) != 0) {
-			vp = NULL;
-			break;
-		}
-	}
-
-out:
-	if (error == ENOTDIR)
-		kprintf("checkpath: .. not a directory\n");
-	if (vp != NULL)
-		vput(vp);
-	return (error);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_quota.c b/sys/vfs/gnu/ext2fs/ext2_quota.c
deleted file mode 100644
index 426d98e..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_quota.c
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1990, 1993, 1995
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Robert Elz at The University of Melbourne.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ufs_quota.c	8.5 (Berkeley) 5/20/95
- * $FreeBSD: src/sys/ufs/ufs/ufs_quota.c,v 1.27.2.3 2002/01/15 10:33:32 phk Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_quota.c,v 1.8 2008/01/05 14:02:41 swildner Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/fcntl.h>
-#include <sys/proc.h>
-#include <sys/nlookup.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <vm/vm_zone.h>
-
-#include "quota.h"
-#include "dinode.h"
-#include "inode.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-
-static MALLOC_DEFINE(M_EXT2DQUOT, "EXT2 quota", "EXT2 quota entries");
-
-/*
- * Quota name to error message mapping.
- */
-static char *quotatypes[] = INITQFNAMES;
-
-static int ext2_chkdqchg (struct inode *, long, struct ucred *, int);
-static int ext2_chkiqchg (struct inode *, long, struct ucred *, int);
-static int ext2_dqget (struct vnode *,
-		u_long, struct ext2mount *, int, struct ext2_dquot **);
-static int ext2_dqsync (struct vnode *, struct ext2_dquot *);
-static void ext2_dqflush (struct vnode *);
-
-#ifdef DIAGNOSTIC
-static void ext2_dqref (struct ext2_dquot *);
-static void ext2_chkdquot (struct inode *);
-#endif
-
-/*
- * Set up the quotas for an inode.
- *
- * This routine completely defines the semantics of quotas.
- * If other criterion want to be used to establish quotas, the
- * MAXQUOTAS value in quotas.h should be increased, and the
- * additional dquots set up here.
- */
-int
-ext2_getinoquota(struct inode *ip)
-{
-	struct ext2mount *ump;
-	struct vnode *vp = ITOV(ip);
-	int error;
-
-	ump = VFSTOEXT2(vp->v_mount);
-	/*
-	 * Set up the user quota based on file uid.
-	 * EINVAL means that quotas are not enabled.
-	 */
-	if (ip->i_dquot[USRQUOTA] == NODQUOT &&
-	    (error = ext2_dqget(vp, ip->i_uid, ump, USRQUOTA, &ip->i_dquot[USRQUOTA])) &&
-	    error != EINVAL)
-		return (error);
-	/*
-	 * Set up the group quota based on file gid.
-	 * EINVAL means that quotas are not enabled.
-	 */
-	if (ip->i_dquot[GRPQUOTA] == NODQUOT &&
-	    (error = ext2_dqget(vp, ip->i_gid, ump, GRPQUOTA, &ip->i_dquot[GRPQUOTA])) &&
-	    error != EINVAL)
-		return (error);
-	return (0);
-}
-
-/*
- * Update disk usage, and take corrective action.
- */
-int
-ext2_chkdq(struct inode *ip, long change, struct ucred *cred, int flags)
-{
-	struct ext2_dquot *dq;
-	int i;
-	int ncurblocks, error;
-
-#ifdef DIAGNOSTIC
-	if ((flags & CHOWN) == 0)
-		ext2_chkdquot(ip);
-#endif
-	if (change == 0)
-		return (0);
-	if (change < 0) {
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if ((dq = ip->i_dquot[i]) == NODQUOT)
-				continue;
-			while (dq->dq_flags & DQ_LOCK) {
-				dq->dq_flags |= DQ_WANT;
-				(void) tsleep((caddr_t)dq, 0, "chkdq1", 0);
-			}
-			ncurblocks = dq->dq_curblocks + change;
-			if (ncurblocks >= 0)
-				dq->dq_curblocks = ncurblocks;
-			else
-				dq->dq_curblocks = 0;
-			dq->dq_flags &= ~DQ_BLKS;
-			dq->dq_flags |= DQ_MOD;
-		}
-		return (0);
-	}
-	if ((flags & FORCE) == 0 && cred->cr_uid != 0) {
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if ((dq = ip->i_dquot[i]) == NODQUOT)
-				continue;
-			error = ext2_chkdqchg(ip, change, cred, i);
-			if (error)
-				return (error);
-		}
-	}
-	for (i = 0; i < MAXQUOTAS; i++) {
-		if ((dq = ip->i_dquot[i]) == NODQUOT)
-			continue;
-		while (dq->dq_flags & DQ_LOCK) {
-			dq->dq_flags |= DQ_WANT;
-			(void) tsleep((caddr_t)dq, 0, "chkdq2", 0);
-		}
-		/* Reset timer when crossing soft limit */
-		if (dq->dq_curblocks + change >= dq->dq_bsoftlimit &&
-		    dq->dq_curblocks < dq->dq_bsoftlimit)
-			dq->dq_btime = time_second +
-			    VFSTOEXT2(ITOV(ip)->v_mount)->um_btime[i];
-		dq->dq_curblocks += change;
-		dq->dq_flags |= DQ_MOD;
-	}
-	return (0);
-}
-
-/*
- * Check for a valid change to a users allocation.
- * Issue an error message if appropriate.
- */
-static int
-ext2_chkdqchg(struct inode *ip, long change, struct ucred *cred, int type)
-{
-	struct ext2_dquot *dq = ip->i_dquot[type];
-	long ncurblocks = dq->dq_curblocks + change;
-
-	/*
-	 * If user would exceed their hard limit, disallow space allocation.
-	 */
-	if (ncurblocks >= dq->dq_bhardlimit && dq->dq_bhardlimit) {
-		if ((dq->dq_flags & DQ_BLKS) == 0 &&
-		    ip->i_uid == cred->cr_uid) {
-			uprintf("\n%s: write failed, %s disk limit reached\n",
-			    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-			    quotatypes[type]);
-			dq->dq_flags |= DQ_BLKS;
-		}
-		return (EDQUOT);
-	}
-	/*
-	 * If user is over their soft limit for too long, disallow space
-	 * allocation. Reset time limit as they cross their soft limit.
-	 */
-	if (ncurblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) {
-		if (dq->dq_curblocks < dq->dq_bsoftlimit) {
-			dq->dq_btime = time_second +
-			    VFSTOEXT2(ITOV(ip)->v_mount)->um_btime[type];
-			if (ip->i_uid == cred->cr_uid)
-				uprintf("\n%s: warning, %s %s\n",
-				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-				    quotatypes[type], "disk quota exceeded");
-			return (0);
-		}
-		if (time_second > dq->dq_btime) {
-			if ((dq->dq_flags & DQ_BLKS) == 0 &&
-			    ip->i_uid == cred->cr_uid) {
-				uprintf("\n%s: write failed, %s %s\n",
-				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-				    quotatypes[type],
-				    "disk quota exceeded for too long");
-				dq->dq_flags |= DQ_BLKS;
-			}
-			return (EDQUOT);
-		}
-	}
-	return (0);
-}
-
-/*
- * Check the inode limit, applying corrective action.
- */
-int
-ext2_chkiq(struct inode *ip, long change, struct ucred *cred, int flags)
-{
-	struct ext2_dquot *dq;
-	int i;
-	int ncurinodes, error;
-
-#ifdef DIAGNOSTIC
-	if ((flags & CHOWN) == 0)
-		ext2_chkdquot(ip);
-#endif
-	if (change == 0)
-		return (0);
-	if (change < 0) {
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if ((dq = ip->i_dquot[i]) == NODQUOT)
-				continue;
-			while (dq->dq_flags & DQ_LOCK) {
-				dq->dq_flags |= DQ_WANT;
-				(void) tsleep((caddr_t)dq, 0, "chkiq1", 0);
-			}
-			ncurinodes = dq->dq_curinodes + change;
-			if (ncurinodes >= 0)
-				dq->dq_curinodes = ncurinodes;
-			else
-				dq->dq_curinodes = 0;
-			dq->dq_flags &= ~DQ_INODS;
-			dq->dq_flags |= DQ_MOD;
-		}
-		return (0);
-	}
-	if ((flags & FORCE) == 0 && cred->cr_uid != 0) {
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if ((dq = ip->i_dquot[i]) == NODQUOT)
-				continue;
-			error = ext2_chkiqchg(ip, change, cred, i);
-			if (error)
-				return (error);
-		}
-	}
-	for (i = 0; i < MAXQUOTAS; i++) {
-		if ((dq = ip->i_dquot[i]) == NODQUOT)
-			continue;
-		while (dq->dq_flags & DQ_LOCK) {
-			dq->dq_flags |= DQ_WANT;
-			(void) tsleep((caddr_t)dq, 0, "chkiq2", 0);
-		}
-		/* Reset timer when crossing soft limit */
-		if (dq->dq_curinodes + change >= dq->dq_isoftlimit &&
-		    dq->dq_curinodes < dq->dq_isoftlimit)
-			dq->dq_itime = time_second +
-			    VFSTOEXT2(ITOV(ip)->v_mount)->um_itime[i];
-		dq->dq_curinodes += change;
-		dq->dq_flags |= DQ_MOD;
-	}
-	return (0);
-}
-
-/*
- * Check for a valid change to a users allocation.
- * Issue an error message if appropriate.
- */
-static int
-ext2_chkiqchg(struct inode *ip, long change, struct ucred *cred, int type)
-{
-	struct ext2_dquot *dq = ip->i_dquot[type];
-	long ncurinodes = dq->dq_curinodes + change;
-
-	/*
-	 * If user would exceed their hard limit, disallow inode allocation.
-	 */
-	if (ncurinodes >= dq->dq_ihardlimit && dq->dq_ihardlimit) {
-		if ((dq->dq_flags & DQ_INODS) == 0 &&
-		    ip->i_uid == cred->cr_uid) {
-			uprintf("\n%s: write failed, %s inode limit reached\n",
-			    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-			    quotatypes[type]);
-			dq->dq_flags |= DQ_INODS;
-		}
-		return (EDQUOT);
-	}
-	/*
-	 * If user is over their soft limit for too long, disallow inode
-	 * allocation. Reset time limit as they cross their soft limit.
-	 */
-	if (ncurinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) {
-		if (dq->dq_curinodes < dq->dq_isoftlimit) {
-			dq->dq_itime = time_second +
-			    VFSTOEXT2(ITOV(ip)->v_mount)->um_itime[type];
-			if (ip->i_uid == cred->cr_uid)
-				uprintf("\n%s: warning, %s %s\n",
-				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-				    quotatypes[type], "inode quota exceeded");
-			return (0);
-		}
-		if (time_second > dq->dq_itime) {
-			if ((dq->dq_flags & DQ_INODS) == 0 &&
-			    ip->i_uid == cred->cr_uid) {
-				uprintf("\n%s: write failed, %s %s\n",
-				    ITOV(ip)->v_mount->mnt_stat.f_mntfromname,
-				    quotatypes[type],
-				    "inode quota exceeded for too long");
-				dq->dq_flags |= DQ_INODS;
-			}
-			return (EDQUOT);
-		}
-	}
-	return (0);
-}
-
-#ifdef DIAGNOSTIC
-/*
- * On filesystems with quotas enabled, it is an error for a file to change
- * size and not to have a dquot structure associated with it.
- */
-static void
-ext2_chkdquot(struct inode *ip)
-{
-	struct ext2mount *ump = VFSTOEXT2(ITOV(ip)->v_mount);
-	int i;
-
-	for (i = 0; i < MAXQUOTAS; i++) {
-		if (ump->um_quotas[i] == NULLVP ||
-		    (ump->um_qflags[i] & (QTF_OPENING|QTF_CLOSING)))
-			continue;
-		if (ip->i_dquot[i] == NODQUOT) {
-			vprint("chkdquot: missing dquot", ITOV(ip));
-			panic("chkdquot: missing dquot");
-		}
-	}
-}
-#endif
-
-/*
- * Code to process quotactl commands.
- */
-
-struct scaninfo {
-	int rescan;
-	int type;
-};
-
-/*
- * Q_QUOTAON - set up a quota file for a particular filesystem.
- */
-static int ext2_quotaon_scan(struct mount *mp, struct vnode *vp, void *data);
-
-int
-ext2_quotaon(struct ucred *cred, struct mount *mp, int type, caddr_t fname)
-{
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	struct vnode *vp, **vpp;
-	struct ext2_dquot *dq;
-	int error;
-	struct nlookupdata nd;
-	struct scaninfo scaninfo;
-
-	vpp = &ump->um_quotas[type];
-	error = nlookup_init(&nd, fname, UIO_USERSPACE, NLC_FOLLOW|NLC_LOCKVP);
-	if (error == 0)
-		error = vn_open(&nd, NULL, FREAD|FWRITE, 0);
-	if (error == 0 && nd.nl_open_vp->v_type != VREG)
-		error = EACCES;
-	if (error) {
-		nlookup_done(&nd);
-		return (error);
-	}
-	vp = nd.nl_open_vp;
-	nd.nl_open_vp = NULL;
-	nlookup_done(&nd);
-
-	vn_unlock(vp);
-	if (*vpp != vp)
-		ext2_quotaoff(mp, type);
-	ump->um_qflags[type] |= QTF_OPENING;
-	mp->mnt_flag |= MNT_QUOTA;
-	vsetflags(vp, VSYSTEM);
-	*vpp = vp;
-	/* XXX release duplicate vp if *vpp == vp? */
-	/*
-	 * Save the credential of the process that turned on quotas.
-	 * Set up the time limits for this quota.
-	 */
-	ump->um_cred[type] = crhold(cred);
-	ump->um_btime[type] = MAX_DQ_TIME;
-	ump->um_itime[type] = MAX_IQ_TIME;
-	if (ext2_dqget(NULLVP, 0, ump, type, &dq) == 0) {
-		if (dq->dq_btime > 0)
-			ump->um_btime[type] = dq->dq_btime;
-		if (dq->dq_itime > 0)
-			ump->um_itime[type] = dq->dq_itime;
-		ext2_dqrele(NULLVP, dq);
-	}
-	/*
-	 * Search vnodes associated with this mount point,
-	 * adding references to quota file being opened.
-	 * NB: only need to add dquot's for inodes being modified.
-	 */
-	scaninfo.rescan = 1;
-	while (scaninfo.rescan) {
-		scaninfo.rescan = 0;
-		error = vmntvnodescan(mp, VMSC_GETVP,
-					NULL, ext2_quotaon_scan, &scaninfo);
-		if (error)
-			break;
-	}
-	ump->um_qflags[type] &= ~QTF_OPENING;
-	if (error)
-		ext2_quotaoff(mp, type);
-	return (error);
-}
-
-static int
-ext2_quotaon_scan(struct mount *mp, struct vnode *vp, void *data)
-{
-	int error;
-	/*struct scaninfo *info = data;*/
-
-	if (vp->v_writecount == 0)
-		return(0);
-	error = ext2_getinoquota(VTOI(vp));
-	return(error);
-}
-
-/*
- * Q_QUOTAOFF - turn off disk quotas for a filesystem.
- */
-
-static int ext2_quotaoff_scan(struct mount *mp, struct vnode *vp, void *data);
-
-int
-ext2_quotaoff(struct mount *mp, int type)
-{
-	struct vnode *qvp;
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	int error;
-	struct scaninfo scaninfo;
-
-	if ((qvp = ump->um_quotas[type]) == NULLVP)
-		return (0);
-	ump->um_qflags[type] |= QTF_CLOSING;
-
-	/*
-	 * Search vnodes associated with this mount point,
-	 * deleting any references to quota file being closed.
-	 */
-	scaninfo.rescan = 1;
-	scaninfo.type = type;
-	while (scaninfo.rescan) {
-		scaninfo.rescan = 0;
-		vmntvnodescan(mp, VMSC_GETVP, NULL, ext2_quotaoff_scan, &scaninfo);
-	}
-	ext2_dqflush(qvp);
-	vclrflags(qvp, VSYSTEM);
-	error = vn_close(qvp, FREAD|FWRITE);
-	ump->um_quotas[type] = NULLVP;
-	crfree(ump->um_cred[type]);
-	ump->um_cred[type] = NOCRED;
-	ump->um_qflags[type] &= ~QTF_CLOSING;
-	for (type = 0; type < MAXQUOTAS; type++) {
-		if (ump->um_quotas[type] != NULLVP)
-			break;
-	}
-	if (type == MAXQUOTAS)
-		mp->mnt_flag &= ~MNT_QUOTA;
-	return (error);
-}
-
-static int
-ext2_quotaoff_scan(struct mount *mp, struct vnode *vp, void *data)
-{
-	struct scaninfo *info = data;
-	struct ext2_dquot *dq;
-	struct inode *ip;
-
-	if (vp->v_type == VNON) {
-		return(0);
-	}
-	ip = VTOI(vp);
-	dq = ip->i_dquot[info->type];
-	ip->i_dquot[info->type] = NODQUOT;
-	ext2_dqrele(vp, dq);
-	return(0);
-}
-
-/*
- * Q_GETQUOTA - return current values in a dqblk structure.
- */
-int
-ext2_getquota(struct mount *mp, u_long id, int type, caddr_t addr)
-{
-	struct ext2_dquot *dq;
-	int error;
-
-	error = ext2_dqget(NULLVP, id, VFSTOEXT2(mp), type, &dq);
-	if (error)
-		return (error);
-	error = copyout((caddr_t)&dq->dq_dqb, addr, sizeof (struct ext2_dqblk));
-	ext2_dqrele(NULLVP, dq);
-	return (error);
-}
-
-/*
- * Q_SETQUOTA - assign an entire dqblk structure.
- */
-int
-ext2_setquota(struct mount *mp, u_long id, int type, caddr_t addr)
-{
-	struct ext2_dquot *dq;
-	struct ext2_dquot *ndq;
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	struct ext2_dqblk newlim;
-	int error;
-
-	error = copyin(addr, (caddr_t)&newlim, sizeof (struct ext2_dqblk));
-	if (error)
-		return (error);
-	error = ext2_dqget(NULLVP, id, ump, type, &ndq);
-	if (error)
-		return (error);
-	dq = ndq;
-	while (dq->dq_flags & DQ_LOCK) {
-		dq->dq_flags |= DQ_WANT;
-		(void) tsleep((caddr_t)dq, 0, "setqta", 0);
-	}
-	/*
-	 * Copy all but the current values.
-	 * Reset time limit if previously had no soft limit or were
-	 * under it, but now have a soft limit and are over it.
-	 */
-	newlim.dqb_curblocks = dq->dq_curblocks;
-	newlim.dqb_curinodes = dq->dq_curinodes;
-	if (dq->dq_id != 0) {
-		newlim.dqb_btime = dq->dq_btime;
-		newlim.dqb_itime = dq->dq_itime;
-	}
-	if (newlim.dqb_bsoftlimit &&
-	    dq->dq_curblocks >= newlim.dqb_bsoftlimit &&
-	    (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit))
-		newlim.dqb_btime = time_second + ump->um_btime[type];
-	if (newlim.dqb_isoftlimit &&
-	    dq->dq_curinodes >= newlim.dqb_isoftlimit &&
-	    (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit))
-		newlim.dqb_itime = time_second + ump->um_itime[type];
-	dq->dq_dqb = newlim;
-	if (dq->dq_curblocks < dq->dq_bsoftlimit)
-		dq->dq_flags &= ~DQ_BLKS;
-	if (dq->dq_curinodes < dq->dq_isoftlimit)
-		dq->dq_flags &= ~DQ_INODS;
-	if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
-	    dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
-		dq->dq_flags |= DQ_FAKE;
-	else
-		dq->dq_flags &= ~DQ_FAKE;
-	dq->dq_flags |= DQ_MOD;
-	ext2_dqrele(NULLVP, dq);
-	return (0);
-}
-
-/*
- * Q_SETUSE - set current inode and block usage.
- */
-int
-ext2_setuse(struct mount *mp, u_long id, int type, caddr_t addr)
-{
-	struct ext2_dquot *dq;
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	struct ext2_dquot *ndq;
-	struct ext2_dqblk usage;
-	int error;
-
-	error = copyin(addr, (caddr_t)&usage, sizeof (struct ext2_dqblk));
-	if (error)
-		return (error);
-	error = ext2_dqget(NULLVP, id, ump, type, &ndq);
-	if (error)
-		return (error);
-	dq = ndq;
-	while (dq->dq_flags & DQ_LOCK) {
-		dq->dq_flags |= DQ_WANT;
-		(void) tsleep((caddr_t)dq, 0, "setuse", 0);
-	}
-	/*
-	 * Reset time limit if have a soft limit and were
-	 * previously under it, but are now over it.
-	 */
-	if (dq->dq_bsoftlimit && dq->dq_curblocks < dq->dq_bsoftlimit &&
-	    usage.dqb_curblocks >= dq->dq_bsoftlimit)
-		dq->dq_btime = time_second + ump->um_btime[type];
-	if (dq->dq_isoftlimit && dq->dq_curinodes < dq->dq_isoftlimit &&
-	    usage.dqb_curinodes >= dq->dq_isoftlimit)
-		dq->dq_itime = time_second + ump->um_itime[type];
-	dq->dq_curblocks = usage.dqb_curblocks;
-	dq->dq_curinodes = usage.dqb_curinodes;
-	if (dq->dq_curblocks < dq->dq_bsoftlimit)
-		dq->dq_flags &= ~DQ_BLKS;
-	if (dq->dq_curinodes < dq->dq_isoftlimit)
-		dq->dq_flags &= ~DQ_INODS;
-	dq->dq_flags |= DQ_MOD;
-	ext2_dqrele(NULLVP, dq);
-	return (0);
-}
-
-/*
- * Q_SYNC - sync quota files to disk.
- */
-
-static int ext2_qsync_scan(struct mount *mp, struct vnode *vp, void *data);
-
-int
-ext2_qsync(struct mount *mp)
-{
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	struct scaninfo scaninfo;
-	int i;
-
-	/*
-	 * Check if the mount point has any quotas.
-	 * If not, simply return.
-	 */
-	for (i = 0; i < MAXQUOTAS; i++)
-		if (ump->um_quotas[i] != NULLVP)
-			break;
-	if (i == MAXQUOTAS)
-		return (0);
-	/*
-	 * Search vnodes associated with this mount point,
-	 * synchronizing any modified ext2_dquot structures.
-	 */
-	scaninfo.rescan = 1;
-	while (scaninfo.rescan) {
-		scaninfo.rescan = 0;
-		vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT,
-				NULL, ext2_qsync_scan, &scaninfo);
-	}
-	return (0);
-}
-
-static int
-ext2_qsync_scan(struct mount *mp, struct vnode *vp, void *data)
-{
-	/*struct scaninfo *info = data;*/
-	struct ext2_dquot *dq;
-	/* int error;*/
-	int i;
-
-	for (i = 0; i < MAXQUOTAS; i++) {
-		dq = VTOI(vp)->i_dquot[i];
-		if (dq != NODQUOT && (dq->dq_flags & DQ_MOD))
-			ext2_dqsync(vp, dq);
-	}
-	return(0);
-}
-
-/*
- * Code pertaining to management of the in-core dquot data structures.
- */
-#define DQHASH(dqvp, id) \
-	(&ext2_dqhashtbl[((((intptr_t)(dqvp)) >> 8) + id) & ext2_dqhash])
-static LIST_HEAD(ext2_dqhash, ext2_dquot) *ext2_dqhashtbl;
-static u_long ext2_dqhash;
-
-/*
- * Dquot free list.
- */
-#define	DQUOTINC	5	/* minimum free dquots desired */
-static TAILQ_HEAD(ext2_dqfreelist, ext2_dquot) ext2_dqfreelist;
-static long ext2_numdquot, ext2_desireddquot = DQUOTINC;
-
-/*
- * Initialize the quota system.
- */
-void
-ext2_dqinit(void)
-{
-	ext2_dqhashtbl = hashinit(desiredvnodes, M_EXT2DQUOT, &ext2_dqhash);
-	TAILQ_INIT(&ext2_dqfreelist);
-}
-
-/*
- * Obtain a dquot structure for the specified identifier and quota file
- * reading the information from the file if necessary.
- */
-static int
-ext2_dqget(struct vnode *vp, u_long id, struct ext2mount *ump, int type,
-      struct ext2_dquot **dqp)
-{
-	struct ext2_dquot *dq;
-	struct ext2_dqhash *dqh;
-	struct vnode *dqvp;
-	struct iovec aiov;
-	struct uio auio;
-	int error;
-
-	dqvp = ump->um_quotas[type];
-	if (dqvp == NULLVP || (ump->um_qflags[type] & QTF_CLOSING)) {
-		*dqp = NODQUOT;
-		return (EINVAL);
-	}
-	/*
-	 * Check the cache first.
-	 */
-	dqh = DQHASH(dqvp, id);
-	for (dq = dqh->lh_first; dq; dq = dq->dq_hash.le_next) {
-		if (dq->dq_id != id ||
-		    dq->dq_ump->um_quotas[dq->dq_type] != dqvp)
-			continue;
-		/*
-		 * Cache hit with no references.  Take
-		 * the structure off the free list.
-		 */
-		if (dq->dq_cnt == 0)
-			TAILQ_REMOVE(&ext2_dqfreelist, dq, dq_freelist);
-		DQREF(dq);
-		*dqp = dq;
-		return (0);
-	}
-	/*
-	 * Not in cache, allocate a new one.
-	 */
-	if (TAILQ_EMPTY(&ext2_dqfreelist) && ext2_numdquot < MAXQUOTAS * desiredvnodes)
-		ext2_desireddquot += DQUOTINC;
-	if (ext2_numdquot < ext2_desireddquot) {
-		dq = (struct ext2_dquot *)kmalloc(sizeof *dq, M_EXT2DQUOT, M_WAITOK | M_ZERO);
-		ext2_numdquot++;
-	} else {
-		if ((dq = TAILQ_FIRST(&ext2_dqfreelist)) == NULL) {
-			tablefull("dquot");
-			*dqp = NODQUOT;
-			return (EUSERS);
-		}
-		if (dq->dq_cnt || (dq->dq_flags & DQ_MOD))
-			panic("dqget: free dquot isn't");
-		TAILQ_REMOVE(&ext2_dqfreelist, dq, dq_freelist);
-		if (dq->dq_ump != NULL)
-			LIST_REMOVE(dq, dq_hash);
-	}
-	/*
-	 * Initialize the contents of the dquot structure.
-	 */
-	if (vp != dqvp)
-		vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY);
-	LIST_INSERT_HEAD(dqh, dq, dq_hash);
-	DQREF(dq);
-	dq->dq_flags = DQ_LOCK;
-	dq->dq_id = id;
-	dq->dq_ump = ump;
-	dq->dq_type = type;
-	auio.uio_iov = &aiov;
-	auio.uio_iovcnt = 1;
-	aiov.iov_base = (caddr_t)&dq->dq_dqb;
-	aiov.iov_len = sizeof (struct ext2_dqblk);
-	auio.uio_resid = sizeof (struct ext2_dqblk);
-	auio.uio_offset = (off_t)(id * sizeof (struct ext2_dqblk));
-	auio.uio_segflg = UIO_SYSSPACE;
-	auio.uio_rw = UIO_READ;
-	auio.uio_td = NULL;
-	error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]);
-	if (auio.uio_resid == sizeof(struct ext2_dqblk) && error == 0)
-		bzero((caddr_t)&dq->dq_dqb, sizeof(struct ext2_dqblk));
-	if (vp != dqvp)
-		vn_unlock(dqvp);
-	if (dq->dq_flags & DQ_WANT)
-		wakeup((caddr_t)dq);
-	dq->dq_flags = 0;
-	/*
-	 * I/O error in reading quota file, release
-	 * quota structure and reflect problem to caller.
-	 */
-	if (error) {
-		LIST_REMOVE(dq, dq_hash);
-		ext2_dqrele(vp, dq);
-		*dqp = NODQUOT;
-		return (error);
-	}
-	/*
-	 * Check for no limit to enforce.
-	 * Initialize time values if necessary.
-	 */
-	if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
-	    dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
-		dq->dq_flags |= DQ_FAKE;
-	if (dq->dq_id != 0) {
-		if (dq->dq_btime == 0)
-			dq->dq_btime = time_second + ump->um_btime[type];
-		if (dq->dq_itime == 0)
-			dq->dq_itime = time_second + ump->um_itime[type];
-	}
-	*dqp = dq;
-	return (0);
-}
-
-#ifdef DIAGNOSTIC
-/*
- * Obtain a reference to a dquot.
- */
-static void
-ext2_dqref(struct ext2_dquot *dq)
-{
-	dq->dq_cnt++;
-}
-#endif
-
-/*
- * Release a reference to a dquot.
- */
-void
-ext2_dqrele(struct vnode *vp, struct ext2_dquot *dq)
-{
-	if (dq == NODQUOT)
-		return;
-	if (dq->dq_cnt > 1) {
-		dq->dq_cnt--;
-		return;
-	}
-	if (dq->dq_flags & DQ_MOD)
-		(void)ext2_dqsync(vp, dq);
-	if (--dq->dq_cnt > 0)
-		return;
-	TAILQ_INSERT_TAIL(&ext2_dqfreelist, dq, dq_freelist);
-}
-
-/*
- * Update the disk quota in the quota file.
- */
-static int
-ext2_dqsync(struct vnode *vp, struct ext2_dquot *dq)
-{
-	struct vnode *dqvp;
-	struct iovec aiov;
-	struct uio auio;
-	int error;
-
-	if (dq == NODQUOT)
-		panic("dqsync: dquot");
-	if ((dq->dq_flags & DQ_MOD) == 0)
-		return (0);
-	if ((dqvp = dq->dq_ump->um_quotas[dq->dq_type]) == NULLVP)
-		panic("dqsync: file");
-	if (vp != dqvp)
-		vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY);
-	while (dq->dq_flags & DQ_LOCK) {
-		dq->dq_flags |= DQ_WANT;
-		(void) tsleep((caddr_t)dq, 0, "dqsync", 0);
-		if ((dq->dq_flags & DQ_MOD) == 0) {
-			if (vp != dqvp)
-				vn_unlock(dqvp);
-			return (0);
-		}
-	}
-	dq->dq_flags |= DQ_LOCK;
-	auio.uio_iov = &aiov;
-	auio.uio_iovcnt = 1;
-	aiov.iov_base = (caddr_t)&dq->dq_dqb;
-	aiov.iov_len = sizeof (struct ext2_dqblk);
-	auio.uio_resid = sizeof (struct ext2_dqblk);
-	auio.uio_offset = (off_t)(dq->dq_id * sizeof (struct ext2_dqblk));
-	auio.uio_segflg = UIO_SYSSPACE;
-	auio.uio_rw = UIO_WRITE;
-	auio.uio_td = NULL;
-	error = VOP_WRITE(dqvp, &auio, 0, dq->dq_ump->um_cred[dq->dq_type]);
-	if (auio.uio_resid && error == 0)
-		error = EIO;
-	if (dq->dq_flags & DQ_WANT)
-		wakeup((caddr_t)dq);
-	dq->dq_flags &= ~(DQ_MOD|DQ_LOCK|DQ_WANT);
-	if (vp != dqvp)
-		vn_unlock(dqvp);
-	return (error);
-}
-
-/*
- * Flush all entries from the cache for a particular vnode.
- */
-static void
-ext2_dqflush(struct vnode *vp)
-{
-	struct ext2_dquot *dq, *nextdq;
-	struct ext2_dqhash *dqh;
-
-	/*
-	 * Move all dquot's that used to refer to this quota
-	 * file off their hash chains (they will eventually
-	 * fall off the head of the free list and be re-used).
-	 */
-	for (dqh = &ext2_dqhashtbl[ext2_dqhash]; dqh >= ext2_dqhashtbl; dqh--) {
-		for (dq = dqh->lh_first; dq; dq = nextdq) {
-			nextdq = dq->dq_hash.le_next;
-			if (dq->dq_ump->um_quotas[dq->dq_type] != vp)
-				continue;
-			if (dq->dq_cnt)
-				panic("dqflush: stray dquot");
-			LIST_REMOVE(dq, dq_hash);
-			dq->dq_ump = NULL;
-		}
-	}
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_readwrite.c b/sys/vfs/gnu/ext2fs/ext2_readwrite.c
deleted file mode 100644
index 65468fc..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_readwrite.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ufs_readwrite.c	8.7 (Berkeley) 1/21/94
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_readwrite.c,v 1.18.2.2 2000/12/22 18:44:33 dillon Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_readwrite.c,v 1.15 2008/06/19 23:27:39 dillon Exp $
- */
-
-#define	BLKSIZE(a, b, c)	blksize(a, b, c)
-#define	FS			struct ext2_sb_info
-#define	I_FS			i_e2fs
-
-/*
- * Vnode op for reading.
- *
- * ext2_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *	     struct ucred *a_cred)
- */
-/* ARGSUSED */
-static int
-ext2_read(struct vop_read_args *ap)
-{
-	struct vnode *vp;
-	struct inode *ip;
-	struct uio *uio;
-	FS *fs;
-	struct buf *bp;
-	daddr_t lbn, nextlbn;
-	off_t nextloffset;
-	off_t bytesinfile;
-	long size, xfersize, blkoffset;
-	int error, orig_resid;
-	int seqcount = ap->a_ioflag >> 16;
-
-	vp = ap->a_vp;
-	ip = VTOI(vp);
-	uio = ap->a_uio;
-
-#ifdef DIAGNOSTIC
-	if (uio->uio_rw != UIO_READ)
-		panic("ext2_read: mode");
-
-	if (vp->v_type == VLNK) {
-		if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen)
-			panic("ext2_read: short symlink");
-	} else if (vp->v_type != VREG && vp->v_type != VDIR)
-		panic("ext2_read: type %d", vp->v_type);
-#endif
-	fs = ip->I_FS;
-#if 0
-	if ((u_quad_t)uio->uio_offset > fs->fs_maxfilesize)
-		return (EFBIG);
-#endif
-
-	orig_resid = uio->uio_resid;
-	for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
-		if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
-			break;
-		lbn = lblkno(fs, uio->uio_offset);
-		nextlbn = lbn + 1;
-		nextloffset = lblktodoff(fs, nextlbn);
-		size = BLKSIZE(fs, ip, lbn);
-		blkoffset = blkoff(fs, uio->uio_offset);
-
-		xfersize = fs->s_frag_size - blkoffset;
-		if (uio->uio_resid < xfersize)
-			xfersize = uio->uio_resid;
-		if (bytesinfile < xfersize)
-			xfersize = bytesinfile;
-
-		if (nextloffset >= ip->i_size) {
-			error = bread(vp, lblktodoff(fs, lbn), size, &bp);
-		} else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
-			error = cluster_read(vp, (off_t)ip->i_size,
-					     lblktodoff(fs, lbn), size, 
-					     uio->uio_resid, 
-					     (ap->a_ioflag >> 16) * BKVASIZE,
-					     &bp);
-		} else if (seqcount > 1) {
-			int nextsize = BLKSIZE(fs, ip, nextlbn);
-			error = breadn(vp, lblktodoff(fs, lbn),
-					size, &nextloffset, &nextsize, 1, &bp);
-		} else {
-			error = bread(vp, lblktodoff(fs, lbn), size, &bp);
-		}
-		if (error) {
-			brelse(bp);
-			bp = NULL;
-			break;
-		}
-
-		/*
-		 * We should only get non-zero b_resid when an I/O error
-		 * has occurred, which should cause us to break above.
-		 * However, if the short read did not cause an error,
-		 * then we want to ensure that we do not uiomove bad
-		 * or uninitialized data.
-		 */
-		size -= bp->b_resid;
-		if (size < xfersize) {
-			if (size == 0)
-				break;
-			xfersize = size;
-		}
-		error = uiomove((char *)bp->b_data + blkoffset,
-				(int)xfersize, uio);
-		if (error)
-			break;
-
-		bqrelse(bp);
-	}
-	if (bp != NULL)
-		bqrelse(bp);
-	if (orig_resid > 0 && (error == 0 || uio->uio_resid != orig_resid) &&
-	    (vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
-		ip->i_flag |= IN_ACCESS;
-	return (error);
-}
-
-/*
- * Vnode op for writing.
- *
- * ext2_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *	      struct ucred *a_cred)
- */
-static int
-ext2_write(struct vop_write_args *ap)
-{
-	struct vnode *vp;
-	struct uio *uio;
-	struct inode *ip;
-	FS *fs;
-	struct buf *bp;
-	struct thread *td;
-	daddr_t lbn;
-	off_t osize;
-	int seqcount;
-	int blkoffset, error, flags, ioflag, resid, size, xfersize;
-
-	ioflag = ap->a_ioflag;
-	seqcount = ap->a_ioflag >> 16;
-	uio = ap->a_uio;
-	vp = ap->a_vp;
-	ip = VTOI(vp);
-
-#ifdef DIAGNOSTIC
-	if (uio->uio_rw != UIO_WRITE)
-		panic("ext2_write: mode");
-#endif
-
-	switch (vp->v_type) {
-	case VREG:
-		if (ioflag & IO_APPEND)
-			uio->uio_offset = ip->i_size;
-		if ((ip->i_flags & APPEND) && uio->uio_offset != ip->i_size)
-			return (EPERM);
-		/* FALLTHROUGH */
-	case VLNK:
-		break;
-	case VDIR:
-		if ((ioflag & IO_SYNC) == 0)
-			panic("ext2_write: nonsync dir write");
-		break;
-	default:
-		panic("ext2_write: type");
-	}
-
-	fs = ip->I_FS;
-#if 0
-	if (uio->uio_offset < 0 ||
-	    (u_quad_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize)
-		return (EFBIG);
-#endif
-	/*
-	 * Maybe this should be above the vnode op call, but so long as
-	 * file servers have no limits, I don't think it matters.
-	 */
-	td = uio->uio_td;
-	if (vp->v_type == VREG && td && td->td_proc &&
-	    uio->uio_offset + uio->uio_resid >
-	    td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
-		lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ);
-		return (EFBIG);
-	}
-
-	resid = uio->uio_resid;
-	osize = ip->i_size;
-	flags = ioflag & IO_SYNC ? B_SYNC : 0;
-
-	for (error = 0; uio->uio_resid > 0;) {
-		lbn = lblkno(fs, uio->uio_offset);
-		blkoffset = blkoff(fs, uio->uio_offset);
-		xfersize = fs->s_frag_size - blkoffset;
-		if (uio->uio_resid < xfersize)
-			xfersize = uio->uio_resid;
-
-		if (uio->uio_offset + xfersize > ip->i_size)
-			vnode_pager_setsize(vp, uio->uio_offset + xfersize);
-
-		/*  
-		 * Avoid a data-consistency race between write() and mmap()
-		 * by ensuring that newly allocated blocks are zerod.  The
-		 * race can occur even in the case where the write covers
-		 * the entire block.
-		 *
-		 * Just set B_CLRBUF unconditionally, even if the write
-		 * covers the whole block.  This also handles the UIO_NOCOPY
-		 * case.  See ffs_write() in ufs for a more sophisticated
-		 * version.
-		 */
-		flags |= B_CLRBUF;
-		error = ext2_balloc(ip, lbn, blkoffset + xfersize,
-				    ap->a_cred, &bp, flags);
-		if (error)
-			break;
-
-		if (uio->uio_offset + xfersize > ip->i_size) {
-			ip->i_size = uio->uio_offset + xfersize;
-		}
-
-		size = BLKSIZE(fs, ip, lbn) - bp->b_resid;
-		if (size < xfersize)
-			xfersize = size;
-
-		error = uiomove((char *)bp->b_data + blkoffset,
-				(int)xfersize, uio);
-		if ((ioflag & IO_VMIO) &&
-		    LIST_FIRST(&bp->b_dep) == NULL) /* in ext2fs? */
-			bp->b_flags |= B_RELBUF;
-
-		if (ioflag & IO_SYNC) {
-			bwrite(bp);
-		} else if (xfersize + blkoffset == fs->s_frag_size) {
-			if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
-				bp->b_flags |= B_CLUSTEROK;
-				cluster_write(bp, (off_t)ip->i_size, vp->v_mount->mnt_stat.f_iosize, seqcount);
-			} else {
-				bawrite(bp);
-			}
-		} else {
-			bp->b_flags |= B_CLUSTEROK;
-			bdwrite(bp);
-		}
-		if (error || xfersize == 0)
-			break;
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-	}
-	/*
-	 * If we successfully wrote any data, and we are not the superuser
-	 * we clear the setuid and setgid bits as a precaution against
-	 * tampering.
-	 */
-	if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)
-		ip->i_mode &= ~(ISUID | ISGID);
-	if (error) {
-		if (ioflag & IO_UNIT) {
-			EXT2_TRUNCATE(vp, osize, ioflag & IO_SYNC, ap->a_cred);
-			uio->uio_offset -= resid - uio->uio_resid;
-			uio->uio_resid = resid;
-		}
-	} else if (resid > uio->uio_resid && (ioflag & IO_SYNC))
-		error = EXT2_UPDATE(vp, 1);
-	return (error);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_subr.c b/sys/vfs/gnu/ext2fs/ext2_subr.c
deleted file mode 100644
index d9ef730..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_subr.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  modified for Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ext2_subr.c	8.2 (Berkeley) 9/21/93
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_subr.c,v 1.13.2.2 2000/08/03 18:48:27 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_subr.c,v 1.12 2006/04/27 23:28:36 dillon Exp $
- */
-
-#include <sys/param.h>
-
-#include <sys/lock.h>
-#include <sys/systm.h>
-#include <sys/ucred.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-
-#include "quota.h"
-#include "inode.h"
-#include "ext2_extern.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-
-#include "opt_ddb.h"
-
-/*
- * Return buffer with the contents of block "offset" from the beginning of
- * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
- * remaining space in the directory.
- */
-int
-ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
-{
-	struct inode *ip;
-	struct ext2_sb_info *fs;
-	struct buf *bp;
-	daddr_t lbn;
-	int bsize, error;
-
-	ip = VTOI(vp);
-	fs = ip->i_e2fs;
-	lbn = lblkno(fs, offset);
-	bsize = blksize(fs, ip, lbn);
-
-	*bpp = NULL;
-	if ((error = bread(vp, lblktodoff(fs, lbn), bsize, &bp)) != 0) {
-		brelse(bp);
-		return (error);
-	}
-	if (res)
-		*res = (char *)bp->b_data + blkoff(fs, offset);
-	*bpp = bp;
-	return (0);
-}
-
diff --git a/sys/vfs/gnu/ext2fs/ext2_vfsops.c b/sys/vfs/gnu/ext2fs/ext2_vfsops.c
deleted file mode 100644
index c3b30dc..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_vfsops.c
+++ /dev/null
@@ -1,1355 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*	
- * Copyright (c) 1989, 1991, 1993, 1994	
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ffs_vfsops.c	8.8 (Berkeley) 4/18/94
- *	$FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $
- *	$DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.57 2008/09/17 21:44:21 dillon Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/nlookup.h>
-#include <sys/proc.h>
-#include <sys/priv.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/diskslice.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-#include <vm/vm_zone.h>
-
-#include <sys/buf2.h>
-#include <sys/thread2.h>
-
-#include "quota.h"
-#include "dinode.h"
-#include "inode.h"
-#include "ext2mount.h"
-#include "ext2_extern.h"
-
-#include "fs.h"
-#include "ext2_fs.h"
-#include "ext2_fs_sb.h"
-
-extern struct vop_ops ext2_vnode_vops;
-extern struct vop_ops ext2_spec_vops;
-extern struct vop_ops ext2_fifo_vops;
-
-static int ext2_fhtovp (struct mount *, struct vnode *,
-				struct fid *, struct vnode **);
-static int ext2_flushfiles (struct mount *mp, int flags);
-static int ext2_mount (struct mount *, char *, caddr_t, struct ucred *);
-static int ext2_mountfs (struct vnode *, struct mount *, struct ucred *);
-static int ext2_root(struct mount *, struct vnode **);
-static int ext2_reload (struct mount *mountp, struct ucred *cred);
-static int ext2_sbupdate (struct ext2mount *, int);
-static int ext2_statfs (struct mount *, struct statfs *, struct ucred *);
-static int ext2_sync (struct mount *, int);
-static int ext2_unmount (struct mount *, int);
-static int ext2_vget (struct mount *, struct vnode *, ino_t, struct vnode **);
-static int ext2_init(struct vfsconf *);
-static int ext2_vptofh (struct vnode *, struct fid *);
-
-static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
-MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
-
-static struct vfsops ext2fs_vfsops = {
-	.vfs_mount =    	ext2_mount,
-	.vfs_unmount =   	ext2_unmount,
-	.vfs_root =     	ext2_root,	/* root inode via vget */
-	.vfs_quotactl =   	ext2_quotactl,	/* quota operations */
-	.vfs_statfs =     	ext2_statfs,
-	.vfs_sync =     	ext2_sync,
-	.vfs_vget =      	ext2_vget,
-	.vfs_fhtovp =     	ext2_fhtovp,
-	.vfs_checkexp =    	ext2_check_export,
-	.vfs_vptofh =     	ext2_vptofh,
-	.vfs_init =     	ext2_init,
-	.vfs_uninit =    	ext2_uninit
-};
-
-VFS_SET(ext2fs_vfsops, ext2fs, 0);
-#define bsd_malloc kmalloc
-#define bsd_free kfree
-
-static int ext2fs_inode_hash_lock;
-
-static int	ext2_check_sb_compat (struct ext2_super_block *es,
-					  cdev_t dev, int ronly);
-static int	compute_sb_data (struct vnode * devvp,
-				     struct ext2_super_block * es,
-				     struct ext2_sb_info * fs);
-
-static int
-ext2_root(struct mount *mp, struct vnode **vpp)
-{
-	struct vnode *nvp;
-	int error;
-
-	error = VFS_VGET(mp, NULL, (ino_t)ROOTINO, &nvp);
-	if (error)
-		return (error);
-	*vpp = nvp;
-	return (0);
-}
-
-/*
- * Do operations associated with quotas
- */
-int
-ext2_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
-	     struct ucred *cred)
-{
-#ifndef QUOTA
-	return (EOPNOTSUPP);
-#else
-	int cmd, type, error;
-
-	type = cmds & SUBCMDMASK;
-	cmd = cmds >> SUBCMDSHIFT;
-
-	if (uid == -1) {
-		switch(type) {
-			case USRQUOTA:
-				uid = cred->cr_ruid;
-				break;
-			case GRPQUOTA:
-				uid = cred->cr_rgid;
-				break;
-			default:
-				return (EINVAL);
-		}
-	}
-
-	/*
-	 * Check permissions.
-	 */
-	switch (cmd) {
-
-	case Q_QUOTAON:
-		error = priv_check_cred(cred, PRIV_UFS_QUOTAON, 0);
-		break;
-
-	case Q_QUOTAOFF:
-		error = priv_check_cred(cred, PRIV_UFS_QUOTAOFF, 0);
-		break;
-
-	case Q_SETQUOTA:
-		error = priv_check_cred(cred, PRIV_VFS_SETQUOTA, 0);
-		break;
-
-	case Q_SETUSE:
-		error = priv_check_cred(cred, PRIV_UFS_SETUSE, 0);
-		break;
-
-	case Q_GETQUOTA:
-		if (uid == cred->cr_ruid)
-			error = 0;
-		else
-			error = priv_check_cred(cred, PRIV_VFS_GETQUOTA, 0);
-		break;
-
-	case Q_SYNC:
-		error = 0;
-		break;
-
-	default:
-		error = EINVAL;
-		break;
-	}
-
-	if (error)
-		return (error);
-
-
-	if ((uint)type >= MAXQUOTAS)
-		return (EINVAL);
-	if (vfs_busy(mp, LK_NOWAIT))
-		return (0);
-
-	switch (cmd) {
-
-	case Q_QUOTAON:
-		error = ext2_quotaon(cred, mp, type, arg);
-		break;
-
-	case Q_QUOTAOFF:
-		error = ext2_quotaoff(mp, type);
-		break;
-
-	case Q_SETQUOTA:
-		error = ext2_setquota(mp, uid, type, arg);
-		break;
-
-	case Q_SETUSE:
-		error = ext2_setuse(mp, uid, type, arg);
-		break;
-
-	case Q_GETQUOTA:
-		error = ext2_getquota(mp, uid, type, arg);
-		break;
-
-	case Q_SYNC:
-		error = ext2_qsync(mp);
-		break;
-
-	default:
-		error = EINVAL;
-		break;
-	}
-	vfs_unbusy(mp);
-	return (error);
-#endif
-}
-
-/*
- * Initial UFS filesystems, done only once.
- */
-int
-ext2_init(struct vfsconf *vfsp)
-{
-	static int done;
-
-	if (done)
-		return (0);
-	done = 1;
-	ext2_ihashinit();
-#ifdef QUOTA
-	ext2_dqinit();
-#endif
-	return (0);
-}
-
-/*
- * VFS Operations.
- *
- * mount system call
- *
- * Parameters:
- *	data:	this is actually a (struct ext2_args *)
- */
-static int
-ext2_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
-{
-	struct vnode *devvp;
-	struct ext2_args args;
-	struct ext2mount *ump = 0;
-	struct ext2_sb_info *fs;
-	size_t size;
-	int error, flags;
-	mode_t accessmode;
-	struct nlookupdata nd;
-
-	if ((error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args))) != 0)
-		return (error);
-
-	/*
-	 * If updating, check whether changing from read-only to
-	 * read/write; if there is no device name, that's all we do.
-	 */
-	if (mp->mnt_flag & MNT_UPDATE) {
-		ump = VFSTOEXT2(mp);
-		fs = ump->um_e2fs;
-		devvp = ump->um_devvp;
-		error = 0;
-		if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
-			flags = WRITECLOSE;
-			if (mp->mnt_flag & MNT_FORCE)
-				flags |= FORCECLOSE;
-			if (vfs_busy(mp, LK_NOWAIT))
-				return (EBUSY);
-			error = ext2_flushfiles(mp, flags);
-			vfs_unbusy(mp);
-			if (!error && fs->s_wasvalid) {
-				fs->s_es->s_state |= EXT2_VALID_FS;
-				ext2_sbupdate(ump, MNT_WAIT);
-			}
-			fs->s_rd_only = 1;
-			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-			VOP_OPEN(devvp, FREAD, FSCRED, NULL);
-			VOP_CLOSE(devvp, FREAD|FWRITE);
-			vn_unlock(devvp);
-		}
-		if (!error && (mp->mnt_flag & MNT_RELOAD))
-			error = ext2_reload(mp, cred);
-		if (error)
-			return (error);
-		if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev,
-		    (mp->mnt_kern_flag & MNTK_WANTRDWR) == 0) != 0)
-			return (EPERM);
-		if (fs->s_rd_only && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
-			/*
-			 * If upgrade to read-write by non-root, then verify
-			 * that user has necessary permissions on the device.
-			 */
-			if (cred->cr_uid != 0) {
-				vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-				error = VOP_EACCESS(devvp, VREAD | VWRITE, cred);
-				if (error) {
-					vn_unlock(devvp);
-					return (error);
-				}
-				vn_unlock(devvp);
-			}
-
-			if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 ||
-			    (fs->s_es->s_state & EXT2_ERROR_FS)) {
-				if (mp->mnt_flag & MNT_FORCE) {
-					kprintf(
-"WARNING: %s was not properly dismounted\n",
-					    fs->fs_fsmnt);
-				} else {
-					kprintf(
-"WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
-					    fs->fs_fsmnt);
-					return (EPERM);
-				}
-			}
-			fs->s_es->s_state &= ~EXT2_VALID_FS;
-			ext2_sbupdate(ump, MNT_WAIT);
-			fs->s_rd_only = 0;
-			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-			VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL);
-			VOP_CLOSE(devvp, FREAD);
-			vn_unlock(devvp);
-		}
-		if (args.fspec == 0) {
-			/*
-			 * Process export requests.
-			 */
-			return (vfs_export(mp, &ump->um_export, &args.export));
-		}
-	}
-	/*
-	 * Not an update, or updating the name: look up the name
-	 * and verify that it refers to a sensible block device.
-	 */
-	devvp = NULL;
-	error = nlookup_init(&nd, args.fspec, UIO_USERSPACE, NLC_FOLLOW);
-	if (error == 0)
-		error = nlookup(&nd);
-	if (error == 0)
-		error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp);
-	nlookup_done(&nd);
-	if (error)
-		return (error);
-
-	if (!vn_isdisk(devvp, &error)) {
-		vrele(devvp);
-		return (error);
-	}
-
-	/*
-	 * If mount by non-root, then verify that user has necessary
-	 * permissions on the device.
-	 */
-	if (cred->cr_uid != 0) {
-		accessmode = VREAD;
-		if ((mp->mnt_flag & MNT_RDONLY) == 0)
-			accessmode |= VWRITE;
-		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-		if ((error = VOP_EACCESS(devvp, accessmode, cred)) != 0) {
-			vput(devvp);
-			return (error);
-		}
-		vn_unlock(devvp);
-	}
-
-	if ((mp->mnt_flag & MNT_UPDATE) == 0) {
-		error = ext2_mountfs(devvp, mp, cred);
-	} else {
-		if (devvp != ump->um_devvp)
-			error = EINVAL;	/* needs translation */
-		else
-			vrele(devvp);
-	}
-	if (error) {
-		vrele(devvp);
-		return (error);
-	}
-	ump = VFSTOEXT2(mp);
-	fs = ump->um_e2fs;
-	copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
-	bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
-	copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
-	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
-	ext2_statfs(mp, &mp->mnt_stat, cred);
-	return (0);
-}
-
-/*
- * checks that the data in the descriptor blocks make sense
- * this is taken from ext2/super.c
- */
-static int
-ext2_check_descriptors(struct ext2_sb_info *sb)
-{
-        int i;
-        int desc_block = 0;
-        unsigned long block = sb->s_es->s_first_data_block;
-        struct ext2_group_desc * gdp = NULL;
-
-        /* ext2_debug ("Checking group descriptors"); */
-
-        for (i = 0; i < sb->s_groups_count; i++)
-        {
-		/* examine next descriptor block */
-                if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)
-                        gdp = (struct ext2_group_desc *) 
-				sb->s_group_desc[desc_block++]->b_data;
-                if (gdp->bg_block_bitmap < block ||
-                    gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
-                {
-                        kprintf ("ext2_check_descriptors: "
-                                    "Block bitmap for group %d"
-                                    " not in group (block %lu)!\n",
-                                    i, (unsigned long) gdp->bg_block_bitmap);
-                        return 0;
-                }
-                if (gdp->bg_inode_bitmap < block ||
-                    gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb))
-                {
-                        kprintf ("ext2_check_descriptors: "
-                                    "Inode bitmap for group %d"
-                                    " not in group (block %lu)!\n",
-                                    i, (unsigned long) gdp->bg_inode_bitmap);
-                        return 0;
-                }
-                if (gdp->bg_inode_table < block ||
-                    gdp->bg_inode_table + sb->s_itb_per_group >=
-                    block + EXT2_BLOCKS_PER_GROUP(sb))
-                {
-                        kprintf ("ext2_check_descriptors: "
-                                    "Inode table for group %d"
-                                    " not in group (block %lu)!\n",
-                                    i, (unsigned long) gdp->bg_inode_table);
-                        return 0;
-                }
-                block += EXT2_BLOCKS_PER_GROUP(sb);
-                gdp++;
-        }
-        return 1;
-}
-
-static int
-ext2_check_sb_compat(struct ext2_super_block *es, cdev_t dev, int ronly)
-{
-	if (es->s_magic != EXT2_SUPER_MAGIC) {
-		kprintf("ext2fs: %s: wrong magic number %#x (expected %#x)\n",
-		    devtoname(dev), es->s_magic, EXT2_SUPER_MAGIC);
-		return (1);
-	}
-	if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
-		if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
-			kprintf(
-"WARNING: mount of %s denied due to unsupported optional features\n",
-			    devtoname(dev));
-			return (1);
-		}
-		if (!ronly &&
-		    (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
-			kprintf(
-"WARNING: R/W mount of %s denied due to unsupported optional features\n",
-			    devtoname(dev));
-			return (1);
-		}
-	}
-	return (0);
-}
-
-/*
- * this computes the fields of the  ext2_sb_info structure from the
- * data in the ext2_super_block structure read in
- */
-static int
-compute_sb_data(struct vnode *devvp, struct ext2_super_block *es,
-		struct ext2_sb_info *fs)
-{
-    int db_count, error;
-    int i, j;
-    int logic_sb_block = 1;	/* XXX for now */
-
-#if 1
-#define V(v)  
-#else
-#define V(v)  kprintf(#v"= %d\n", fs->v);
-#endif
-
-    fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; 
-    V(s_blocksize)
-    fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size;
-    V(s_bshift)
-    fs->s_fsbtodb = es->s_log_block_size + 1;
-    V(s_fsbtodb)
-    fs->s_qbmask = fs->s_blocksize - 1;
-    V(s_bmask)
-    fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es);
-    V(s_blocksize_bits)
-    fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size;
-    V(s_frag_size)
-    if (fs->s_frag_size)
-	fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size;
-    V(s_frags_per_block)
-    fs->s_blocks_per_group = es->s_blocks_per_group;
-    V(s_blocks_per_group)
-    fs->s_frags_per_group = es->s_frags_per_group;
-    V(s_frags_per_group)
-    fs->s_inodes_per_group = es->s_inodes_per_group;
-    V(s_inodes_per_group)
-    if (es->s_rev_level == EXT2_GOOD_OLD_REV) {
-        fs->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
-        fs->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
-    } else {
-        fs->s_first_ino = es->s_first_ino;
-        fs->s_inode_size = es->s_inode_size;
-        /*
-         * Simple sanity check for superblock inode size value.
-         */
-        if (fs->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
-            fs->s_inode_size > fs->s_blocksize ||
-            (fs->s_inode_size & (fs->s_inode_size - 1)) != 0) {
-            kprintf("EXT2-fs: invalid inode size %d\n",
-                fs->s_inode_size);
-            return (EIO);
-        }
-    }
-    V(s_first_ino)
-    V(s_inode_size)
-    fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs);
-    V(s_inodes_per_block)
-    fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block;
-    V(s_itb_per_group)
-    fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc);
-    V(s_desc_per_block)
-    /* s_resuid / s_resgid ? */
-    fs->s_groups_count = (es->s_blocks_count -
-			  es->s_first_data_block +
-			  EXT2_BLOCKS_PER_GROUP(fs) - 1) /
-			 EXT2_BLOCKS_PER_GROUP(fs);
-    V(s_groups_count)
-    db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) /
-	EXT2_DESC_PER_BLOCK(fs);
-    fs->s_db_per_group = db_count;
-    V(s_db_per_group)
-
-    fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
-		M_EXT2MNT, M_WAITOK);
-
-    /* adjust logic_sb_block */
-    if(fs->s_blocksize > SBSIZE) 
-	/* Godmar thinks: if the blocksize is greater than 1024, then
-	   the superblock is logically part of block zero. 
-	 */
-        logic_sb_block = 0;
-    
-    for (i = 0; i < db_count; i++) {
-	error = bread(devvp, fsbtodoff(fs, logic_sb_block + i + 1), 
-		      fs->s_blocksize, &fs->s_group_desc[i]);
-	if(error) {
-	    for (j = 0; j < i; j++)
-		brelse(fs->s_group_desc[j]);
-	    bsd_free(fs->s_group_desc, M_EXT2MNT);
-	    kprintf("EXT2-fs: unable to read group descriptors (%d)\n", error);
-	    return EIO;
-	}
-	/* Set the B_LOCKED flag on the buffer, then brelse() it */
-	LCK_BUF(fs->s_group_desc[i])
-    }
-    if(!ext2_check_descriptors(fs)) {
-	    for (j = 0; j < db_count; j++)
-		    ULCK_BUF(fs->s_group_desc[j])
-	    bsd_free(fs->s_group_desc, M_EXT2MNT);
-	    kprintf("EXT2-fs: (ext2_check_descriptors failure) "
-		   "unable to read group descriptors\n");
-	    return EIO;
-    }
-
-    for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
-	    fs->s_inode_bitmap_number[i] = 0;
-	    fs->s_inode_bitmap[i] = NULL;
-	    fs->s_block_bitmap_number[i] = 0;
-	    fs->s_block_bitmap[i] = NULL;
-    }
-    fs->s_loaded_inode_bitmaps = 0;
-    fs->s_loaded_block_bitmaps = 0;
-    return 0;
-}
-
-/*
- * Reload all incore data for a filesystem (used after running fsck on
- * the root filesystem and finding things to fix). The filesystem must
- * be mounted read-only.
- *
- * Things to do to update the mount:
- *	1) invalidate all cached meta-data.
- *	2) re-read superblock from disk.
- *	3) re-read summary information from disk.
- *	4) invalidate all inactive vnodes.
- *	5) invalidate all cached file data.
- *	6) re-read inode data for all active vnodes.
- */
-static int ext2_reload_scan1(struct mount *mp, struct vnode *vp, void *rescan);
-static int ext2_reload_scan2(struct mount *mp, struct vnode *vp, void *rescan);
-
-struct scaninfo {
-	int rescan;
-	int allerror;
-	int waitfor;
-	struct vnode *devvp;
-	struct ext2_sb_info *fs;
-};
-
-static int
-ext2_reload(struct mount *mountp, struct ucred *cred)
-{
-	struct vnode *devvp;
-	struct buf *bp;
-	struct ext2_super_block * es;
-	struct ext2_sb_info *fs;
-	int error;
-	struct scaninfo scaninfo;
-
-	if ((mountp->mnt_flag & MNT_RDONLY) == 0)
-		return (EINVAL);
-	/*
-	 * Step 1: invalidate all cached meta-data.
-	 */
-	devvp = VFSTOEXT2(mountp)->um_devvp;
-	if (vinvalbuf(devvp, 0, 0, 0))
-		panic("ext2_reload: dirty1");
-	/*
-	 * Step 2: re-read superblock from disk.
-	 * constants have been adjusted for ext2
-	 */
-	if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
-		return (error);
-	es = (struct ext2_super_block *)bp->b_data;
-	if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) {
-		brelse(bp);
-		return (EIO);		/* XXX needs translation */
-	}
-	fs = VFSTOEXT2(mountp)->um_e2fs;
-	bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
-
-	if((error = compute_sb_data(devvp, es, fs)) != 0) {
-		brelse(bp);
-		return error;
-	}
-#ifdef UNKLAR
-	if (fs->fs_sbsize < SBSIZE)
-		bp->b_flags |= B_INVAL;
-#endif
-	brelse(bp);
-
-	scaninfo.rescan = 1;
-	scaninfo.devvp = devvp;
-	scaninfo.fs = fs;
-	while (error == 0 && scaninfo.rescan) {
-	    scaninfo.rescan = 0;
-	    error = vmntvnodescan(mountp, VMSC_GETVX, ext2_reload_scan1, 
-				ext2_reload_scan2, &scaninfo);
-	}
-	return(error);
-}
-
-static int
-ext2_reload_scan1(struct mount *mp, struct vnode *vp, void *data)
-{
-	/*struct scaninfo *info = data;*/
-
-	return(0);
-}
-
-static int
-ext2_reload_scan2(struct mount *mp, struct vnode *vp, void *data)
-{
-	struct scaninfo *info = data;
-	struct inode *ip;
-	struct buf *bp;
-	int error;
-
-	/*
-	 * Try to recycle
-	 */
-	if (vrecycle(vp))
-		return(0);
-
-	/*
-	 * Step 5: invalidate all cached file data.
-	 */
-	if (vinvalbuf(vp, 0, 0, 0))
-		panic("ext2_reload: dirty2");
-	/*
-	 * Step 6: re-read inode data for all active vnodes.
-	 */
-	ip = VTOI(vp);
-	error = bread(info->devvp, 
-		      fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)),
-		      (int)info->fs->s_blocksize, &bp);
-	if (error)
-		return (error);
-	ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + 
-	    EXT2_INODE_SIZE(info->fs) * ino_to_fsbo(info->fs, ip->i_number)),
-	    &ip->i_din);
-	brelse(bp);
-	return(0);
-}
-
-/*
- * Common code for mount and mountroot
- */
-static int
-ext2_mountfs(struct vnode *devvp, struct mount *mp, struct ucred *cred)
-{
-	struct ext2mount *ump;
-	struct buf *bp;
-	struct ext2_sb_info *fs;
-	struct ext2_super_block * es;
-	cdev_t dev;
-	struct partinfo dpart;
-	int error, i;
-	int ronly;
-
-	/*
-	 * Disallow multiple mounts of the same device.
-	 * Disallow mounting of a device that is currently in use
-	 * (except for root, which might share swap device for miniroot).
-	 * Flush out any old buffers remaining from a previous use.
-	 */
-	if ((error = vfs_mountedon(devvp)) != 0)
-		return (error);
-	if (vcount(devvp) > 0)
-		return (EBUSY);
-	if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)) != 0)
-		return (error);
-#ifdef READONLY
-/* turn on this to force it to be read-only */
-	mp->mnt_flag |= MNT_RDONLY;
-#endif
-
-	ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
-	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
-	error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL);
-	vn_unlock(devvp);
-	if (error)
-		return (error);
-	dev = devvp->v_rdev;
-	if (dev->si_iosize_max != 0)
-		mp->mnt_iosize_max = dev->si_iosize_max;
-	if (mp->mnt_iosize_max > MAXPHYS)
-		mp->mnt_iosize_max = MAXPHYS;
-	VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, NULL);
-
-	bp = NULL;
-	ump = NULL;
-	if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0)
-		goto out;
-	es = (struct ext2_super_block *)bp->b_data;
-	if (ext2_check_sb_compat(es, dev, ronly) != 0) {
-		error = EINVAL;		/* XXX needs translation */
-		goto out;
-	}
-	if ((es->s_state & EXT2_VALID_FS) == 0 ||
-	    (es->s_state & EXT2_ERROR_FS)) {
-		if (ronly || (mp->mnt_flag & MNT_FORCE)) {
-			kprintf(
-"WARNING: Filesystem was not properly dismounted\n");
-		} else {
-			kprintf(
-"WARNING: R/W mount denied.  Filesystem is not clean - run fsck\n");
-			error = EPERM;
-			goto out;
-		}
-	}
-	ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK | M_ZERO);
-	ump->um_malloctype = M_EXT2NODE;
-	ump->um_blkatoff = ext2_blkatoff;
-	ump->um_truncate = ext2_truncate;
-	ump->um_update = ext2_update;
-	ump->um_valloc = ext2_valloc;
-	ump->um_vfree = ext2_vfree;
-	/* I don't know whether this is the right strategy. Note that
-	   we dynamically allocate both a ext2_sb_info and a ext2_super_block
-	   while Linux keeps the super block in a locked buffer
-	 */
-	ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), 
-		M_EXT2MNT, M_WAITOK);
-	ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), 
-		M_EXT2MNT, M_WAITOK);
-	bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
-	if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
-		goto out;
-	/*
-	 * We don't free the group descriptors allocated by compute_sb_data()
-	 * until ext2_unmount().  This is OK since the mount will succeed.
-	 */
-	brelse(bp);
-	bp = NULL;
-	fs = ump->um_e2fs;
-	fs->s_rd_only = ronly;	/* ronly is set according to mnt_flags */
-	/* if the fs is not mounted read-only, make sure the super block is 
-	   always written back on a sync()
-	 */
-	fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0;
-	if (ronly == 0) {
-		fs->s_dirt = 1;		/* mark it modified */
-		fs->s_es->s_state &= ~EXT2_VALID_FS;	/* set fs invalid */
-	}
-	mp->mnt_data = (qaddr_t)ump;
-	mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
-	mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
-	mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN;
-	mp->mnt_flag |= MNT_LOCAL;
-	ump->um_mountp = mp;
-	ump->um_dev = dev;
-	ump->um_devvp = devvp;
-	/* setting those two parameters allows us to use 
-	   ext2_bmap w/o changse !
-	*/
-	ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
-	ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
-	ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
-	for (i = 0; i < MAXQUOTAS; i++)
-		ump->um_quotas[i] = NULLVP; 
-	dev->si_mountpoint = mp;
-
-	vfs_add_vnodeops(mp, &ext2_vnode_vops, &mp->mnt_vn_norm_ops);
-	vfs_add_vnodeops(mp, &ext2_spec_vops, &mp->mnt_vn_spec_ops);
-	vfs_add_vnodeops(mp, &ext2_fifo_vops, &mp->mnt_vn_fifo_ops);
-
-	if (ronly == 0) 
-		ext2_sbupdate(ump, MNT_WAIT);
-	return (0);
-out:
-	if (bp)
-		brelse(bp);
-	VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE);
-	if (ump) {
-		bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
-		bsd_free(ump->um_e2fs, M_EXT2MNT);
-		bsd_free(ump, M_EXT2MNT);
-		mp->mnt_data = (qaddr_t)0;
-	}
-	return (error);
-}
-
-/*
- * unmount system call
- */
-static int
-ext2_unmount(struct mount *mp, int mntflags)
-{
-	struct ext2mount *ump;
-	struct ext2_sb_info *fs;
-	int error, flags, ronly, i;
-
-	flags = 0;
-	if (mntflags & MNT_FORCE) {
-		if (mp->mnt_flag & MNT_ROOTFS)
-			return (EINVAL);
-		flags |= FORCECLOSE;
-	}
-	if ((error = ext2_flushfiles(mp, flags)) != 0)
-		return (error);
-	ump = VFSTOEXT2(mp);
-	fs = ump->um_e2fs;
-	ronly = fs->s_rd_only;
-	if (ronly == 0) {
-		if (fs->s_wasvalid)
-			fs->s_es->s_state |= EXT2_VALID_FS;
-		ext2_sbupdate(ump, MNT_WAIT);
-	}
-
-	/* release buffers containing group descriptors */
-	for(i = 0; i < fs->s_db_per_group; i++) 
-		ULCK_BUF(fs->s_group_desc[i])
-	bsd_free(fs->s_group_desc, M_EXT2MNT);
-
-	/* release cached inode/block bitmaps */
-        for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
-                if (fs->s_inode_bitmap[i])
-			ULCK_BUF(fs->s_inode_bitmap[i])
-
-        for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
-                if (fs->s_block_bitmap[i])
-			ULCK_BUF(fs->s_block_bitmap[i])
-
-	ump->um_devvp->v_rdev->si_mountpoint = NULL;
-	error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE);
-	vrele(ump->um_devvp);
-	bsd_free(fs->s_es, M_EXT2MNT);
-	bsd_free(fs, M_EXT2MNT);
-	bsd_free(ump, M_EXT2MNT);
-	mp->mnt_data = (qaddr_t)0;
-	mp->mnt_flag &= ~MNT_LOCAL;
-	return (error);
-}
-
-/*
- * Flush out all the files in a filesystem.
- */
-static int
-ext2_flushfiles(struct mount *mp, int flags)
-{
-	struct ext2mount *ump;
-	int error;
-#if QUOTA
-	int i;
-#endif
-
-	ump = VFSTOEXT2(mp);
-#if QUOTA
-	if (mp->mnt_flag & MNT_QUOTA) {
-		if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
-			return (error);
-		for (i = 0; i < MAXQUOTAS; i++) {
-			if (ump->um_quotas[i] == NULLVP)
-				continue;
-			ext2_quotaoff(mp, i);
-		}
-		/*
-		 * Here we fall through to vflush again to ensure
-		 * that we have gotten rid of all the system vnodes.
-		 */
-	}
-#endif
-	error = vflush(mp, 0, flags);
-	return (error);
-}
-
-/*
- * Get file system statistics.
- * taken from ext2/super.c ext2_statfs
- */
-static int
-ext2_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
-{
-        unsigned long overhead;
-	struct ext2mount *ump;
-	struct ext2_sb_info *fs;
-	struct ext2_super_block *es;
-	int i, nsb;
-
-	ump = VFSTOEXT2(mp);
-	fs = ump->um_e2fs;
-	es = fs->s_es;
-
-	if (es->s_magic != EXT2_SUPER_MAGIC)
-		panic("ext2_statfs - magic number spoiled");
-
-	/*
-	 * Compute the overhead (FS structures)
-	 */
-	if (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) {
-		nsb = 0;
-		for (i = 0 ; i < fs->s_groups_count; i++)
-			if (ext2_group_sparse(i))
-				nsb++;
-	} else
-		nsb = fs->s_groups_count;
-	overhead = es->s_first_data_block + 
-	    /* Superblocks and block group descriptors: */
-	    nsb * (1 + fs->s_db_per_group) +
-	    /* Inode bitmap, block bitmap, and inode table: */
-	    fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
-
-	sbp->f_bsize = EXT2_FRAG_SIZE(fs);	
-	sbp->f_iosize = EXT2_BLOCK_SIZE(fs);
-	sbp->f_blocks = es->s_blocks_count - overhead;
-	sbp->f_bfree = es->s_free_blocks_count; 
-	sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; 
-	sbp->f_files = es->s_inodes_count; 
-	sbp->f_ffree = es->s_free_inodes_count; 
-	if (sbp != &mp->mnt_stat) {
-		sbp->f_type = mp->mnt_vfc->vfc_typenum;
-		bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
-			(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
-	}
-	return (0);
-}
-
-/*
- * Go through the disk queues to initiate sandbagged IO;
- * go through the inodes to write those that have been modified;
- * initiate the writing of the super block if it has been modified.
- *
- * Note: we are always called with the filesystem marked `MPBUSY'.
- */
-
-static int ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data);
-
-static int
-ext2_sync(struct mount *mp, int waitfor)
-{
-	struct ext2mount *ump = VFSTOEXT2(mp);
-	struct ext2_sb_info *fs;
-	struct scaninfo scaninfo;
-	int error;
-
-	fs = ump->um_e2fs;
-	if (fs->s_dirt != 0 && fs->s_rd_only != 0) {		/* XXX */
-		kprintf("fs = %s\n", fs->fs_fsmnt);
-		panic("ext2_sync: rofs mod");
-	}
-
-	/*
-	 * Write back each (modified) inode.
-	 */
-	scaninfo.allerror = 0;
-	scaninfo.rescan = 1;
-	scaninfo.waitfor = waitfor;
-	while (scaninfo.rescan) {
-		scaninfo.rescan = 0;
-		vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT, 
-				NULL, ext2_sync_scan, &scaninfo);
-	}
-
-	/*
-	 * Force stale file system control information to be flushed.
-	 */
-	if ((waitfor & MNT_LAZY) == 0) {
-		vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY);
-		if ((error = VOP_FSYNC(ump->um_devvp, waitfor, 0)) != 0)
-			scaninfo.allerror = error;
-		vn_unlock(ump->um_devvp);
-	}
-#if QUOTA
-	ext2_qsync(mp);
-#endif
-	/*
-	 * Write back modified superblock.
-	 */
-	if (fs->s_dirt != 0) {
-		fs->s_dirt = 0;
-		fs->s_es->s_wtime = time_second;
-		if ((error = ext2_sbupdate(ump, waitfor)) != 0)
-			scaninfo.allerror = error;
-	}
-	return (scaninfo.allerror);
-}
-
-static int
-ext2_sync_scan(struct mount *mp, struct vnode *vp, void *data)
-{
-	struct scaninfo *info = data;
-	struct inode *ip;
-	int error;
-
-	ip = VTOI(vp);
-	if (vp->v_type == VNON ||
-	    ((ip->i_flag &
-	    (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
-	    (RB_EMPTY(&vp->v_rbdirty_tree) || (info->waitfor & MNT_LAZY)))) {
-		return(0);
-	}
-	if ((error = VOP_FSYNC(vp, info->waitfor, 0)) != 0)
-		info->allerror = error;
-	return(0);
-}
-
-/*
- * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it
- * in from disk.  If it is in core, wait for the lock bit to clear, then
- * return the inode locked.  Detection and handling of mount points must be
- * done by the calling routine.
- */
-static int
-ext2_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
-{
-	struct ext2_sb_info *fs;
-	struct inode *ip;
-	struct ext2mount *ump;
-	struct buf *bp;
-	struct vnode *vp;
-	cdev_t dev;
-	int i, error;
-	int used_blocks;
-
-	ump = VFSTOEXT2(mp);
-	dev = ump->um_dev;
-restart:
-	if ((*vpp = ext2_ihashget(dev, ino)) != NULL)
-		return (0);
-
-	/*
-	 * Lock out the creation of new entries in the FFS hash table in
-	 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate
-	 * may occur!
-	 */
-	if (ext2fs_inode_hash_lock) {
-		while (ext2fs_inode_hash_lock) {
-			ext2fs_inode_hash_lock = -1;
-			tsleep(&ext2fs_inode_hash_lock, 0, "e2vget", 0);
-		}
-		goto restart;
-	}
-	ext2fs_inode_hash_lock = 1;
-
-	/*
-	 * If this MALLOC() is performed after the getnewvnode()
-	 * it might block, leaving a vnode with a NULL v_data to be
-	 * found by ext2_sync() if a sync happens to fire right then,
-	 * which will cause a panic because ext2_sync() blindly
-	 * dereferences vp->v_data (as well it should).
-	 */
-	MALLOC(ip, struct inode *, sizeof(struct inode), M_EXT2NODE, M_WAITOK);
-
-	/* Allocate a new vnode/inode. */
-	if ((error = getnewvnode(VT_EXT2FS, mp, &vp, 0, LK_CANRECURSE)) != 0) {
-		if (ext2fs_inode_hash_lock < 0)
-			wakeup(&ext2fs_inode_hash_lock);
-		ext2fs_inode_hash_lock = 0;
-		*vpp = NULL;
-		FREE(ip, M_EXT2NODE);
-		return (error);
-	}
-	bzero((caddr_t)ip, sizeof(struct inode));
-	vp->v_data = ip;
-	ip->i_vnode = vp;
-	ip->i_e2fs = fs = ump->um_e2fs;
-	ip->i_dev = dev;
-	ip->i_number = ino;
-#if QUOTA
-	for (i = 0; i < MAXQUOTAS; i++)
-		ip->i_dquot[i] = NODQUOT;
-#endif
-	/*
-	 * Put it onto its hash chain.  Since our vnode is locked, other
-	 * requests for this inode will block if they arrive while we are
-	 * sleeping waiting for old data structures to be purged or for the
-	 * contents of the disk portion of this inode to be read.
-	 */
-	ext2_ihashins(ip);
-
-	if (ext2fs_inode_hash_lock < 0)
-		wakeup(&ext2fs_inode_hash_lock);
-	ext2fs_inode_hash_lock = 0;
-
-	/* Read in the disk contents for the inode, copy into the inode. */
-#if 0
-kprintf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
-#endif
-	error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)),
-		      (int)fs->s_blocksize, &bp);
-	if (error) {
-		/*
-		 * The inode does not contain anything useful, so it would
-		 * be misleading to leave it on its hash chain. With mode
-		 * still zero, it will be unlinked and returned to the free
-		 * list by vput().
-		 */
-		brelse(bp);
-		vx_put(vp);
-		*vpp = NULL;
-		return (error);
-	}
-	/* convert ext2 inode to dinode */
-	ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
-			ino_to_fsbo(fs, ino)), &ip->i_din);
-	ip->i_block_group = ino_to_cg(fs, ino);
-	ip->i_next_alloc_block = 0;
-	ip->i_next_alloc_goal = 0;
-	ip->i_prealloc_count = 0;
-	ip->i_prealloc_block = 0;
-        /* now we want to make sure that block pointers for unused
-           blocks are zeroed out - ext2_balloc depends on this 
-	   although for regular files and directories only
-	*/
-	if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) {
-		used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize;
-		for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
-			ip->i_db[i] = 0;
-	}
-#if 0
-	ext2_print_inode(ip);
-#endif
-	bqrelse(bp);
-
-	/*
-	 * Initialize the vnode from the inode, check for aliases.
-	 * Note that the underlying vnode may have changed.
-	 */
-	if ((error = ext2_vinit(mp, &vp)) != 0) {
-		vx_put(vp);
-		*vpp = NULL;
-		return (error);
-	}
-
-	/*
-	 * Finish inode initialization now that aliasing has been resolved.
-	 */
-	ip->i_devvp = ump->um_devvp;
-	vref(ip->i_devvp);
-	/*
-	 * Set up a generation number for this inode if it does not
-	 * already have one. This should only happen on old filesystems.
-	 */
-	if (ip->i_gen == 0) {
-		ip->i_gen = krandom() / 2 + 1;
-		if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
-			ip->i_flag |= IN_MODIFIED;
-	}
-	/*
-	 * Return the locked and refd vnode.
-	 */
-	*vpp = vp;
-	return (0);
-}
-
-/*
- * File handle to vnode
- *
- * Have to be really careful about stale file handles:
- * - check that the inode number is valid
- * - call ext2_vget() to get the locked inode
- * - check for an unallocated inode (i_mode == 0)
- * - check that the given client host has export rights and return
- *   those rights via. exflagsp and credanonp
- */
-static int
-ext2_fhtovp(struct mount *mp, struct vnode *rootvp,
-	    struct fid *fhp, struct vnode **vpp)
-{
-	struct ufid *ufhp;
-	struct ext2_sb_info *fs;
-	struct inode *ip;
-        struct vnode *nvp;
-        int error;
-
-	ufhp = (struct ufid *)fhp;
-	fs = VFSTOEXT2(mp)->um_e2fs;
-	if (ufhp->ufid_ino < ROOTINO ||
-	    ufhp->ufid_ino > fs->s_groups_count * fs->s_es->s_inodes_per_group)
-		return (ESTALE);
-
-	error = VFS_VGET(mp, rootvp, ufhp->ufid_ino, &nvp);
-	if (error) {
-		*vpp = NULLVP;
-		return (error);
-	}
-	ip = VTOI(nvp);
-	if (ip->i_mode == 0 ||
-	    ip->i_gen != ufhp->ufid_gen ||
-	    (VFSTOEXT2(mp)->um_i_effnlink_valid ? ip->i_effnlink :
-	    ip->i_nlink) <= 0) {
-		vput(nvp);
-		*vpp = NULLVP;
-		return (ESTALE);
-	}
-	*vpp = nvp;
-	return (0);
-}
-
-/*
- * Vnode pointer to File handle
- */
-/* ARGSUSED */
-static int
-ext2_vptofh(struct vnode *vp, struct fid *fhp)
-{
-	struct inode *ip;
-	struct ufid *ufhp;
-
-	ip = VTOI(vp);
-	ufhp = (struct ufid *)fhp;
-	ufhp->ufid_len = sizeof(struct ufid);
-	ufhp->ufid_ino = ip->i_number;
-	ufhp->ufid_gen = ip->i_gen;
-	return (0);
-}
-
-/*
- * This is the generic part of fhtovp called after the underlying
- * filesystem has validated the file handle.
- *
- * Verify that a host should have access to a filesystem.
- */
-int
-ext2_check_export(struct mount *mp, struct sockaddr *nam, int *exflagsp,
-                 struct ucred **credanonp)
-{
-	struct netcred *np;
-	struct ext2mount *ump;
-	 
-	ump = VFSTOEXT2(mp);
-	/*
-	 * Get the export permission structure for this <mp, client> tuple.
-	 */
-	np = vfs_export_lookup(mp, &ump->um_export, nam);
-	if (np == NULL)
-		return (EACCES);
-
-	*exflagsp = np->netc_exflags;
-	*credanonp = &np->netc_anon;
-	return (0);
-}
-
-/*
- * Write a superblock and associated information back to disk.
- */
-static int
-ext2_sbupdate(struct ext2mount *mp, int waitfor)
-{
-	struct ext2_sb_info *fs = mp->um_e2fs;
-	struct ext2_super_block *es = fs->s_es;
-	struct buf *bp;
-	int error = 0;
-/*
-kprintf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
-*/
-	bp = getblk(mp->um_devvp, SBOFF, SBSIZE, 0, 0);
-	bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block));
-	if (waitfor == MNT_WAIT)
-		error = bwrite(bp);
-	else
-		bawrite(bp);
-
-	/*
-	 * The buffers for group descriptors, inode bitmaps and block bitmaps
-	 * are not busy at this point and are (hopefully) written by the
-	 * usual sync mechanism. No need to write them here
-	 */
-
-	return (error);
-}
diff --git a/sys/vfs/gnu/ext2fs/ext2_vnops.c b/sys/vfs/gnu/ext2fs/ext2_vnops.c
deleted file mode 100644
index 790ed9a..0000000
--- a/sys/vfs/gnu/ext2fs/ext2_vnops.c
+++ /dev/null
@@ -1,2115 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
- *	@(#)ext2_vnops.c	8.7 (Berkeley) 2/3/94
- * $FreeBSD: src/sys/gnu/ext2fs/ext2_vnops.c,v 1.51.2.2 2003/01/02 17:26:18 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.43 2008/06/19 23:27:39 dillon Exp $
- */
-
-#include "opt_quota.h"
-#include "opt_suiddir.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/resourcevar.h>
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/buf.h>
-#include <sys/stat.h>
-#include <sys/proc.h>
-#include <sys/priv.h>
-#include <sys/mount.h>
-#include <sys/time.h>
-#include <sys/vnode.h>
-#include <sys/dirent.h>
-#include <sys/lockf.h>
-#include <sys/event.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/jail.h>
-#include <sys/namei.h>
-#include <sys/signalvar.h>
-#include <sys/unistd.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_zone.h>
-#include <vm/vnode_pager.h>
-
-#include <sys/buf2.h>
-#include <sys/thread2.h>
-
-#include <vfs/fifofs/fifo.h>
-
-#include "dir.h"
-#include "quota.h"
-#include "inode.h"
-#include "ext2mount.h"
-#include "ext2_fs_sb.h"
-#include "fs.h"
-#include "ext2_extern.h"
-#include "ext2_fs.h"
-
-static int ext2_access (struct vop_access_args *);
-static int ext2_advlock (struct vop_advlock_args *);
-static int ext2_chmod (struct vnode *, int, struct ucred *);
-static int ext2_chown (struct vnode *, uid_t, gid_t, struct ucred *);
-static int ext2_close (struct vop_close_args *);
-static int ext2_getattr (struct vop_getattr_args *);
-static int ext2_makeinode (int mode, struct vnode *, struct vnode **, struct componentname *);
-static int ext2_mmap (struct vop_mmap_args *);
-static int ext2_open (struct vop_open_args *);
-static int ext2_pathconf (struct vop_pathconf_args *);
-static int ext2_print (struct vop_print_args *);
-static int ext2_readlink (struct vop_readlink_args *);
-static int ext2_setattr (struct vop_setattr_args *);
-static int ext2_strategy (struct vop_strategy_args *);
-static int ext2_whiteout (struct vop_old_whiteout_args *);
-static int filt_ext2read (struct knote *kn, long hint);
-static int filt_ext2write (struct knote *kn, long hint);
-static int filt_ext2vnode (struct knote *kn, long hint);
-static void filt_ext2detach (struct knote *kn);
-static int ext2_kqfilter (struct vop_kqfilter_args *ap);
-static int ext2fifo_close (struct vop_close_args *);
-static int ext2fifo_kqfilter (struct vop_kqfilter_args *);
-static int ext2fifo_read (struct vop_read_args *);
-static int ext2fifo_write (struct vop_write_args *);
-
-static int ext2_fsync (struct vop_fsync_args *);
-static int ext2_read (struct vop_read_args *);
-static int ext2_write (struct vop_write_args *);
-static int ext2_remove (struct vop_old_remove_args *);
-static int ext2_link (struct vop_old_link_args *);
-static int ext2_rename (struct vop_old_rename_args *);
-static int ext2_mkdir (struct vop_old_mkdir_args *);
-static int ext2_rmdir (struct vop_old_rmdir_args *);
-static int ext2_create (struct vop_old_create_args *);
-static int ext2_mknod (struct vop_old_mknod_args *);
-static int ext2_symlink (struct vop_old_symlink_args *);
-
-#include "ext2_readwrite.c"
-
-union _qcvt {
-	int64_t qcvt;
-	int32_t val[2];
-};
-#define SETHIGH(q, h) { \
-	union _qcvt tmp; \
-	tmp.qcvt = (q); \
-	tmp.val[_QUAD_HIGHWORD] = (h); \
-	(q) = tmp.qcvt; \
-}
-#define SETLOW(q, l) { \
-	union _qcvt tmp; \
-	tmp.qcvt = (q); \
-	tmp.val[_QUAD_LOWWORD] = (l); \
-	(q) = tmp.qcvt; \
-}
-#define VN_KNOTE(vp, b) \
-	KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, (b))
-
-#define OFSFMT(vp)		((vp)->v_mount->mnt_maxsymlinklen <= 0)
-
-/*
- * A virgin directory (no blushing please).
- * Note that the type and namlen fields are reversed relative to ufs.
- * Also, we don't use `struct odirtemplate', since it would just cause
- * endianness problems.
- */
-static struct dirtemplate ext2_mastertemplate = {
-	0, 12, 1, EXT2_FT_DIR, ".",
-	0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".."
-};
-static struct dirtemplate ext2_omastertemplate = {
-	0, 12, 1, EXT2_FT_UNKNOWN, ".",
-	0, DIRBLKSIZ - 12, 2, EXT2_FT_UNKNOWN, ".."
-};
-
-/*
- * Create a regular file
- *
- * ext2_create(struct vnode *a_dvp, struct vnode **a_vpp,
- *	       struct componentname *a_cnp, struct vattr *a_vap)
- */
-static int
-ext2_create(struct vop_old_create_args *ap)
-{
-	int error;
-
-	error =
-	    ext2_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
-	    ap->a_dvp, ap->a_vpp, ap->a_cnp);
-	if (error)
-		return (error);
-	return (0);
-}
-
-/*
- * Synch an open file.
- *
- * ext2_fsync(struct vnode *a_vp, struct ucred *a_cred, int a_waitfor,
- *	      struct proc *a_p)
- */
-/* ARGSUSED */
-
-static int ext2_fsync_bp(struct buf *bp, void *data);
-
-struct ext2_fsync_bp_info {
-	struct vnode *vp;
-	int waitfor;
-};
-
-static int
-ext2_fsync(struct vop_fsync_args *ap)
-{
-	struct ext2_fsync_bp_info info;
-	struct vnode *vp = ap->a_vp;
-	int count;
-
-	/* 
-	 * XXX why is all this fs specific?
-	 */
-
-	/*
-	 * Flush all dirty buffers associated with a vnode.
-	 */
-	ext2_discard_prealloc(VTOI(vp));
-
-	lwkt_gettoken(&vp->v_token);
-	info.vp = vp;
-loop:
-	info.waitfor = ap->a_waitfor;
-	count = RB_SCAN(buf_rb_tree, &vp->v_rbdirty_tree, NULL, 
-			ext2_fsync_bp, &info);
-	if (count)
-		goto loop;
-
-	if (ap->a_waitfor == MNT_WAIT) {
-		bio_track_wait(&vp->v_track_write, 0, 0);
-#if DIAGNOSTIC
-		if (!RB_EMPTY(&vp->v_rbdirty_tree)) {
-			vprint("ext2_fsync: dirty", vp);
-			goto loop;
-		}
-#endif
-	}
-	lwkt_reltoken(&vp->v_token);
-	return (EXT2_UPDATE(ap->a_vp, ap->a_waitfor == MNT_WAIT));
-}
-
-static int
-ext2_fsync_bp(struct buf *bp, void *data)
-{
-	struct ext2_fsync_bp_info *info = data;
-
-	if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
-		return(0);
-	if ((bp->b_flags & B_DELWRI) == 0)
-		panic("ext2_fsync: not dirty");
-	bremfree(bp);
-
-	/*
-	 * Wait for I/O associated with indirect blocks to complete,
-	 * since there is no way to quickly wait for them below.
-	 */
-	if (bp->b_vp == info->vp || (info->waitfor & MNT_NOWAIT))
-		bawrite(bp);
-	else
-		bwrite(bp);
-	return(1);
-}
-
-/*
- * Mknod vnode call
- *
- * ext2_mknod(struct vnode *a_dvp, struct vnode **a_vpp,
- *	      struct componentname *a_cnp, struct vattr *a_vap)
- */
-/* ARGSUSED */
-static int
-ext2_mknod(struct vop_old_mknod_args *ap)
-{
-	struct vattr *vap = ap->a_vap;
-	struct vnode **vpp = ap->a_vpp;
-	struct inode *ip;
-	ino_t ino;
-	int error;
-
-	if (vap->va_rmajor != VNOVAL &&
-	    makeudev(vap->va_rmajor, vap->va_rminor) == NOUDEV) {
-		return (EINVAL);
-	}
-
-	error = ext2_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
-	    ap->a_dvp, vpp, ap->a_cnp);
-	if (error)
-		return (error);
-	ip = VTOI(*vpp);
-	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
-	if (vap->va_rmajor != VNOVAL) {
-		/*
-		 * Want to be able to use this to make badblock
-		 * inodes, so don't truncate the dev number.
-		 */
-		ip->i_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
-	}
-	/*
-	 * Remove inode, then reload it through VFS_VGET so it is
-	 * checked to see if it is an alias of an existing entry in
-	 * the inode cache.
-	 */
-	(*vpp)->v_type = VNON;
-	ino = ip->i_number;	/* Save this before vgone() invalidates ip. */
-	vgone_vxlocked(*vpp);
-	vput(*vpp);
-	error = VFS_VGET(ap->a_dvp->v_mount, NULL, ino, vpp);
-	if (error) {
-		*vpp = NULL;
-		return (error);
-	}
-	return (0);
-}
-
-/*
- * ext2_remove(struct vnode *a_dvp, struct vnode *a_vp,
- *	       struct componentname *a_cnp)
- */
-static int
-ext2_remove(struct vop_old_remove_args *ap)
-{
-	struct inode *ip;
-	struct vnode *vp = ap->a_vp;
-	struct vnode *dvp = ap->a_dvp;
-	int error;
-
-	ip = VTOI(vp);
-	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
-	    (VTOI(dvp)->i_flags & APPEND)) {
-		error = EPERM;
-		goto out;
-	}
-	error = ext2_dirremove(dvp, ap->a_cnp);
-	if (error == 0) {
-		ip->i_nlink--;
-		ip->i_flag |= IN_CHANGE;
-	}
-out:
-	return (error);
-}
-
-/*
- * link vnode call
- *
- * ext2_link(struct vnode *a_tdvp, struct vnode *a_vp,
- *	     struct componentname *a_cnp)
- */
-static int
-ext2_link(struct vop_old_link_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct vnode *tdvp = ap->a_tdvp;
-	struct componentname *cnp = ap->a_cnp;
-	struct inode *ip;
-	int error;
-
-	if (tdvp->v_mount != vp->v_mount) {
-		error = EXDEV;
-		goto out2;
-	}
-	if (tdvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
-		goto out2;
-	}
-	ip = VTOI(vp);
-	if ((nlink_t)ip->i_nlink >= LINK_MAX) {
-		error = EMLINK;
-		goto out1;
-	}
-	if (ip->i_flags & (IMMUTABLE | APPEND)) {
-		error = EPERM;
-		goto out1;
-	}
-	ip->i_nlink++;
-	ip->i_flag |= IN_CHANGE;
-	error = EXT2_UPDATE(vp, 1);
-	if (!error)
-		error = ext2_direnter(ip, tdvp, cnp);
-	if (error) {
-		ip->i_nlink--;
-		ip->i_flag |= IN_CHANGE;
-	}
-out1:
-	if (tdvp != vp)
-		vn_unlock(vp);
-out2:
-	return (error);
-}
-
-/*
- * Rename system call.  fdvp, fvp are ref'd.  tvp, tdvp are ref'd and locked.
- * all vp's are released and must be in an unlocked state on return.
- *
- * ext2_rename(struct vnode *a_fdvp, struct vnode *a_fvp,
- *		struct componentname *a_fcnp, struct vnode *a_tdvp,
- *		struct vnode *a_tvp, struct componentname *a_tcnp)
- */
-static int
-ext2_rename(struct vop_old_rename_args *ap)
-{
-	struct vnode *tvp = ap->a_tvp;
-	struct vnode *tdvp = ap->a_tdvp;
-	struct vnode *fvp = ap->a_fvp;
-	struct vnode *fdvp = ap->a_fdvp;
-	struct componentname *tcnp = ap->a_tcnp;
-	struct componentname *fcnp = ap->a_fcnp;
-	struct inode *ip, *xp, *dp;
-	struct dirtemplate dirbuf;
-	int doingdirectory = 0, oldparent = 0, newparent = 0;
-	int error = 0;
-	u_char namlen;
-
-	/*
-	 * Check for cross-device rename.
-	 */
-	if ((fvp->v_mount != tdvp->v_mount) ||
-	    (tvp && (fvp->v_mount != tvp->v_mount)) ||
-	    tvp == tdvp) {
-		error = EXDEV;
-abortit:
-		if (tdvp == tvp)
-			vrele(tdvp);
-		else
-			vput(tdvp);
-		if (tvp)
-			vput(tvp);
-		vrele(fdvp);
-		vrele(fvp);
-		return (error);
-	}
-
-	if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
-	    (VTOI(tdvp)->i_flags & APPEND))) {
-		error = EPERM;
-		goto abortit;
-	}
-
-	/*
-	 * Renaming a file to itself has no effect.  The upper layers should
-	 * not call us in that case.  Temporarily just warn if they do.
-	 */
-	if (fvp == tvp) {
-		error = 0;
-		goto abortit;
-	}
-
-	if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
-		goto abortit;
-
-	/*
-	 * fvp, tvp, tdvp locked.  fdvp not locked but note that fdvp may
-	 * be equal to tdvp.
-	 */
-	dp = VTOI(fdvp);
-	ip = VTOI(fvp);
- 	if (ip->i_nlink >= LINK_MAX) {
- 		vn_unlock(fvp);
- 		error = EMLINK;
- 		goto abortit;
- 	}
-	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
-	    || (dp->i_flags & APPEND)) {
-		vn_unlock(fvp);
-		error = EPERM;
-		goto abortit;
-	}
-	if ((ip->i_mode & IFMT) == IFDIR) {
-		/*
-		 * Avoid ".", "..", and aliases of "." for obvious reasons.
-		 */
-		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
-		    dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & CNP_ISDOTDOT ||
-		    (ip->i_flag & IN_RENAME)) {
-			vn_unlock(fvp);
-			error = EINVAL;
-			goto abortit;
-		}
-		ip->i_flag |= IN_RENAME;
-		oldparent = dp->i_number;
-		doingdirectory++;
-	}
-
-	/*
-	 * tvp is non-NULL if the target exists.   fvp is still locked but
-	 * we will unlock it soon.  The 'bad' goto target requires dp and
-	 * xp to be correctly assigned.
-	 */
-	dp = VTOI(tdvp);
-	if (tvp)
-		xp = VTOI(tvp);
-	else
-		xp = NULL;
-
-	/*
-	 * 1) Bump link count while we're moving stuff
-	 *    around.  If we crash somewhere before
-	 *    completing our work, the link count
-	 *    may be wrong, but correctable.
-	 */
-	ip->i_nlink++;
-	ip->i_flag |= IN_CHANGE;
-	if ((error = EXT2_UPDATE(fvp, 1)) != 0) {
-		vn_unlock(fvp);
-		goto bad;
-	}
-
-	/*
-	 * If ".." must be changed (ie the directory gets a new
-	 * parent) then the source directory must not be in the
-	 * directory heirarchy above the target, as this would
-	 * orphan everything below the source directory. Also
-	 * the user must have write permission in the source so
-	 * as to be able to change "..". We must repeat the call
-	 * to namei, as the parent directory is unlocked by the
-	 * call to checkpath().
-	 */
-	error = VOP_EACCESS(fvp, VWRITE, tcnp->cn_cred);
-	vn_unlock(fvp);
-
-	/*
-	 * tvp (if not NULL) and tdvp are locked.  fvp and fdvp are not.
-	 * dp and xp are set according to tdvp and tvp.
-	 */
-	if (oldparent != dp->i_number)
-		newparent = dp->i_number;
-	if (doingdirectory && newparent) {
-		if (error)	/* write access check above */
-			goto bad;
-
-		/*
-		 * Prepare for relookup, get rid of xp
-		 */
-		if (xp != NULL) {
-			vput(tvp);
-			xp = NULL;
-		}
-
-		/*
-		 * checkpath vput()'s tdvp (VTOI(dp)) on return no matter what,
-		 * get an extra ref so we wind up with just an unlocked, ref'd
-		 * tdvp.  The 'out' target skips xp and tdvp cleanups.  Our
-		 * tdvp is now unlocked so we have to clean it up ourselves.
-		 */
-		vref(tdvp);
-		error = ext2_checkpath(ip, dp, tcnp->cn_cred);
-		tcnp->cn_flags |= CNP_PDIRUNLOCK;
-		if (error) {
-			vrele(tdvp);
-			goto out;
-		}
-		/*
-		 * relookup no longer messes with the ref count.  An unlocked
-		 * tdvp must be passed and if no error occurs a locked tdvp
-		 * will be returned.  We have to use the out target again.
-		 */
-		error = relookup(tdvp, &tvp, tcnp);
-		if (error) {
-			if (tcnp->cn_flags & CNP_PDIRUNLOCK)
-				vrele(tdvp);
-			else
-				vput(tdvp);
-			goto out;
-		}
-
-		/*
-		 * tdvp is locked at this point.  in the RENAME case tvp may
-		 * be NULL without an error, assign xp accordingly.  The
-		 * 'bad' target can be used again after this.
-		 */
-		dp = VTOI(tdvp);
-		if (tvp)
-			xp = VTOI(tvp);
-	}
-	/*
-	 * 2) If target doesn't exist, link the target
-	 *    to the source and unlink the source.
-	 *    Otherwise, rewrite the target directory
-	 *    entry to reference the source inode and
-	 *    expunge the original entry's existence.
-	 *
-	 * tdvp and tvp are cleaned up by this code.  tvp is only good if
-	 * xp is not NULL.
-	 */
-	if (xp == NULL) {
-		if (dp->i_dev != ip->i_dev)
-			panic("ext2_rename: EXDEV");
-		/*
-		 * Account for ".." in new directory.
-		 * When source and destination have the same
-		 * parent we don't fool with the link count.
-		 */
-		if (doingdirectory && newparent) {
-			if ((nlink_t)dp->i_nlink >= LINK_MAX) {
-				error = EMLINK;
-				goto bad;
-			}
-			dp->i_nlink++;
-			dp->i_flag |= IN_CHANGE;
-			error = EXT2_UPDATE(tdvp, 1);
-			if (error)
-				goto bad;
-		}
-		error = ext2_direnter(ip, tdvp, tcnp);
-		if (error) {
-			if (doingdirectory && newparent) {
-				dp->i_nlink--;
-				dp->i_flag |= IN_CHANGE;
-				EXT2_UPDATE(tdvp, 1);
-			}
-			goto bad;
-		}
-
-		/*
-		 * manual cleanup, we can't use the bad or out target after
-		 * this.
-		 */
-		vput(tdvp);
-	} else {
-		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
-			panic("ext2_rename: EXDEV");
-		/*
-		 * Short circuit rename(foo, foo).
-		 */
-		if (xp->i_number == ip->i_number)
-			panic("ext2_rename: same file");
-		/*
-		 * If the parent directory is "sticky", then the user must
-		 * own the parent directory, or the destination of the rename,
-		 * otherwise the destination may not be changed (except by
-		 * root). This implements append-only directories.
-		 */
-		if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
-		    tcnp->cn_cred->cr_uid != dp->i_uid &&
-		    xp->i_uid != tcnp->cn_cred->cr_uid) {
-			error = EPERM;
-			goto bad;
-		}
-		/*
-		 * Target must be empty if a directory and have no links
-		 * to it. Also, ensure source and target are compatible
-		 * (both directories, or both not directories).
-		 */
-		if ((xp->i_mode&IFMT) == IFDIR) {
-			if (! ext2_dirempty(xp, dp->i_number, tcnp->cn_cred) || 
-			    xp->i_nlink > 2) {
-				error = ENOTEMPTY;
-				goto bad;
-			}
-			if (!doingdirectory) {
-				error = ENOTDIR;
-				goto bad;
-			}
-		} else if (doingdirectory) {
-			error = EISDIR;
-			goto bad;
-		}
-		error = ext2_dirrewrite(dp, ip, tcnp);
-		if (error)
-			goto bad;
-		/*
-		 * If the target directory is in the same
-		 * directory as the source directory,
-		 * decrement the link count on the parent
-		 * of the target directory.
-		 */
-		 if (doingdirectory && !newparent) {
-			dp->i_nlink--;
-			dp->i_flag |= IN_CHANGE;
-		}
-
-		/*
-		 * manual cleanup, we can't use the bad or out target after
-		 * this.
-		 */
-		vput(tdvp);
-
-		/*
-		 * Adjust the link count of the target to
-		 * reflect the dirrewrite above.  If this is
-		 * a directory it is empty and there are
-		 * no links to it, so we can squash the inode and
-		 * any space associated with it.  We disallowed
-		 * renaming over top of a directory with links to
-		 * it above, as the remaining link would point to
-		 * a directory without "." or ".." entries.
-		 */
-		xp->i_nlink--;
-		if (doingdirectory) {
-			if (--xp->i_nlink != 0)
-				panic("ext2_rename: linked directory");
-			error = EXT2_TRUNCATE(tvp, (off_t)0, IO_SYNC,
-					      tcnp->cn_cred);
-		}
-		xp->i_flag |= IN_CHANGE;
-		vput(tvp);
-		xp = NULL;
-	}
-
-	/*
-	 * tvp and tdvp have been cleaned up.  The bad and out targets may
-	 * not be used.  fvp and fdvp are ref'd but not locked.  ip
-	 * still represents the old fvp and ip->i_flag may still have IN_RENAME
-	 * set (if doingdirectory).
-	 */
-
-	/*
-	 * 3) Unlink the source.
-	 *
-	 * fdvp is locked and ref'd. ap->a_fvp holds the old lookup unlocked
-	 * and ref'd, fvp will hold the new lookup locked and ref'd.
-	 *
-	 * After the relookup ap->a_fvp must be released as part of our
-	 * cleanup, not just fdvp and fvp.  And, on success, fdvp and
-	 * fvp will be locked so the bad and out targets cannot be used.
-	 */
-	fcnp->cn_flags &= ~CNP_MODMASK;
-	fcnp->cn_flags |= CNP_LOCKPARENT;
-	KKASSERT(fcnp->cn_flags & CNP_PDIRUNLOCK);
-	error = relookup(fdvp, &fvp, fcnp);
-	if (error) {
-		/*
-		 * From name has disappeared.
-		 */
-		if (doingdirectory)
-			panic("ext2_rename: lost dir entry");
-		/* ip->i_flag only sets IN_RENAME if doingdirectory */
-		vrele(ap->a_fvp);
-		if (fcnp->cn_flags & CNP_PDIRUNLOCK)
-			vrele(fdvp);
-		else
-			vput(fdvp);
-		return (0);
-	}
-	KKASSERT((fcnp->cn_flags & CNP_PDIRUNLOCK) == 0);
-
-	/*
-	 * This case shouldn't occur
-	 */
-	if (fvp == NULL) {
-		/*
-		 * From name has disappeared.
-		 */
-		if (doingdirectory)
-			panic("ext2_rename: lost dir entry");
-		/* ip->i_flag only sets IN_RENAME if doingdirectory */
-		vrele(ap->a_fvp);
-		vput(fvp);
-		vput(fdvp);
-		return (0);
-	}
-
-	/*
-	 * fvp and fdvp are both ref'd and locked.
-	 */
-	xp = VTOI(fvp);
-	dp = VTOI(fdvp);
-
-	/*
-	 * Ensure that the directory entry still exists and has not
-	 * changed while the new name has been entered. If the source is
-	 * a file then the entry may have been unlinked or renamed. In
-	 * either case there is no further work to be done. If the source
-	 * is a directory then it cannot have been rmdir'ed; its link
-	 * count of three would cause a rmdir to fail with ENOTEMPTY.
-	 * The IN_RENAME flag ensures that it cannot be moved by another
-	 * rename.
-	 */
-	if (xp != ip) {
-		if (doingdirectory)
-			panic("ext2_rename: lost dir entry");
-		/* ip->i_flag only sets IN_RENAME if doingdirectory */
-	} else {
-		/*
-		 * If the source is a directory with a
-		 * new parent, the link count of the old
-		 * parent directory must be decremented
-		 * and ".." set to point to the new parent.
-		 */
-		if (doingdirectory && newparent) {
-			dp->i_nlink--;
-			dp->i_flag |= IN_CHANGE;
-			error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
-					sizeof (struct dirtemplate), (off_t)0,
-					UIO_SYSSPACE, IO_NODELOCKED,
-					tcnp->cn_cred, NULL);
-			if (error == 0) {
-				/* Like ext2 little-endian: */
-				namlen = dirbuf.dotdot_type;
-				if (namlen != 2 ||
-				    dirbuf.dotdot_name[0] != '.' ||
-				    dirbuf.dotdot_name[1] != '.') {
-					ext2_dirbad(xp, (doff_t)12,
-					    "rename: mangled dir");
-				} else {
-					dirbuf.dotdot_ino = newparent;
-					vn_rdwr(UIO_WRITE, fvp,
-						(caddr_t)&dirbuf,
-						sizeof (struct dirtemplate),
-						(off_t)0, UIO_SYSSPACE,
-						IO_NODELOCKED|IO_SYNC,
-						tcnp->cn_cred, NULL);
-				}
-			}
-		}
-		error = ext2_dirremove(fdvp, fcnp);
-		if (!error) {
-			xp->i_nlink--;
-			xp->i_flag |= IN_CHANGE;
-		}
-		xp->i_flag &= ~IN_RENAME;
-	}
-	vput(fdvp);
-	vput(fvp);
-	vrele(ap->a_fvp);
-	return (error);
-
-bad:
-	if (xp)
-		vput(ITOV(xp));
-	if (dp)
-		vput(ITOV(dp));
-out:
-	if (doingdirectory)
-		ip->i_flag &= ~IN_RENAME;
-	if (vn_lock(fvp, LK_EXCLUSIVE) == 0) {
-		ip->i_nlink--;
-		ip->i_flag |= IN_CHANGE;
-		ip->i_flag &= ~IN_RENAME;
-		vput(fvp);
-	} else {
-		vrele(fvp);
-	}
-	return (error);
-}
-
-/*
- * Mkdir system call
- *
- * ext2_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
- *	      struct componentname *a_cnp, struct vattr *a_vap)
- */
-static int
-ext2_mkdir(struct vop_old_mkdir_args *ap)
-{
-	struct vnode *dvp = ap->a_dvp;
-	struct vattr *vap = ap->a_vap;
-	struct componentname *cnp = ap->a_cnp;
-	struct inode *ip, *dp;
-	struct vnode *tvp;
-	struct dirtemplate dirtemplate, *dtp;
-	int error, dmode;
-
-	dp = VTOI(dvp);
-	if ((nlink_t)dp->i_nlink >= LINK_MAX) {
-		error = EMLINK;
-		goto out;
-	}
-	dmode = vap->va_mode & 0777;
-	dmode |= IFDIR;
-	/*
-	 * Must simulate part of ext2_makeinode here to acquire the inode,
-	 * but not have it entered in the parent directory. The entry is
-	 * made later after writing "." and ".." entries.
-	 */
-	error = EXT2_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
-	if (error)
-		goto out;
-	ip = VTOI(tvp);
-	ip->i_gid = dp->i_gid;
-#ifdef SUIDDIR
-	{
-#ifdef QUOTA
-		struct ucred ucred, *ucp;
-		ucp = cnp->cn_cred;
-#endif
-		/*
-		 * if we are hacking owners here, (only do this where told to)
-		 * and we are not giving it TOO root, (would subvert quotas)
-		 * then go ahead and give it to the other user.
-		 * The new directory also inherits the SUID bit. 
-		 * If user's UID and dir UID are the same,
-		 * 'give it away' so that the SUID is still forced on.
-		 */
-		if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
-		   (dp->i_mode & ISUID) && dp->i_uid) {
-			dmode |= ISUID;
-			ip->i_uid = dp->i_uid;
-#ifdef QUOTA
-			if (dp->i_uid != cnp->cn_cred->cr_uid) {
-				/*
-				 * make sure the correct user gets charged
-				 * for the space.
-				 * Make a dummy credential for the victim.
-				 * XXX This seems to never be accessed out of
-				 * our context so a stack variable is ok.
-				 */
-				ucred.cr_ref = 1;
-				ucred.cr_uid = ip->i_uid;
-				ucred.cr_ngroups = 1;
-				ucred.cr_groups[0] = dp->i_gid;
-				ucp = &ucred;
-			}
-#endif
-		} else {
-			ip->i_uid = cnp->cn_cred->cr_uid;
-		}
-#ifdef QUOTA
-		if ((error = ext2_getinoquota(ip)) ||
-	    	(error = ext2_chkiq(ip, 1, ucp, 0))) {
-			EXT2_VFREE(tvp, ip->i_number, dmode);
-			vput(tvp);
-			return (error);
-		}
-#endif
-	}
-#else
-	ip->i_uid = cnp->cn_cred->cr_uid;
-#ifdef QUOTA
-	if ((error = ext2_getinoquota(ip)) ||
-	    (error = ext2_chkiq(ip, 1, cnp->cn_cred, 0))) {
-		EXT2_VFREE(tvp, ip->i_number, dmode);
-		vput(tvp);
-		return (error);
-	}
-#endif
-#endif
-	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
-	ip->i_mode = dmode;
-	tvp->v_type = VDIR;	/* Rest init'd in getnewvnode(). */
-	ip->i_nlink = 2;
-	if (cnp->cn_flags & CNP_ISWHITEOUT)
-		ip->i_flags |= UF_OPAQUE;
-	error = EXT2_UPDATE(tvp, 1);
-
-	/*
-	 * The vnode must have a VM object in order to issue buffer cache
-	 * ops on it.
-	 */
-	vinitvmio(tvp, 0, PAGE_SIZE, -1);
-
-	/*
-	 * Bump link count in parent directory
-	 * to reflect work done below.  Should
-	 * be done before reference is created
-	 * so reparation is possible if we crash.
-	 */
-	dp->i_nlink++;
-	dp->i_flag |= IN_CHANGE;
-	error = EXT2_UPDATE(dvp, 1);
-	if (error)
-		goto bad;
-
-	/* Initialize directory with "." and ".." from static template. */
-	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
-	    EXT2_FEATURE_INCOMPAT_FILETYPE))
-		dtp = &ext2_mastertemplate;
-	else
-		dtp = &ext2_omastertemplate;
-	dirtemplate = *dtp;
-	dirtemplate.dot_ino = ip->i_number;
-	dirtemplate.dotdot_ino = dp->i_number;
-	/* note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE 
-	 * so let's just redefine it - for this function only
-	 */
-#undef  DIRBLKSIZ 
-#define DIRBLKSIZ  VTOI(dvp)->i_e2fs->s_blocksize
-	dirtemplate.dotdot_reclen = DIRBLKSIZ - 12;
-	error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
-			sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
-			IO_NODELOCKED|IO_SYNC, cnp->cn_cred, NULL);
-	if (error) {
-		dp->i_nlink--;
-		dp->i_flag |= IN_CHANGE;
-		goto bad;
-	}
-	if (DIRBLKSIZ > VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
-		panic("ext2_mkdir: blksize"); /* XXX should grow with balloc() */
-	else {
-		ip->i_size = DIRBLKSIZ;
-		ip->i_flag |= IN_CHANGE;
-	}
-
-	/* Directory set up, now install its entry in the parent directory. */
-	error = ext2_direnter(ip, dvp, cnp);
-	if (error) {
-		dp->i_nlink--;
-		dp->i_flag |= IN_CHANGE;
-	}
-bad:
-	/*
-	 * No need to do an explicit VOP_TRUNCATE here, vrele will do this
-	 * for us because we set the link count to 0.
-	 */
-	if (error) {
-		ip->i_nlink = 0;
-		ip->i_flag |= IN_CHANGE;
-		vput(tvp);
-	} else
-		*ap->a_vpp = tvp;
-out:
-	return (error);
-#undef  DIRBLKSIZ
-#define DIRBLKSIZ  DEV_BSIZE
-}
-
-/*
- * Rmdir system call.
- *
- * ext2_rmdir(struct vnode *a_dvp, struct vnode *a_vp,
- *	      struct componentname *a_cnp)
- */
-static int
-ext2_rmdir(struct vop_old_rmdir_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct vnode *dvp = ap->a_dvp;
-	struct componentname *cnp = ap->a_cnp;
-	struct inode *ip, *dp;
-	int error;
-
-	ip = VTOI(vp);
-	dp = VTOI(dvp);
-
-	/*
-	 * Verify the directory is empty (and valid).
-	 * (Rmdir ".." won't be valid since
-	 *  ".." will contain a reference to
-	 *  the current directory and thus be
-	 *  non-empty.)
-	 */
-	error = 0;
-	if (ip->i_nlink != 2 || !ext2_dirempty(ip, dp->i_number, cnp->cn_cred)) {
-		error = ENOTEMPTY;
-		goto out;
-	}
-	if ((dp->i_flags & APPEND)
-	    || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
-		error = EPERM;
-		goto out;
-	}
-	/*
-	 * Delete reference to directory before purging
-	 * inode.  If we crash in between, the directory
-	 * will be reattached to lost+found,
-	 */
-	error = ext2_dirremove(dvp, cnp);
-	if (error)
-		goto out;
-	dp->i_nlink--;
-	dp->i_flag |= IN_CHANGE;
-	vn_unlock(dvp);
-	/*
-	 * Truncate inode.  The only stuff left
-	 * in the directory is "." and "..".  The
-	 * "." reference is inconsequential since
-	 * we're quashing it.  The ".." reference
-	 * has already been adjusted above.  We've
-	 * removed the "." reference and the reference
-	 * in the parent directory, but there may be
-	 * other hard links so decrement by 2 and
-	 * worry about them later.
-	 */
-	ip->i_nlink -= 2;
-	error = EXT2_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred);
-	vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
-out:
-	return (error);
-}
-
-/*
- * symlink -- make a symbolic link
- *
- * ext2_symlink(struct vnode *a_dvp, struct vnode **a_vpp,
- *		struct componentname *a_cnp, struct vattr *a_vap,
- *		char *a_target)
- */
-static int
-ext2_symlink(struct vop_old_symlink_args *ap)
-{
-	struct vnode *vp, **vpp = ap->a_vpp;
-	struct inode *ip;
-	int len, error;
-
-	error = ext2_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
-	    vpp, ap->a_cnp);
-	if (error)
-		return (error);
-	vp = *vpp;
-	len = strlen(ap->a_target);
-	if (len < vp->v_mount->mnt_maxsymlinklen) {
-		ip = VTOI(vp);
-		bcopy(ap->a_target, (char *)ip->i_shortlink, len);
-		ip->i_size = len;
-		ip->i_flag |= IN_CHANGE | IN_UPDATE;
-	} else {
-		/*
-		 * Make sure we have a VM object in order to use
-		 * the buffer cache.
-		 */
-		if (vp->v_object == NULL)
-			vinitvmio(vp, 0, PAGE_SIZE, -1);
-
-		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
-				UIO_SYSSPACE, IO_NODELOCKED, 
-				ap->a_cnp->cn_cred, NULL);
-
-		if (error)
-			vput(vp);
-	}
-
-	return (error);
-}
-
-/*
- * Allocate a new inode.
- */
-static int
-ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
-	       struct componentname *cnp)
-{
-	struct inode *ip, *pdir;
-	struct vnode *tvp;
-	int error;
-
-	pdir = VTOI(dvp);
-	*vpp = NULL;
-	if ((mode & IFMT) == 0)
-		mode |= IFREG;
-
-	error = EXT2_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
-	if (error) {
-		return (error);
-	}
-	ip = VTOI(tvp);
-	ip->i_gid = pdir->i_gid;
-#ifdef SUIDDIR
-	{
-#ifdef QUOTA
-		struct ucred ucred, *ucp;
-		ucp = cnp->cn_cred;
-#endif
-		/*
-		 * if we are
-		 * not the owner of the directory,
-		 * and we are hacking owners here, (only do this where told to)
-		 * and we are not giving it TOO root, (would subvert quotas)
-		 * then go ahead and give it to the other user.
-		 * Note that this drops off the execute bits for security.
-		 */
-		if ( (dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
-		     (pdir->i_mode & ISUID) &&
-		     (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
-			ip->i_uid = pdir->i_uid;
-			mode &= ~07111;
-#ifdef QUOTA
-			/*
-			 * make sure the correct user gets charged
-			 * for the space.
-			 * Quickly knock up a dummy credential for the victim.
-			 * XXX This seems to never be accessed out of our
-			 * context so a stack variable is ok.
-			 */
-			ucred.cr_ref = 1;
-			ucred.cr_uid = ip->i_uid;
-			ucred.cr_ngroups = 1;
-			ucred.cr_groups[0] = pdir->i_gid;
-			ucp = &ucred;
-#endif
-		} else {
-			ip->i_uid = cnp->cn_cred->cr_uid;
-		}
-	
-#ifdef QUOTA
-		if ((error = ext2_getinoquota(ip)) ||
-	    	(error = ext2_chkiq(ip, 1, ucp, 0))) {
-			EXT2_VFREE(tvp, ip->i_number, mode);
-			vput(tvp);
-			return (error);
-		}
-#endif
-	}
-#else
-	ip->i_uid = cnp->cn_cred->cr_uid;
-#ifdef QUOTA
-	if ((error = ext2_getinoquota(ip)) ||
-	    (error = ext2_chkiq(ip, 1, cnp->cn_cred, 0))) {
-		EXT2_VFREE(tvp, ip->i_number, mode);
-		vput(tvp);
-		return (error);
-	}
-#endif
-#endif
-	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
-	ip->i_mode = mode;
-	tvp->v_type = IFTOVT(mode);	/* Rest init'd in getnewvnode(). */
-	ip->i_nlink = 1;
-	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
-	    priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, 0))
-		ip->i_mode &= ~ISGID;
-
-	if (cnp->cn_flags & CNP_ISWHITEOUT)
-		ip->i_flags |= UF_OPAQUE;
-
-	/*
-	 * Regular files and directories need VM objects.  Softlinks do 
-	 * not (not immediately anyway).
-	 */
-	if (tvp->v_type == VREG || tvp->v_type == VDIR)
-		vinitvmio(tvp, 0, PAGE_SIZE, -1);
-
-	/*
-	 * Make sure inode goes to disk before directory entry.
-	 */
-	error = EXT2_UPDATE(tvp, 1);
-	if (error)
-		goto bad;
-	error = ext2_direnter(ip, dvp, cnp);
-	if (error)
-		goto bad;
-
-	*vpp = tvp;
-	return (0);
-
-bad:
-	/*
-	 * Write error occurred trying to update the inode
-	 * or the directory so must deallocate the inode.
-	 */
-	ip->i_nlink = 0;
-	ip->i_flag |= IN_CHANGE;
-	vput(tvp);
-	return (error);
-}
-
-void
-ext2_itimes(struct vnode *vp)
-{
-	struct inode *ip;
-	struct timespec ts;
-
-	ip = VTOI(vp);
-	if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
-		return;
-	if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
-		ip->i_flag |= IN_LAZYMOD;
-	else
-		ip->i_flag |= IN_MODIFIED;
-	if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
-		vfs_timestamp(&ts);
-		if (ip->i_flag & IN_ACCESS) {
-			ip->i_atime = ts.tv_sec;
-			ip->i_atimensec = ts.tv_nsec;
-		}
-		if (ip->i_flag & IN_UPDATE) {
-			ip->i_mtime = ts.tv_sec;
-			ip->i_mtimensec = ts.tv_nsec;
-			ip->i_modrev++;
-		}
-		if (ip->i_flag & IN_CHANGE) {
-			ip->i_ctime = ts.tv_sec;
-			ip->i_ctimensec = ts.tv_nsec;
-		}
-	}
-	ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
-}
-
-/*
- * Open called.
- *
- * Nothing to do.
- *
- * ext2_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
- *	     struct file *a_fp)
- */
-/* ARGSUSED */
-static
-int
-ext2_open(struct vop_open_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-
-	/*
-	 * Files marked append-only must be opened for appending.
-	 */
-	if ((VTOI(vp)->i_flags & APPEND) &&
-	    (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) {
-		return (EPERM);
-	}
-	return (vop_stdopen(ap));
-}
-
-/*
- * Close called.
- *
- * Update the times on the inode.
- *
- * ext2_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
- */
-/* ARGSUSED */
-static
-int
-ext2_close(struct vop_close_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-
-	if (vp->v_sysref.refcnt > 1)
-		ext2_itimes(vp);
-	return (vop_stdclose(ap));
-}
-
-/*
- * ext2_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
- */
-static
-int
-ext2_access(struct vop_access_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	int error;
-
-#ifdef QUOTA
-	if (ap->a_mode & VWRITE) {
-		switch (vp->v_type) {
-		case VDIR:
-		case VLNK:
-		case VREG:
-			if ((error = ext2_getinoquota(ip)) != 0)
-				return (error);
-			break;
-		default:
-			break;
-		}
-	}
-#endif
-
-	error = vop_helper_access(ap, ip->i_uid, ip->i_gid, ip->i_mode,
-				  ip->i_flags);
-	return (error);
-}
-
-/*
- * ext2_getattr(struct vnode *a_vp, struct vattr *a_vap)
- */
-/* ARGSUSED */
-static
-int
-ext2_getattr(struct vop_getattr_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	struct vattr *vap = ap->a_vap;
-
-	ext2_itimes(vp);
-	/*
-	 * Copy from inode table
-	 */
-	vap->va_fsid = dev2udev(ip->i_dev);
-	vap->va_fileid = ip->i_number;
-	vap->va_mode = ip->i_mode & ~IFMT;
-	vap->va_nlink = VFSTOEXT2(vp->v_mount)->um_i_effnlink_valid ?
-	    ip->i_effnlink : ip->i_nlink;
-	vap->va_uid = ip->i_uid;
-	vap->va_gid = ip->i_gid;
-	vap->va_rmajor = umajor(ip->i_rdev);
-	vap->va_rminor = uminor(ip->i_rdev);
-	vap->va_size = ip->i_din.di_size;
-	vap->va_atime.tv_sec = ip->i_atime;
-	vap->va_atime.tv_nsec = ip->i_atimensec;
-	vap->va_mtime.tv_sec = ip->i_mtime;
-	vap->va_mtime.tv_nsec = ip->i_mtimensec;
-	vap->va_ctime.tv_sec = ip->i_ctime;
-	vap->va_ctime.tv_nsec = ip->i_ctimensec;
-	vap->va_flags = ip->i_flags;
-	vap->va_gen = ip->i_gen;
-	vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
-	vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
-	vap->va_type = IFTOVT(ip->i_mode);
-	vap->va_filerev = ip->i_modrev;
-	return (0);
-}
-
-/*
- * Set attribute vnode op. called from several syscalls
- *
- * ext2_setattr(struct vnode *a_vp, struct vattr *a_vap, struct ucred *a_cred)
- */
-static
-int
-ext2_setattr(struct vop_setattr_args *ap)
-{
-	struct vattr *vap = ap->a_vap;
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	struct ucred *cred = ap->a_cred;
-	int error;
-
-	/*
-	 * Check for unsettable attributes.
-	 */
-	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
-	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
-	    (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
-	    ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
-		return (EINVAL);
-	}
-	if (vap->va_flags != VNOVAL) {
-		if (vp->v_mount->mnt_flag & MNT_RDONLY)
-			return (EROFS);
-		if (cred->cr_uid != ip->i_uid &&
-		    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)))
-			return (error);
-		/*
-		 * Note that a root chflags becomes a user chflags when
-		 * we are jailed, unless the jail.chflags_allowed sysctl
-		 * is set.
-		 */
-		if (cred->cr_uid == 0 && 
-		    (!jailed(cred) || jail_chflags_allowed)) {
-			if ((ip->i_flags
-			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
-			    securelevel > 0)
-				return (EPERM);
-			ip->i_flags = vap->va_flags;
-		} else {
-			if (ip->i_flags
-			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
-			    (vap->va_flags & UF_SETTABLE) != vap->va_flags)
-				return (EPERM);
-			ip->i_flags &= SF_SETTABLE;
-			ip->i_flags |= (vap->va_flags & UF_SETTABLE);
-		}
-		ip->i_flag |= IN_CHANGE;
-		if (vap->va_flags & (IMMUTABLE | APPEND))
-			return (0);
-	}
-	if (ip->i_flags & (IMMUTABLE | APPEND))
-		return (EPERM);
-	/*
-	 * Go through the fields and update iff not VNOVAL.
-	 */
-	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
-		if (vp->v_mount->mnt_flag & MNT_RDONLY)
-			return (EROFS);
-		if ((error = ext2_chown(vp, vap->va_uid, vap->va_gid, cred)) != 0)
-			return (error);
-	}
-	if (vap->va_size != VNOVAL) {
-		/*
-		 * Disallow write attempts on read-only filesystems;
-		 * unless the file is a socket, fifo, or a block or
-		 * character device resident on the filesystem.
-		 */
-		switch (vp->v_type) {
-		case VDIR:
-			return (EISDIR);
-		case VLNK:
-		case VREG:
-			if (vp->v_mount->mnt_flag & MNT_RDONLY)
-				return (EROFS);
-			break;
-		default:
-			break;
-		}
-		if ((error = EXT2_TRUNCATE(vp, vap->va_size, 0, cred)) != 0)
-			return (error);
-	}
-	ip = VTOI(vp);
-	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
-		if (vp->v_mount->mnt_flag & MNT_RDONLY)
-			return (EROFS);
-		if (cred->cr_uid != ip->i_uid &&
-		    (error = priv_check_cred(cred, PRIV_VFS_SETATTR, 0)) &&
-		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-		    (error = VOP_EACCESS(vp, VWRITE, cred))))
-			return (error);
-		if (vap->va_atime.tv_sec != VNOVAL)
-			ip->i_flag |= IN_ACCESS;
-		if (vap->va_mtime.tv_sec != VNOVAL)
-			ip->i_flag |= IN_CHANGE | IN_UPDATE;
-		ext2_itimes(vp);
-		if (vap->va_atime.tv_sec != VNOVAL) {
-			ip->i_atime = vap->va_atime.tv_sec;
-			ip->i_atimensec = vap->va_atime.tv_nsec;
-		}
-		if (vap->va_mtime.tv_sec != VNOVAL) {
-			ip->i_mtime = vap->va_mtime.tv_sec;
-			ip->i_mtimensec = vap->va_mtime.tv_nsec;
-		}
-		error = EXT2_UPDATE(vp, 0);
-		if (error)
-			return (error);
-	}
-	error = 0;
-	if (vap->va_mode != (mode_t)VNOVAL) {
-		if (vp->v_mount->mnt_flag & MNT_RDONLY)
-			return (EROFS);
-		error = ext2_chmod(vp, (int)vap->va_mode, cred);
-	}
-	VN_KNOTE(vp, NOTE_ATTRIB);
-	return (error);
-}
-
-/*
- * Change the mode on a file.
- * Inode must be locked before calling.
- */
-static int
-ext2_chmod(struct vnode *vp, int mode, struct ucred *cred)
-{
-	struct inode *ip = VTOI(vp);
-	int error;
-
-	if (cred->cr_uid != ip->i_uid) {
-	    error = priv_check_cred(cred, PRIV_VFS_CHMOD, 0);
-	    if (error)
-		return (error);
-	}
-	if (cred->cr_uid) {
-		if (vp->v_type != VDIR && (mode & S_ISTXT))
-			return (EFTYPE);
-		if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
-			return (EPERM);
-	}
-	ip->i_mode &= ~ALLPERMS;
-	ip->i_mode |= (mode & ALLPERMS);
-	ip->i_flag |= IN_CHANGE;
-	return (0);
-}
-
-/*
- * Perform chown operation on inode ip;
- * inode must be locked prior to call.
- */
-static int
-ext2_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred)
-{
-	struct inode *ip = VTOI(vp);
-	uid_t ouid;
-	gid_t ogid;
-	int error = 0;
-#ifdef QUOTA
-	int i;
-	long change;
-#endif
-
-	if (uid == (uid_t)VNOVAL)
-		uid = ip->i_uid;
-	if (gid == (gid_t)VNOVAL)
-		gid = ip->i_gid;
-	/*
-	 * If we don't own the file, are trying to change the owner
-	 * of the file, or are not a member of the target group,
-	 * the caller must be superuser or the call fails.
-	 */
-	if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
-	    (gid != ip->i_gid && !(cred->cr_gid == gid ||
-	    groupmember((gid_t)gid, cred)))) &&
-	    (error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0)))
-		return (error);
-	ogid = ip->i_gid;
-	ouid = ip->i_uid;
-#ifdef QUOTA
-	if ((error = ext2_getinoquota(ip)) != 0)
-		return (error);
-	if (ouid == uid) {
-		ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
-		ip->i_dquot[USRQUOTA] = NODQUOT;
-	}
-	if (ogid == gid) {
-		ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
-		ip->i_dquot[GRPQUOTA] = NODQUOT;
-	}
-	change = ip->i_blocks;
-	(void) ext2_chkdq(ip, -change, cred, CHOWN);
-	(void) ext2_chkiq(ip, -1, cred, CHOWN);
-	for (i = 0; i < MAXQUOTAS; i++) {
-		ext2_dqrele(vp, ip->i_dquot[i]);
-		ip->i_dquot[i] = NODQUOT;
-	}
-#endif
-	ip->i_gid = gid;
-	ip->i_uid = uid;
-#ifdef QUOTA
-	if ((error = ext2_getinoquota(ip)) == 0) {
-		if (ouid == uid) {
-			ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
-			ip->i_dquot[USRQUOTA] = NODQUOT;
-		}
-		if (ogid == gid) {
-			ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
-			ip->i_dquot[GRPQUOTA] = NODQUOT;
-		}
-		if ((error = ext2_chkdq(ip, change, cred, CHOWN)) == 0) {
-			if ((error = ext2_chkiq(ip, 1, cred, CHOWN)) == 0)
-				goto good;
-			else
-				(void)ext2_chkdq(ip, -change, cred, CHOWN|FORCE);
-		}
-		for (i = 0; i < MAXQUOTAS; i++) {
-			ext2_dqrele(vp, ip->i_dquot[i]);
-			ip->i_dquot[i] = NODQUOT;
-		}
-	}
-	ip->i_gid = ogid;
-	ip->i_uid = ouid;
-	if (ext2_getinoquota(ip) == 0) {
-		if (ouid == uid) {
-			ext2_dqrele(vp, ip->i_dquot[USRQUOTA]);
-			ip->i_dquot[USRQUOTA] = NODQUOT;
-		}
-		if (ogid == gid) {
-			ext2_dqrele(vp, ip->i_dquot[GRPQUOTA]);
-			ip->i_dquot[GRPQUOTA] = NODQUOT;
-		}
-		(void) ext2_chkdq(ip, change, cred, FORCE|CHOWN);
-		(void) ext2_chkiq(ip, 1, cred, FORCE|CHOWN);
-		(void) ext2_getinoquota(ip);
-	}
-	return (error);
-good:
-	if (ext2_getinoquota(ip))
-		panic("ext2_chown: lost quota");
-#endif /* QUOTA */
-	ip->i_flag |= IN_CHANGE;
-	if (cred->cr_uid != 0 && (ouid != uid || ogid != gid))
-		ip->i_mode &= ~(ISUID | ISGID);
-	return (0);
-}
-
-/*
- * Mmap a file
- *
- * NB Currently unsupported.
- *
- * ext2_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred)
- */
-/* ARGSUSED */
-static
-int
-ext2_mmap(struct vop_mmap_args *ap)
-{
-	return (EINVAL);
-}
-
-/*
- * whiteout vnode call
- *
- * ext2_whiteout(struct vnode *a_dvp, struct componentname *a_cnp, int a_flags)
- */
-static
-int
-ext2_whiteout(struct vop_old_whiteout_args *ap)
-{
-	return (EOPNOTSUPP);
-}
-
-/*
- * Return target name of a symbolic link
- *
- * ext2_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
- */
-static
-int
-ext2_readlink(struct vop_readlink_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-	int isize;
-
-	isize = ip->i_size;
-	if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
-	    (ip->i_din.di_blocks == 0)) {   /* XXX - for old fastlink support */
-		uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
-		return (0);
-	}
-	return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
-}
-
-/*
- * Calculate the logical to physical mapping if not done already,
- * then call the device strategy routine.
- *
- * In order to be able to swap to a file, the VOP_BMAP operation may not
- * deadlock on memory.  See ext2_bmap() for details.
- *
- * ext2_strategy(struct vnode *a_vp, struct bio *a_bio)
- */
-static
-int
-ext2_strategy(struct vop_strategy_args *ap)
-{
-	struct bio *bio = ap->a_bio;
-	struct bio *nbio;
-	struct buf *bp = bio->bio_buf;
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip;
-	int error;
-
-	ip = VTOI(vp);
-	if (vp->v_type == VBLK || vp->v_type == VCHR)
-		panic("ext2_strategy: spec");
-	nbio = push_bio(bio);
-	if (nbio->bio_offset == NOOFFSET) {
-		error = VOP_BMAP(vp, bio->bio_offset, &nbio->bio_offset,
-				 NULL, NULL, bp->b_cmd);
-		if (error) {
-			bp->b_error = error;
-			bp->b_flags |= B_ERROR;
-			/* I/O was never started on nbio, must biodone(bio) */
-			biodone(bio);
-			return (error);
-		}
-		if (nbio->bio_offset == NOOFFSET)
-			vfs_bio_clrbuf(bp);
-	}
-	if (nbio->bio_offset == NOOFFSET) {
-		/* I/O was never started on nbio, must biodone(bio) */
-		biodone(bio);
-		return (0);
-	}
-	vn_strategy(ip->i_devvp, nbio);
-	return (0);
-}
-
-/*
- * Print out the contents of an inode.
- *
- * ext2_print(struct vnode *a_vp)
- */
-static
-int
-ext2_print(struct vop_print_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct inode *ip = VTOI(vp);
-
-	kprintf("tag VT_EXT2FS, ino %lu, on dev %s (%d, %d)",
-	    (u_long)ip->i_number, devtoname(ip->i_dev), major(ip->i_dev),
-	    minor(ip->i_dev));
-	if (vp->v_type == VFIFO)
-		fifo_printinfo(vp);
-	lockmgr_printinfo(&vp->v_lock);
-	kprintf("\n");
-	return (0);
-}
-
-/*
- * Read wrapper for fifos.
- *
- * ext2fifo_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *		struct ucred *a_cred)
- */
-static
-int
-ext2fifo_read(struct vop_read_args *ap)
-{
-	int error, resid;
-	struct inode *ip;
-	struct uio *uio;
-
-	uio = ap->a_uio;
-	resid = uio->uio_resid;
-	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
-	ip = VTOI(ap->a_vp);
-	if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
-	    (uio->uio_resid != resid || (error == 0 && resid != 0)))
-		VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
-	return (error);
-}
-
-/*
- * Write wrapper for fifos.
- *
- * ext2fifo_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *		 struct ucred *a_cred)
- */
-static
-int
-ext2fifo_write(struct vop_write_args *ap)
-{
-	int error, resid;
-	struct inode *ip;
-	struct uio *uio;
-
-	uio = ap->a_uio;
-	resid = uio->uio_resid;
-	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
-	ip = VTOI(ap->a_vp);
-	if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
-		VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
-	return (error);
-}
-
-/*
- * Close wrapper for fifos.
- *
- * Update the times on the inode then do device close.
- *
- * ext2fifo_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
- */
-static
-int
-ext2fifo_close(struct vop_close_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-
-	if (vp->v_sysref.refcnt > 1)
-		ext2_itimes(vp);
-	return (VOCALL(&fifo_vnode_vops, &ap->a_head));
-}
-
-/*
- * Kqfilter wrapper for fifos.
- *
- * Fall through to ext2 kqfilter routines if needed 
- */
-static
-int
-ext2fifo_kqfilter(struct vop_kqfilter_args *ap)
-{
-	int error;
-
-	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
-	if (error)
-		error = ext2_kqfilter(ap);
-	return (error);
-}
-
-/*
- * Return POSIX pathconf information applicable to ext2 filesystems.
- *
- * ext2_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
- */
-static
-int
-ext2_pathconf(struct vop_pathconf_args *ap)
-{
-	switch (ap->a_name) {
-	case _PC_LINK_MAX:
-		*ap->a_retval = LINK_MAX;
-		return (0);
-	case _PC_NAME_MAX:
-		*ap->a_retval = NAME_MAX;
-		return (0);
-	case _PC_PATH_MAX:
-		*ap->a_retval = PATH_MAX;
-		return (0);
-	case _PC_PIPE_BUF:
-		*ap->a_retval = PIPE_BUF;
-		return (0);
-	case _PC_CHOWN_RESTRICTED:
-		*ap->a_retval = 1;
-		return (0);
-	case _PC_NO_TRUNC:
-		*ap->a_retval = 1;
-		return (0);
-	default:
-		return (EINVAL);
-	}
-	/* NOTREACHED */
-}
-
-/*
- * Advisory record locking support
- *
- * ext2_advlock(struct vnode *a_vp, caddr_t a_id, int a_op, struct flock *a_fl,
- *	       int a_flags)
- */
-static
-int
-ext2_advlock(struct vop_advlock_args *ap)
-{
-	struct inode *ip = VTOI(ap->a_vp);
-
-	return (lf_advlock(ap, &(ip->i_lockf), ip->i_size));
-}
-
-/*
- * Initialize the vnode associated with a new inode, handle aliased
- * vnodes.
- */
-int
-ext2_vinit(struct mount *mntp, struct vnode **vpp)
-{
-	struct inode *ip;
-	struct vnode *vp;
-	struct timeval tv;
-
-	vp = *vpp;
-	ip = VTOI(vp);
-
-	switch(vp->v_type = IFTOVT(ip->i_mode)) {
-	case VCHR:
-	case VBLK:
-		vp->v_ops = &mntp->mnt_vn_spec_ops;
-		addaliasu(vp, umajor(ip->i_rdev), uminor(ip->i_rdev));
-		break;
-	case VFIFO:
-		vp->v_ops = &mntp->mnt_vn_fifo_ops;
-		break;
-	case VDIR:
-	case VREG:
-		vinitvmio(vp, ip->i_size, PAGE_SIZE, -1); /* XXX */
-		break;
-	case VLNK:
-		if ((ip->i_size >= vp->v_mount->mnt_maxsymlinklen) &&
-		    ip->i_din.di_blocks != 0
-		) {
-			vinitvmio(vp, ip->i_size, PAGE_SIZE, -1);
-		}
-		break;
-	default:
-		break;
-
-	}
-
-	if (ip->i_number == ROOTINO)
-		vp->v_flag |= VROOT;
-	/*
-	 * Initialize modrev times
-	 */
-	getmicrouptime(&tv);
-	SETHIGH(ip->i_modrev, tv.tv_sec);
-	SETLOW(ip->i_modrev, tv.tv_usec * 4294);
-	*vpp = vp;
-	return (0);
-}
-
-static struct filterops ext2read_filtops = 
-	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2read };
-static struct filterops ext2write_filtops = 
-	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2write };
-static struct filterops ext2vnode_filtops = 
-	{ FILTEROP_ISFD, NULL, filt_ext2detach, filt_ext2vnode };
-
-/*
- * ext2_kqfilter(struct vnode *a_vp, struct knote *a_kn)
- */
-static int
-ext2_kqfilter(struct vop_kqfilter_args *ap)
-{
-	struct vnode *vp = ap->a_vp;
-	struct knote *kn = ap->a_kn;
-
-	switch (kn->kn_filter) {
-	case EVFILT_READ:
-		kn->kn_fop = &ext2read_filtops;
-		break;
-	case EVFILT_WRITE:
-		kn->kn_fop = &ext2write_filtops;
-		break;
-	case EVFILT_VNODE:
-		kn->kn_fop = &ext2vnode_filtops;
-		break;
-	default:
-		return (EOPNOTSUPP);
-	}
-
-	kn->kn_hook = (caddr_t)vp;
-
-	/* XXX: kq token actually protects the list */
-	lwkt_gettoken(&vp->v_token);
-	knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
-	lwkt_reltoken(&vp->v_token);
-
-	return (0);
-}
-
-static void
-filt_ext2detach(struct knote *kn)
-{
-	struct vnode *vp = (struct vnode *)kn->kn_hook;
-
-	lwkt_gettoken(&vp->v_token);
-	knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
-	lwkt_reltoken(&vp->v_token);
-}
-
-/*ARGSUSED*/
-static int
-filt_ext2read(struct knote *kn, long hint)
-{
-	struct vnode *vp = (struct vnode *)kn->kn_hook;
-	struct inode *ip = VTOI(vp);
-	off_t off;
-
-	/*
-	 * filesystem is gone, so set the EOF flag and schedule 
-	 * the knote for deletion.
-	 */
-	if (hint == NOTE_REVOKE) {
-		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
-		return (1);
-	}
-        off = ip->i_size - kn->kn_fp->f_offset;
-	kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX;
-	if (kn->kn_sfflags & NOTE_OLDAPI)
-		return(1);
-        return (kn->kn_data != 0);
-}
-
-/*ARGSUSED*/
-static int
-filt_ext2write(struct knote *kn, long hint)
-{
-	/*
-	 * filesystem is gone, so set the EOF flag and schedule 
-	 * the knote for deletion.
-	 */
-	if (hint == NOTE_REVOKE)
-		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
-
-        kn->kn_data = 0;
-        return (1);
-}
-
-static int
-filt_ext2vnode(struct knote *kn, long hint)
-{
-	if (kn->kn_sfflags & hint)
-		kn->kn_fflags |= hint;
-	if (hint == NOTE_REVOKE) {
-		kn->kn_flags |= (EV_EOF | EV_NODATA);
-		return (1);
-	}
-	return (kn->kn_fflags != 0);
-}
-
-struct vop_ops ext2_vnode_vops = {
-	.vop_default =		vop_defaultop,
-	.vop_fsync =		ext2_fsync,
-	.vop_read =		ext2_read,
-	.vop_reallocblks =	ext2_reallocblks,
-	.vop_write =		ext2_write,
-	.vop_access =		ext2_access,
-	.vop_advlock =		ext2_advlock,
-	.vop_bmap =		ext2_bmap,
-	.vop_old_lookup =	ext2_lookup,
-	.vop_close =		ext2_close,
-	.vop_old_create =	ext2_create,
-	.vop_getattr =		ext2_getattr,
-	.vop_inactive =		ext2_inactive,
-	.vop_old_link =		ext2_link,
-	.vop_old_mkdir =	ext2_mkdir,
-	.vop_old_mknod =	ext2_mknod,
-	.vop_mmap =		ext2_mmap,
-	.vop_open =		ext2_open,
-	.vop_pathconf =		ext2_pathconf,
-	.vop_kqfilter =		ext2_kqfilter,
-	.vop_print =		ext2_print,
-	.vop_readdir =		ext2_readdir,
-	.vop_readlink =		ext2_readlink,
-	.vop_reclaim =		ext2_reclaim,
-	.vop_old_remove =	ext2_remove,
-	.vop_old_rename =	ext2_rename,
-	.vop_old_rmdir =	ext2_rmdir,
-	.vop_setattr =		ext2_setattr,
-	.vop_strategy =		ext2_strategy,
-	.vop_old_symlink =	ext2_symlink,
-	.vop_old_whiteout =	ext2_whiteout,
-	.vop_getpages =		vop_stdgetpages,
-	.vop_putpages =		vop_stdputpages
-};
-
-struct vop_ops ext2_spec_vops = {
-	.vop_default =		vop_defaultop,
-	.vop_fsync =		ext2_fsync,
-	.vop_access =		ext2_access,
-	.vop_close =		ext2_close,
-	.vop_getattr =		ext2_getattr,
-	.vop_inactive =		ext2_inactive,
-	.vop_print =		ext2_print,
-	.vop_read =		vop_stdnoread,
-	.vop_reclaim =		ext2_reclaim,
-	.vop_setattr =		ext2_setattr,
-	.vop_write =		vop_stdnowrite
-};
-
-struct vop_ops ext2_fifo_vops = {
-	.vop_default =		ext2_vnoperatefifo,
-	.vop_fsync =		ext2_fsync,
-	.vop_access =		ext2_access,
-	.vop_close =		ext2fifo_close,
-	.vop_getattr =		ext2_getattr,
-	.vop_inactive =		ext2_inactive,
-	.vop_kqfilter =		ext2fifo_kqfilter,
-	.vop_print =		ext2_print,
-	.vop_read =		ext2fifo_read,
-	.vop_reclaim =		ext2_reclaim,
-	.vop_setattr =		ext2_setattr,
-	.vop_write =		ext2fifo_write
-};
-
-VNODEOP_SET(ext2_vnode_vops);
-VNODEOP_SET(ext2_spec_vops);
-VNODEOP_SET(ext2_fifo_vops);
-
-/*
- * ext2_vnoperate()
- */
-int
-ext2_vnoperate(struct vop_generic_args *ap)
-{
-	return (VOCALL(&ext2_vnode_vops, ap));
-}
-
-/*
- * ext2_vnoperatefifo()
- */
-int
-ext2_vnoperatefifo(struct vop_generic_args *ap)
-{
-	return (VOCALL(&ext2_fifo_vops, ap));
-}
-
diff --git a/sys/vfs/gnu/ext2fs/ext2mount.h b/sys/vfs/gnu/ext2fs/ext2mount.h
deleted file mode 100644
index 0c3a198..0000000
--- a/sys/vfs/gnu/ext2fs/ext2mount.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)ufsmount.h	8.6 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/ufs/ufs/ufsmount.h,v 1.17 1999/12/29 04:55:06 peter Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2mount.h,v 1.4 2006/09/10 01:26:40 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_EXT2MOUNT_H_
-#define _VFS_GNU_EXT2FS_EXT2MOUNT_H_
-
-/*
- * Arguments to mount UFS-based filesystems
- */
-struct ext2_args {
-	char	*fspec;			/* block special device to mount */
-	struct	export_args export;	/* network export information */
-};
-
-/*
- * Arguments to mount MFS
- */
-struct mfs_args {
-	char	*fspec;			/* name to export for statfs */
-	struct	export_args export;	/* if exported MFSes are supported */
-	caddr_t	base;			/* base of filesystem in memory */
-	u_long	size;			/* size of filesystem */
-};
-
-#ifdef _KERNEL
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_EXT2MNT);
-#endif
-
-struct buf;
-struct inode;
-struct timeval;
-struct ucred;
-struct uio;
-struct vnode;
-struct netexport;
-
-/* This structure describes the UFS specific mount structure data. */
-struct ext2mount {
-	struct	mount *um_mountp;		/* filesystem vfs structure */
-	cdev_t	um_dev;				/* device mounted */
-	struct	vnode *um_devvp;		/* block device mounted vnode */
-
-	struct	ext2_sb_info *um_e2fs;
-	struct	vnode *um_quotas[MAXQUOTAS];	/* pointer to quota files */
-	struct	ucred *um_cred[MAXQUOTAS];	/* quota file access cred */
-	u_long	um_nindir;			/* indirect ptrs per block */
-	u_long	um_bptrtodb;			/* indir ptr to disk block */
-	u_long	um_seqinc;			/* inc between seq blocks */
-	time_t	um_btime[MAXQUOTAS];		/* block quota time limit */
-	time_t	um_itime[MAXQUOTAS];		/* inode quota time limit */
-	char	um_qflags[MAXQUOTAS];		/* quota specific flags */
-	struct	netexport um_export;		/* export information */
-	int64_t	um_savedmaxfilesize;		/* XXX - limit maxfilesize */
-	struct malloc_type *um_malloctype;	/* The inodes malloctype */
-	int	um_i_effnlink_valid;		/* i_effnlink valid? */
-	int	(*um_blkatoff) (struct vnode *, off_t, char **, struct buf **);
-	int	(*um_truncate) (struct vnode *, off_t, int, struct ucred *);
-	int	(*um_update) (struct vnode *, int);
-	int	(*um_valloc) (struct vnode *, int, struct ucred *, struct vnode **);
-	int	(*um_vfree) (struct vnode *, ino_t, int);
-};
-
-#define	um_e2fsb um_e2fs->s_es
-
-#define EXT2_BLKATOFF(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_blkatoff(aa, bb, cc, dd)
-#define EXT2_TRUNCATE(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_truncate(aa, bb, cc, dd)
-#define EXT2_UPDATE(aa, bb) VFSTOEXT2((aa)->v_mount)->um_update(aa, bb)
-#define EXT2_VALLOC(aa, bb, cc, dd) VFSTOEXT2((aa)->v_mount)->um_valloc(aa, bb, cc, dd)
-#define EXT2_VFREE(aa, bb, cc) VFSTOEXT2((aa)->v_mount)->um_vfree(aa, bb, cc)
-
-/*
- * Flags describing the state of quotas.
- */
-#define	QTF_OPENING	0x01			/* Q_QUOTAON in progress */
-#define	QTF_CLOSING	0x02			/* Q_QUOTAOFF in progress */
-
-/* Convert mount ptr to ext2mount ptr. */
-#define VFSTOEXT2(mp)	((struct ext2mount *)((mp)->mnt_data))
-
-/*
- * Macros to access filesystem parameters in the ext2mount structure.
- * Used by ext2_bmap.
- */
-#define MNINDIR(ump)			((ump)->um_nindir)
-#define	blkptrtodb(ump, b)		((b) << (ump)->um_bptrtodb)
-#define	is_sequential(ump, a, b)	((b) == (a) + ump->um_seqinc)
-#endif /* _KERNEL */
-
-#endif /* !_VFS_GNU_EXT2FS_EXT2MOUNT_H_ */
diff --git a/sys/vfs/gnu/ext2fs/fs.h b/sys/vfs/gnu/ext2fs/fs.h
deleted file mode 100644
index 74b9ec2..0000000
--- a/sys/vfs/gnu/ext2fs/fs.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  modified for EXT2FS support in Lites 1.1
- *
- *  Aug 1995, Godmar Back (gback@cs.utah.edu)
- *  University of Utah, Department of Computer Science
- */
-/*
- * Copyright (c) 1982, 1986, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)fs.h	8.7 (Berkeley) 4/19/94
- * $FreeBSD: src/sys/gnu/ext2fs/fs.h,v 1.5.2.1 2000/11/11 13:12:45 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/fs.h,v 1.11 2006/08/12 00:26:20 dillon Exp $
- */
-
-/*
- * Each disk drive contains some number of file systems.
- * A file system consists of a number of cylinder groups.
- * Each cylinder group has inodes and data.
- *
- * A file system is described by its super-block, which in turn
- * describes the cylinder groups.  The super-block is critical
- * data and is replicated in each cylinder group to protect against
- * catastrophic loss.  This is done at `newfs' time and the critical
- * super-block data does not change, so the copies need not be
- * referenced further unless disaster strikes.
- *
- * The first boot and super blocks are given in absolute disk addresses.
- * The byte-offset forms are preferred, as they don't imply a sector size.
- */
-#define BBSIZE		1024
-#define SBSIZE		1024
-#define	BBOFF		((off_t)(0))
-#define	SBOFF		((off_t)(BBOFF + BBSIZE))
-#define	BBLOCK		((daddr_t)(0))
-#define	SBLOCK		((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
-
-/*
- * The path name on which the file system is mounted is maintained
- * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in 
- * the super block for this name.
- */
-#define MAXMNTLEN 512
-
-/*
- * Macros for access to superblock array structures
- */
-
-/*
- * Convert cylinder group to base address of its global summary info.
- */
-#define fs_cs(fs, cgindx)      (((struct ext2_group_desc *) \
-        (fs->s_group_desc[cgindx / EXT2_DESC_PER_BLOCK(fs)]->b_data)) \
-		[cgindx % EXT2_DESC_PER_BLOCK(fs)])
-
-/*
- * Turn file system block numbers into disk block addresses.
- * This maps file system blocks to device size blocks.
- */
-#define fsbtodb(fs, b)	((b) << ((fs)->s_fsbtodb))
-#define	dbtofsb(fs, b)	((b) >> ((fs)->s_fsbtodb))
-
-/* get group containing inode */
-#define ino_to_cg(fs, x)	(((x) - 1) / EXT2_INODES_PER_GROUP(fs))
-
-/* get block containing inode from its number x */
-#define	ino_to_fsba(fs, x)	(fs_cs(fs, ino_to_cg(fs, x)).bg_inode_table + \
-	(((x)-1) % EXT2_INODES_PER_GROUP(fs))/EXT2_INODES_PER_BLOCK(fs))
-
-/* get offset for inode in block */
-#define	ino_to_fsbo(fs, x)	((x-1) % EXT2_INODES_PER_BLOCK(fs))
-
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-#define	dtog(fs, d)	(((d) - fs->s_es->s_first_data_block) / \
-			EXT2_BLOCKS_PER_GROUP(fs))
-#define	dtogd(fs, d)	(((d) - fs->s_es->s_first_data_block) % \
-			EXT2_BLOCKS_PER_GROUP(fs))
-
-/*
- * The following macros optimize certain frequently calculated
- * quantities by using shifts and masks in place of divisions
- * modulos and multiplications.
- */
-#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
-	((loc) & (fs)->s_qbmask)
-
-#define lblktosize(fs, blk)	/* calculates (blk * fs->fs_bsize) */ \
-	((blk) << (fs->s_bshift))
-
-/*
- * Used when converting logical blocks to offsets for getblk, bread,
- * etc.
- */
-#define lblktodoff(fs, blk)	/* calculates (blk * fs->fs_bsize) */ \
-	((off_t)(blk) << (fs)->s_bshift)
-#define fsbtodoff(fs, blk)	/* calculates (blk * fs->fs_fsize) */ \
-	((off_t)(blk) * (fs)->s_frag_size)
-#define dofftofsb(fs, blk)	/* calculates blk / fs->fs_fsize */   \
-	((daddr_t)((blk) / (fs)->s_frag_size))
-#define dbtodoff(fs, b)		/* calculates diskblk * sectorsize */ \
-	((off_t)(b) * ((fs)->s_frag_size >> (fs)->s_fsbtodb))
-
-#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
-	((loc) >> (fs->s_bshift))
-
-/* no fragments -> logical block number equal # of frags */
-#define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
-	((loc) >> (fs->s_bshift))
-
-#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
-	roundup(size, fs->s_frag_size)
-	/* was (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) */
-
-/*
- * Determining the size of a file block in the file system.
- * easy w/o fragments
- */
-#define blksize(fs, ip, lbn) ((fs)->s_frag_size)
-
-/*
- * INOPB is the number of inodes in a secondary storage block.
- */
-#define	INOPB(fs)	EXT2_INODES_PER_BLOCK(fs)
-
-/*
- * NINDIR is the number of indirects in a file system block.
- */
-#define	NINDIR(fs)	(EXT2_ADDR_PER_BLOCK(fs))
-
-extern int inside[], around[];
-extern u_char *fragtbl[];
-
-/* a few remarks about superblock locking/unlocking
- * Linux provides special routines for doing so
- * I haven't figured out yet what BSD does
- * I think I'll try a vn_lock/vn_unlock on the device vnode
- */
-#define  DEVVP(inode)		(VFSTOEXT2(ITOV(inode)->v_mount)->um_devvp)
-#define  lock_super(devvp)   	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY)
-#define  unlock_super(devvp) 	vn_unlock(devvp)
-
-/*
- * To lock a buffer, set the B_LOCKED flag and then brelse() it. To unlock,
- * reset the B_LOCKED flag and brelse() the buffer back on the LRU list
- */
-#define LCK_BUF(bp) { \
-	crit_enter(); \
-	(bp)->b_flags |= B_LOCKED; \
-	crit_exit(); \
-	brelse(bp); \
-}
-
-#define ULCK_BUF(bp) { \
-	long flags; \
-	crit_enter(); \
-	flags = (bp)->b_flags; \
-	(bp)->b_flags &= ~(B_DIRTY | B_LOCKED); \
-	BUF_LOCK(bp, LK_EXCLUSIVE); \
-	bremfree(bp); \
-	crit_exit(); \
-	if (flags & B_DIRTY) \
-		bwrite(bp); \
-	else \
-		brelse(bp); \
-}
diff --git a/sys/vfs/gnu/ext2fs/i386-bitops.h b/sys/vfs/gnu/ext2fs/i386-bitops.h
deleted file mode 100644
index 1bdea89..0000000
--- a/sys/vfs/gnu/ext2fs/i386-bitops.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * $FreeBSD: src/sys/gnu/ext2fs/i386-bitops.h,v 1.5 1999/11/15 23:16:06 obrien Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/i386-bitops.h,v 1.4 2006/04/04 17:34:32 dillon Exp $
- */
-/*
- * this is mixture of i386/bitops.h and asm/string.h
- * taken from the Linux source tree 
- *
- * XXX replace with Mach routines or reprogram in C
- */
-#ifndef _VFS_GNU_EXT2FS_I386_BITOPS_H_
-#define	_VFS_GNU_EXT2FS_I386_BITOPS_H_
-
-/*
- * Copyright 1992, Linus Torvalds.
- */
-
-/*
- * These have to be done with inline assembly: that way the bit-setting
- * is guaranteed to be atomic. All bit operations return 0 if the bit
- * was cleared before the operation and != 0 if it was not.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-
-/*
- * Some hacks to defeat gcc over-optimizations..
- */
-struct __dummy { unsigned long a[100]; };
-#define ADDR (*(struct __dummy *) addr)
-
-static __inline__ int
-set_bit(int nr, void *addr)
-{
-	int oldbit;
-
-	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
-	return oldbit;
-}
-
-static __inline__ int
-clear_bit(int nr, void *addr)
-{
-	int oldbit;
-
-	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
-	return oldbit;
-}
-
-static __inline__ int
-change_bit(int nr, void *addr)
-{
-	int oldbit;
-
-	__asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
-	return oldbit;
-}
-
-/*
- * This routine doesn't need to be atomic, but it's faster to code it
- * this way.
- */
-static __inline__ int
-test_bit(int nr, void *addr)
-{
-	int oldbit;
-
-	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit)
-		:"m" (ADDR),"ir" (nr));
-	return oldbit;
-}
-
-/*
- * Find-bit routines..
- */
-static __inline__ int
-find_first_zero_bit(void *addr, unsigned size)
-{
-	int res;
-	int _count = (size + 31) >> 5;
-
-	if (!size)
-		return 0;
-	__asm__("			\n\
-		cld			\n\
-		movl $-1,%%eax		\n\
-		xorl %%edx,%%edx	\n\
-		repe; scasl		\n\
-		je 1f			\n\
-		xorl -4(%%edi),%%eax	\n\
-		subl $4,%%edi		\n\
-		bsfl %%eax,%%edx	\n\
-1:		subl %%ebx,%%edi	\n\
-		shll $3,%%edi		\n\
-		addl %%edi,%%edx"
-		: "=c" (_count), "=D" (addr), "=d" (res)
-		: "0" (_count), "1" (addr), "b" (addr)
-		: "ax");
-	return res;
-}
-
-static __inline__ int
-find_next_zero_bit(void *addr, int size, int offset)
-{
-	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-	int set = 0, bit = offset & 31, res;
-	
-	if (bit) {
-		/*
-		 * Look for zero in first byte
-		 */
-		__asm__("			\n\
-			bsfl %1,%0		\n\
-			jne 1f			\n\
-			movl $32, %0		\n\
-1:			"
-			: "=r" (set)
-			: "r" (~(*p >> bit)));
-		if (set < (32 - bit))
-			return set + offset;
-		set = 32 - bit;
-		p++;
-	}
-	/*
-	 * No zero yet, search remaining full bytes for a zero
-	 */
-	res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
-	return (offset + set + res);
-}
-
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-static __inline__ unsigned long
-ffz(unsigned long word)
-{
-	__asm__("bsfl %1,%0"
-		:"=r" (word)
-		:"r" (~word));
-	return word;
-}
-
-/* 
- * memscan() taken from linux asm/string.h
- */
-/*
- * find the first occurrence of byte 'c', or 1 past the area if none
- */
-static __inline__ char *
-memscan(void *addr, unsigned char c, int size)
-{
-        if (!size)
-                return addr;
-        __asm__("			\n\
-		cld			\n\
-                repnz; scasb		\n\
-                jnz 1f			\n\
-                dec %%edi		\n\
-1:              "
-                : "=D" (addr), "=c" (size)
-                : "0" (addr), "1" (size), "a" (c));
-        return addr;
-}
-
-#endif /* _VFS_GNU_EXT2FS_I386_BITOPS_H_ */
diff --git a/sys/vfs/gnu/ext2fs/inode.h b/sys/vfs/gnu/ext2fs/inode.h
deleted file mode 100644
index 130404c..0000000
--- a/sys/vfs/gnu/ext2fs/inode.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*-
- * Copyright (c) 1982, 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)inode.h	8.9 (Berkeley) 5/14/95
- * $FreeBSD: src/sys/ufs/ufs/inode.h,v 1.28.2.2 2001/09/29 12:52:52 iedowse Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/inode.h,v 1.3 2006/09/10 01:26:40 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_INODE_H_
-#define	_VFS_GNU_EXT2FS_INODE_H_
-
-#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
-
-#ifndef _SYS_LOCK_H_
-#include <sys/lock.h>
-#endif
-#ifndef _SYS_LOCKF_H
-#include <sys/lockf.h>
-#endif
-
-#endif
-
-#ifndef _SYS_QUEUE_H_
-#include <sys/queue.h>
-#endif
-#include "dinode.h"
-
-/*
- * The size of a logical block number.
- */
-typedef long ext2_lbn_t;
-
-/*
- * This must agree with the definition in "dir.h"
- */
-#define	doff_t		int32_t
-
-#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
-
-/*
- * An EXT2FS inode is basically a UFS inode with some spare fields
- * redefined and a different superblock structure.
- */
-struct inode {
-	struct inode	*i_next;/* Hash chain */
-	struct	vnode  *i_vnode;/* Vnode associated with this inode. */
-	struct	vnode  *i_devvp;/* Vnode for block I/O. */
-	uint32_t i_flag;	/* flags, see below */
-	cdev_t	  i_dev;	/* Device associated with the inode. */
-	ino_t	  i_number;	/* The identity of the inode. */
-	int	  i_effnlink;	/* i_nlink when I/O completes */
-
-	struct	ext2_sb_info *i_e2fs;	/* EXT2FS */
-	struct	 ext2_dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
-	u_quad_t i_modrev;	/* Revision level for NFS lease. */
-	struct	 lockf i_lockf;/* Head of byte-level lock list. */
-	/*
-	 * Side effects; used during directory lookup.
-	 */
-	int32_t	  i_count;	/* Size of free slot in directory. */
-	doff_t	  i_endoff;	/* End of useful stuff in directory. */
-	doff_t	  i_diroff;	/* Offset in dir, where we found last entry. */
-	doff_t	  i_offset;	/* Offset of free space in directory. */
-	ino_t	  i_ino;	/* Inode number of found directory. */
-	uint32_t i_reclen;	/* Size of found directory entry. */
-	uint32_t i_spare[3];	/* XXX actually non-spare (for ext2fs). */
-
-	struct dirhash *i_dirhash; /* Hashing for large directories */
-	/*
-	 * The on-disk dinode itself (128 bytes)
-	 */
-	struct	ext2_dinode i_din;
-};
-
-#ifndef NO_I_DEFINES
-
-#define	i_atime		i_din.di_atime
-#define	i_atimensec	i_din.di_atimensec
-#define	i_blocks	i_din.di_blocks
-#define	i_ctime		i_din.di_ctime
-#define	i_ctimensec	i_din.di_ctimensec
-#define	i_db		i_din.di_db
-#define	i_flags		i_din.di_flags
-#define	i_gen		i_din.di_gen
-#define	i_gid		i_din.di_gid
-#define	i_ib		i_din.di_ib
-#define	i_mode		i_din.di_mode
-#define	i_mtime		i_din.di_mtime
-#define	i_mtimensec	i_din.di_mtimensec
-#define	i_nlink		i_din.di_nlink
-#define	i_rdev		i_din.di_rdev
-#define	i_shortlink	i_din.di_shortlink
-#define	i_size		i_din.di_size
-#define	i_uid		i_din.di_uid
-
-#endif
-
-#endif
-
-/* These flags are kept in i_flag. */
-#define	IN_ACCESS	0x0001		/* Access time update request. */
-#define	IN_CHANGE	0x0002		/* Inode change time update request. */
-#define	IN_UPDATE	0x0004		/* Modification time update request. */
-#define	IN_MODIFIED	0x0008		/* Inode has been modified. */
-#define	IN_RENAME	0x0010		/* Inode is being renamed. */
-#define	IN_SHLOCK	0x0020		/* File has shared lock. */
-#define	IN_EXLOCK	0x0040		/* File has exclusive lock. */
-#define	IN_HASHED	0x0080		/* Inode is on hash list */
-#define	IN_LAZYMOD	0x0100		/* Modified, but don't write yet. */
-
-#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
-
-/*
- * Structure used to pass around logical block paths generated by
- * ext2_getlbns and used by truncate and bmap code.
- */
-struct indir {
-	ext2_daddr_t in_lbn;		/* Logical block number. */
-	int	in_off;			/* Offset in buffer. */
-	int	in_exists;		/* Flag if the block exists. */
-};
-
-/* Convert between inode pointers and vnode pointers. */
-#define VTOI(vp)	((struct inode *)(vp)->v_data)
-#define ITOV(ip)	((ip)->i_vnode)
-
-/* Determine if soft dependencies are being done */
-#define DOINGSOFTDEP(vp)	((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
-#define DOINGASYNC(vp)		((vp)->v_mount->mnt_flag & MNT_ASYNC)
-
-/* This overlays the fid structure (see mount.h). */
-struct ufid {
-	uint16_t ufid_len;	/* Length of structure. */
-	uint16_t ufid_pad;	/* Force 32-bit alignment. */
-	ino_t	  ufid_ino;	/* File number (ino). */
-	int32_t	  ufid_gen;	/* Generation number. */
-};
-#endif /* _KERNEL || _KERNEL_STRUCTURES */
-
-#endif /* !_VFS_GNU_EXT2FS_INODE_H_ */
diff --git a/sys/vfs/gnu/ext2fs/quota.h b/sys/vfs/gnu/ext2fs/quota.h
deleted file mode 100644
index bbe3de8..0000000
--- a/sys/vfs/gnu/ext2fs/quota.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Robert Elz at The University of Melbourne.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)quota.h	8.3 (Berkeley) 8/19/94
- * $FreeBSD: src/sys/ufs/ufs/quota.h,v 1.15.2.1 2003/02/27 12:04:13 das Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/quota.h,v 1.3 2006/05/06 18:48:52 dillon Exp $
- */
-
-#ifndef _VFS_GNU_EXT2FS_QUOTA_H_
-#define	_VFS_GNU_EXT2FS_QUOTA_H_
-
-/*
- * Definitions for disk quotas imposed on the average user
- * (big brother finally hits UNIX).
- *
- * The following constants define the amount of time given a user before the
- * soft limits are treated as hard limits (usually resulting in an allocation
- * failure). The timer is started when the user crosses their soft limit, it
- * is reset when they go below their soft limit.
- */
-#define	MAX_IQ_TIME	(7*24*60*60)	/* seconds in 1 week */
-#define	MAX_DQ_TIME	(7*24*60*60)	/* seconds in 1 week */
-
-/*
- * The following constants define the usage of the quota file array in the
- * ext2mount structure and dquot array in the inode structure.  The semantics
- * of the elements of these arrays are defined in the routine getinoquota;
- * the remainder of the quota code treats them generically and need not be
- * inspected when changing the size of the array.
- */
-#define	MAXQUOTAS	2
-#define	USRQUOTA	0	/* element used for user quotas */
-#define	GRPQUOTA	1	/* element used for group quotas */
-
-/*
- * Definitions for the default names of the quotas files.
- */
-#define INITQFNAMES { \
-	"user",		/* USRQUOTA */ \
-	"group",	/* GRPQUOTA */ \
-	"undefined", \
-}
-#define	QUOTAFILENAME	"quota"
-#define	QUOTAGROUP	"operator"
-
-/*
- * Command definitions for the 'quotactl' system call.  The commands are
- * broken into a main command defined below and a subcommand that is used
- * to convey the type of quota that is being manipulated (see above).
- */
-#define SUBCMDMASK	0x00ff
-#define SUBCMDSHIFT	8
-#define	QCMD(cmd, type)	(((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-
-#define	Q_QUOTAON	0x0100	/* enable quotas */
-#define	Q_QUOTAOFF	0x0200	/* disable quotas */
-#define	Q_GETQUOTA	0x0300	/* get limits and usage */
-#define	Q_SETQUOTA	0x0400	/* set limits and usage */
-#define	Q_SETUSE	0x0500	/* set usage */
-#define	Q_SYNC		0x0600	/* sync disk copy of a filesystems quotas */
-
-/*
- * The following structure defines the format of the disk quota file
- * (as it appears on disk) - the file is an array of these structures
- * indexed by user or group number.  The setquota system call establishes
- * the vnode for each quota file (a pointer is retained in the ext2mount
- * structure).
- */
-struct ext2_dqblk {
-	uint32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
-	uint32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
-	uint32_t dqb_curblocks;	/* current block count */
-	uint32_t dqb_ihardlimit;	/* maximum # allocated inodes + 1 */
-	uint32_t dqb_isoftlimit;	/* preferred inode limit */
-	uint32_t dqb_curinodes;	/* current # allocated inodes */
-	time_t	  dqb_btime;		/* time limit for excessive disk use */
-	time_t	  dqb_itime;		/* time limit for excessive files */
-};
-
-#ifdef _KERNEL
-
-#include <sys/queue.h>
-
-/*
- * The following structure records disk usage for a user or group on a
- * filesystem. There is one allocated for each quota that exists on any
- * filesystem for the current user or group. A cache is kept of recently
- * used entries.
- */
-struct ext2_dquot {
-	LIST_ENTRY(ext2_dquot) dq_hash;	/* hash list */
-	TAILQ_ENTRY(ext2_dquot) dq_freelist;	/* free list */
-	uint16_t dq_flags;		/* flags, see below */
-	uint16_t dq_type;		/* quota type of this dquot */
-	uint32_t dq_cnt;		/* count of active references */
-	uint32_t dq_id;		/* identifier this applies to */
-	struct	ext2mount *dq_ump;	/* filesystem that this is taken from */
-	struct	ext2_dqblk dq_dqb;	/* actual usage & quotas */
-};
-/*
- * Flag values.
- */
-#define	DQ_LOCK		0x01		/* this quota locked (no MODS) */
-#define	DQ_WANT		0x02		/* wakeup on unlock */
-#define	DQ_MOD		0x04		/* this quota modified since read */
-#define	DQ_FAKE		0x08		/* no limits here, just usage */
-#define	DQ_BLKS		0x10		/* has been warned about blk limit */
-#define	DQ_INODS	0x20		/* has been warned about inode limit */
-/*
- * Shorthand notation.
- */
-#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
-#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
-#define	dq_curblocks	dq_dqb.dqb_curblocks
-#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
-#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
-#define	dq_curinodes	dq_dqb.dqb_curinodes
-#define	dq_btime	dq_dqb.dqb_btime
-#define	dq_itime	dq_dqb.dqb_itime
-
-/*
- * If the system has never checked for a quota for this file, then it is
- * set to NODQUOT.  Once a write attempt is made the inode pointer is set
- * to reference a dquot structure.
- */
-#define	NODQUOT		NULL
-
-/*
- * Flags to ext2_chkdq() and ext2_chkiq()
- */
-#define	FORCE	0x01	/* force usage changes independent of limits */
-#define	CHOWN	0x02	/* (advisory) change initiated by chown */
-
-/*
- * Macros to avoid subroutine calls to trivial functions.
- */
-#ifdef DIAGNOSTIC
-#define	DQREF(dq)	ext2_dqref(dq)
-#else
-#define	DQREF(dq)	(dq)->dq_cnt++
-#endif
-
-struct inode;
-struct mount;
-struct proc;
-struct thread;
-struct ucred;
-struct vnode;
-
-int	ext2_chkdq(struct inode *, long, struct ucred *, int);
-int	ext2_chkiq(struct inode *, long, struct ucred *, int);
-void	ext2_dqinit(void);
-void	ext2_dqrele(struct vnode *, struct ext2_dquot *);
-int	ext2_getinoquota(struct inode *);
-int	ext2_getquota(struct mount *, u_long, int, caddr_t);
-int	ext2_qsync(struct mount *mp);
-int	ext2_quotaoff(struct mount *, int);
-int	ext2_quotaon(struct ucred *, struct mount *, int, caddr_t);
-int	ext2_setquota(struct mount *, u_long, int, caddr_t);
-int	ext2_setuse(struct mount *, u_long, int, caddr_t);
-int	ext2_quotactl(struct mount *, int, uid_t, caddr_t, struct ucred *);
-
-#else /* !_KERNEL */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int	quotactl(const char *, int, int, void *);
-__END_DECLS
-
-#endif /* _KERNEL */
-
-#endif /* !_VFS_GNU_EXT2FS_QUOTA_H_ */
-- 
1.7.4.4

