<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.comp.boot-loaders.u-boot">
    <title>gmane.comp.boot-loaders.u-boot</title>
    <link>http://blog.gmane.org/gmane.comp.boot-loaders.u-boot</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132150"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132149"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132148"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132147"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132146"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132145"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132144"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132143"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132142"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132141"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132140"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132139"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132138"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132137"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132136"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132135"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132134"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132133"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132132"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132131"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132150">
    <title>Re: [PATCH v4 4/6] armv7: Use -march=armv7-a and thereby enable Thumb-2</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132150</link>
    <description>&lt;pre&gt;
Allen's final patch did make it into the Tegra tree and I can confirm that
the issue is gone now. Thanks.

Thierry
_______________________________________________
U-Boot mailing list
U-Boot&amp;lt; at &amp;gt;lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
&lt;/pre&gt;</description>
    <dc:creator>Thierry Reding</dc:creator>
    <dc:date>2012-05-24T06:46:50</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132149">
    <title>Re: [PATCH 5/7] OMAP5: EMIF: Add support for DDR3 device</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132149</link>
    <description>&lt;pre&gt;Hi Tom,


 ok, and there are only few omap checks that are in the common lpddr2
and ddr3 init
paths, that we should be able to get rid of, so we can have generic
lpddr2_init and
ddr3_init.  But anyways as you said we can do all these only after the
current code
works for DDR3 on your am33xx.

 yeah, sounds correct.
  How about something like this, similar to the above
#define DDR2 1
#define LPDDR2 2
#define DDR3 3
#define LPDDR3 4

and soc specific code returns the correct ddr type. For OMAP
get_ddr_type()
{
 switch(EMIF_SDRAM_CONFIG &amp;amp; SDRAM_TYPE) {
 case 3:
     return DDR3;
 case 4:
 case 5:
 default:
    return LPDDR2;
}
We can avoid the #ifdef s in the emif code and use the type returned by
SOC to do the required initialisations. ?

Thanks,
 Sricharan
&lt;/pre&gt;</description>
    <dc:creator>R, Sricharan</dc:creator>
    <dc:date>2012-05-24T06:45:23</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132148">
    <title>Re: [PATCH] drivers/net/armada100_fec.c: Fix compile warning</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132148</link>
    <description>&lt;pre&gt;


Acked-By: Prafulla Wadaskar &amp;lt;Prafulla&amp;lt; at &amp;gt;marvell.com&amp;gt;

Regards..
Prafulla . . .
&lt;/pre&gt;</description>
    <dc:creator>Prafulla Wadaskar</dc:creator>
    <dc:date>2012-05-24T06:45:06</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132147">
    <title>[PATCH v3 1/1] Add ZFS filesystem support</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132147</link>
    <description>&lt;pre&gt;U-Boot port is based on sources forked from GRUB-0.97 by Sun in 2004,
which can be found here:
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/grub/grub-0.97/stage2/zfs-include/zfs.h

Released by Sun for GRUB under the license:
  *  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.

GRUB official releases include ZFS in version:
ftp://alpha.gnu.org/gnu/grub/grub-1.99~rc1.tar.gz

And patched against GRUB Bazaar repository for ashift fixes (4KB HDDs)
more conveniently found at github:
https://github.com/pendor/grub-zfs/commit/e7b6ef3ac3b9685ac4c394c897b1d4221b7381f1

Signed-off-by: Jorgen Lundman &amp;lt;lundman&amp;lt; at &amp;gt;lundman.net&amp;gt;

---

v3: * add missing patch revision history (this text)
    * Submitted as single patch per Wolfgang Denk instructions

v2: * Keep Makefile placement alphabetically sorted.
    * Clean ugly line breaks and indentation errors
    * Fix license corruption in fs/Makefile
---
 Makefile                     |    2 +-
 common/Makefile              |    1 +
 common/cmd_zfs.c             |  236 +++++
 fs/Makefile                  |    3 +-
 fs/{ =&amp;gt; zfs}/Makefile        |   39 +-
 fs/zfs/dev.c                 |  137 +++
 fs/zfs/zfs.c                 | 2396 ++++++++++++++++++++++++++++++++++++++++++
 fs/zfs/zfs_fletcher.c        |   84 ++
 fs/zfs/zfs_lzjb.c            |   94 ++
 fs/zfs/zfs_sha256.c          |  145 +++
 include/config_cmd_all.h     |    1 +
 include/zfs/dmu.h            |  119 +++
 include/zfs/dmu_objset.h     |   43 +
 include/zfs/dnode.h          |   80 ++
 include/zfs/dsl_dataset.h    |   52 +
 include/zfs/dsl_dir.h        |   48 +
 include/zfs/sa_impl.h        |   34 +
 include/zfs/spa.h            |  311 ++++++
 include/zfs/uberblock_impl.h |   57 +
 include/zfs/vdev_impl.h      |   69 ++
 include/zfs/zap_impl.h       |  112 ++
 include/zfs/zap_leaf.h       |  103 ++
 include/zfs/zfs.h            |  122 +++
 include/zfs/zfs_acl.h        |   55 +
 include/zfs/zfs_znode.h      |   70 ++
 include/zfs/zil.h            |   56 +
 include/zfs/zio.h            |   92 ++
 include/zfs/zio_checksum.h   |   49 +
 include/zfs_common.h         |   94 ++
 29 files changed, 4687 insertions(+), 17 deletions(-)
 create mode 100644 common/cmd_zfs.c
 copy fs/{ =&amp;gt; zfs}/Makefile (56%)
 create mode 100644 fs/zfs/dev.c
 create mode 100644 fs/zfs/zfs.c
 create mode 100644 fs/zfs/zfs_fletcher.c
 create mode 100644 fs/zfs/zfs_lzjb.c
 create mode 100644 fs/zfs/zfs_sha256.c
 create mode 100644 include/zfs/dmu.h
 create mode 100644 include/zfs/dmu_objset.h
 create mode 100644 include/zfs/dnode.h
 create mode 100644 include/zfs/dsl_dataset.h
 create mode 100644 include/zfs/dsl_dir.h
 create mode 100644 include/zfs/sa_impl.h
 create mode 100644 include/zfs/spa.h
 create mode 100644 include/zfs/uberblock_impl.h
 create mode 100644 include/zfs/vdev_impl.h
 create mode 100644 include/zfs/zap_impl.h
 create mode 100644 include/zfs/zap_leaf.h
 create mode 100644 include/zfs/zfs.h
 create mode 100644 include/zfs/zfs_acl.h
 create mode 100644 include/zfs/zfs_znode.h
 create mode 100644 include/zfs/zil.h
 create mode 100644 include/zfs/zio.h
 create mode 100644 include/zfs/zio_checksum.h
 create mode 100644 include/zfs_common.h

diff --git a/Makefile b/Makefile
index 351a8f0..d3b84bf 100644
--- a/Makefile
+++ b/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -244,7 +244,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; endif
 LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
 LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
 fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
-fs/ubifs/libubifs.o
+fs/ubifs/libubifs.o fs/zfs/libzfs.o
 LIBS += net/libnet.o
 LIBS += disk/libdisk.o
 LIBS += drivers/bios_emulator/libatibiosemu.o
diff --git a/common/Makefile b/common/Makefile
index 6e23baa..4de03da 100644
--- a/common/Makefile
+++ b/common/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -164,6 +164,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
+COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o
 COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
 
 # others
diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c
new file mode 100644
index 0000000..a6ea2c0
--- /dev/null
+++ b/common/cmd_zfs.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,236 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *
+ * ZFS filesystem porting to Uboot by
+ * Jorgen Lundman &amp;lt;lundman at lundman.net&amp;gt;
+ *
+ * zfsfs support
+ * made from existing GRUB Sources by Sun, GNU and others.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;part.h&amp;gt;
+#include &amp;lt;config.h&amp;gt;
+#include &amp;lt;command.h&amp;gt;
+#include &amp;lt;image.h&amp;gt;
+#include &amp;lt;linux/ctype.h&amp;gt;
+#include &amp;lt;asm/byteorder.h&amp;gt;
+#include &amp;lt;zfs_common.h&amp;gt;
+#include &amp;lt;linux/stat.h&amp;gt;
+#include &amp;lt;malloc.h&amp;gt;
+
+#if defined(CONFIG_CMD_USB) &amp;amp;&amp;amp; defined(CONFIG_USB_STORAGE)
+#include &amp;lt;usb.h&amp;gt;
+#endif
+
+#if !defined(CONFIG_DOS_PARTITION) &amp;amp;&amp;amp; !defined(CONFIG_EFI_PARTITION)
+#error DOS or EFI partition support must be selected
+#endif
+
+#define DOS_PART_MAGIC_OFFSET0x1fe
+#define DOS_FS_TYPE_OFFSET0x36
+#define DOS_FS32_TYPE_OFFSET0x52
+
+static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+char *filename = NULL;
+char *ep;
+int dev;
+unsigned long part = 1;
+ulong addr = 0;
+ulong part_length;
+disk_partition_t info;
+char buf[12];
+unsigned long count;
+const char *addr_str;
+struct zfs_file zfile;
+struct device_s vdev;
+
+if (argc &amp;lt; 3)
+return CMD_RET_USAGE;
+
+count = 0;
+addr = simple_strtoul(argv[3], NULL, 16);
+filename = getenv("bootfile");
+switch (argc) {
+case 3:
+addr_str = getenv("loadaddr");
+if (addr_str != NULL)
+addr = simple_strtoul(addr_str, NULL, 16);
+else
+addr = CONFIG_SYS_LOAD_ADDR;
+
+break;
+case 4:
+break;
+case 5:
+filename = argv[4];
+break;
+case 6:
+filename = argv[4];
+count = simple_strtoul(argv[5], NULL, 16);
+break;
+
+default:
+return cmd_usage(cmdtp);
+}
+
+if (!filename) {
+puts("** No boot file defined **\n");
+return 1;
+}
+
+dev = (int)simple_strtoul(argv[2], &amp;amp;ep, 16);
+zfs_dev_desc = get_dev(argv[1], dev);
+if (zfs_dev_desc == NULL) {
+printf("** Block device %s %d not supported\n", argv[1], dev);
+return 1;
+}
+
+if (*ep) {
+if (*ep != ':') {
+puts("** Invalid boot device, use `dev[:part]' **\n");
+return 1;
+}
+part = simple_strtoul(++ep, NULL, 16);
+}
+
+if (part != 0) {
+if (get_partition_info(zfs_dev_desc, part, &amp;amp;info)) {
+printf("** Bad partition %lu **\n", part);
+return 1;
+}
+
+if (strncmp((char *)info.type, BOOT_PART_TYPE,
+strlen(BOOT_PART_TYPE)) != 0) {
+printf("** Invalid partition type \"%s\" (expect \"" BOOT_PART_TYPE "\")\n",
+   info.type);
+return 1;
+}
+printf("Loading file \"%s\" "
+   "from %s device %d:%lu %s\n",
+   filename, argv[1], dev, part, info.name);
+} else {
+printf("Loading file \"%s\" from %s device %d\n",
+   filename, argv[1], dev);
+}
+
+part_length = zfs_set_blk_dev(zfs_dev_desc, part);
+if (part_length == 0) {
+printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
+return 1;
+}
+
+vdev.part_length = part_length;
+
+memset(&amp;amp;zfile, 0, sizeof(zfile));
+zfile.device = &amp;amp;vdev;
+if (zfs_open(&amp;amp;zfile, filename)) {
+printf("** File not found %s\n", filename);
+return 1;
+}
+
+if ((count &amp;lt; zfile.size) &amp;amp;&amp;amp; (count != 0))
+zfile.size = (uint64_t)count;
+
+if (zfs_read(&amp;amp;zfile, (char *)addr, zfile.size) != zfile.size) {
+printf("** Unable to read \"%s\" from %s %d:%lu **\n",
+   filename, argv[1], dev, part);
+zfs_close(&amp;amp;zfile);
+return 1;
+}
+
+zfs_close(&amp;amp;zfile);
+
+/* Loading ok, update default load address */
+load_addr = addr;
+
+printf("%llu bytes read\n", zfile.size);
+sprintf(buf, "%llX", zfile.size);
+setenv("filesize", buf);
+
+return 0;
+}
+
+
+int zfs_print(const char *entry, const struct zfs_dirhook_info *data)
+{
+printf("%s %s\n",
+   data-&amp;gt;dir ? "&amp;lt;DIR&amp;gt; " : " ",
+   entry);
+return 0; /* 0 continue, 1 stop */
+}
+
+
+
+static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+const char *filename = "/";
+int dev;
+unsigned long part = 1;
+char *ep;
+int part_length;
+struct device_s vdev;
+
+if (argc &amp;lt; 3)
+return cmd_usage(cmdtp);
+
+dev = (int)simple_strtoul(argv[2], &amp;amp;ep, 16);
+zfs_dev_desc = get_dev(argv[1], dev);
+
+if (zfs_dev_desc == NULL) {
+printf("\n** Block device %s %d not supported\n", argv[1], dev);
+return 1;
+}
+
+if (*ep) {
+if (*ep != ':') {
+puts("\n** Invalid boot device, use `dev[:part]' **\n");
+return 1;
+}
+part = simple_strtoul(++ep, NULL, 16);
+}
+
+if (argc == 4)
+filename = argv[3];
+
+part_length = zfs_set_blk_dev(zfs_dev_desc, part);
+if (part_length == 0) {
+printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
+return 1;
+}
+
+vdev.part_length = part_length;
+
+zfs_ls(&amp;amp;vdev, filename,
+   zfs_print);
+
+return 0;
+}
+
+
+U_BOOT_CMD(zfsls, 4, 1, do_zfs_ls,
+   "list files in a directory (default /)",
+   "&amp;lt;interface&amp;gt; &amp;lt;dev[:part]&amp;gt; [directory]\n"
+   "  - list files from 'dev' on 'interface' in a '/DATASET/&amp;lt; at &amp;gt;/$dir/'");
+
+U_BOOT_CMD(zfsload, 6, 0, do_zfs_load,
+   "load binary file from a ZFS filesystem",
+   "&amp;lt;interface&amp;gt; &amp;lt;dev[:part]&amp;gt; [addr] [filename] [bytes]\n"
+   "  - load binary file '/DATASET/&amp;lt; at &amp;gt;/$dir/$file' from 'dev' on 'interface'\n"
+   " to address 'addr' from ZFS filesystem");
diff --git a/fs/Makefile b/fs/Makefile
index 22aad12..baa7e96 100644
--- a/fs/Makefile
+++ b/fs/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #
 # (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd&amp;lt; at &amp;gt;denx.de.
+# Wolfgang Denk, DENX Software Engineering, &amp;lt;wd at denx.de&amp;gt;
 #
 # See file CREDITS for list of people who contributed to this
 # project.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -30,6 +30,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; subdirs-$(CONFIG_CMD_JFFS2) += jffs2
 subdirs-$(CONFIG_CMD_REISER) += reiserfs
 subdirs-$(CONFIG_YAFFS2) += yaffs2
 subdirs-$(CONFIG_CMD_UBIFS) += ubifs
+subdirs-$(CONFIG_CMD_ZFS) += zfs
 
 SUBDIRS:= $(subdirs-y)
 
diff --git a/fs/Makefile b/fs/zfs/Makefile
similarity index 56%
copy from fs/Makefile
copy to fs/zfs/Makefile
index 22aad12..938fc5e 100644
--- a/fs/Makefile
+++ b/fs/zfs/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,6 +1,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #
-# (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd&amp;lt; at &amp;gt;denx.de.
+# (C) Copyright 2012
+# Jorgen Lundman &amp;lt;lundman at lundman.net&amp;gt;
 #
 # See file CREDITS for list of people who contributed to this
 # project.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -20,19 +20,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 # MA 02111-1307 USA
 #
-#
 
-subdirs-$(CONFIG_CMD_CRAMFS) := cramfs
-subdirs-$(CONFIG_CMD_EXT2) += ext2
-subdirs-$(CONFIG_CMD_FAT) += fat
-subdirs-$(CONFIG_CMD_FDOS) += fdos
-subdirs-$(CONFIG_CMD_JFFS2) += jffs2
-subdirs-$(CONFIG_CMD_REISER) += reiserfs
-subdirs-$(CONFIG_YAFFS2) += yaffs2
-subdirs-$(CONFIG_CMD_UBIFS) += ubifs
+include $(TOPDIR)/config.mk
+
+LIB= $(obj)libzfs.o
+
+AOBJS=
+COBJS-$(CONFIG_CMD_ZFS) := dev.o zfs.o zfs_fletcher.o zfs_sha256.o zfs_lzjb.o
+
+SRCS:= $(AOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS:= $(addprefix $(obj),$(AOBJS) $(COBJS-y))
+
+
+all:$(LIB) $(AOBJS)
+
+$(LIB):$(obj).depend $(OBJS)
+$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
 
-SUBDIRS:= $(subdirs-y)
+sinclude $(obj).depend
 
-$(obj).depend all:
-&amp;lt; at &amp;gt;for dir in $(SUBDIRS) ; do \
-$(MAKE) -C $$dir $&amp;lt; at &amp;gt; ; done
+#########################################################################
diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c
new file mode 100644
index 0000000..ab32865
--- /dev/null
+++ b/fs/zfs/dev.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,137 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *
+ *based on code of fs/reiserfs/dev.c by
+ *
+ *(C) Copyright 2003 - 2004
+ *Sysgo AG, &amp;lt;www.elinos.com&amp;gt;, Pavel Bartusek &amp;lt;pba&amp;lt; at &amp;gt;sysgo.com&amp;gt;
+ *
+ *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.
+ */
+
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;config.h&amp;gt;
+#include &amp;lt;zfs_common.h&amp;gt;
+
+static block_dev_desc_t *zfs_block_dev_desc;
+static disk_partition_t part_info;
+
+int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part)
+{
+zfs_block_dev_desc = rbdd;
+
+if (part == 0) {
+/* disk doesn't use partition table */
+part_info.start = 0;
+part_info.size = rbdd-&amp;gt;lba;
+part_info.blksz = rbdd-&amp;gt;blksz;
+} else {
+if (get_partition_info(zfs_block_dev_desc, part, &amp;amp;part_info))
+return 0;
+}
+
+return part_info.size;
+}
+
+/* err */
+int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
+{
+short sec_buffer[SECTOR_SIZE/sizeof(short)];
+char *sec_buf = sec_buffer;
+unsigned block_len;
+
+/*
+ *Check partition boundaries
+ */
+if ((sector &amp;lt; 0) ||
+((sector + ((byte_offset + byte_len - 1) &amp;gt;&amp;gt; SECTOR_BITS)) &amp;gt;=
+ part_info.size)) {
+/*errnum = ERR_OUTSIDE_PART; */
+printf(" ** zfs_devread() read outside partition sector %d\n", sector);
+return 1;
+}
+
+/*
+ *Get the read to the beginning of a partition.
+ */
+sector += byte_offset &amp;gt;&amp;gt; SECTOR_BITS;
+byte_offset &amp;amp;= SECTOR_SIZE - 1;
+
+debug(" &amp;lt;%d, %d, %d&amp;gt;\n", sector, byte_offset, byte_len);
+
+if (zfs_block_dev_desc == NULL) {
+printf("** Invalid Block Device Descriptor (NULL)\n");
+return 1;
+}
+
+if (byte_offset != 0) {
+/* read first part which isn't aligned with start of sector */
+if (zfs_block_dev_desc-&amp;gt;block_read(zfs_block_dev_desc-&amp;gt;dev,
+   part_info.start + sector, 1,
+   (unsigned long *) sec_buf) != 1) {
+printf(" ** zfs_devread() read error **\n");
+return 1;
+}
+memcpy(buf, sec_buf + byte_offset,
+   min(SECTOR_SIZE - byte_offset, byte_len));
+buf += min(SECTOR_SIZE - byte_offset, byte_len);
+byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
+sector++;
+}
+
+if (byte_len == 0)
+return 0;
+
+/*read sector aligned part */
+block_len = byte_len &amp;amp; ~(SECTOR_SIZE - 1);
+
+if (block_len == 0) {
+u8 p[SECTOR_SIZE];
+
+block_len = SECTOR_SIZE;
+zfs_block_dev_desc-&amp;gt;block_read(zfs_block_dev_desc-&amp;gt;dev,
+   part_info.start + sector,
+   1, (unsigned long *)p);
+memcpy(buf, p, byte_len);
+return 0;
+}
+
+if (zfs_block_dev_desc-&amp;gt;block_read(zfs_block_dev_desc-&amp;gt;dev,
+   part_info.start + sector,
+   block_len / SECTOR_SIZE,
+   (unsigned long *) buf) !=
+block_len / SECTOR_SIZE) {
+printf(" ** zfs_devread() read error - block\n");
+return 1;
+}
+
+block_len = byte_len &amp;amp; ~(SECTOR_SIZE - 1);
+buf += block_len;
+byte_len -= block_len;
+sector += block_len / SECTOR_SIZE;
+
+if (byte_len != 0) {
+/* read rest of data which are not in whole sector */
+if (zfs_block_dev_desc-&amp;gt;
+block_read(zfs_block_dev_desc-&amp;gt;dev,
+   part_info.start + sector, 1,
+   (unsigned long *) sec_buf) != 1) {
+printf(" ** zfs_devread() read error - last part\n");
+return 1;
+}
+memcpy(buf, sec_buf, byte_len);
+}
+return 0;
+}
diff --git a/fs/zfs/zfs.c b/fs/zfs/zfs.c
new file mode 100644
index 0000000..d6e0e23
--- /dev/null
+++ b/fs/zfs/zfs.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,2396 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *
+ * ZFS filesystem ported to u-boot by
+ * Jorgen Lundman &amp;lt;lundman at lundman.net&amp;gt;
+ *
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004
+ *Free Software Foundation, Inc.
+ *Copyright 2004Sun Microsystems, Inc.
+ *
+ *GRUB 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.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ *
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;malloc.h&amp;gt;
+#include &amp;lt;linux/stat.h&amp;gt;
+#include &amp;lt;linux/time.h&amp;gt;
+#include &amp;lt;linux/ctype.h&amp;gt;
+#include &amp;lt;asm/byteorder.h&amp;gt;
+#include "zfs_common.h"
+
+block_dev_desc_t *zfs_dev_desc;
+
+/*
+ * The zfs plug-in routines for GRUB are:
+ *
+ * zfs_mount() - locates a valid uberblock of the root pool and reads
+ *in its MOS at the memory address MOS.
+ *
+ * zfs_open() - locates a plain file object by following the MOS
+ *and places its dnode at the memory address DNODE.
+ *
+ * zfs_read() - read in the data blocks pointed by the DNODE.
+ *
+ */
+
+#include &amp;lt;zfs/zfs.h&amp;gt;
+#include &amp;lt;zfs/zio.h&amp;gt;
+#include &amp;lt;zfs/dnode.h&amp;gt;
+#include &amp;lt;zfs/uberblock_impl.h&amp;gt;
+#include &amp;lt;zfs/vdev_impl.h&amp;gt;
+#include &amp;lt;zfs/zio_checksum.h&amp;gt;
+#include &amp;lt;zfs/zap_impl.h&amp;gt;
+#include &amp;lt;zfs/zap_leaf.h&amp;gt;
+#include &amp;lt;zfs/zfs_znode.h&amp;gt;
+#include &amp;lt;zfs/dmu.h&amp;gt;
+#include &amp;lt;zfs/dmu_objset.h&amp;gt;
+#include &amp;lt;zfs/sa_impl.h&amp;gt;
+#include &amp;lt;zfs/dsl_dir.h&amp;gt;
+#include &amp;lt;zfs/dsl_dataset.h&amp;gt;
+
+
+#defineZPOOL_PROP_BOOTFS"bootfs"
+
+
+/*
+ * For nvlist manipulation. (from nvpair.h)
+ */
+#defineNV_ENCODE_NATIVE0
+#defineNV_ENCODE_XDR1
+#defineNV_BIG_ENDIAN0
+#defineNV_LITTLE_ENDIAN1
+#defineDATA_TYPE_UINT648
+#defineDATA_TYPE_STRING9
+#defineDATA_TYPE_NVLIST19
+#defineDATA_TYPE_NVLIST_ARRAY20
+
+
+/*
+ * Macros to get fields in a bp or DVA.
+ */
+#defineP2PHASE(x, align)((x) &amp;amp; ((align) - 1))
+#defineDVA_OFFSET_TO_PHYS_SECTOR(offset)\
+((offset + VDEV_LABEL_START_SIZE) &amp;gt;&amp;gt; SPA_MINBLOCKSHIFT)
+
+/*
+ * return x rounded down to an align boundary
+ * eg, P2ALIGN(1200, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(1024, 1024) == 1024 (1*align)
+ * eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align)
+ * eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align)
+ */
+#defineP2ALIGN(x, align)((x) &amp;amp; -(align))
+
+/*
+ * FAT ZAP data structures
+ */
+#defineZFS_CRC64_POLY 0xC96C5795D7870F42ULL/* ECMA-182, reflected form */
+#defineZAP_HASH_IDX(hash, n)(((n) == 0) ? 0 : ((hash) &amp;gt;&amp;gt; (64 - (n))))
+#defineCHAIN_END0xffff/* end of the chunk chain */
+
+/*
+ * The amount of space within the chunk available for the array is:
+ * chunk size - space for type (1) - space for next pointer (2)
+ */
+#defineZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
+
+#defineZAP_LEAF_HASH_SHIFT(bs)(bs - 5)
+#defineZAP_LEAF_HASH_NUMENTRIES(bs) (1 &amp;lt;&amp;lt; ZAP_LEAF_HASH_SHIFT(bs))
+#defineLEAF_HASH(bs, h)\
+((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) &amp;amp;\
+ ((h) &amp;gt;&amp;gt; (64 - ZAP_LEAF_HASH_SHIFT(bs)-l-&amp;gt;l_hdr.lh_prefix_len)))
+
+/*
+ * The amount of space available for chunks is:
+ * block size shift - hash entry size (2) * number of hash
+ * entries - header space (2*chunksize)
+ */
+#defineZAP_LEAF_NUMCHUNKS(bs)\
+(((1&amp;lt;&amp;lt;bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(bs)) /\
+ ZAP_LEAF_CHUNKSIZE - 2)
+
+/*
+ * The chunks start immediately after the hash table.  The end of the
+ * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
+ * chunk_t.
+ */
+#defineZAP_LEAF_CHUNK(l, bs, idx)\
+((zap_leaf_chunk_t *)(l-&amp;gt;l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx]
+#defineZAP_LEAF_ENTRY(l, bs, idx) (&amp;amp;ZAP_LEAF_CHUNK(l, bs, idx).l_entry)
+
+
+/*
+ * Decompression Entry - lzjb
+ */
+#ifndefNBBY
+#defineNBBY8
+#endif
+
+
+
+typedef int zfs_decomp_func_t(void *s_start, void *d_start,
+  uint32_t s_len, uint32_t d_len);
+typedef struct decomp_entry {
+char *name;
+zfs_decomp_func_t *decomp_func;
+} decomp_entry_t;
+
+typedef struct dnode_end {
+dnode_phys_t dn;
+grub_zfs_endian_t endian;
+} dnode_end_t;
+
+struct grub_zfs_data {
+/* cache for a file block of the currently zfs_open()-ed file */
+char *file_buf;
+uint64_t file_start;
+uint64_t file_end;
+
+/* XXX: ashift is per vdev, not per pool.  We currently only ever touch
+ * a single vdev, but when/if raid-z or stripes are supported, this
+ * may need revision.
+ */
+uint64_t vdev_ashift;
+uint64_t label_txg;
+uint64_t pool_guid;
+
+/* cache for a dnode block */
+dnode_phys_t *dnode_buf;
+dnode_phys_t *dnode_mdn;
+uint64_t dnode_start;
+uint64_t dnode_end;
+grub_zfs_endian_t dnode_endian;
+
+uberblock_t current_uberblock;
+
+dnode_end_t mos;
+dnode_end_t mdn;
+dnode_end_t dnode;
+
+uint64_t vdev_phys_sector;
+
+int (*userhook)(const char *, const struct zfs_dirhook_info *);
+struct zfs_dirhook_info *dirinfo;
+
+};
+
+
+
+
+static int
+zlib_decompress(void *s, void *d,
+uint32_t slen, uint32_t dlen)
+{
+if (zlib_decompress(s, d, slen, dlen) &amp;lt; 0)
+return ZFS_ERR_BAD_FS;
+return ZFS_ERR_NONE;
+}
+
+static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = {
+{"inherit", NULL},/* ZIO_COMPRESS_INHERIT */
+{"on", lzjb_decompress},/* ZIO_COMPRESS_ON */
+{"off", NULL},/* ZIO_COMPRESS_OFF */
+{"lzjb", lzjb_decompress},/* ZIO_COMPRESS_LZJB */
+{"empty", NULL},/* ZIO_COMPRESS_EMPTY */
+{"gzip-1", zlib_decompress},  /* ZIO_COMPRESS_GZIP1 */
+{"gzip-2", zlib_decompress},  /* ZIO_COMPRESS_GZIP2 */
+{"gzip-3", zlib_decompress},  /* ZIO_COMPRESS_GZIP3 */
+{"gzip-4", zlib_decompress},  /* ZIO_COMPRESS_GZIP4 */
+{"gzip-5", zlib_decompress},  /* ZIO_COMPRESS_GZIP5 */
+{"gzip-6", zlib_decompress},  /* ZIO_COMPRESS_GZIP6 */
+{"gzip-7", zlib_decompress},  /* ZIO_COMPRESS_GZIP7 */
+{"gzip-8", zlib_decompress},  /* ZIO_COMPRESS_GZIP8 */
+{"gzip-9", zlib_decompress},  /* ZIO_COMPRESS_GZIP9 */
+};
+
+
+
+static int zio_read_data(blkptr_t *bp, grub_zfs_endian_t endian,
+ void *buf, struct grub_zfs_data *data);
+
+static int
+zio_read(blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
+ size_t *size, struct grub_zfs_data *data);
+
+/*
+ * Our own version of log2().  Same thing as highbit()-1.
+ */
+static int
+zfs_log2(uint64_t num)
+{
+int i = 0;
+
+while (num &amp;gt; 1) {
+i++;
+num = num &amp;gt;&amp;gt; 1;
+}
+
+return i;
+}
+
+
+/* Checksum Functions */
+static void
+zio_checksum_off(const void *buf __attribute__ ((unused)),
+ uint64_t size __attribute__ ((unused)),
+ grub_zfs_endian_t endian __attribute__ ((unused)),
+ zio_cksum_t *zcp)
+{
+ZIO_SET_CHECKSUM(zcp, 0, 0, 0, 0);
+}
+
+/* Checksum Table and Values */
+static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
+{NULL, 0, 0, "inherit"},
+{NULL, 0, 0, "on"},
+{zio_checksum_off, 0, 0, "off"},
+{zio_checksum_SHA256, 1, 1, "label"},
+{zio_checksum_SHA256, 1, 1, "gang_header"},
+{NULL, 0, 0, "zilog"},
+{fletcher_2, 0, 0, "fletcher2"},
+{fletcher_4, 1, 0, "fletcher4"},
+{zio_checksum_SHA256, 1, 0, "SHA256"},
+{NULL, 0, 0, "zilog2"},
+};
+
+/*
+ * zio_checksum_verify: Provides support for checksum verification.
+ *
+ * Fletcher2, Fletcher4, and SHA256 are supported.
+ *
+ */
+static int
+zio_checksum_verify(zio_cksum_t zc, uint32_t checksum,
+grub_zfs_endian_t endian, char *buf, int size)
+{
+zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1;
+zio_checksum_info_t *ci = &amp;amp;zio_checksum_table[checksum];
+zio_cksum_t actual_cksum, expected_cksum;
+
+if (checksum &amp;gt;= ZIO_CHECKSUM_FUNCTIONS || ci-&amp;gt;ci_func == NULL) {
+printf("zfs unknown checksum function %d\n", checksum);
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+
+if (ci-&amp;gt;ci_eck) {
+expected_cksum = zec-&amp;gt;zec_cksum;
+zec-&amp;gt;zec_cksum = zc;
+ci-&amp;gt;ci_func(buf, size, endian, &amp;amp;actual_cksum);
+zec-&amp;gt;zec_cksum = expected_cksum;
+zc = expected_cksum;
+} else {
+ci-&amp;gt;ci_func(buf, size, endian, &amp;amp;actual_cksum);
+}
+
+if ((actual_cksum.zc_word[0] != zc.zc_word[0])
+|| (actual_cksum.zc_word[1] != zc.zc_word[1])
+|| (actual_cksum.zc_word[2] != zc.zc_word[2])
+|| (actual_cksum.zc_word[3] != zc.zc_word[3])) {
+return ZFS_ERR_BAD_FS;
+}
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * vdev_uberblock_compare takes two uberblock structures and returns an integer
+ * indicating the more recent of the two.
+ *Return Value = 1 if ub2 is more recent
+ *Return Value = -1 if ub1 is more recent
+ * The most recent uberblock is determined using its transaction number and
+ * timestamp.  The uberblock with the highest transaction number is
+ * considered "newer".If the transaction numbers of the two blocks match, the
+ * timestamps are compared to determine the "newer" of the two.
+ */
+static int
+vdev_uberblock_compare(uberblock_t *ub1, uberblock_t *ub2)
+{
+grub_zfs_endian_t ub1_endian, ub2_endian;
+if (grub_zfs_to_cpu64(ub1-&amp;gt;ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC)
+ub1_endian = LITTLE_ENDIAN;
+else
+ub1_endian = BIG_ENDIAN;
+if (grub_zfs_to_cpu64(ub2-&amp;gt;ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC)
+ub2_endian = LITTLE_ENDIAN;
+else
+ub2_endian = BIG_ENDIAN;
+
+if (grub_zfs_to_cpu64(ub1-&amp;gt;ub_txg, ub1_endian)
+&amp;lt; grub_zfs_to_cpu64(ub2-&amp;gt;ub_txg, ub2_endian))
+return -1;
+if (grub_zfs_to_cpu64(ub1-&amp;gt;ub_txg, ub1_endian)
+&amp;gt; grub_zfs_to_cpu64(ub2-&amp;gt;ub_txg, ub2_endian))
+return 1;
+
+if (grub_zfs_to_cpu64(ub1-&amp;gt;ub_timestamp, ub1_endian)
+&amp;lt; grub_zfs_to_cpu64(ub2-&amp;gt;ub_timestamp, ub2_endian))
+return -1;
+if (grub_zfs_to_cpu64(ub1-&amp;gt;ub_timestamp, ub1_endian)
+&amp;gt; grub_zfs_to_cpu64(ub2-&amp;gt;ub_timestamp, ub2_endian))
+return 1;
+
+return 0;
+}
+
+/*
+ * Three pieces of information are needed to verify an uberblock: the magic
+ * number, the version number, and the checksum.
+ *
+ * Currently Implemented: version number, magic number, label txg
+ * Need to Implement: checksum
+ *
+ */
+static int
+uberblock_verify(uberblock_t *uber, int offset, struct grub_zfs_data *data)
+{
+int err;
+grub_zfs_endian_t endian = UNKNOWN_ENDIAN;
+zio_cksum_t zc;
+
+if (uber-&amp;gt;ub_txg &amp;lt; data-&amp;gt;label_txg) {
+debug("ignoring partially written label: uber_txg &amp;lt; label_txg %llu %llu\n",
+  uber-&amp;gt;ub_txg, data-&amp;gt;label_txg);
+return ZFS_ERR_BAD_FS;
+}
+
+if (grub_zfs_to_cpu64(uber-&amp;gt;ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC
+&amp;amp;&amp;amp; grub_zfs_to_cpu64(uber-&amp;gt;ub_version, LITTLE_ENDIAN) &amp;gt; 0
+&amp;amp;&amp;amp; grub_zfs_to_cpu64(uber-&amp;gt;ub_version, LITTLE_ENDIAN) &amp;lt;= SPA_VERSION)
+endian = LITTLE_ENDIAN;
+
+if (grub_zfs_to_cpu64(uber-&amp;gt;ub_magic, BIG_ENDIAN) == UBERBLOCK_MAGIC
+&amp;amp;&amp;amp; grub_zfs_to_cpu64(uber-&amp;gt;ub_version, BIG_ENDIAN) &amp;gt; 0
+&amp;amp;&amp;amp; grub_zfs_to_cpu64(uber-&amp;gt;ub_version, BIG_ENDIAN) &amp;lt;= SPA_VERSION)
+endian = BIG_ENDIAN;
+
+if (endian == UNKNOWN_ENDIAN) {
+printf("invalid uberblock magic\n");
+return ZFS_ERR_BAD_FS;
+}
+
+memset(&amp;amp;zc, 0, sizeof(zc));
+zc.zc_word[0] = grub_cpu_to_zfs64(offset, endian);
+err = zio_checksum_verify(zc, ZIO_CHECKSUM_LABEL, endian,
+  (char *) uber, UBERBLOCK_SIZE(data-&amp;gt;vdev_ashift));
+
+if (!err) {
+/* Check that the data pointed by the rootbp is usable. */
+void *osp = NULL;
+size_t ospsize;
+err = zio_read(&amp;amp;uber-&amp;gt;ub_rootbp, endian, &amp;amp;osp, &amp;amp;ospsize, data);
+free(osp);
+
+if (!err &amp;amp;&amp;amp; ospsize &amp;lt; OBJSET_PHYS_SIZE_V14) {
+printf("uberblock rootbp points to invalid data\n");
+return ZFS_ERR_BAD_FS;
+}
+}
+
+return err;
+}
+
+/*
+ * Find the best uberblock.
+ * Return:
+ *  Success - Pointer to the best uberblock.
+ *  Failure - NULL
+ */
+static uberblock_t *find_bestub(char *ub_array, struct grub_zfs_data *data)
+{
+const uint64_t sector = data-&amp;gt;vdev_phys_sector;
+uberblock_t *ubbest = NULL;
+uberblock_t *ubnext;
+unsigned int i, offset, pickedub = 0;
+int err = ZFS_ERR_NONE;
+
+const unsigned int UBCOUNT = UBERBLOCK_COUNT(data-&amp;gt;vdev_ashift);
+const uint64_t UBBYTES = UBERBLOCK_SIZE(data-&amp;gt;vdev_ashift);
+
+for (i = 0; i &amp;lt; UBCOUNT; i++) {
+ubnext = (uberblock_t *) (i * UBBYTES + ub_array);
+offset = (sector &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT) + VDEV_PHYS_SIZE + (i * UBBYTES);
+
+err = uberblock_verify(ubnext, offset, data);
+if (err)
+continue;
+
+if (ubbest == NULL || vdev_uberblock_compare(ubnext, ubbest) &amp;gt; 0) {
+ubbest = ubnext;
+pickedub = i;
+}
+}
+
+if (ubbest)
+debug("zfs Found best uberblock at idx %d, txg %llu\n",
+  pickedub, (unsigned long long) ubbest-&amp;gt;ub_txg);
+
+return ubbest;
+}
+
+static inline size_t
+get_psize(blkptr_t *bp, grub_zfs_endian_t endian)
+{
+return (((grub_zfs_to_cpu64((bp)-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 16) &amp;amp; 0xffff) + 1)
+&amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+}
+
+static uint64_t
+dva_get_offset(dva_t *dva, grub_zfs_endian_t endian)
+{
+return grub_zfs_to_cpu64((dva)-&amp;gt;dva_word[1],
+ endian) &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+}
+
+/*
+ * Read a block of data based on the gang block address dva,
+ * and put its data in buf.
+ *
+ */
+static int
+zio_read_gang(blkptr_t *bp, grub_zfs_endian_t endian, dva_t *dva, void *buf,
+  struct grub_zfs_data *data)
+{
+zio_gbh_phys_t *zio_gb;
+uint64_t offset, sector;
+unsigned i;
+int err;
+zio_cksum_t zc;
+
+memset(&amp;amp;zc, 0, sizeof(zc));
+
+zio_gb = malloc(SPA_GANGBLOCKSIZE);
+if (!zio_gb)
+return ZFS_ERR_OUT_OF_MEMORY;
+
+offset = dva_get_offset(dva, endian);
+sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
+
+/* read in the gang block header */
+err = zfs_devread(sector, 0, SPA_GANGBLOCKSIZE, (char *) zio_gb);
+
+if (err) {
+free(zio_gb);
+return err;
+}
+
+/* XXX */
+/* self checksuming the gang block header */
+ZIO_SET_CHECKSUM(&amp;amp;zc, DVA_GET_VDEV(dva),
+ dva_get_offset(dva, endian), bp-&amp;gt;blk_birth, 0);
+err = zio_checksum_verify(zc, ZIO_CHECKSUM_GANG_HEADER, endian,
+  (char *) zio_gb, SPA_GANGBLOCKSIZE);
+if (err) {
+free(zio_gb);
+return err;
+}
+
+endian = (grub_zfs_to_cpu64(bp-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 63) &amp;amp; 1;
+
+for (i = 0; i &amp;lt; SPA_GBH_NBLKPTRS; i++) {
+if (zio_gb-&amp;gt;zg_blkptr[i].blk_birth == 0)
+continue;
+
+err = zio_read_data(&amp;amp;zio_gb-&amp;gt;zg_blkptr[i], endian, buf, data);
+if (err) {
+free(zio_gb);
+return err;
+}
+buf = (char *) buf + get_psize(&amp;amp;zio_gb-&amp;gt;zg_blkptr[i], endian);
+}
+free(zio_gb);
+return ZFS_ERR_NONE;
+}
+
+/*
+ * Read in a block of raw data to buf.
+ */
+static int
+zio_read_data(blkptr_t *bp, grub_zfs_endian_t endian, void *buf,
+  struct grub_zfs_data *data)
+{
+int i, psize;
+int err = ZFS_ERR_NONE;
+
+psize = get_psize(bp, endian);
+
+/* pick a good dva from the block pointer */
+for (i = 0; i &amp;lt; SPA_DVAS_PER_BP; i++) {
+uint64_t offset, sector;
+
+if (bp-&amp;gt;blk_dva[i].dva_word[0] == 0 &amp;amp;&amp;amp; bp-&amp;gt;blk_dva[i].dva_word[1] == 0)
+continue;
+
+if ((grub_zfs_to_cpu64(bp-&amp;gt;blk_dva[i].dva_word[1], endian)&amp;gt;&amp;gt;63) &amp;amp; 1) {
+err = zio_read_gang(bp, endian, &amp;amp;bp-&amp;gt;blk_dva[i], buf, data);
+} else {
+/* read in a data block */
+offset = dva_get_offset(&amp;amp;bp-&amp;gt;blk_dva[i], endian);
+sector = DVA_OFFSET_TO_PHYS_SECTOR(offset);
+
+err = zfs_devread(sector, 0, psize, buf);
+}
+
+if (!err) {
+/*Check the underlying checksum before we rule this DVA as "good"*/
+uint32_t checkalgo = (grub_zfs_to_cpu64((bp)-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 40) &amp;amp; 0xff;
+
+err = zio_checksum_verify(bp-&amp;gt;blk_cksum, checkalgo, endian, buf, psize);
+if (!err)
+return ZFS_ERR_NONE;
+}
+
+/* If read failed or checksum bad, reset the error. Hopefully we've got some more DVA's to try.*/
+}
+
+if (!err) {
+printf("couldn't find a valid DVA\n");
+err = ZFS_ERR_BAD_FS;
+}
+
+return err;
+}
+
+/*
+ * Read in a block of data, verify its checksum, decompress if needed,
+ * and put the uncompressed data in buf.
+ */
+static int
+zio_read(blkptr_t *bp, grub_zfs_endian_t endian, void **buf,
+ size_t *size, struct grub_zfs_data *data)
+{
+size_t lsize, psize;
+unsigned int comp;
+char *compbuf = NULL;
+int err;
+
+*buf = NULL;
+
+comp = (grub_zfs_to_cpu64((bp)-&amp;gt;blk_prop, endian)&amp;gt;&amp;gt;32) &amp;amp; 0xff;
+lsize = (BP_IS_HOLE(bp) ? 0 :
+ (((grub_zfs_to_cpu64((bp)-&amp;gt;blk_prop, endian) &amp;amp; 0xffff) + 1)
+  &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT));
+psize = get_psize(bp, endian);
+
+if (size)
+*size = lsize;
+
+if (comp &amp;gt;= ZIO_COMPRESS_FUNCTIONS) {
+printf("compression algorithm %u not supported\n", (unsigned int) comp);
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+
+if (comp != ZIO_COMPRESS_OFF &amp;amp;&amp;amp; decomp_table[comp].decomp_func == NULL) {
+printf("compression algorithm %s not supported\n", decomp_table[comp].name);
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+
+if (comp != ZIO_COMPRESS_OFF) {
+compbuf = malloc(psize);
+if (!compbuf)
+return ZFS_ERR_OUT_OF_MEMORY;
+} else {
+compbuf = *buf = malloc(lsize);
+}
+
+err = zio_read_data(bp, endian, compbuf, data);
+if (err) {
+free(compbuf);
+*buf = NULL;
+return err;
+}
+
+if (comp != ZIO_COMPRESS_OFF) {
+*buf = malloc(lsize);
+if (!*buf) {
+free(compbuf);
+return ZFS_ERR_OUT_OF_MEMORY;
+}
+
+err = decomp_table[comp].decomp_func(compbuf, *buf, psize, lsize);
+free(compbuf);
+if (err) {
+free(*buf);
+*buf = NULL;
+return err;
+}
+}
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * Get the block from a block id.
+ * push the block onto the stack.
+ *
+ */
+static int
+dmu_read(dnode_end_t *dn, uint64_t blkid, void **buf,
+ grub_zfs_endian_t *endian_out, struct grub_zfs_data *data)
+{
+int idx, level;
+blkptr_t *bp_array = dn-&amp;gt;dn.dn_blkptr;
+int epbs = dn-&amp;gt;dn.dn_indblkshift - SPA_BLKPTRSHIFT;
+blkptr_t *bp;
+void *tmpbuf = 0;
+grub_zfs_endian_t endian;
+int err = ZFS_ERR_NONE;
+
+bp = malloc(sizeof(blkptr_t));
+if (!bp)
+return ZFS_ERR_OUT_OF_MEMORY;
+
+endian = dn-&amp;gt;endian;
+for (level = dn-&amp;gt;dn.dn_nlevels - 1; level &amp;gt;= 0; level--) {
+idx = (blkid &amp;gt;&amp;gt; (epbs * level)) &amp;amp; ((1 &amp;lt;&amp;lt; epbs) - 1);
+*bp = bp_array[idx];
+if (bp_array != dn-&amp;gt;dn.dn_blkptr) {
+free(bp_array);
+bp_array = 0;
+}
+
+if (BP_IS_HOLE(bp)) {
+size_t size = grub_zfs_to_cpu16(dn-&amp;gt;dn.dn_datablkszsec,
+dn-&amp;gt;endian)
+&amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+*buf = malloc(size);
+if (*buf) {
+err = ZFS_ERR_OUT_OF_MEMORY;
+break;
+}
+memset(*buf, 0, size);
+endian = (grub_zfs_to_cpu64(bp-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 63) &amp;amp; 1;
+break;
+}
+if (level == 0) {
+err = zio_read(bp, endian, buf, 0, data);
+endian = (grub_zfs_to_cpu64(bp-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 63) &amp;amp; 1;
+break;
+}
+err = zio_read(bp, endian, &amp;amp;tmpbuf, 0, data);
+endian = (grub_zfs_to_cpu64(bp-&amp;gt;blk_prop, endian) &amp;gt;&amp;gt; 63) &amp;amp; 1;
+if (err)
+break;
+bp_array = tmpbuf;
+}
+if (bp_array != dn-&amp;gt;dn.dn_blkptr)
+free(bp_array);
+if (endian_out)
+*endian_out = endian;
+
+free(bp);
+return err;
+}
+
+/*
+ * mzap_lookup: Looks up property described by "name" and returns the value
+ * in "value".
+ */
+static int
+mzap_lookup(mzap_phys_t *zapobj, grub_zfs_endian_t endian,
+int objsize, char *name, uint64_t * value)
+{
+int i, chunks;
+mzap_ent_phys_t *mzap_ent = zapobj-&amp;gt;mz_chunk;
+
+chunks = objsize / MZAP_ENT_LEN - 1;
+for (i = 0; i &amp;lt; chunks; i++) {
+if (strcmp(mzap_ent[i].mze_name, name) == 0) {
+*value = grub_zfs_to_cpu64(mzap_ent[i].mze_value, endian);
+return ZFS_ERR_NONE;
+}
+}
+
+printf("couldn't find '%s'\n", name);
+return ZFS_ERR_FILE_NOT_FOUND;
+}
+
+static int
+mzap_iterate(mzap_phys_t *zapobj, grub_zfs_endian_t endian, int objsize,
+ int (*hook)(const char *name,
+ uint64_t val,
+ struct grub_zfs_data *data),
+ struct grub_zfs_data *data)
+{
+int i, chunks;
+mzap_ent_phys_t *mzap_ent = zapobj-&amp;gt;mz_chunk;
+
+chunks = objsize / MZAP_ENT_LEN - 1;
+for (i = 0; i &amp;lt; chunks; i++) {
+if (hook(mzap_ent[i].mze_name,
+ grub_zfs_to_cpu64(mzap_ent[i].mze_value, endian),
+ data))
+return 1;
+}
+
+return 0;
+}
+
+static uint64_t
+zap_hash(uint64_t salt, const char *name)
+{
+static uint64_t table[256];
+const uint8_t *cp;
+uint8_t c;
+uint64_t crc = salt;
+
+if (table[128] == 0) {
+uint64_t *ct;
+int i, j;
+for (i = 0; i &amp;lt; 256; i++) {
+for (ct = table + i, *ct = i, j = 8; j &amp;gt; 0; j--)
+*ct = (*ct &amp;gt;&amp;gt; 1) ^ (-(*ct &amp;amp; 1) &amp;amp; ZFS_CRC64_POLY);
+}
+}
+
+for (cp = (const uint8_t *) name; (c = *cp) != '\0'; cp++)
+crc = (crc &amp;gt;&amp;gt; 8) ^ table[(crc ^ c) &amp;amp; 0xFF];
+
+/*
+ * Only use 28 bits, since we need 4 bits in the cookie for the
+ * collision differentiator.  We MUST use the high bits, since
+ * those are the onces that we first pay attention to when
+ * chosing the bucket.
+ */
+crc &amp;amp;= ~((1ULL &amp;lt;&amp;lt; (64 - ZAP_HASHBITS)) - 1);
+
+return crc;
+}
+
+/*
+ * Only to be used on 8-bit arrays.
+ * array_len is actual len in bytes (not encoded le_value_length).
+ * buf is null-terminated.
+ */
+/* XXX */
+static int
+zap_leaf_array_equal(zap_leaf_phys_t *l, grub_zfs_endian_t endian,
+ int blksft, int chunk, int array_len, const char *buf)
+{
+int bseen = 0;
+
+while (bseen &amp;lt; array_len) {
+struct zap_leaf_array *la = &amp;amp;ZAP_LEAF_CHUNK(l, blksft, chunk).l_array;
+int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
+
+if (chunk &amp;gt;= ZAP_LEAF_NUMCHUNKS(blksft))
+return 0;
+
+if (memcmp(la-&amp;gt;la_array, buf + bseen, toread) != 0)
+break;
+chunk = grub_zfs_to_cpu16(la-&amp;gt;la_next, endian);
+bseen += toread;
+}
+return (bseen == array_len);
+}
+
+/* XXX */
+static int
+zap_leaf_array_get(zap_leaf_phys_t *l, grub_zfs_endian_t endian, int blksft,
+   int chunk, int array_len, char *buf)
+{
+int bseen = 0;
+
+while (bseen &amp;lt; array_len) {
+struct zap_leaf_array *la = &amp;amp;ZAP_LEAF_CHUNK(l, blksft, chunk).l_array;
+int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
+
+if (chunk &amp;gt;= ZAP_LEAF_NUMCHUNKS(blksft))
+/* Don't use errno because this error is to be ignored.  */
+return ZFS_ERR_BAD_FS;
+
+memcpy(buf + bseen, la-&amp;gt;la_array,  toread);
+chunk = grub_zfs_to_cpu16(la-&amp;gt;la_next, endian);
+bseen += toread;
+}
+return ZFS_ERR_NONE;
+}
+
+
+/*
+ * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the
+ * value for the property "name".
+ *
+ */
+/* XXX */
+static int
+zap_leaf_lookup(zap_leaf_phys_t *l, grub_zfs_endian_t endian,
+int blksft, uint64_t h,
+const char *name, uint64_t *value)
+{
+uint16_t chunk;
+struct zap_leaf_entry *le;
+
+/* Verify if this is a valid leaf block */
+if (grub_zfs_to_cpu64(l-&amp;gt;l_hdr.lh_block_type, endian) != ZBT_LEAF) {
+printf("invalid leaf type\n");
+return ZFS_ERR_BAD_FS;
+}
+if (grub_zfs_to_cpu32(l-&amp;gt;l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) {
+printf("invalid leaf magic\n");
+return ZFS_ERR_BAD_FS;
+}
+
+for (chunk = grub_zfs_to_cpu16(l-&amp;gt;l_hash[LEAF_HASH(blksft, h)], endian);
+ chunk != CHAIN_END; chunk = le-&amp;gt;le_next) {
+
+if (chunk &amp;gt;= ZAP_LEAF_NUMCHUNKS(blksft)) {
+printf("invalid chunk number\n");
+return ZFS_ERR_BAD_FS;
+}
+
+le = ZAP_LEAF_ENTRY(l, blksft, chunk);
+
+/* Verify the chunk entry */
+if (le-&amp;gt;le_type != ZAP_CHUNK_ENTRY) {
+printf("invalid chunk entry\n");
+return ZFS_ERR_BAD_FS;
+}
+
+if (grub_zfs_to_cpu64(le-&amp;gt;le_hash, endian) != h)
+continue;
+
+if (zap_leaf_array_equal(l, endian, blksft,
+ grub_zfs_to_cpu16(le-&amp;gt;le_name_chunk, endian),
+ grub_zfs_to_cpu16(le-&amp;gt;le_name_length, endian),
+ name)) {
+struct zap_leaf_array *la;
+
+if (le-&amp;gt;le_int_size != 8 || le-&amp;gt;le_value_length != 1) {
+printf("invalid leaf chunk entry\n");
+return ZFS_ERR_BAD_FS;
+}
+/* get the uint64_t property value */
+la = &amp;amp;ZAP_LEAF_CHUNK(l, blksft, le-&amp;gt;le_value_chunk).l_array;
+
+*value = grub_be_to_cpu64(la-&amp;gt;la_array64);
+
+return ZFS_ERR_NONE;
+}
+}
+
+printf("couldn't find '%s'\n", name);
+return ZFS_ERR_FILE_NOT_FOUND;
+}
+
+
+/* Verify if this is a fat zap header block */
+static int
+zap_verify(zap_phys_t *zap)
+{
+if (zap-&amp;gt;zap_magic != (uint64_t) ZAP_MAGIC) {
+printf("bad ZAP magic\n");
+return ZFS_ERR_BAD_FS;
+}
+
+if (zap-&amp;gt;zap_flags != 0) {
+printf("bad ZAP flags\n");
+return ZFS_ERR_BAD_FS;
+}
+
+if (zap-&amp;gt;zap_salt == 0) {
+printf("bad ZAP salt\n");
+return ZFS_ERR_BAD_FS;
+}
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * Fat ZAP lookup
+ *
+ */
+/* XXX */
+static int
+fzap_lookup(dnode_end_t *zap_dnode, zap_phys_t *zap,
+char *name, uint64_t *value, struct grub_zfs_data *data)
+{
+void *l;
+uint64_t hash, idx, blkid;
+int blksft = zfs_log2(grub_zfs_to_cpu16(zap_dnode-&amp;gt;dn.dn_datablkszsec,
+zap_dnode-&amp;gt;endian) &amp;lt;&amp;lt; DNODE_SHIFT);
+int err;
+grub_zfs_endian_t leafendian;
+
+err = zap_verify(zap);
+if (err)
+return err;
+
+hash = zap_hash(zap-&amp;gt;zap_salt, name);
+
+/* get block id from index */
+if (zap-&amp;gt;zap_ptrtbl.zt_numblks != 0) {
+printf("external pointer tables not supported\n");
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+idx = ZAP_HASH_IDX(hash, zap-&amp;gt;zap_ptrtbl.zt_shift);
+blkid = ((uint64_t *) zap)[idx + (1 &amp;lt;&amp;lt; (blksft - 3 - 1))];
+
+/* Get the leaf block */
+if ((1U &amp;lt;&amp;lt; blksft) &amp;lt; sizeof(zap_leaf_phys_t)) {
+printf("ZAP leaf is too small\n");
+return ZFS_ERR_BAD_FS;
+}
+err = dmu_read(zap_dnode, blkid, &amp;amp;l, &amp;amp;leafendian, data);
+if (err)
+return err;
+
+err = zap_leaf_lookup(l, leafendian, blksft, hash, name, value);
+free(l);
+return err;
+}
+
+/* XXX */
+static int
+fzap_iterate(dnode_end_t *zap_dnode, zap_phys_t *zap,
+ int (*hook)(const char *name,
+ uint64_t val,
+ struct grub_zfs_data *data),
+ struct grub_zfs_data *data)
+{
+zap_leaf_phys_t *l;
+void *l_in;
+uint64_t idx, blkid;
+uint16_t chunk;
+int blksft = zfs_log2(grub_zfs_to_cpu16(zap_dnode-&amp;gt;dn.dn_datablkszsec,
+zap_dnode-&amp;gt;endian) &amp;lt;&amp;lt; DNODE_SHIFT);
+int err;
+grub_zfs_endian_t endian;
+
+if (zap_verify(zap))
+return 0;
+
+/* get block id from index */
+if (zap-&amp;gt;zap_ptrtbl.zt_numblks != 0) {
+printf("external pointer tables not supported\n");
+return 0;
+}
+/* Get the leaf block */
+if ((1U &amp;lt;&amp;lt; blksft) &amp;lt; sizeof(zap_leaf_phys_t)) {
+printf("ZAP leaf is too small\n");
+return 0;
+}
+for (idx = 0; idx &amp;lt; zap-&amp;gt;zap_ptrtbl.zt_numblks; idx++) {
+blkid = ((uint64_t *) zap)[idx + (1 &amp;lt;&amp;lt; (blksft - 3 - 1))];
+
+err = dmu_read(zap_dnode, blkid, &amp;amp;l_in, &amp;amp;endian, data);
+l = l_in;
+if (err)
+continue;
+
+/* Verify if this is a valid leaf block */
+if (grub_zfs_to_cpu64(l-&amp;gt;l_hdr.lh_block_type, endian) != ZBT_LEAF) {
+free(l);
+continue;
+}
+if (grub_zfs_to_cpu32(l-&amp;gt;l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) {
+free(l);
+continue;
+}
+
+for (chunk = 0; chunk &amp;lt; ZAP_LEAF_NUMCHUNKS(blksft); chunk++) {
+char *buf;
+struct zap_leaf_array *la;
+struct zap_leaf_entry *le;
+uint64_t val;
+le = ZAP_LEAF_ENTRY(l, blksft, chunk);
+
+/* Verify the chunk entry */
+if (le-&amp;gt;le_type != ZAP_CHUNK_ENTRY)
+continue;
+
+buf = malloc(grub_zfs_to_cpu16(le-&amp;gt;le_name_length, endian)
+ + 1);
+if (zap_leaf_array_get(l, endian, blksft, le-&amp;gt;le_name_chunk,
+   le-&amp;gt;le_name_length, buf)) {
+free(buf);
+continue;
+}
+buf[le-&amp;gt;le_name_length] = 0;
+
+if (le-&amp;gt;le_int_size != 8
+|| grub_zfs_to_cpu16(le-&amp;gt;le_value_length, endian) != 1)
+continue;
+
+/* get the uint64_t property value */
+la = &amp;amp;ZAP_LEAF_CHUNK(l, blksft, le-&amp;gt;le_value_chunk).l_array;
+val = grub_be_to_cpu64(la-&amp;gt;la_array64);
+if (hook(buf, val, data))
+return 1;
+free(buf);
+}
+}
+return 0;
+}
+
+
+/*
+ * Read in the data of a zap object and find the value for a matching
+ * property name.
+ *
+ */
+static int
+zap_lookup(dnode_end_t *zap_dnode, char *name, uint64_t *val,
+   struct grub_zfs_data *data)
+{
+uint64_t block_type;
+int size;
+void *zapbuf;
+int err;
+grub_zfs_endian_t endian;
+
+/* Read in the first block of the zap object data. */
+size = grub_zfs_to_cpu16(zap_dnode-&amp;gt;dn.dn_datablkszsec,
+ zap_dnode-&amp;gt;endian) &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+err = dmu_read(zap_dnode, 0, &amp;amp;zapbuf, &amp;amp;endian, data);
+if (err)
+return err;
+block_type = grub_zfs_to_cpu64(*((uint64_t *) zapbuf), endian);
+
+if (block_type == ZBT_MICRO) {
+err = (mzap_lookup(zapbuf, endian, size, name, val));
+free(zapbuf);
+return err;
+} else if (block_type == ZBT_HEADER) {
+/* this is a fat zap */
+err = (fzap_lookup(zap_dnode, zapbuf, name, val, data));
+free(zapbuf);
+return err;
+}
+
+printf("unknown ZAP type\n");
+return ZFS_ERR_BAD_FS;
+}
+
+static int
+zap_iterate(dnode_end_t *zap_dnode,
+int (*hook)(const char *name, uint64_t val,
+struct grub_zfs_data *data),
+struct grub_zfs_data *data)
+{
+uint64_t block_type;
+int size;
+void *zapbuf;
+int err;
+int ret;
+grub_zfs_endian_t endian;
+
+/* Read in the first block of the zap object data. */
+size = grub_zfs_to_cpu16(zap_dnode-&amp;gt;dn.dn_datablkszsec, zap_dnode-&amp;gt;endian) &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+err = dmu_read(zap_dnode, 0, &amp;amp;zapbuf, &amp;amp;endian, data);
+if (err)
+return 0;
+block_type = grub_zfs_to_cpu64(*((uint64_t *) zapbuf), endian);
+
+if (block_type == ZBT_MICRO) {
+ret = mzap_iterate(zapbuf, endian, size, hook, data);
+free(zapbuf);
+return ret;
+} else if (block_type == ZBT_HEADER) {
+/* this is a fat zap */
+ret = fzap_iterate(zap_dnode, zapbuf, hook, data);
+free(zapbuf);
+return ret;
+}
+printf("unknown ZAP type\n");
+return 0;
+}
+
+
+/*
+ * Get the dnode of an object number from the metadnode of an object set.
+ *
+ * Input
+ *mdn - metadnode to get the object dnode
+ *objnum - object number for the object dnode
+ *buf - data buffer that holds the returning dnode
+ */
+static int
+dnode_get(dnode_end_t *mdn, uint64_t objnum, uint8_t type,
+  dnode_end_t *buf, struct grub_zfs_data *data)
+{
+uint64_t blkid, blksz;/* the block id this object dnode is in */
+int epbs;/* shift of number of dnodes in a block */
+int idx;/* index within a block */
+void *dnbuf;
+int err;
+grub_zfs_endian_t endian;
+
+blksz = grub_zfs_to_cpu16(mdn-&amp;gt;dn.dn_datablkszsec,
+  mdn-&amp;gt;endian) &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+
+epbs = zfs_log2(blksz) - DNODE_SHIFT;
+blkid = objnum &amp;gt;&amp;gt; epbs;
+idx = objnum &amp;amp; ((1 &amp;lt;&amp;lt; epbs) - 1);
+
+if (data-&amp;gt;dnode_buf != NULL &amp;amp;&amp;amp; memcmp(data-&amp;gt;dnode_mdn, mdn,
+  sizeof(*mdn)) == 0
+&amp;amp;&amp;amp; objnum &amp;gt;= data-&amp;gt;dnode_start &amp;amp;&amp;amp; objnum &amp;lt; data-&amp;gt;dnode_end) {
+memmove(&amp;amp;(buf-&amp;gt;dn), &amp;amp;(data-&amp;gt;dnode_buf)[idx], DNODE_SIZE);
+buf-&amp;gt;endian = data-&amp;gt;dnode_endian;
+if (type &amp;amp;&amp;amp; buf-&amp;gt;dn.dn_type != type)  {
+printf("incorrect dnode type: %02X != %02x\n", buf-&amp;gt;dn.dn_type, type);
+return ZFS_ERR_BAD_FS;
+}
+return ZFS_ERR_NONE;
+}
+
+err = dmu_read(mdn, blkid, &amp;amp;dnbuf, &amp;amp;endian, data);
+if (err)
+return err;
+
+free(data-&amp;gt;dnode_buf);
+free(data-&amp;gt;dnode_mdn);
+data-&amp;gt;dnode_mdn = malloc(sizeof(*mdn));
+if (!data-&amp;gt;dnode_mdn) {
+data-&amp;gt;dnode_buf = 0;
+} else {
+memcpy(data-&amp;gt;dnode_mdn, mdn, sizeof(*mdn));
+data-&amp;gt;dnode_buf = dnbuf;
+data-&amp;gt;dnode_start = blkid &amp;lt;&amp;lt; epbs;
+data-&amp;gt;dnode_end = (blkid + 1) &amp;lt;&amp;lt; epbs;
+data-&amp;gt;dnode_endian = endian;
+}
+
+memmove(&amp;amp;(buf-&amp;gt;dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
+buf-&amp;gt;endian = endian;
+if (type &amp;amp;&amp;amp; buf-&amp;gt;dn.dn_type != type) {
+printf("incorrect dnode type\n");
+return ZFS_ERR_BAD_FS;
+}
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * Get the file dnode for a given file name where mdn is the meta dnode
+ * for this ZFS object set. When found, place the file dnode in dn.
+ * The 'path' argument will be mangled.
+ *
+ */
+static int
+dnode_get_path(dnode_end_t *mdn, const char *path_in, dnode_end_t *dn,
+   struct grub_zfs_data *data)
+{
+uint64_t objnum, version;
+char *cname, ch;
+int err = ZFS_ERR_NONE;
+char *path, *path_buf;
+struct dnode_chain {
+struct dnode_chain *next;
+dnode_end_t dn;
+};
+struct dnode_chain *dnode_path = 0, *dn_new, *root;
+
+dn_new = malloc(sizeof(*dn_new));
+if (!dn_new)
+return ZFS_ERR_OUT_OF_MEMORY;
+dn_new-&amp;gt;next = 0;
+dnode_path = root = dn_new;
+
+err = dnode_get(mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
+&amp;amp;(dnode_path-&amp;gt;dn), data);
+if (err) {
+free(dn_new);
+return err;
+}
+
+err = zap_lookup(&amp;amp;(dnode_path-&amp;gt;dn), ZPL_VERSION_STR, &amp;amp;version, data);
+if (err) {
+free(dn_new);
+return err;
+}
+if (version &amp;gt; ZPL_VERSION) {
+free(dn_new);
+printf("too new ZPL version\n");
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+
+err = zap_lookup(&amp;amp;(dnode_path-&amp;gt;dn), ZFS_ROOT_OBJ, &amp;amp;objnum, data);
+if (err) {
+free(dn_new);
+return err;
+}
+
+err = dnode_get(mdn, objnum, 0, &amp;amp;(dnode_path-&amp;gt;dn), data);
+if (err) {
+free(dn_new);
+return err;
+}
+
+path = path_buf = strdup(path_in);
+if (!path_buf) {
+free(dn_new);
+return ZFS_ERR_OUT_OF_MEMORY;
+}
+
+while (1) {
+/* skip leading slashes */
+while (*path == '/')
+path++;
+if (!*path)
+break;
+/* get the next component name */
+cname = path;
+while (*path &amp;amp;&amp;amp; *path != '/')
+path++;
+/* Skip dot.  */
+if (cname + 1 == path &amp;amp;&amp;amp; cname[0] == '.')
+continue;
+/* Handle double dot.  */
+if (cname + 2 == path &amp;amp;&amp;amp; cname[0] == '.' &amp;amp;&amp;amp; cname[1] == '.')  {
+if (dn_new-&amp;gt;next) {
+dn_new = dnode_path;
+dnode_path = dn_new-&amp;gt;next;
+free(dn_new);
+} else {
+printf("can't resolve ..\n");
+err = ZFS_ERR_FILE_NOT_FOUND;
+break;
+}
+continue;
+}
+
+ch = *path;
+*path = 0;/* ensure null termination */
+
+if (dnode_path-&amp;gt;dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) {
+free(path_buf);
+printf("not a directory\n");
+return ZFS_ERR_BAD_FILE_TYPE;
+}
+err = zap_lookup(&amp;amp;(dnode_path-&amp;gt;dn), cname, &amp;amp;objnum, data);
+if (err)
+break;
+
+dn_new = malloc(sizeof(*dn_new));
+if (!dn_new) {
+err = ZFS_ERR_OUT_OF_MEMORY;
+break;
+}
+dn_new-&amp;gt;next = dnode_path;
+dnode_path = dn_new;
+
+objnum = ZFS_DIRENT_OBJ(objnum);
+err = dnode_get(mdn, objnum, 0, &amp;amp;(dnode_path-&amp;gt;dn), data);
+if (err)
+break;
+
+*path = ch;
+}
+
+if (!err)
+memcpy(dn, &amp;amp;(dnode_path-&amp;gt;dn), sizeof(*dn));
+
+while (dnode_path) {
+dn_new = dnode_path-&amp;gt;next;
+free(dnode_path);
+dnode_path = dn_new;
+}
+free(path_buf);
+return err;
+}
+
+
+/*
+ * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname),
+ * e.g. pool/rootfs, or a given object number (obj), e.g. the object number
+ * of pool/rootfs.
+ *
+ * If no fsname and no obj are given, return the DSL_DIR metadnode.
+ * If fsname is given, return its metadnode and its matching object number.
+ * If only obj is given, return the metadnode for this object number.
+ *
+ */
+static int
+get_filesystem_dnode(dnode_end_t *mosmdn, char *fsname,
+ dnode_end_t *mdn, struct grub_zfs_data *data)
+{
+uint64_t objnum;
+int err;
+
+err = dnode_get(mosmdn, DMU_POOL_DIRECTORY_OBJECT,
+DMU_OT_OBJECT_DIRECTORY, mdn, data);
+if (err)
+return err;
+
+err = zap_lookup(mdn, DMU_POOL_ROOT_DATASET, &amp;amp;objnum, data);
+if (err)
+return err;
+
+err = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
+if (err)
+return err;
+
+while (*fsname) {
+uint64_t childobj;
+char *cname, ch;
+
+while (*fsname == '/')
+fsname++;
+
+if (!*fsname || *fsname == '&amp;lt; at &amp;gt;')
+break;
+
+cname = fsname;
+while (*fsname &amp;amp;&amp;amp; !isspace(*fsname) &amp;amp;&amp;amp; *fsname != '/')
+fsname++;
+ch = *fsname;
+*fsname = 0;
+
+childobj = grub_zfs_to_cpu64((((dsl_dir_phys_t *) DN_BONUS(&amp;amp;mdn-&amp;gt;dn)))-&amp;gt;dd_child_dir_zapobj, mdn-&amp;gt;endian);
+err = dnode_get(mosmdn, childobj,
+DMU_OT_DSL_DIR_CHILD_MAP, mdn, data);
+if (err)
+return err;
+
+err = zap_lookup(mdn, cname, &amp;amp;objnum, data);
+if (err)
+return err;
+
+err = dnode_get(mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data);
+if (err)
+return err;
+
+*fsname = ch;
+}
+return ZFS_ERR_NONE;
+}
+
+static int
+make_mdn(dnode_end_t *mdn, struct grub_zfs_data *data)
+{
+void *osp;
+blkptr_t *bp;
+size_t ospsize;
+int err;
+
+bp = &amp;amp;(((dsl_dataset_phys_t *) DN_BONUS(&amp;amp;mdn-&amp;gt;dn))-&amp;gt;ds_bp);
+err = zio_read(bp, mdn-&amp;gt;endian, &amp;amp;osp, &amp;amp;ospsize, data);
+if (err)
+return err;
+if (ospsize &amp;lt; OBJSET_PHYS_SIZE_V14) {
+free(osp);
+printf("too small osp\n");
+return ZFS_ERR_BAD_FS;
+}
+
+mdn-&amp;gt;endian = (grub_zfs_to_cpu64(bp-&amp;gt;blk_prop, mdn-&amp;gt;endian)&amp;gt;&amp;gt;63) &amp;amp; 1;
+memmove((char *) &amp;amp;(mdn-&amp;gt;dn),
+(char *) &amp;amp;((objset_phys_t *) osp)-&amp;gt;os_meta_dnode, DNODE_SIZE);
+free(osp);
+return ZFS_ERR_NONE;
+}
+
+static int
+dnode_get_fullpath(const char *fullpath, dnode_end_t *mdn,
+   uint64_t *mdnobj, dnode_end_t *dn, int *isfs,
+   struct grub_zfs_data *data)
+{
+char *fsname, *snapname;
+const char *ptr_at, *filename;
+uint64_t headobj;
+int err;
+
+ptr_at = strchr(fullpath, '&amp;lt; at &amp;gt;');
+if (!ptr_at) {
+*isfs = 1;
+filename = 0;
+snapname = 0;
+fsname = strdup(fullpath);
+} else {
+const char *ptr_slash = strchr(ptr_at, '/');
+
+*isfs = 0;
+fsname = malloc(ptr_at - fullpath + 1);
+if (!fsname)
+return ZFS_ERR_OUT_OF_MEMORY;
+memcpy(fsname, fullpath, ptr_at - fullpath);
+fsname[ptr_at - fullpath] = 0;
+if (ptr_at[1] &amp;amp;&amp;amp; ptr_at[1] != '/') {
+snapname = malloc(ptr_slash - ptr_at);
+if (!snapname) {
+free(fsname);
+return ZFS_ERR_OUT_OF_MEMORY;
+}
+memcpy(snapname, ptr_at + 1, ptr_slash - ptr_at - 1);
+snapname[ptr_slash - ptr_at - 1] = 0;
+} else {
+snapname = 0;
+}
+if (ptr_slash)
+filename = ptr_slash;
+else
+filename = "/";
+printf("zfs fsname = '%s' snapname='%s' filename = '%s'\n",
+   fsname, snapname, filename);
+}
+
+
+err = get_filesystem_dnode(&amp;amp;(data-&amp;gt;mos), fsname, dn, data);
+
+if (err) {
+free(fsname);
+free(snapname);
+return err;
+}
+
+headobj = grub_zfs_to_cpu64(((dsl_dir_phys_t *) DN_BONUS(&amp;amp;dn-&amp;gt;dn))-&amp;gt;dd_head_dataset_obj, dn-&amp;gt;endian);
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), headobj, DMU_OT_DSL_DATASET, mdn, data);
+if (err) {
+free(fsname);
+free(snapname);
+return err;
+}
+
+if (snapname) {
+uint64_t snapobj;
+
+snapobj = grub_zfs_to_cpu64(((dsl_dataset_phys_t *) DN_BONUS(&amp;amp;mdn-&amp;gt;dn))-&amp;gt;ds_snapnames_zapobj, mdn-&amp;gt;endian);
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), snapobj,
+DMU_OT_DSL_DS_SNAP_MAP, mdn, data);
+if (!err)
+err = zap_lookup(mdn, snapname, &amp;amp;headobj, data);
+if (!err)
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), headobj, DMU_OT_DSL_DATASET, mdn, data);
+if (err) {
+free(fsname);
+free(snapname);
+return err;
+}
+}
+
+if (mdnobj)
+*mdnobj = headobj;
+
+make_mdn(mdn, data);
+
+if (*isfs) {
+free(fsname);
+free(snapname);
+return ZFS_ERR_NONE;
+}
+err = dnode_get_path(mdn, filename, dn, data);
+free(fsname);
+free(snapname);
+return err;
+}
+
+/*
+ * For a given XDR packed nvlist, verify the first 4 bytes and move on.
+ *
+ * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) :
+ *
+ *encoding method/host endian(4 bytes)
+ *nvl_version(4 bytes)
+ *nvl_nvflag(4 bytes)
+ *encoded nvpairs:
+ *encoded size of the nvpair(4 bytes)
+ *decoded size of the nvpair(4 bytes)
+ *name string size(4 bytes)
+ *name string data(sizeof(NV_ALIGN4(string))
+ *data type(4 bytes)
+ *# of elements in the nvpair(4 bytes)
+ *data
+ *2 zero's for the last nvpair
+ *(end of the entire list)(8 bytes)
+ *
+ */
+
+static int
+nvlist_find_value(char *nvlist, char *name, int valtype, char **val,
+  size_t *size_out, size_t *nelm_out)
+{
+int name_len, type, encode_size;
+char *nvpair, *nvp_name;
+
+/* Verify if the 1st and 2nd byte in the nvlist are valid. */
+/* NOTE: independently of what endianness header announces all
+   subsequent values are big-endian.  */
+if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN
+   &amp;amp;&amp;amp; nvlist[1] != NV_BIG_ENDIAN)) {
+printf("zfs incorrect nvlist header\n");
+return ZFS_ERR_BAD_FS;
+}
+
+/* skip the header, nvl_version, and nvl_nvflag */
+nvlist = nvlist + 4 * 3;
+/*
+ * Loop thru the nvpair list
+ * The XDR representation of an integer is in big-endian byte order.
+ */
+while ((encode_size = grub_be_to_cpu32(*(uint32_t *) nvlist))) {
+int nelm;
+
+nvpair = nvlist + 4 * 2;/* skip the encode/decode size */
+
+name_len = grub_be_to_cpu32(*(uint32_t *) nvpair);
+nvpair += 4;
+
+nvp_name = nvpair;
+nvpair = nvpair + ((name_len + 3) &amp;amp; ~3);/* align */
+
+type = grub_be_to_cpu32(*(uint32_t *) nvpair);
+nvpair += 4;
+
+nelm = grub_be_to_cpu32(*(uint32_t *) nvpair);
+if (nelm &amp;lt; 1) {
+printf("empty nvpair\n");
+return ZFS_ERR_BAD_FS;
+}
+
+nvpair += 4;
+
+if ((strncmp(nvp_name, name, name_len) == 0) &amp;amp;&amp;amp; type == valtype) {
+*val = nvpair;
+*size_out = encode_size;
+if (nelm_out)
+*nelm_out = nelm;
+return 1;
+}
+
+nvlist += encode_size;/* goto the next nvpair */
+}
+return 0;
+}
+
+int
+grub_zfs_nvlist_lookup_uint64(char *nvlist, char *name, uint64_t *out)
+{
+char *nvpair;
+size_t size;
+int found;
+
+found = nvlist_find_value(nvlist, name, DATA_TYPE_UINT64, &amp;amp;nvpair, &amp;amp;size, 0);
+if (!found)
+return 0;
+if (size &amp;lt; sizeof(uint64_t)) {
+printf("invalid uint64\n");
+return ZFS_ERR_BAD_FS;
+}
+
+*out = grub_be_to_cpu64(*(uint64_t *) nvpair);
+return 1;
+}
+
+char *
+grub_zfs_nvlist_lookup_string(char *nvlist, char *name)
+{
+char *nvpair;
+char *ret;
+size_t slen;
+size_t size;
+int found;
+
+found = nvlist_find_value(nvlist, name, DATA_TYPE_STRING, &amp;amp;nvpair, &amp;amp;size, 0);
+if (!found)
+return 0;
+if (size &amp;lt; 4) {
+printf("invalid string\n");
+return 0;
+}
+slen = grub_be_to_cpu32(*(uint32_t *) nvpair);
+if (slen &amp;gt; size - 4)
+slen = size - 4;
+ret = malloc(slen + 1);
+if (!ret)
+return 0;
+memcpy(ret, nvpair + 4, slen);
+ret[slen] = 0;
+return ret;
+}
+
+char *
+grub_zfs_nvlist_lookup_nvlist(char *nvlist, char *name)
+{
+char *nvpair;
+char *ret;
+size_t size;
+int found;
+
+found = nvlist_find_value(nvlist, name, DATA_TYPE_NVLIST, &amp;amp;nvpair,
+  &amp;amp;size, 0);
+if (!found)
+return 0;
+ret = calloc(1, size + 3 * sizeof(uint32_t));
+if (!ret)
+return 0;
+memcpy(ret, nvlist, sizeof(uint32_t));
+
+memcpy(ret + sizeof(uint32_t), nvpair, size);
+return ret;
+}
+
+int
+grub_zfs_nvlist_lookup_nvlist_array_get_nelm(char *nvlist, char *name)
+{
+char *nvpair;
+size_t nelm, size;
+int found;
+
+found = nvlist_find_value(nvlist, name, DATA_TYPE_NVLIST, &amp;amp;nvpair,
+  &amp;amp;size, &amp;amp;nelm);
+if (!found)
+return -1;
+return nelm;
+}
+
+char *
+grub_zfs_nvlist_lookup_nvlist_array(char *nvlist, char *name,
+size_t index)
+{
+char *nvpair, *nvpairptr;
+int found;
+char *ret;
+size_t size;
+unsigned i;
+size_t nelm;
+
+found = nvlist_find_value(nvlist, name, DATA_TYPE_NVLIST, &amp;amp;nvpair,
+  &amp;amp;size, &amp;amp;nelm);
+if (!found)
+return 0;
+if (index &amp;gt;= nelm) {
+printf("trying to lookup past nvlist array\n");
+return 0;
+}
+
+nvpairptr = nvpair;
+
+for (i = 0; i &amp;lt; index; i++) {
+uint32_t encode_size;
+
+/* skip the header, nvl_version, and nvl_nvflag */
+nvpairptr = nvpairptr + 4 * 2;
+
+while (nvpairptr &amp;lt; nvpair + size
+   &amp;amp;&amp;amp; (encode_size = grub_be_to_cpu32(*(uint32_t *) nvpairptr)))
+nvlist += encode_size;/* goto the next nvpair */
+
+nvlist = nvlist + 4 * 2;/* skip the ending 2 zeros - 8 bytes */
+}
+
+if (nvpairptr &amp;gt;= nvpair + size
+|| nvpairptr + grub_be_to_cpu32(*(uint32_t *) (nvpairptr + 4 * 2))
+&amp;gt;= nvpair + size) {
+printf("incorrect nvlist array\n");
+return 0;
+}
+
+ret = calloc(1, grub_be_to_cpu32(*(uint32_t *) (nvpairptr + 4 * 2))
+ + 3 * sizeof(uint32_t));
+if (!ret)
+return 0;
+memcpy(ret, nvlist, sizeof(uint32_t));
+
+memcpy(ret + sizeof(uint32_t), nvpairptr, size);
+return ret;
+}
+
+static int
+zfs_fetch_nvlist(struct grub_zfs_data *data, char **nvlist)
+{
+int err;
+
+*nvlist = malloc(VDEV_PHYS_SIZE);
+/* Read in the vdev name-value pair list (112K). */
+err = zfs_devread(data-&amp;gt;vdev_phys_sector, 0, VDEV_PHYS_SIZE, *nvlist);
+if (err) {
+free(*nvlist);
+*nvlist = 0;
+return err;
+}
+return ZFS_ERR_NONE;
+}
+
+/*
+ * Check the disk label information and retrieve needed vdev name-value pairs.
+ *
+ */
+static int
+check_pool_label(struct grub_zfs_data *data)
+{
+uint64_t pool_state;
+char *nvlist;/* for the pool */
+char *vdevnvlist;/* for the vdev */
+uint64_t diskguid;
+uint64_t version;
+int found;
+int err;
+
+err = zfs_fetch_nvlist(data, &amp;amp;nvlist);
+if (err)
+return err;
+
+found = grub_zfs_nvlist_lookup_uint64(nvlist, ZPOOL_CONFIG_POOL_STATE,
+  &amp;amp;pool_state);
+if (!found) {
+free(nvlist);
+printf("zfs pool state not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+if (pool_state == POOL_STATE_DESTROYED) {
+free(nvlist);
+printf("zpool is marked as destroyed\n");
+return ZFS_ERR_BAD_FS;
+}
+
+data-&amp;gt;label_txg = 0;
+found = grub_zfs_nvlist_lookup_uint64(nvlist, ZPOOL_CONFIG_POOL_TXG,
+  &amp;amp;data-&amp;gt;label_txg);
+if (!found) {
+free(nvlist);
+printf("zfs pool txg not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+/* not an active device */
+if (data-&amp;gt;label_txg == 0) {
+free(nvlist);
+printf("zpool is not active\n");
+return ZFS_ERR_BAD_FS;
+}
+
+found = grub_zfs_nvlist_lookup_uint64(nvlist, ZPOOL_CONFIG_VERSION,
+  &amp;amp;version);
+if (!found) {
+free(nvlist);
+printf("zpool config version not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+if (version &amp;gt; SPA_VERSION) {
+free(nvlist);
+printf("SPA version too new %llu &amp;gt; %llu\n",
+   (unsigned long long) version,
+   (unsigned long long) SPA_VERSION);
+return ZFS_ERR_NOT_IMPLEMENTED_YET;
+}
+
+vdevnvlist = grub_zfs_nvlist_lookup_nvlist(nvlist, ZPOOL_CONFIG_VDEV_TREE);
+if (!vdevnvlist) {
+free(nvlist);
+printf("ZFS config vdev tree not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+found = grub_zfs_nvlist_lookup_uint64(vdevnvlist, ZPOOL_CONFIG_ASHIFT,
+  &amp;amp;data-&amp;gt;vdev_ashift);
+free(vdevnvlist);
+if (!found) {
+free(nvlist);
+printf("ZPOOL config ashift not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+found = grub_zfs_nvlist_lookup_uint64(nvlist, ZPOOL_CONFIG_GUID, &amp;amp;diskguid);
+if (!found) {
+free(nvlist);
+printf("ZPOOL config guid not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+found = grub_zfs_nvlist_lookup_uint64(nvlist, ZPOOL_CONFIG_POOL_GUID, &amp;amp;data-&amp;gt;pool_guid);
+if (!found) {
+free(nvlist);
+printf("ZPOOL config pool guid not found\n");
+return ZFS_ERR_BAD_FS;
+}
+
+free(nvlist);
+
+printf("ZFS Pool GUID: %llu (%016llx) Label: GUID: %llu (%016llx), txg: %llu, SPA v%llu, ashift: %llu\n",
+   (unsigned long long) data-&amp;gt;pool_guid,
+   (unsigned long long) data-&amp;gt;pool_guid,
+   (unsigned long long) diskguid,
+   (unsigned long long) diskguid,
+   (unsigned long long) data-&amp;gt;label_txg,
+   (unsigned long long) version,
+   (unsigned long long) data-&amp;gt;vdev_ashift);
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * vdev_label_start returns the physical disk offset (in bytes) of
+ * label "l".
+ */
+static uint64_t vdev_label_start(uint64_t psize, int l)
+{
+return (l * sizeof(vdev_label_t) + (l &amp;lt; VDEV_LABELS / 2 ?
+0 : psize -
+VDEV_LABELS * sizeof(vdev_label_t)));
+}
+
+void
+zfs_unmount(struct grub_zfs_data *data)
+{
+free(data-&amp;gt;dnode_buf);
+free(data-&amp;gt;dnode_mdn);
+free(data-&amp;gt;file_buf);
+free(data);
+}
+
+/*
+ * zfs_mount() locates a valid uberblock of the root pool and read in its MOS
+ * to the memory address MOS.
+ *
+ */
+struct grub_zfs_data *
+zfs_mount(device_t dev)
+{
+struct grub_zfs_data *data = 0;
+int label = 0, bestlabel = -1;
+char *ub_array;
+uberblock_t *ubbest;
+uberblock_t *ubcur = NULL;
+void *osp = 0;
+size_t ospsize;
+int err;
+
+data = malloc(sizeof(*data));
+if (!data)
+return 0;
+memset(data, 0, sizeof(*data));
+
+ub_array = malloc(VDEV_UBERBLOCK_RING);
+if (!ub_array) {
+zfs_unmount(data);
+return 0;
+}
+
+ubbest = malloc(sizeof(*ubbest));
+if (!ubbest) {
+zfs_unmount(data);
+return 0;
+}
+memset(ubbest, 0, sizeof(*ubbest));
+
+/*
+ * some eltorito stacks don't give us a size and
+ * we end up setting the size to MAXUINT, further
+ * some of these devices stop working once a single
+ * read past the end has been issued. Checking
+ * for a maximum part_length and skipping the backup
+ * labels at the end of the slice/partition/device
+ * avoids breaking down on such devices.
+ */
+const int vdevnum =
+dev-&amp;gt;part_length == 0 ?
+VDEV_LABELS / 2 : VDEV_LABELS;
+
+/* Size in bytes of the device (disk or partition) aligned to label size*/
+uint64_t device_size =
+dev-&amp;gt;part_length &amp;lt;&amp;lt; SECTOR_BITS;
+
+const uint64_t alignedbytes =
+P2ALIGN(device_size, (uint64_t) sizeof(vdev_label_t));
+
+for (label = 0; label &amp;lt; vdevnum; label++) {
+uint64_t labelstartbytes = vdev_label_start(alignedbytes, label);
+uint64_t labelstart = labelstartbytes &amp;gt;&amp;gt; SECTOR_BITS;
+
+debug("zfs reading label %d at sector %llu (byte %llu)\n",
+  label, (unsigned long long) labelstart,
+  (unsigned long long) labelstartbytes);
+
+data-&amp;gt;vdev_phys_sector = labelstart +
+((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) &amp;gt;&amp;gt; SECTOR_BITS);
+
+err = check_pool_label(data);
+if (err) {
+printf("zfs error checking label %d\n", label);
+continue;
+}
+
+/* Read in the uberblock ring (128K). */
+err = zfs_devread(data-&amp;gt;vdev_phys_sector  +
+  (VDEV_PHYS_SIZE &amp;gt;&amp;gt; SECTOR_BITS),
+  0, VDEV_UBERBLOCK_RING, ub_array);
+if (err) {
+printf("zfs error reading uberblock ring for label %d\n", label);
+continue;
+}
+
+ubcur = find_bestub(ub_array, data);
+if (!ubcur) {
+printf("zfs No good uberblocks found in label %d\n", label);
+continue;
+}
+
+if (vdev_uberblock_compare(ubcur, ubbest) &amp;gt; 0) {
+/* Looks like the block is good, so use it.*/
+memcpy(ubbest, ubcur, sizeof(*ubbest));
+bestlabel = label;
+debug("zfs Current best uberblock found in label %d\n", label);
+}
+}
+free(ub_array);
+
+/* We zero'd the structure to begin with.  If we never assigned to it,
+   magic will still be zero. */
+if (!ubbest-&amp;gt;ub_magic) {
+printf("couldn't find a valid ZFS label\n");
+zfs_unmount(data);
+free(ubbest);
+return 0;
+}
+
+debug("zfs ubbest %p in label %d\n", ubbest, bestlabel);
+
+grub_zfs_endian_t ub_endian =
+grub_zfs_to_cpu64(ubbest-&amp;gt;ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC
+? LITTLE_ENDIAN : BIG_ENDIAN;
+
+debug("zfs endian set to %s\n", !ub_endian ? "big" : "little");
+
+err = zio_read(&amp;amp;ubbest-&amp;gt;ub_rootbp, ub_endian, &amp;amp;osp, &amp;amp;ospsize, data);
+
+if (err) {
+printf("couldn't zio_read object directory\n");
+zfs_unmount(data);
+free(ubbest);
+return 0;
+}
+
+if (ospsize &amp;lt; OBJSET_PHYS_SIZE_V14) {
+printf("osp too small\n");
+zfs_unmount(data);
+free(osp);
+free(ubbest);
+return 0;
+}
+
+/* Got the MOS. Save it at the memory addr MOS. */
+memmove(&amp;amp;(data-&amp;gt;mos.dn), &amp;amp;((objset_phys_t *) osp)-&amp;gt;os_meta_dnode, DNODE_SIZE);
+data-&amp;gt;mos.endian =
+(grub_zfs_to_cpu64(ubbest-&amp;gt;ub_rootbp.blk_prop, ub_endian) &amp;gt;&amp;gt; 63) &amp;amp; 1;
+memmove(&amp;amp;(data-&amp;gt;current_uberblock), ubbest, sizeof(uberblock_t));
+
+free(osp);
+free(ubbest);
+
+return data;
+}
+
+int
+grub_zfs_fetch_nvlist(device_t dev, char **nvlist)
+{
+struct grub_zfs_data *zfs;
+int err;
+
+zfs = zfs_mount(dev);
+if (!zfs)
+return ZFS_ERR_BAD_FS;
+err = zfs_fetch_nvlist(zfs, nvlist);
+zfs_unmount(zfs);
+return err;
+}
+
+static int
+zfs_label(device_t device, char **label)
+{
+char *nvlist;
+int err;
+struct grub_zfs_data *data;
+
+data = zfs_mount(device);
+if (!data)
+return ZFS_ERR_BAD_FS;
+
+err = zfs_fetch_nvlist(data, &amp;amp;nvlist);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+
+*label = grub_zfs_nvlist_lookup_string(nvlist, ZPOOL_CONFIG_POOL_NAME);
+free(nvlist);
+zfs_unmount(data);
+return ZFS_ERR_NONE;
+}
+
+static int
+zfs_uuid(device_t device, char **uuid)
+{
+struct grub_zfs_data *data;
+
+data = zfs_mount(device);
+if (!data)
+return ZFS_ERR_BAD_FS;
+
+*uuid = malloc(17); /* %016llx + nil */
+if (!*uuid)
+return ZFS_ERR_OUT_OF_MEMORY;
+
+/* *uuid = xasprintf ("%016llx", (long long unsigned) data-&amp;gt;pool_guid);*/
+snprintf(*uuid, 17, "%016llx", (long long unsigned) data-&amp;gt;pool_guid);
+zfs_unmount(data);
+
+return ZFS_ERR_NONE;
+}
+
+/*
+ * zfs_open() locates a file in the rootpool by following the
+ * MOS and places the dnode of the file in the memory address DNODE.
+ */
+int
+zfs_open(struct zfs_file *file, const char *fsfilename)
+{
+struct grub_zfs_data *data;
+int err;
+int isfs;
+
+data = zfs_mount(file-&amp;gt;device);
+if (!data)
+return ZFS_ERR_BAD_FS;
+
+err = dnode_get_fullpath(fsfilename, &amp;amp;(data-&amp;gt;mdn), 0,
+ &amp;amp;(data-&amp;gt;dnode), &amp;amp;isfs, data);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+
+if (isfs) {
+zfs_unmount(data);
+printf("Missing &amp;lt; at &amp;gt; or / separator\n");
+return ZFS_ERR_FILE_NOT_FOUND;
+}
+
+/* We found the dnode for this file. Verify if it is a plain file. */
+if (data-&amp;gt;dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS) {
+zfs_unmount(data);
+printf("not a file\n");
+return ZFS_ERR_BAD_FILE_TYPE;
+}
+
+/* get the file size and set the file position to 0 */
+
+/*
+ * For DMU_OT_SA we will need to locate the SIZE attribute
+ * attribute, which could be either in the bonus buffer
+ * or the "spill" block.
+ */
+if (data-&amp;gt;dnode.dn.dn_bonustype == DMU_OT_SA) {
+void *sahdrp;
+int hdrsize;
+
+if (data-&amp;gt;dnode.dn.dn_bonuslen != 0) {
+sahdrp = (sa_hdr_phys_t *) DN_BONUS(&amp;amp;data-&amp;gt;dnode.dn);
+} else if (data-&amp;gt;dnode.dn.dn_flags &amp;amp; DNODE_FLAG_SPILL_BLKPTR) {
+blkptr_t *bp = &amp;amp;data-&amp;gt;dnode.dn.dn_spill;
+
+err = zio_read(bp, data-&amp;gt;dnode.endian, &amp;amp;sahdrp, NULL, data);
+if (err)
+return err;
+} else {
+printf("filesystem is corrupt :(\n");
+return ZFS_ERR_BAD_FS;
+}
+
+hdrsize = SA_HDR_SIZE(((sa_hdr_phys_t *) sahdrp));
+file-&amp;gt;size = *(uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET);
+} else {
+file-&amp;gt;size = grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS(&amp;amp;data-&amp;gt;dnode.dn))-&amp;gt;zp_size, data-&amp;gt;dnode.endian);
+}
+
+file-&amp;gt;data = data;
+file-&amp;gt;offset = 0;
+
+return ZFS_ERR_NONE;
+}
+
+uint64_t
+zfs_read(zfs_file_t file, char *buf, uint64_t len)
+{
+struct grub_zfs_data *data = (struct grub_zfs_data *) file-&amp;gt;data;
+int blksz, movesize;
+uint64_t length;
+int64_t red;
+int err;
+
+if (data-&amp;gt;file_buf == NULL) {
+data-&amp;gt;file_buf = malloc(SPA_MAXBLOCKSIZE);
+if (!data-&amp;gt;file_buf)
+return -1;
+data-&amp;gt;file_start = data-&amp;gt;file_end = 0;
+}
+
+/*
+ * If offset is in memory, move it into the buffer provided and return.
+ */
+if (file-&amp;gt;offset &amp;gt;= data-&amp;gt;file_start
+&amp;amp;&amp;amp; file-&amp;gt;offset + len &amp;lt;= data-&amp;gt;file_end) {
+memmove(buf, data-&amp;gt;file_buf + file-&amp;gt;offset - data-&amp;gt;file_start,
+len);
+return len;
+}
+
+blksz = grub_zfs_to_cpu16(data-&amp;gt;dnode.dn.dn_datablkszsec,
+  data-&amp;gt;dnode.endian) &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT;
+
+/*
+ * Entire Dnode is too big to fit into the space available. We
+ * will need to read it in chunks.This could be optimized to
+ * read in as large a chunk as there is space available, but for
+ * now, this only reads in one data block at a time.
+ */
+length = len;
+red = 0;
+while (length) {
+void *t;
+/*
+ * Find requested blkid and the offset within that block.
+ */
+uint64_t blkid = (file-&amp;gt;offset + red) / blksz;
+free(data-&amp;gt;file_buf);
+data-&amp;gt;file_buf = 0;
+
+err = dmu_read(&amp;amp;(data-&amp;gt;dnode), blkid, &amp;amp;t,
+   0, data);
+data-&amp;gt;file_buf = t;
+if (err)
+return -1;
+
+data-&amp;gt;file_start = blkid * blksz;
+data-&amp;gt;file_end = data-&amp;gt;file_start + blksz;
+
+movesize = MIN(length, data-&amp;gt;file_end - (int) file-&amp;gt;offset - red);
+
+memmove(buf, data-&amp;gt;file_buf + file-&amp;gt;offset + red
+- data-&amp;gt;file_start, movesize);
+buf += movesize;
+length -= movesize;
+red += movesize;
+}
+
+return len;
+}
+
+int
+zfs_close(zfs_file_t file)
+{
+zfs_unmount((struct grub_zfs_data *) file-&amp;gt;data);
+return ZFS_ERR_NONE;
+}
+
+int
+grub_zfs_getmdnobj(device_t dev, const char *fsfilename,
+   uint64_t *mdnobj)
+{
+struct grub_zfs_data *data;
+int err;
+int isfs;
+
+data = zfs_mount(dev);
+if (!data)
+return ZFS_ERR_BAD_FS;
+
+err = dnode_get_fullpath(fsfilename, &amp;amp;(data-&amp;gt;mdn), mdnobj,
+ &amp;amp;(data-&amp;gt;dnode), &amp;amp;isfs, data);
+zfs_unmount(data);
+return err;
+}
+
+static void
+fill_fs_info(struct zfs_dirhook_info *info,
+ dnode_end_t mdn, struct grub_zfs_data *data)
+{
+int err;
+dnode_end_t dn;
+uint64_t objnum;
+uint64_t headobj;
+
+memset(info, 0, sizeof(*info));
+
+info-&amp;gt;dir = 1;
+
+if (mdn.dn.dn_type == DMU_OT_DSL_DIR) {
+headobj = grub_zfs_to_cpu64(((dsl_dir_phys_t *) DN_BONUS(&amp;amp;mdn.dn))-&amp;gt;dd_head_dataset_obj, mdn.endian);
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), headobj, DMU_OT_DSL_DATASET, &amp;amp;mdn, data);
+if (err) {
+printf("zfs failed here 1\n");
+return;
+}
+}
+make_mdn(&amp;amp;mdn, data);
+err = dnode_get(&amp;amp;mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE,
+&amp;amp;dn, data);
+if (err) {
+printf("zfs failed here 2\n");
+return;
+}
+
+err = zap_lookup(&amp;amp;dn, ZFS_ROOT_OBJ, &amp;amp;objnum, data);
+if (err) {
+printf("zfs failed here 3\n");
+return;
+}
+
+err = dnode_get(&amp;amp;mdn, objnum, 0, &amp;amp;dn, data);
+if (err) {
+printf("zfs failed here 4\n");
+return;
+}
+
+info-&amp;gt;mtimeset = 1;
+info-&amp;gt;mtime = grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS(&amp;amp;dn.dn))-&amp;gt;zp_mtime[0], dn.endian);
+
+return;
+}
+
+static int iterate_zap(const char *name, uint64_t val, struct grub_zfs_data *data)
+{
+struct zfs_dirhook_info info;
+dnode_end_t dn;
+
+memset(&amp;amp;info, 0, sizeof(info));
+
+dnode_get(&amp;amp;(data-&amp;gt;mdn), val, 0, &amp;amp;dn, data);
+info.mtimeset = 1;
+info.mtime = grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS(&amp;amp;dn.dn))-&amp;gt;zp_mtime[0], dn.endian);
+info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS);
+debug("zfs type=%d, name=%s\n",
+  (int)dn.dn.dn_type, (char *)name);
+if (!data-&amp;gt;userhook)
+return 0;
+return data-&amp;gt;userhook(name, &amp;amp;info);
+}
+
+static int iterate_zap_fs(const char *name, uint64_t val, struct grub_zfs_data *data)
+{
+struct zfs_dirhook_info info;
+dnode_end_t mdn;
+int err;
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), val, 0, &amp;amp;mdn, data);
+if (err)
+return 0;
+if (mdn.dn.dn_type != DMU_OT_DSL_DIR)
+return 0;
+
+fill_fs_info(&amp;amp;info, mdn, data);
+
+if (!data-&amp;gt;userhook)
+return 0;
+return data-&amp;gt;userhook(name, &amp;amp;info);
+}
+
+static int iterate_zap_snap(const char *name, uint64_t val, struct grub_zfs_data *data)
+{
+struct zfs_dirhook_info info;
+char *name2;
+int ret = 0;
+dnode_end_t mdn;
+int err;
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), val, 0, &amp;amp;mdn, data);
+if (err)
+return 0;
+
+if (mdn.dn.dn_type != DMU_OT_DSL_DATASET)
+return 0;
+
+fill_fs_info(&amp;amp;info, mdn, data);
+
+name2 = malloc(strlen(name) + 2);
+name2[0] = '&amp;lt; at &amp;gt;';
+memcpy(name2 + 1, name, strlen(name) + 1);
+if (data-&amp;gt;userhook)
+ret = data-&amp;gt;userhook(name2, &amp;amp;info);
+free(name2);
+return ret;
+}
+
+int
+zfs_ls(device_t device, const char *path,
+   int (*hook)(const char *, const struct zfs_dirhook_info *))
+{
+struct grub_zfs_data *data;
+int err;
+int isfs;
+#if 0
+char *label = NULL;
+
+zfs_label(device, &amp;amp;label);
+if (label)
+printf("ZPOOL label '%s'\n",
+   label);
+#endif
+
+data = zfs_mount(device);
+if (!data)
+return ZFS_ERR_BAD_FS;
+
+data-&amp;gt;userhook = hook;
+
+err = dnode_get_fullpath(path, &amp;amp;(data-&amp;gt;mdn), 0, &amp;amp;(data-&amp;gt;dnode), &amp;amp;isfs, data);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+if (isfs) {
+uint64_t childobj, headobj;
+uint64_t snapobj;
+dnode_end_t dn;
+struct zfs_dirhook_info info;
+
+fill_fs_info(&amp;amp;info, data-&amp;gt;dnode, data);
+hook("&amp;lt; at &amp;gt;", &amp;amp;info);
+
+childobj = grub_zfs_to_cpu64(((dsl_dir_phys_t *) DN_BONUS(&amp;amp;data-&amp;gt;dnode.dn))-&amp;gt;dd_child_dir_zapobj, data-&amp;gt;dnode.endian);
+headobj = grub_zfs_to_cpu64(((dsl_dir_phys_t *) DN_BONUS(&amp;amp;data-&amp;gt;dnode.dn))-&amp;gt;dd_head_dataset_obj, data-&amp;gt;dnode.endian);
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), childobj,
+DMU_OT_DSL_DIR_CHILD_MAP, &amp;amp;dn, data);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+
+
+zap_iterate(&amp;amp;dn, iterate_zap_fs, data);
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), headobj, DMU_OT_DSL_DATASET, &amp;amp;dn, data);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+
+snapobj = grub_zfs_to_cpu64(((dsl_dataset_phys_t *) DN_BONUS(&amp;amp;dn.dn))-&amp;gt;ds_snapnames_zapobj, dn.endian);
+
+err = dnode_get(&amp;amp;(data-&amp;gt;mos), snapobj,
+DMU_OT_DSL_DS_SNAP_MAP, &amp;amp;dn, data);
+if (err) {
+zfs_unmount(data);
+return err;
+}
+
+zap_iterate(&amp;amp;dn, iterate_zap_snap, data);
+} else {
+if (data-&amp;gt;dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) {
+zfs_unmount(data);
+printf("not a directory\n");
+return ZFS_ERR_BAD_FILE_TYPE;
+}
+zap_iterate(&amp;amp;(data-&amp;gt;dnode), iterate_zap, data);
+}
+zfs_unmount(data);
+return ZFS_ERR_NONE;
+}
+
diff --git a/fs/zfs/zfs_fletcher.c b/fs/zfs/zfs_fletcher.c
new file mode 100644
index 0000000..d96c6ff
--- /dev/null
+++ b/fs/zfs/zfs_fletcher.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,84 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004,2009
+ *Free Software Foundation, Inc.
+ *Copyright 2007 Sun Microsystems, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;malloc.h&amp;gt;
+#include &amp;lt;linux/stat.h&amp;gt;
+#include &amp;lt;linux/time.h&amp;gt;
+#include &amp;lt;linux/ctype.h&amp;gt;
+#include &amp;lt;asm/byteorder.h&amp;gt;
+#include "zfs_common.h"
+
+#include &amp;lt;zfs/zfs.h&amp;gt;
+#include &amp;lt;zfs/zio.h&amp;gt;
+#include &amp;lt;zfs/dnode.h&amp;gt;
+#include &amp;lt;zfs/uberblock_impl.h&amp;gt;
+#include &amp;lt;zfs/vdev_impl.h&amp;gt;
+#include &amp;lt;zfs/zio_checksum.h&amp;gt;
+#include &amp;lt;zfs/zap_impl.h&amp;gt;
+#include &amp;lt;zfs/zap_leaf.h&amp;gt;
+#include &amp;lt;zfs/zfs_znode.h&amp;gt;
+#include &amp;lt;zfs/dmu.h&amp;gt;
+#include &amp;lt;zfs/dmu_objset.h&amp;gt;
+#include &amp;lt;zfs/dsl_dir.h&amp;gt;
+#include &amp;lt;zfs/dsl_dataset.h&amp;gt;
+
+void
+fletcher_2(const void *buf, uint64_t size, grub_zfs_endian_t endian,
+   zio_cksum_t *zcp)
+{
+const uint64_t *ip = buf;
+const uint64_t *ipend = ip + (size / sizeof(uint64_t));
+uint64_t a0, b0, a1, b1;
+
+for (a0 = b0 = a1 = b1 = 0; ip &amp;lt; ipend; ip += 2) {
+a0 += grub_zfs_to_cpu64(ip[0], endian);
+a1 += grub_zfs_to_cpu64(ip[1], endian);
+b0 += a0;
+b1 += a1;
+}
+
+zcp-&amp;gt;zc_word[0] = grub_cpu_to_zfs64(a0, endian);
+zcp-&amp;gt;zc_word[1] = grub_cpu_to_zfs64(a1, endian);
+zcp-&amp;gt;zc_word[2] = grub_cpu_to_zfs64(b0, endian);
+zcp-&amp;gt;zc_word[3] = grub_cpu_to_zfs64(b1, endian);
+}
+
+void
+fletcher_4(const void *buf, uint64_t size, grub_zfs_endian_t endian,
+   zio_cksum_t *zcp)
+{
+const uint32_t *ip = buf;
+const uint32_t *ipend = ip + (size / sizeof(uint32_t));
+uint64_t a, b, c, d;
+
+for (a = b = c = d = 0; ip &amp;lt; ipend; ip++) {
+a += grub_zfs_to_cpu32(ip[0], endian);
+b += a;
+c += b;
+d += c;
+}
+
+zcp-&amp;gt;zc_word[0] = grub_cpu_to_zfs64(a, endian);
+zcp-&amp;gt;zc_word[1] = grub_cpu_to_zfs64(b, endian);
+zcp-&amp;gt;zc_word[2] = grub_cpu_to_zfs64(c, endian);
+zcp-&amp;gt;zc_word[3] = grub_cpu_to_zfs64(d, endian);
+}
+
diff --git a/fs/zfs/zfs_lzjb.c b/fs/zfs/zfs_lzjb.c
new file mode 100644
index 0000000..33e9b90
--- /dev/null
+++ b/fs/zfs/zfs_lzjb.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,94 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004,2009
+ *Free Software Foundation, Inc.
+ *Copyright 2007 Sun Microsystems, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;malloc.h&amp;gt;
+#include &amp;lt;linux/stat.h&amp;gt;
+#include &amp;lt;linux/time.h&amp;gt;
+#include &amp;lt;linux/ctype.h&amp;gt;
+#include &amp;lt;asm/byteorder.h&amp;gt;
+#include "zfs_common.h"
+
+#include &amp;lt;zfs/zfs.h&amp;gt;
+#include &amp;lt;zfs/zio.h&amp;gt;
+#include &amp;lt;zfs/dnode.h&amp;gt;
+#include &amp;lt;zfs/uberblock_impl.h&amp;gt;
+#include &amp;lt;zfs/vdev_impl.h&amp;gt;
+#include &amp;lt;zfs/zio_checksum.h&amp;gt;
+#include &amp;lt;zfs/zap_impl.h&amp;gt;
+#include &amp;lt;zfs/zap_leaf.h&amp;gt;
+#include &amp;lt;zfs/zfs_znode.h&amp;gt;
+#include &amp;lt;zfs/dmu.h&amp;gt;
+#include &amp;lt;zfs/dmu_objset.h&amp;gt;
+#include &amp;lt;zfs/dsl_dir.h&amp;gt;
+#include &amp;lt;zfs/dsl_dataset.h&amp;gt;
+
+#defineMATCH_BITS6
+#defineMATCH_MIN3
+#defineOFFSET_MASK((1 &amp;lt;&amp;lt; (16 - MATCH_BITS)) - 1)
+
+/*
+ * Decompression Entry - lzjb
+ */
+#ifndefNBBY
+#defineNBBY8
+#endif
+
+int
+lzjb_decompress(void *s_start, void *d_start, uint32_t s_len,
+uint32_t d_len)
+{
+uint8_t *src = s_start;
+uint8_t *dst = d_start;
+uint8_t *d_end = (uint8_t *) d_start + d_len;
+uint8_t *s_end = (uint8_t *) s_start + s_len;
+uint8_t *cpy, copymap = 0;
+int copymask = 1 &amp;lt;&amp;lt; (NBBY - 1);
+
+while (dst &amp;lt; d_end &amp;amp;&amp;amp; src &amp;lt; s_end) {
+if ((copymask &amp;lt;&amp;lt;= 1) == (1 &amp;lt;&amp;lt; NBBY)) {
+copymask = 1;
+copymap = *src++;
+}
+if (src &amp;gt;= s_end) {
+printf("lzjb decompression failed\n");
+return ZFS_ERR_BAD_FS;
+}
+if (copymap &amp;amp; copymask) {
+int mlen = (src[0] &amp;gt;&amp;gt; (NBBY - MATCH_BITS)) + MATCH_MIN;
+int offset = ((src[0] &amp;lt;&amp;lt; NBBY) | src[1]) &amp;amp; OFFSET_MASK;
+src += 2;
+cpy = dst - offset;
+if (src &amp;gt; s_end || cpy &amp;lt; (uint8_t *) d_start) {
+printf("lzjb decompression failed\n");
+return ZFS_ERR_BAD_FS;
+}
+while (--mlen &amp;gt;= 0 &amp;amp;&amp;amp; dst &amp;lt; d_end)
+*dst++ = *cpy++;
+} else {
+*dst++ = *src++;
+}
+}
+if (dst &amp;lt; d_end) {
+printf("lzjb decompression failed\n");
+return ZFS_ERR_BAD_FS;
+}
+return ZFS_ERR_NONE;
+}
diff --git a/fs/zfs/zfs_sha256.c b/fs/zfs/zfs_sha256.c
new file mode 100644
index 0000000..7a9439a
--- /dev/null
+++ b/fs/zfs/zfs_sha256.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,145 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004,2009
+ *Free Software Foundation, Inc.
+ *Copyright 2007 Sun Microsystems, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;malloc.h&amp;gt;
+#include &amp;lt;linux/stat.h&amp;gt;
+#include &amp;lt;linux/time.h&amp;gt;
+#include &amp;lt;linux/ctype.h&amp;gt;
+#include &amp;lt;asm/byteorder.h&amp;gt;
+#include "zfs_common.h"
+
+#include &amp;lt;zfs/zfs.h&amp;gt;
+#include &amp;lt;zfs/zio.h&amp;gt;
+#include &amp;lt;zfs/dnode.h&amp;gt;
+#include &amp;lt;zfs/uberblock_impl.h&amp;gt;
+#include &amp;lt;zfs/vdev_impl.h&amp;gt;
+#include &amp;lt;zfs/zio_checksum.h&amp;gt;
+#include &amp;lt;zfs/zap_impl.h&amp;gt;
+#include &amp;lt;zfs/zap_leaf.h&amp;gt;
+#include &amp;lt;zfs/zfs_znode.h&amp;gt;
+#include &amp;lt;zfs/dmu.h&amp;gt;
+#include &amp;lt;zfs/dmu_objset.h&amp;gt;
+#include &amp;lt;zfs/dsl_dir.h&amp;gt;
+#include &amp;lt;zfs/dsl_dataset.h&amp;gt;
+
+/*
+ * SHA-256 checksum, as specified in FIPS 180-2, available at:
+ * http://csrc.nist.gov/cryptval
+ *
+ * This is a very compact implementation of SHA-256.
+ * It is designed to be simple and portable, not to be fast.
+ */
+
+/*
+ * The literal definitions according to FIPS180-2 would be:
+ *
+ *Ch(x, y, z)(((x) &amp;amp; (y)) ^ ((~(x)) &amp;amp; (z)))
+ *Maj(x, y, z)(((x) &amp;amp; (y)) | ((x) &amp;amp; (z)) | ((y) &amp;amp; (z)))
+ *
+ * We use logical equivalents which require one less op.
+ */
+#defineCh(x, y, z)((z) ^ ((x) &amp;amp; ((y) ^ (z))))
+#defineMaj(x, y, z)(((x) &amp;amp; (y)) ^ ((z) &amp;amp; ((x) ^ (y))))
+#defineRot32(x, s)(((x) &amp;gt;&amp;gt; s) | ((x) &amp;lt;&amp;lt; (32 - s)))
+#defineSIGMA0(x)(Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22))
+#defineSIGMA1(x)(Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25))
+#definesigma0(x)(Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) &amp;gt;&amp;gt; 3))
+#definesigma1(x)(Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) &amp;gt;&amp;gt; 10))
+
+static const uint32_t SHA256_K[64] = {
+0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static void
+SHA256Transform(uint32_t *H, const uint8_t *cp)
+{
+uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
+
+for (t = 0; t &amp;lt; 16; t++, cp += 4)
+W[t] = (cp[0] &amp;lt;&amp;lt; 24) | (cp[1] &amp;lt;&amp;lt; 16) | (cp[2] &amp;lt;&amp;lt; 8) | cp[3];
+
+for (t = 16; t &amp;lt; 64; t++)
+W[t] = sigma1(W[t - 2]) + W[t - 7] +
+sigma0(W[t - 15]) + W[t - 16];
+
+a = H[0]; b = H[1]; c = H[2]; d = H[3];
+e = H[4]; f = H[5]; g = H[6]; h = H[7];
+
+for (t = 0; t &amp;lt; 64; t++) {
+T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
+T2 = SIGMA0(a) + Maj(a, b, c);
+h = g; g = f; f = e; e = d + T1;
+d = c; c = b; b = a; a = T1 + T2;
+}
+
+H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+}
+
+void
+zio_checksum_SHA256(const void *buf, uint64_t size,
+grub_zfs_endian_t endian, zio_cksum_t *zcp)
+{
+uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
+uint8_t pad[128];
+unsigned padsize = size &amp;amp; 63;
+unsigned i;
+
+for (i = 0; i &amp;lt; size - padsize; i += 64)
+SHA256Transform(H, (uint8_t *)buf + i);
+
+for (i = 0; i &amp;lt; padsize; i++)
+pad[i] = ((uint8_t *)buf)[i];
+
+for (pad[padsize++] = 0x80; (padsize &amp;amp; 63) != 56; padsize++)
+pad[padsize] = 0;
+
+for (i = 0; i &amp;lt; 8; i++)
+pad[padsize++] = (size &amp;lt;&amp;lt; 3) &amp;gt;&amp;gt; (56 - 8 * i);
+
+for (i = 0; i &amp;lt; padsize; i += 64)
+SHA256Transform(H, pad + i);
+
+zcp-&amp;gt;zc_word[0] = grub_cpu_to_zfs64((uint64_t)H[0] &amp;lt;&amp;lt; 32 | H[1],
+endian);
+zcp-&amp;gt;zc_word[1] = grub_cpu_to_zfs64((uint64_t)H[2] &amp;lt;&amp;lt; 32 | H[3],
+endian);
+zcp-&amp;gt;zc_word[2] = grub_cpu_to_zfs64((uint64_t)H[4] &amp;lt;&amp;lt; 32 | H[5],
+endian);
+zcp-&amp;gt;zc_word[3] = grub_cpu_to_zfs64((uint64_t)H[6] &amp;lt;&amp;lt; 32 | H[7],
+endian);
+}
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 55f4f7a..5933ae9 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,6 +36,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define CONFIG_CMD_ELF/* ELF (VxWorks) load/boot cmd*/
 #define CONFIG_CMD_EXT2/* EXT2 Support*/
 #define CONFIG_CMD_FAT/* FAT support*/
+#define CONFIG_CMD_ZFS/* ZFS support*/
 #define CONFIG_CMD_FDC/* Floppy Disk Support*/
 #define CONFIG_CMD_FDOS/* Floppy DOS support*/
 #define CONFIG_CMD_FLASH/* flinfo, erase, protect*/
diff --git a/include/zfs/dmu.h b/include/zfs/dmu.h
new file mode 100644
index 0000000..bee317e
--- /dev/null
+++ b/include/zfs/dmu.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,119 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_DMU_H
+#define_SYS_DMU_H
+
+/*
+ * This file describes the interface that the DMU provides for its
+ * consumers.
+ *
+ * The DMU also interacts with the SPA.  That interface is described in
+ * dmu_spa.h.
+ */
+typedef enum dmu_object_type {
+DMU_OT_NONE,
+/* general: */
+DMU_OT_OBJECT_DIRECTORY,/* ZAP */
+DMU_OT_OBJECT_ARRAY,/* UINT64 */
+DMU_OT_PACKED_NVLIST,/* UINT8 (XDR by nvlist_pack/unpack) */
+DMU_OT_PACKED_NVLIST_SIZE,/* UINT64 */
+DMU_OT_BPLIST,/* UINT64 */
+DMU_OT_BPLIST_HDR,/* UINT64 */
+/* spa: */
+DMU_OT_SPACE_MAP_HEADER,/* UINT64 */
+DMU_OT_SPACE_MAP,/* UINT64 */
+/* zil: */
+DMU_OT_INTENT_LOG,/* UINT64 */
+/* dmu: */
+DMU_OT_DNODE,/* DNODE */
+DMU_OT_OBJSET,/* OBJSET */
+/* dsl: */
+DMU_OT_DSL_DIR,/* UINT64 */
+DMU_OT_DSL_DIR_CHILD_MAP,/* ZAP */
+DMU_OT_DSL_DS_SNAP_MAP,/* ZAP */
+DMU_OT_DSL_PROPS,/* ZAP */
+DMU_OT_DSL_DATASET,/* UINT64 */
+/* zpl: */
+DMU_OT_ZNODE,/* ZNODE */
+DMU_OT_OLDACL,/* OLD ACL */
+DMU_OT_PLAIN_FILE_CONTENTS,/* UINT8 */
+DMU_OT_DIRECTORY_CONTENTS,/* ZAP */
+DMU_OT_MASTER_NODE,/* ZAP */
+DMU_OT_UNLINKED_SET,/* ZAP */
+/* zvol: */
+DMU_OT_ZVOL,/* UINT8 */
+DMU_OT_ZVOL_PROP,/* ZAP */
+/* other; for testing only! */
+DMU_OT_PLAIN_OTHER,/* UINT8 */
+DMU_OT_UINT64_OTHER,/* UINT64 */
+DMU_OT_ZAP_OTHER,/* ZAP */
+/* new object types: */
+DMU_OT_ERROR_LOG,/* ZAP */
+DMU_OT_SPA_HISTORY,/* UINT8 */
+DMU_OT_SPA_HISTORY_OFFSETS,/* spa_his_phys_t */
+DMU_OT_POOL_PROPS,/* ZAP */
+DMU_OT_DSL_PERMS,/* ZAP */
+DMU_OT_ACL,/* ACL */
+DMU_OT_SYSACL,/* SYSACL */
+DMU_OT_FUID,/* FUID table (Packed NVLIST UINT8) */
+DMU_OT_FUID_SIZE,/* FUID table size UINT64 */
+DMU_OT_NEXT_CLONES,/* ZAP */
+DMU_OT_SCRUB_QUEUE,/* ZAP */
+DMU_OT_USERGROUP_USED,/* ZAP */
+DMU_OT_USERGROUP_QUOTA,/* ZAP */
+DMU_OT_USERREFS,/* ZAP */
+DMU_OT_DDT_ZAP,/* ZAP */
+DMU_OT_DDT_STATS,/* ZAP */
+DMU_OT_SA,/* System attr */
+DMU_OT_SA_MASTER_NODE,/* ZAP */
+DMU_OT_SA_ATTR_REGISTRATION,/* ZAP */
+DMU_OT_SA_ATTR_LAYOUTS,/* ZAP */
+DMU_OT_NUMTYPES
+} dmu_object_type_t;
+
+typedef enum dmu_objset_type {
+DMU_OST_NONE,
+DMU_OST_META,
+DMU_OST_ZFS,
+DMU_OST_ZVOL,
+DMU_OST_OTHER,/* For testing only! */
+DMU_OST_ANY,/* Be careful! */
+DMU_OST_NUMTYPES
+} dmu_objset_type_t;
+
+/*
+ * The names of zap entries in the DIRECTORY_OBJECT of the MOS.
+ */
+#defineDMU_POOL_DIRECTORY_OBJECT1
+#defineDMU_POOL_CONFIG"config"
+#defineDMU_POOL_ROOT_DATASET"root_dataset"
+#defineDMU_POOL_SYNC_BPLIST"sync_bplist"
+#defineDMU_POOL_ERRLOG_SCRUB"errlog_scrub"
+#defineDMU_POOL_ERRLOG_LAST"errlog_last"
+#defineDMU_POOL_SPARES"spares"
+#defineDMU_POOL_DEFLATE"deflate"
+#defineDMU_POOL_HISTORY"history"
+#defineDMU_POOL_PROPS"pool_props"
+#defineDMU_POOL_L2CACHE"l2cache"
+
+#endif/* _SYS_DMU_H */
diff --git a/include/zfs/dmu_objset.h b/include/zfs/dmu_objset.h
new file mode 100644
index 0000000..176cad7
--- /dev/null
+++ b/include/zfs/dmu_objset.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,43 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *  Copyright (C) 2010  Robert Millan &amp;lt;rmh&amp;lt; at &amp;gt;gnu.org&amp;gt;
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_DMU_OBJSET_H
+#define_SYS_DMU_OBJSET_H
+
+#include &amp;lt;zfs/zil.h&amp;gt;
+
+#define OBJSET_PHYS_SIZE2048
+#define OBJSET_PHYS_SIZE_V141024
+
+typedef struct objset_phys {
+dnode_phys_t os_meta_dnode;
+zil_header_t os_zil_header;
+uint64_t os_type;
+uint64_t os_flags;
+char os_pad[OBJSET_PHYS_SIZE - sizeof(dnode_phys_t)*3 -
+    sizeof(zil_header_t) - sizeof(uint64_t)*2];
+dnode_phys_t os_userused_dnode;
+dnode_phys_t os_groupused_dnode;
+} objset_phys_t;
+
+#endif /* _SYS_DMU_OBJSET_H */
diff --git a/include/zfs/dnode.h b/include/zfs/dnode.h
new file mode 100644
index 0000000..9ec3d43
--- /dev/null
+++ b/include/zfs/dnode.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,80 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_DNODE_H
+#define_SYS_DNODE_H
+
+#include &amp;lt;zfs/spa.h&amp;gt;
+
+/*
+ * Fixed constants.
+ */
+#defineDNODE_SHIFT9/* 512 bytes */
+#defineDN_MIN_INDBLKSHIFT10/* 1k */
+#defineDN_MAX_INDBLKSHIFT14/* 16k */
+#defineDNODE_BLOCK_SHIFT14/* 16k */
+#defineDNODE_CORE_SIZE64/* 64 bytes for dnode sans blkptrs */
+#defineDN_MAX_OBJECT_SHIFT48/* 256 trillion (zfs_fid_t limit) */
+#defineDN_MAX_OFFSET_SHIFT64/* 2^64 bytes in a dnode */
+
+/*
+ * Derived constants.
+ */
+#defineDNODE_SIZE(1 &amp;lt;&amp;lt; DNODE_SHIFT)
+#defineDN_MAX_NBLKPTR((DNODE_SIZE - DNODE_CORE_SIZE) &amp;gt;&amp;gt; SPA_BLKPTRSHIFT)
+#defineDN_MAX_BONUSLEN(DNODE_SIZE - DNODE_CORE_SIZE - (1 &amp;lt;&amp;lt; SPA_BLKPTRSHIFT))
+#defineDN_MAX_OBJECT(1ULL &amp;lt;&amp;lt; DN_MAX_OBJECT_SHIFT)
+
+#defineDNODES_PER_BLOCK_SHIFT(DNODE_BLOCK_SHIFT - DNODE_SHIFT)
+#defineDNODES_PER_BLOCK(1ULL &amp;lt;&amp;lt; DNODES_PER_BLOCK_SHIFT)
+#defineDNODES_PER_LEVEL_SHIFT(DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT)
+
+#defineDNODE_FLAG_SPILL_BLKPTR (1&amp;lt;&amp;lt;2)
+
+#defineDN_BONUS(dnp)((void *)((dnp)-&amp;gt;dn_bonus + \
+(((dnp)-&amp;gt;dn_nblkptr - 1) * sizeof(blkptr_t))))
+
+typedef struct dnode_phys {
+uint8_t dn_type;/* dmu_object_type_t */
+uint8_t dn_indblkshift;/* ln2(indirect block size) */
+uint8_t dn_nlevels;/* 1=dn_blkptr-&amp;gt;data blocks */
+uint8_t dn_nblkptr;/* length of dn_blkptr */
+uint8_t dn_bonustype;/* type of data in bonus buffer */
+uint8_tdn_checksum;/* ZIO_CHECKSUM type */
+uint8_tdn_compress;/* ZIO_COMPRESS type */
+uint8_t dn_flags;/* DNODE_FLAG_* */
+uint16_t dn_datablkszsec;/* data block size in 512b sectors */
+uint16_t dn_bonuslen;/* length of dn_bonus */
+uint8_t dn_pad2[4];
+
+/* accounting is protected by dn_dirty_mtx */
+uint64_t dn_maxblkid;/* largest allocated block ID */
+uint64_t dn_used;/* bytes (or sectors) of disk space */
+
+uint64_t dn_pad3[4];
+
+blkptr_t dn_blkptr[1];
+uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof(blkptr_t)];
+blkptr_t dn_spill;
+} dnode_phys_t;
+
+#endif/* _SYS_DNODE_H */
diff --git a/include/zfs/dsl_dataset.h b/include/zfs/dsl_dataset.h
new file mode 100644
index 0000000..c6de7ab
--- /dev/null
+++ b/include/zfs/dsl_dataset.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,52 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_DSL_DATASET_H
+#define_SYS_DSL_DATASET_H
+
+typedef struct dsl_dataset_phys {
+uint64_t ds_dir_obj;
+uint64_t ds_prev_snap_obj;
+uint64_t ds_prev_snap_txg;
+uint64_t ds_next_snap_obj;
+uint64_t ds_snapnames_zapobj;/* zap obj of snaps; ==0 for snaps */
+uint64_t ds_num_children;/* clone/snap children; ==0 for head */
+uint64_t ds_creation_time;/* seconds since 1970 */
+uint64_t ds_creation_txg;
+uint64_t ds_deadlist_obj;
+uint64_t ds_used_bytes;
+uint64_t ds_compressed_bytes;
+uint64_t ds_uncompressed_bytes;
+uint64_t ds_unique_bytes;/* only relevant to snapshots */
+/*
+ * The ds_fsid_guid is a 56-bit ID that can change to avoid
+ * collisions.  The ds_guid is a 64-bit ID that will never
+ * change, so there is a small probability that it will collide.
+ */
+uint64_t ds_fsid_guid;
+uint64_t ds_guid;
+uint64_t ds_flags;
+blkptr_t ds_bp;
+uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */
+} dsl_dataset_phys_t;
+
+#endif /* _SYS_DSL_DATASET_H */
diff --git a/include/zfs/dsl_dir.h b/include/zfs/dsl_dir.h
new file mode 100644
index 0000000..c04e0b6
--- /dev/null
+++ b/include/zfs/dsl_dir.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,48 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_DSL_DIR_H
+#define_SYS_DSL_DIR_H
+
+typedef struct dsl_dir_phys {
+uint64_t dd_creation_time; /* not actually used */
+uint64_t dd_head_dataset_obj;
+uint64_t dd_parent_obj;
+uint64_t dd_clone_parent_obj;
+uint64_t dd_child_dir_zapobj;
+/*
+ * how much space our children are accounting for; for leaf
+ * datasets, == physical space used by fs + snaps
+ */
+uint64_t dd_used_bytes;
+uint64_t dd_compressed_bytes;
+uint64_t dd_uncompressed_bytes;
+/* Administrative quota setting */
+uint64_t dd_quota;
+/* Administrative reservation setting */
+uint64_t dd_reserved;
+uint64_t dd_props_zapobj;
+uint64_t dd_deleg_zapobj;/* dataset permissions */
+uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */
+} dsl_dir_phys_t;
+
+#endif /* _SYS_DSL_DIR_H */
diff --git a/include/zfs/sa_impl.h b/include/zfs/sa_impl.h
new file mode 100644
index 0000000..4ec49fe
--- /dev/null
+++ b/include/zfs/sa_impl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,34 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#ifndef_SYS_SA_IMPL_H
+#define_SYS_SA_IMPL_H
+
+typedef struct sa_hdr_phys {
+uint32_t sa_magic;
+uint16_t sa_layout_info;
+uint16_t sa_lengths[1];
+} sa_hdr_phys_t;
+
+#defineSA_HDR_SIZE(hdr)BF32_GET_SB(hdr-&amp;gt;sa_layout_info, 10, 16, 3, 0)
+#defineSA_SIZE_OFFSET0x8
+
+#endif/* _SYS_SA_IMPL_H */
diff --git a/include/zfs/spa.h b/include/zfs/spa.h
new file mode 100644
index 0000000..100e2a6
--- /dev/null
+++ b/include/zfs/spa.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,311 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004,2009
+ *Free Software Foundation, Inc.
+ *Copyright 2010 Sun Microsystems, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+
+#ifndef GRUB_ZFS_SPA_HEADER
+#defineGRUB_ZFS_SPA_HEADER 1
+
+typedef enum grub_zfs_endian {
+UNKNOWN_ENDIAN = -2,
+LITTLE_ENDIAN = -1,
+BIG_ENDIAN = 0
+} grub_zfs_endian_t;
+
+
+#define grub_zfs_to_cpu16(x, a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu16(x) \
+: grub_le_to_cpu16(x))
+#define grub_cpu_to_zfs16(x, a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be16(x) \
+: grub_cpu_to_le16(x))
+
+#define grub_zfs_to_cpu32(x, a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu32(x) \
+: grub_le_to_cpu32(x))
+#define grub_cpu_to_zfs32(x, a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be32(x) \
+: grub_cpu_to_le32(x))
+
+#define grub_zfs_to_cpu64(x, a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu64(x) \
+: grub_le_to_cpu64(x))
+#define grub_cpu_to_zfs64(x, a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be64(x) \
+: grub_cpu_to_le64(x))
+
+/*
+ * General-purpose 32-bit and 64-bit bitfield encodings.
+ */
+#defineBF32_DECODE(x, low, len)P2PHASE((x) &amp;gt;&amp;gt; (low), 1U &amp;lt;&amp;lt; (len))
+#defineBF64_DECODE(x, low, len)P2PHASE((x) &amp;gt;&amp;gt; (low), 1ULL &amp;lt;&amp;lt; (len))
+#defineBF32_ENCODE(x, low, len)(P2PHASE((x), 1U &amp;lt;&amp;lt; (len)) &amp;lt;&amp;lt; (low))
+#defineBF64_ENCODE(x, low, len)(P2PHASE((x), 1ULL &amp;lt;&amp;lt; (len)) &amp;lt;&amp;lt; (low))
+
+#defineBF32_GET(x, low, len)BF32_DECODE(x, low, len)
+#defineBF64_GET(x, low, len)BF64_DECODE(x, low, len)
+
+#defineBF32_SET(x, low, len, val)\
+((x) ^= BF32_ENCODE((x &amp;gt;&amp;gt; low) ^ (val), low, len))
+#defineBF64_SET(x, low, len, val)\
+((x) ^= BF64_ENCODE((x &amp;gt;&amp;gt; low) ^ (val), low, len))
+
+#defineBF32_GET_SB(x, low, len, shift, bias)\
+((BF32_GET(x, low, len) + (bias)) &amp;lt;&amp;lt; (shift))
+#defineBF64_GET_SB(x, low, len, shift, bias)\
+((BF64_GET(x, low, len) + (bias)) &amp;lt;&amp;lt; (shift))
+
+#defineBF32_SET_SB(x, low, len, shift, bias, val)\
+BF32_SET(x, low, len, ((val) &amp;gt;&amp;gt; (shift)) - (bias))
+#defineBF64_SET_SB(x, low, len, shift, bias, val)\
+BF64_SET(x, low, len, ((val) &amp;gt;&amp;gt; (shift)) - (bias))
+
+/*
+ * We currently support nine block sizes, from 512 bytes to 128K.
+ * We could go higher, but the benefits are near-zero and the cost
+ * of COWing a giant block to modify one byte would become excessive.
+ */
+#defineSPA_MINBLOCKSHIFT9
+#defineSPA_MAXBLOCKSHIFT17
+#defineSPA_MINBLOCKSIZE(1ULL &amp;lt;&amp;lt; SPA_MINBLOCKSHIFT)
+#defineSPA_MAXBLOCKSIZE(1ULL &amp;lt;&amp;lt; SPA_MAXBLOCKSHIFT)
+
+#defineSPA_BLOCKSIZES(SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1)
+
+/*
+ * Size of block to hold the configuration data (a packed nvlist)
+ */
+#defineSPA_CONFIG_BLOCKSIZE(1 &amp;lt;&amp;lt; 14)
+
+/*
+ * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB.
+ * The ASIZE encoding should be at least 64 times larger (6 more bits)
+ * to support up to 4-way RAID-Z mirror mode with worst-case gang block
+ * overhead, three DVAs per bp, plus one more bit in case we do anything
+ * else that expands the ASIZE.
+ */
+#defineSPA_LSIZEBITS16/* LSIZE up to 32M (2^16 * 512)*/
+#defineSPA_PSIZEBITS16/* PSIZE up to 32M (2^16 * 512)*/
+#defineSPA_ASIZEBITS24/* ASIZE up to 64 times larger*/
+
+/*
+ * All SPA data is represented by 128-bit data virtual addresses (DVAs).
+ * The members of the dva_t should be considered opaque outside the SPA.
+ */
+typedef struct dva {
+uint64_tdva_word[2];
+} dva_t;
+
+/*
+ * Each block has a 256-bit checksum -- strong enough for cryptographic hashes.
+ */
+typedef struct zio_cksum {
+uint64_tzc_word[4];
+} zio_cksum_t;
+
+/*
+ * Each block is described by its DVAs, time of birth, checksum, etc.
+ * The word-by-word, bit-by-bit layout of the blkptr is as follows:
+ *
+ *6456484032241680
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 0|vdev1| GRID|  ASIZE|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 1|G| offset1|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 2|vdev2| GRID|  ASIZE|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 3|G| offset2|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 4|vdev3| GRID|  ASIZE|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 5|G| offset3|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 6|BDX|lvl| type| cksum | comp|  PSIZE|  LSIZE|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 7|padding|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 8|padding|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * 9|physical birth txg|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * a|logical birth txg|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * b|fill count|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * c|checksum[0]|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * d|checksum[1]|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * e|checksum[2]|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ * f|checksum[3]|
+ *+-------+-------+-------+-------+-------+-------+-------+-------+
+ *
+ * Legend:
+ *
+ * vdevvirtual device ID
+ * offsetoffset into virtual device
+ * LSIZElogical size
+ * PSIZEphysical size (after compression)
+ * ASIZEallocated size (including RAID-Z parity and gang block headers)
+ * GRIDRAID-Z layout information (reserved for future use)
+ * cksumchecksum function
+ * compcompression function
+ * Ggang block indicator
+ * Bbyteorder (endianness)
+ * Ddedup
+ * Xunused
+ * lvllevel of indirection
+ * typeDMU object type
+ * phys birthtxg of block allocation; zero if same as logical birth txg
+ * log. birthtransaction group in which the block was logically born
+ * fill countnumber of non-zero blocks under this bp
+ * checksum[4]256-bit checksum of the data this bp describes
+ */
+#defineSPA_BLKPTRSHIFT7/* blkptr_t is 128 bytes*/
+#defineSPA_DVAS_PER_BP3/* Number of DVAs in a bp*/
+
+typedef struct blkptr {
+dva_tblk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */
+uint64_tblk_prop;/* size, compression, type, etc*/
+uint64_tblk_pad[2];/* Extra space for the future*/
+uint64_tblk_phys_birth;/* txg when block was allocated*/
+uint64_tblk_birth;/* transaction group at birth*/
+uint64_tblk_fill;/* fill count*/
+zio_cksum_tblk_cksum;/* 256-bit checksum*/
+} blkptr_t;
+
+/*
+ * Macros to get and set fields in a bp or DVA.
+ */
+#defineDVA_GET_ASIZE(dva)\
+BF64_GET_SB((dva)-&amp;gt;dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0)
+#defineDVA_SET_ASIZE(dva, x)\
+BF64_SET_SB((dva)-&amp;gt;dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x)
+
+#defineDVA_GET_GRID(dva)BF64_GET((dva)-&amp;gt;dva_word[0], 24, 8)
+#defineDVA_SET_GRID(dva, x)BF64_SET((dva)-&amp;gt;dva_word[0], 24, 8, x)
+
+#defineDVA_GET_VDEV(dva)BF64_GET((dva)-&amp;gt;dva_word[0], 32, 32)
+#defineDVA_SET_VDEV(dva, x)BF64_SET((dva)-&amp;gt;dva_word[0], 32, 32, x)
+
+#defineDVA_GET_GANG(dva)BF64_GET((dva)-&amp;gt;dva_word[1], 63, 1)
+#defineDVA_SET_GANG(dva, x)BF64_SET((dva)-&amp;gt;dva_word[1], 63, 1, x)
+
+#defineBP_GET_LSIZE(bp)\
+BF64_GET_SB((bp)-&amp;gt;blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1)
+#defineBP_SET_LSIZE(bp, x)\
+BF64_SET_SB((bp)-&amp;gt;blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
+
+#defineBP_GET_COMPRESS(bp)BF64_GET((bp)-&amp;gt;blk_prop, 32, 8)
+#defineBP_SET_COMPRESS(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 32, 8, x)
+
+#defineBP_GET_CHECKSUM(bp)BF64_GET((bp)-&amp;gt;blk_prop, 40, 8)
+#defineBP_SET_CHECKSUM(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 40, 8, x)
+
+#defineBP_GET_TYPE(bp)BF64_GET((bp)-&amp;gt;blk_prop, 48, 8)
+#defineBP_SET_TYPE(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 48, 8, x)
+
+#defineBP_GET_LEVEL(bp)BF64_GET((bp)-&amp;gt;blk_prop, 56, 5)
+#defineBP_SET_LEVEL(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 56, 5, x)
+
+#defineBP_GET_PROP_BIT_61(bp)BF64_GET((bp)-&amp;gt;blk_prop, 61, 1)
+#defineBP_SET_PROP_BIT_61(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 61, 1, x)
+
+#defineBP_GET_DEDUP(bp)BF64_GET((bp)-&amp;gt;blk_prop, 62, 1)
+#defineBP_SET_DEDUP(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 62, 1, x)
+
+#defineBP_GET_BYTEORDER(bp)(0 - BF64_GET((bp)-&amp;gt;blk_prop, 63, 1))
+#defineBP_SET_BYTEORDER(bp, x)BF64_SET((bp)-&amp;gt;blk_prop, 63, 1, x)
+
+#defineBP_PHYSICAL_BIRTH(bp)\
+((bp)-&amp;gt;blk_phys_birth ? (bp)-&amp;gt;blk_phys_birth : (bp)-&amp;gt;blk_birth)
+
+#defineBP_SET_BIRTH(bp, logical, physical)\
+{\
+(bp)-&amp;gt;blk_birth = (logical);\
+(bp)-&amp;gt;blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \
+}
+
+#defineBP_GET_ASIZE(bp)\
+(DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[0]) + DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[1]) + \
+ DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[2]))
+
+#defineBP_GET_UCSIZE(bp)\
+((BP_GET_LEVEL(bp) &amp;gt; 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ?\
+ BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp));
+
+#defineBP_GET_NDVAS(bp)\
+(!!DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[0]) +\
+ !!DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[1]) +\
+ !!DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[2]))
+
+#defineBP_COUNT_GANG(bp)\
+(DVA_GET_GANG(&amp;amp;(bp)-&amp;gt;blk_dva[0]) +\
+ DVA_GET_GANG(&amp;amp;(bp)-&amp;gt;blk_dva[1]) +\
+ DVA_GET_GANG(&amp;amp;(bp)-&amp;gt;blk_dva[2]))
+
+#defineDVA_EQUAL(dva1, dva2)\
+((dva1)-&amp;gt;dva_word[1] == (dva2)-&amp;gt;dva_word[1] &amp;amp;&amp;amp;\
+ (dva1)-&amp;gt;dva_word[0] == (dva2)-&amp;gt;dva_word[0])
+
+#defineBP_EQUAL(bp1, bp2)\
+(BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) &amp;amp;&amp;amp;\
+ DVA_EQUAL(&amp;amp;(bp1)-&amp;gt;blk_dva[0], &amp;amp;(bp2)-&amp;gt;blk_dva[0]) &amp;amp;&amp;amp;\
+ DVA_EQUAL(&amp;amp;(bp1)-&amp;gt;blk_dva[1], &amp;amp;(bp2)-&amp;gt;blk_dva[1]) &amp;amp;&amp;amp;\
+ DVA_EQUAL(&amp;amp;(bp1)-&amp;gt;blk_dva[2], &amp;amp;(bp2)-&amp;gt;blk_dva[2]))
+
+#defineZIO_CHECKSUM_EQUAL(zc1, zc2)\
+(0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) |\
+   ((zc1).zc_word[1] - (zc2).zc_word[1]) |\
+   ((zc1).zc_word[2] - (zc2).zc_word[2]) |\
+   ((zc1).zc_word[3] - (zc2).zc_word[3])))
+
+#defineDVA_IS_VALID(dva)(DVA_GET_ASIZE(dva) != 0)
+
+#defineZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3)\
+{\
+(zcp)-&amp;gt;zc_word[0] = w0;\
+(zcp)-&amp;gt;zc_word[1] = w1;\
+(zcp)-&amp;gt;zc_word[2] = w2;\
+(zcp)-&amp;gt;zc_word[3] = w3;\
+}
+
+#defineBP_IDENTITY(bp)(&amp;amp;(bp)-&amp;gt;blk_dva[0])
+#defineBP_IS_GANG(bp)DVA_GET_GANG(BP_IDENTITY(bp))
+#defineBP_IS_HOLE(bp)((bp)-&amp;gt;blk_birth == 0)
+
+/* BP_IS_RAIDZ(bp) assumes no block compression */
+#defineBP_IS_RAIDZ(bp)(DVA_GET_ASIZE(&amp;amp;(bp)-&amp;gt;blk_dva[0]) &amp;gt; \
+ BP_GET_PSIZE(bp))
+
+#defineBP_ZERO(bp)\
+{\
+(bp)-&amp;gt;blk_dva[0].dva_word[0] = 0;\
+(bp)-&amp;gt;blk_dva[0].dva_word[1] = 0;\
+(bp)-&amp;gt;blk_dva[1].dva_word[0] = 0;\
+(bp)-&amp;gt;blk_dva[1].dva_word[1] = 0;\
+(bp)-&amp;gt;blk_dva[2].dva_word[0] = 0;\
+(bp)-&amp;gt;blk_dva[2].dva_word[1] = 0;\
+(bp)-&amp;gt;blk_prop = 0;\
+(bp)-&amp;gt;blk_pad[0] = 0;\
+(bp)-&amp;gt;blk_pad[1] = 0;\
+(bp)-&amp;gt;blk_phys_birth = 0;\
+(bp)-&amp;gt;blk_birth = 0;\
+(bp)-&amp;gt;blk_fill = 0;\
+ZIO_SET_CHECKSUM(&amp;amp;(bp)-&amp;gt;blk_cksum, 0, 0, 0, 0);\
+}
+
+#defineBP_SPRINTF_LEN320
+
+#endif/* ! GRUB_ZFS_SPA_HEADER */
diff --git a/include/zfs/uberblock_impl.h b/include/zfs/uberblock_impl.h
new file mode 100644
index 0000000..12daf98
--- /dev/null
+++ b/include/zfs/uberblock_impl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,57 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004
+ *  Free Software Foundation, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_UBERBLOCK_IMPL_H
+#define_SYS_UBERBLOCK_IMPL_H
+
+#define UBMAX(a, b) ((a) &amp;gt; (b) ? (a) : (b))
+
+/*
+ * The uberblock version is incremented whenever an incompatible on-disk
+ * format change is made to the SPA, DMU, or ZAP.
+ *
+ * Note: the first two fields should never be moved.  When a storage pool
+ * is opened, the uberblock must be read off the disk before the version
+ * can be checked.If the ub_version field is moved, we may not detect
+ * version mismatch.  If the ub_magic field is moved, applications that
+ * expect the magic number in the first word won't work.
+ */
+#defineUBERBLOCK_MAGIC0x00bab10c/* oo-ba-bloc!*/
+#defineUBERBLOCK_SHIFT10/* up to 1K*/
+
+typedef struct uberblock {
+uint64_tub_magic;/* UBERBLOCK_MAGIC*/
+uint64_tub_version;/* ZFS_VERSION*/
+uint64_tub_txg;/* txg of last sync*/
+uint64_tub_guid_sum;/* sum of all vdev guids*/
+uint64_tub_timestamp;/* UTC time of last sync*/
+blkptr_tub_rootbp;/* MOS objset_phys_t*/
+} uberblock_t;
+
+#defineVDEV_UBERBLOCK_SHIFT(as)UBMAX(as, UBERBLOCK_SHIFT)
+#defineUBERBLOCK_SIZE(as)(1ULL &amp;lt;&amp;lt; VDEV_UBERBLOCK_SHIFT(as))
+
+/* Number of uberblocks that can fit in the ring at a given ashift */
+#define UBERBLOCK_COUNT(as) (VDEV_UBERBLOCK_RING &amp;gt;&amp;gt; VDEV_UBERBLOCK_SHIFT(as))
+
+#endif/* _SYS_UBERBLOCK_IMPL_H */
diff --git a/include/zfs/vdev_impl.h b/include/zfs/vdev_impl.h
new file mode 100644
index 0000000..97033c9
--- /dev/null
+++ b/include/zfs/vdev_impl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,69 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_VDEV_IMPL_H
+#define_SYS_VDEV_IMPL_H
+
+#defineVDEV_SKIP_SIZE(8 &amp;lt;&amp;lt; 10)
+#defineVDEV_BOOT_HEADER_SIZE(8 &amp;lt;&amp;lt; 10)
+#defineVDEV_PHYS_SIZE(112 &amp;lt;&amp;lt; 10)
+#defineVDEV_UBERBLOCK_RING(128 &amp;lt;&amp;lt; 10)
+
+/* ZFS boot block */
+#defineVDEV_BOOT_MAGIC0x2f5b007b10cULL
+#defineVDEV_BOOT_VERSION1/* version number*/
+
+typedef struct vdev_boot_header {
+uint64_tvb_magic;/* VDEV_BOOT_MAGIC*/
+uint64_tvb_version;/* VDEV_BOOT_VERSION*/
+uint64_tvb_offset;/* start offset(bytes) */
+uint64_tvb_size;/* size (bytes)*/
+charvb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof(uint64_t)];
+} vdev_boot_header_t;
+
+typedef struct vdev_phys {
+charvp_nvlist[VDEV_PHYS_SIZE - sizeof(zio_eck_t)];
+zio_eck_tvp_zbt;
+} vdev_phys_t;
+
+typedef struct vdev_label {
+charvl_pad[VDEV_SKIP_SIZE];/*   8K*/
+vdev_boot_header_t vl_boot_header;/*   8K*/
+vdev_phys_tvl_vdev_phys;/* 112K*/
+charvl_uberblock[VDEV_UBERBLOCK_RING];/* 128K*/
+} vdev_label_t;/* 256K total */
+
+/*
+ * Size and offset of embedded boot loader region on each label.
+ * The total size of the first two labels plus the boot area is 4MB.
+ */
+#defineVDEV_BOOT_OFFSET(2 * sizeof(vdev_label_t))
+#defineVDEV_BOOT_SIZE(7ULL &amp;lt;&amp;lt; 19)/* 3.5M*/
+
+/*
+ * Size of label regions at the start and end of each leaf device.
+ */
+#defineVDEV_LABEL_START_SIZE(2 * sizeof(vdev_label_t) + VDEV_BOOT_SIZE)
+#defineVDEV_LABEL_END_SIZE(2 * sizeof(vdev_label_t))
+#defineVDEV_LABELS4
+
+#endif/* _SYS_VDEV_IMPL_H */
diff --git a/include/zfs/zap_impl.h b/include/zfs/zap_impl.h
new file mode 100644
index 0000000..65e9311
--- /dev/null
+++ b/include/zfs/zap_impl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,112 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004
+ *  Free Software Foundation, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_ZAP_IMPL_H
+#define_SYS_ZAP_IMPL_H
+
+#defineZAP_MAGIC 0x2F52AB2ABULL
+
+#defineZAP_HASHBITS28
+#defineMZAP_ENT_LEN64
+#defineMZAP_NAME_LEN(MZAP_ENT_LEN - 8 - 4 - 2)
+#defineMZAP_MAX_BLKSHIFTSPA_MAXBLOCKSHIFT
+#defineMZAP_MAX_BLKSZ(1 &amp;lt;&amp;lt; MZAP_MAX_BLKSHIFT)
+
+typedef struct mzap_ent_phys {
+uint64_t mze_value;
+uint32_t mze_cd;
+uint16_t mze_pad;/* in case we want to chain them someday */
+char mze_name[MZAP_NAME_LEN];
+} mzap_ent_phys_t;
+
+typedef struct mzap_phys {
+uint64_t mz_block_type;/* ZBT_MICRO */
+uint64_t mz_salt;
+uint64_t mz_pad[6];
+mzap_ent_phys_t mz_chunk[1];
+/* actually variable size depending on block size */
+} mzap_phys_t;
+
+/*
+ * The (fat) zap is stored in one object. It is an array of
+ * 1&amp;lt;&amp;lt;FZAP_BLOCK_SHIFT byte blocks. The layout looks like one of:
+ *
+ * ptrtbl fits in first block:
+ *[zap_phys_t zap_ptrtbl_shift &amp;lt; 6] [zap_leaf_t] ...
+ *
+ * ptrtbl too big for first block:
+ *[zap_phys_t zap_ptrtbl_shift &amp;gt;= 6] [zap_leaf_t] [ptrtbl] ...
+ *
+ */
+
+#defineZBT_LEAF((1ULL &amp;lt;&amp;lt; 63) + 0)
+#defineZBT_HEADER((1ULL &amp;lt;&amp;lt; 63) + 1)
+#defineZBT_MICRO((1ULL &amp;lt;&amp;lt; 63) + 3)
+/* any other values are ptrtbl blocks */
+
+/*
+ * the embedded pointer table takes up half a block:
+ * block size / entry size (2^3) / 2
+ */
+#defineZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1)
+
+/*
+ * The embedded pointer table starts half-way through the block.  Since
+ * the pointer table itself is half the block, it starts at (64-bit)
+ * word number (1&amp;lt;&amp;lt;ZAP_EMBEDDED_PTRTBL_SHIFT(zap)).
+ */
+#defineZAP_EMBEDDED_PTRTBL_ENT(zap, idx) \
+((uint64_t *)(zap)-&amp;gt;zap_f.zap_phys) \
+[(idx) + (1&amp;lt;&amp;lt;ZAP_EMBEDDED_PTRTBL_SHIFT(zap))]
+
+/*
+ * TAKE NOTE:
+ * If zap_phys_t is modified, zap_byteswap() must be modified.
+ */
+typedef struct zap_phys {
+uint64_t zap_block_type;/* ZBT_HEADER */
+uint64_t zap_magic;/* ZAP_MAGIC */
+
+struct zap_table_phys {
+uint64_t zt_blk;/* starting block number */
+uint64_t zt_numblks;/* number of blocks */
+uint64_t zt_shift;/* bits to index it */
+uint64_t zt_nextblk;/* next (larger) copy start block */
+uint64_t zt_blks_copied; /* number source blocks copied */
+} zap_ptrtbl;
+
+uint64_t zap_freeblk;/* the next free block */
+uint64_t zap_num_leafs;/* number of leafs */
+uint64_t zap_num_entries;/* number of entries */
+uint64_t zap_salt;/* salt to stir into hash function */
+uint64_t zap_normflags;/* flags for u8_textprep_str() */
+uint64_t zap_flags;/* zap_flag_t */
+/*
+ * This structure is followed by padding, and then the embedded
+ * pointer table.  The embedded pointer table takes up second
+ * half of the block.  It is accessed using the
+ * ZAP_EMBEDDED_PTRTBL_ENT() macro.
+ */
+} zap_phys_t;
+
+#endif /* _SYS_ZAP_IMPL_H */
diff --git a/include/zfs/zap_leaf.h b/include/zfs/zap_leaf.h
new file mode 100644
index 0000000..4ddddb5
--- /dev/null
+++ b/include/zfs/zap_leaf.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,103 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004
+ *  Free Software Foundation, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_ZAP_LEAF_H
+#define_SYS_ZAP_LEAF_H
+
+#defineZAP_LEAF_MAGIC 0x2AB1EAF
+
+/* chunk size = 24 bytes */
+#defineZAP_LEAF_CHUNKSIZE 24
+
+/*
+ * The amount of space within the chunk available for the array is:
+ * chunk size - space for type (1) - space for next pointer (2)
+ */
+#defineZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
+
+typedef enum zap_chunk_type {
+ZAP_CHUNK_FREE = 253,
+ZAP_CHUNK_ENTRY = 252,
+ZAP_CHUNK_ARRAY = 251,
+ZAP_CHUNK_TYPE_MAX = 250
+} zap_chunk_type_t;
+
+/*
+ * TAKE NOTE:
+ * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
+ */
+typedef struct zap_leaf_phys {
+struct zap_leaf_header {
+uint64_t lh_block_type;/* ZBT_LEAF */
+uint64_t lh_pad1;
+uint64_t lh_prefix;/* hash prefix of this leaf */
+uint32_t lh_magic;/* ZAP_LEAF_MAGIC */
+uint16_t lh_nfree;/* number free chunks */
+uint16_t lh_nentries;/* number of entries */
+uint16_t lh_prefix_len;/* num bits used to id this */
+
+/* above is accessable to zap, below is zap_leaf private */
+
+uint16_t lh_freelist;/* chunk head of free list */
+uint8_t lh_pad2[12];
+} l_hdr; /* 2 24-byte chunks */
+
+/*
+ * The header is followed by a hash table with
+ * ZAP_LEAF_HASH_NUMENTRIES(zap) entries.  The hash table is
+ * followed by an array of ZAP_LEAF_NUMCHUNKS(zap)
+ * zap_leaf_chunk structures.  These structures are accessed
+ * with the ZAP_LEAF_CHUNK() macro.
+ */
+
+uint16_t l_hash[1];
+} zap_leaf_phys_t;
+
+typedef union zap_leaf_chunk {
+struct zap_leaf_entry {
+uint8_t le_type;/* always ZAP_CHUNK_ENTRY */
+uint8_t le_int_size;/* size of ints */
+uint16_t le_next;/* next entry in hash chain */
+uint16_t le_name_chunk;/* first chunk of the name */
+uint16_t le_name_length;/* bytes in name, incl null */
+uint16_t le_value_chunk;/* first chunk of the value */
+uint16_t le_value_length;/* value length in ints */
+uint32_t le_cd;/* collision differentiator */
+uint64_t le_hash;/* hash value of the name */
+} l_entry;
+struct zap_leaf_array {
+uint8_t la_type;/* always ZAP_CHUNK_ARRAY */
+union {
+uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
+uint64_t la_array64;
+} __attribute__ ((packed));
+uint16_t la_next;/* next blk or CHAIN_END */
+} l_array;
+struct zap_leaf_free {
+uint8_t lf_type;/* always ZAP_CHUNK_FREE */
+uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
+uint16_t lf_next;/* next in free list, or CHAIN_END */
+} l_free;
+} zap_leaf_chunk_t;
+
+#endif /* _SYS_ZAP_LEAF_H */
diff --git a/include/zfs/zfs.h b/include/zfs/zfs.h
new file mode 100644
index 0000000..b6d41c0
--- /dev/null
+++ b/include/zfs/zfs.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,122 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2009
+ *  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+ /*
+  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+  */
+
+#ifndefGRUB_ZFS_HEADER
+#defineGRUB_ZFS_HEADER 1
+
+
+/*
+ * On-disk version number.
+ */
+#defineSPA_VERSION28ULL
+
+/*
+ * The following are configuration names used in the nvlist describing a pool's
+ * configuration.
+ */
+#defineZPOOL_CONFIG_VERSION"version"
+#defineZPOOL_CONFIG_POOL_NAME"name"
+#defineZPOOL_CONFIG_POOL_STATE"state"
+#defineZPOOL_CONFIG_POOL_TXG"txg"
+#defineZPOOL_CONFIG_POOL_GUID"pool_guid"
+#defineZPOOL_CONFIG_CREATE_TXG"create_txg"
+#defineZPOOL_CONFIG_TOP_GUID"top_guid"
+#defineZPOOL_CONFIG_VDEV_TREE"vdev_tree"
+#defineZPOOL_CONFIG_TYPE"type"
+#defineZPOOL_CONFIG_CHILDREN"children"
+#defineZPOOL_CONFIG_ID"id"
+#defineZPOOL_CONFIG_GUID"guid"
+#defineZPOOL_CONFIG_PATH"path"
+#defineZPOOL_CONFIG_DEVID"devid"
+#defineZPOOL_CONFIG_METASLAB_ARRAY"metaslab_array"
+#defineZPOOL_CONFIG_METASLAB_SHIFT"metaslab_shift"
+#defineZPOOL_CONFIG_ASHIFT"ashift"
+#defineZPOOL_CONFIG_ASIZE"asize"
+#defineZPOOL_CONFIG_DTL"DTL"
+#defineZPOOL_CONFIG_STATS"stats"
+#defineZPOOL_CONFIG_WHOLE_DISK"whole_disk"
+#defineZPOOL_CONFIG_ERRCOUNT"error_count"
+#defineZPOOL_CONFIG_NOT_PRESENT"not_present"
+#defineZPOOL_CONFIG_SPARES"spares"
+#defineZPOOL_CONFIG_IS_SPARE"is_spare"
+#defineZPOOL_CONFIG_NPARITY"nparity"
+#defineZPOOL_CONFIG_PHYS_PATH"phys_path"
+#defineZPOOL_CONFIG_L2CACHE"l2cache"
+#defineZPOOL_CONFIG_HOLE_ARRAY"hole_array"
+#defineZPOOL_CONFIG_VDEV_CHILDREN"vdev_children"
+#defineZPOOL_CONFIG_IS_HOLE"is_hole"
+#defineZPOOL_CONFIG_DDT_HISTOGRAM"ddt_histogram"
+#defineZPOOL_CONFIG_DDT_OBJ_STATS"ddt_object_stats"
+#defineZPOOL_CONFIG_DDT_STATS"ddt_stats"
+/*
+ * The persistent vdev state is stored as separate values rather than a single
+ * 'vdev_state' entry.  This is because a device can be in multiple states, such
+ * as offline and degraded.
+ */
+#defineZPOOL_CONFIG_OFFLINE"offline"
+#defineZPOOL_CONFIG_FAULTED"faulted"
+#defineZPOOL_CONFIG_DEGRADED"degraded"
+#defineZPOOL_CONFIG_REMOVED"removed"
+
+#defineVDEV_TYPE_ROOT"root"
+#defineVDEV_TYPE_MIRROR"mirror"
+#defineVDEV_TYPE_REPLACING"replacing"
+#defineVDEV_TYPE_RAIDZ"raidz"
+#defineVDEV_TYPE_DISK"disk"
+#defineVDEV_TYPE_FILE"file"
+#defineVDEV_TYPE_MISSING"missing"
+#defineVDEV_TYPE_HOLE"hole"
+#defineVDEV_TYPE_SPARE"spare"
+#defineVDEV_TYPE_L2CACHE"l2cache"
+
+/*
+ * pool state.  The following states are written to disk as part of the normal
+ * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE.  The remaining
+ * states are software abstractions used at various levels to communicate pool
+ * state.
+ */
+typedef enum pool_state {
+POOL_STATE_ACTIVE = 0,/* In active use*/
+POOL_STATE_EXPORTED,/* Explicitly exported*/
+POOL_STATE_DESTROYED,/* Explicitly destroyed*/
+POOL_STATE_SPARE,/* Reserved for hot spare use*/
+POOL_STATE_L2CACHE,/* Level 2 ARC device*/
+POOL_STATE_UNINITIALIZED,/* Internal spa_t state*/
+POOL_STATE_UNAVAIL,/* Internal libzfs state*/
+POOL_STATE_POTENTIALLY_ACTIVE/* Internal libzfs state*/
+} pool_state_t;
+
+struct grub_zfs_data;
+
+int grub_zfs_fetch_nvlist(device_t dev, char **nvlist);
+int grub_zfs_getmdnobj(device_t dev, const char *fsfilename,
+       uint64_t *mdnobj);
+
+char *grub_zfs_nvlist_lookup_string(char *nvlist, char *name);
+char *grub_zfs_nvlist_lookup_nvlist(char *nvlist, char *name);
+int grub_zfs_nvlist_lookup_uint64(char *nvlist, char *name,
+   uint64_t *out);
+char *grub_zfs_nvlist_lookup_nvlist_array(char *nvlist, char *name,
+   size_t index);
+int grub_zfs_nvlist_lookup_nvlist_array_get_nelm(char *nvlist, char *name);
+
+#endif/* ! GRUB_ZFS_HEADER */
diff --git a/include/zfs/zfs_acl.h b/include/zfs/zfs_acl.h
new file mode 100644
index 0000000..66749af
--- /dev/null
+++ b/include/zfs/zfs_acl.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,55 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *GRUB  --  GRand Unified Bootloader
+ *Copyright (C) 1999,2000,2001,2002,2003,2004
+ *  Free Software Foundation, Inc.
+ *
+ *GRUB 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 3 of the License, or
+ *(at your option) any later version.
+ *
+ *GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_FS_ZFS_ACL_H
+#define_SYS_FS_ZFS_ACL_H
+
+typedef struct zfs_oldace {
+uint32_tz_fuid;/* "who" */
+uint32_tz_access_mask;/* access mask */
+uint16_tz_flags;/* flags, i.e inheritance */
+uint16_tz_type;/* type of entry allow/deny */
+} zfs_oldace_t;
+
+#defineACE_SLOT_CNT6
+
+typedef struct zfs_znode_acl_v0 {
+uint64_tz_acl_extern_obj;  /* ext acl pieces */
+uint32_tz_acl_count;  /* Number of ACEs */
+uint16_tz_acl_version;  /* acl version */
+uint16_tz_acl_pad;  /* pad */
+zfs_oldace_tz_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */
+} zfs_znode_acl_v0_t;
+
+#defineZFS_ACE_SPACE(sizeof(zfs_oldace_t) * ACE_SLOT_CNT)
+
+typedef struct zfs_znode_acl {
+uint64_tz_acl_extern_obj;  /* ext acl pieces */
+uint32_tz_acl_size;  /* Number of bytes in ACL */
+uint16_tz_acl_version;  /* acl version */
+uint16_tz_acl_count;  /* ace count */
+uint8_tz_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */
+} zfs_znode_acl_t;
+
+
+#endif/* _SYS_FS_ZFS_ACL_H */
diff --git a/include/zfs/zfs_znode.h b/include/zfs/zfs_znode.h
new file mode 100644
index 0000000..e3265e3
--- /dev/null
+++ b/include/zfs/zfs_znode.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,70 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_FS_ZFS_ZNODE_H
+#define_SYS_FS_ZFS_ZNODE_H
+
+#include &amp;lt;zfs/zfs_acl.h&amp;gt;
+
+#defineMASTER_NODE_OBJ1
+#defineZFS_ROOT_OBJ"ROOT"
+#defineZPL_VERSION_STR"VERSION"
+#defineZFS_SA_ATTRS"SA_ATTRS"
+
+#defineZPL_VERSION5ULL
+
+#defineZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48)
+
+/*
+ * This is the persistent portion of the znode.  It is stored
+ * in the "bonus buffer" of the file.  Short symbolic links
+ * are also stored in the bonus buffer.
+ */
+typedef struct znode_phys {
+uint64_t zp_atime[2];      /*  0 - last file access time */
+uint64_t zp_mtime[2];/* 16 - last file modification time */
+uint64_t zp_ctime[2];/* 32 - last file change time */
+uint64_t zp_crtime[2];/* 48 - creation time */
+uint64_t zp_gen;/* 64 - generation (txg of creation) */
+uint64_t zp_mode;/* 72 - file mode bits */
+uint64_t zp_size;/* 80 - size of file */
+uint64_t zp_parent;/* 88 - directory parent (`..') */
+uint64_t zp_links;/* 96 - number of links to file */
+uint64_t zp_xattr;/* 104 - DMU object for xattrs */
+uint64_t zp_rdev;/* 112 - dev_t for VBLK &amp;amp; VCHR files */
+uint64_t zp_flags;/* 120 - persistent flags */
+uint64_t zp_uid;/* 128 - file owner */
+uint64_t zp_gid;/* 136 - owning group */
+uint64_t zp_pad[4];/* 144 - future */
+zfs_znode_acl_t zp_acl;/* 176 - 263 ACL */
+/*
+ * Data may pad out any remaining bytes in the znode buffer, eg:
+ *
+ * |&amp;lt;---------------------- dnode_phys (512) ------------------------&amp;gt;|
+ * |&amp;lt;-- dnode (192) ---&amp;gt;|&amp;lt;----------- "bonus" buffer (320) ----------&amp;gt;|
+ *|&amp;lt;---- znode (264) ----&amp;gt;|&amp;lt;---- data (56) ----&amp;gt;|
+ *
+ * At present, we only use this space to store symbolic links.
+ */
+} znode_phys_t;
+
+#endif/* _SYS_FS_ZFS_ZNODE_H */
diff --git a/include/zfs/zil.h b/include/zfs/zil.h
new file mode 100644
index 0000000..bc9d5e9
--- /dev/null
+++ b/include/zfs/zil.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,56 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef_SYS_ZIL_H
+#define_SYS_ZIL_H
+
+/*
+ * Intent log format:
+ *
+ * Each objset has its own intent log.  The log header (zil_header_t)
+ * for objset N's intent log is kept in the Nth object of the SPA's
+ * intent_log objset.  The log header points to a chain of log blocks,
+ * each of which contains log records (i.e., transactions) followed by
+ * a log block trailer (zil_trailer_t).  The format of a log record
+ * depends on the record (or transaction) type, but all records begin
+ * with a common structure that defines the type, length, and txg.
+ */
+
+/*
+ * Intent log header - this on disk structure holds fields to manage
+ * the log.  All fields are 64 bit to easily handle cross architectures.
+ */
+typedef struct zil_header {
+uint64_t zh_claim_txg;   /* txg in which log blocks were claimed */
+uint64_t zh_replay_seq;  /* highest replayed sequence number */
+blkptr_t zh_log;/* log chain */
+uint64_t zh_claim_seq;/* highest claimed sequence number */
+uint64_t zh_flags;/* header flags */
+uint64_t zh_pad[4];
+} zil_header_t;
+
+/*
+ * zh_flags bit settings
+ */
+#defineZIL_REPLAY_NEEDED 0x1/* replay needed - internal only */
+
+#endif/* _SYS_ZIL_H */
diff --git a/include/zfs/zio.h b/include/zfs/zio.h
new file mode 100644
index 0000000..38f90d5
--- /dev/null
+++ b/include/zfs/zio.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,92 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _ZIO_H
+#define_ZIO_H
+
+#include &amp;lt;zfs/spa.h&amp;gt;
+
+#defineZEC_MAGIC0x210da7ab10c7a11ULL/* zio data bloc tail */
+
+typedef struct zio_eck {
+uint64_tzec_magic;/* for validation, endianness*/
+zio_cksum_tzec_cksum;/* 256-bit checksum*/
+} zio_eck_t;
+
+/*
+ * Gang block headers are self-checksumming and contain an array
+ * of block pointers.
+ */
+#defineSPA_GANGBLOCKSIZESPA_MINBLOCKSIZE
+#defineSPA_GBH_NBLKPTRS((SPA_GANGBLOCKSIZE - \
+sizeof(zio_eck_t)) / sizeof(blkptr_t))
+#defineSPA_GBH_FILLER((SPA_GANGBLOCKSIZE - \
+sizeof(zio_eck_t) - \
+(SPA_GBH_NBLKPTRS * sizeof(blkptr_t))) /\
+sizeof(uint64_t))
+
+#defineZIO_GET_IOSIZE(zio)\
+(BP_IS_GANG((zio)-&amp;gt;io_bp) ? \
+SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)-&amp;gt;io_bp))
+
+typedef struct zio_gbh {
+blkptr_tzg_blkptr[SPA_GBH_NBLKPTRS];
+uint64_tzg_filler[SPA_GBH_FILLER];
+zio_eck_tzg_tail;
+} zio_gbh_phys_t;
+
+enum zio_checksum {
+ZIO_CHECKSUM_INHERIT = 0,
+ZIO_CHECKSUM_ON,
+ZIO_CHECKSUM_OFF,
+ZIO_CHECKSUM_LABEL,
+ZIO_CHECKSUM_GANG_HEADER,
+ZIO_CHECKSUM_ZILOG,
+ZIO_CHECKSUM_FLETCHER_2,
+ZIO_CHECKSUM_FLETCHER_4,
+ZIO_CHECKSUM_SHA256,
+ZIO_CHECKSUM_ZILOG2,
+ZIO_CHECKSUM_FUNCTIONS
+};
+
+#defineZIO_CHECKSUM_ON_VALUEZIO_CHECKSUM_FLETCHER_2
+#defineZIO_CHECKSUM_DEFAULTZIO_CHECKSUM_ON
+
+enum zio_compress {
+ZIO_COMPRESS_INHERIT = 0,
+ZIO_COMPRESS_ON,
+ZIO_COMPRESS_OFF,
+ZIO_COMPRESS_LZJB,
+ZIO_COMPRESS_EMPTY,
+ZIO_COMPRESS_GZIP1,
+ZIO_COMPRESS_GZIP2,
+ZIO_COMPRESS_GZIP3,
+ZIO_COMPRESS_GZIP4,
+ZIO_COMPRESS_GZIP5,
+ZIO_COMPRESS_GZIP6,
+ZIO_COMPRESS_GZIP7,
+ZIO_COMPRESS_GZIP8,
+ZIO_COMPRESS_GZIP9,
+ZIO_COMPRESS_FUNCTIONS
+};
+
+#endif/* _ZIO_H */
diff --git a/include/zfs/zio_checksum.h b/include/zfs/zio_checksum.h
new file mode 100644
index 0000000..8ade44a
--- /dev/null
+++ b/include/zfs/zio_checksum.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,49 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_ZIO_CHECKSUM_H
+#define_SYS_ZIO_CHECKSUM_H
+
+/*
+ * Signature for checksum functions.
+ */
+typedef void zio_checksum_t(const void *data, uint64_t size,
+    grub_zfs_endian_t endian, zio_cksum_t *zcp);
+
+/*
+ * Information about each checksum function.
+ */
+typedef struct zio_checksum_info {
+zio_checksum_t*ci_func; /* checksum function for each byteorder */
+intci_correctable;/* number of correctable bits*/
+intci_eck;/* uses zio embedded checksum? */
+char*ci_name;/* descriptive name */
+} zio_checksum_info_t;
+
+extern void zio_checksum_SHA256(const void *, uint64_t,
+ grub_zfs_endian_t endian, zio_cksum_t *);
+extern void fletcher_2(const void *, uint64_t, grub_zfs_endian_t endian,
+zio_cksum_t *);
+extern void fletcher_4(const void *, uint64_t, grub_zfs_endian_t endian,
+zio_cksum_t *);
+
+#endif/* _SYS_ZIO_CHECKSUM_H */
diff --git a/include/zfs_common.h b/include/zfs_common.h
new file mode 100644
index 0000000..969dbf5
--- /dev/null
+++ b/include/zfs_common.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,94 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * ZFS filesystem implementation in Uboot by
+ * Jorgen Lundman &amp;lt;lundman at lundman.net&amp;gt;
+ *
+ * zfsfs support
+ * made from existing GRUB Sources by Sun, GNU and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __ZFS_COMMON__
+#define __ZFS_COMMON__
+
+#define SECTOR_SIZE0x200
+#define SECTOR_BITS9
+
+#define grub_le_to_cpu16 le16_to_cpu
+#define grub_be_to_cpu16 be16_to_cpu
+#define grub_le_to_cpu32 le32_to_cpu
+#define grub_be_to_cpu32 be32_to_cpu
+#define grub_le_to_cpu64 le64_to_cpu
+#define grub_be_to_cpu64 be64_to_cpu
+
+#define grub_cpu_to_le64 cpu_to_le64
+#define grub_cpu_to_be64 cpu_to_be64
+
+enum zfs_errors {
+ZFS_ERR_NONE = 0,
+ZFS_ERR_NOT_IMPLEMENTED_YET = -1,
+ZFS_ERR_BAD_FS = -2,
+ZFS_ERR_OUT_OF_MEMORY = -3,
+ZFS_ERR_FILE_NOT_FOUND = -4,
+ZFS_ERR_BAD_FILE_TYPE = -5,
+ZFS_ERR_OUT_OF_RANGE = -6,
+};
+
+struct zfs_filesystem {
+
+/* Block Device Descriptor */
+block_dev_desc_t *dev_desc;
+};
+
+
+extern block_dev_desc_t *zfs_dev_desc;
+
+struct device_s {
+uint64_t part_length;
+};
+typedef struct device_s *device_t;
+
+struct zfs_file {
+device_t device;
+uint64_t size;
+void *data;
+uint64_t offset;
+};
+
+typedef struct zfs_file *zfs_file_t;
+
+struct zfs_dirhook_info {
+int dir;
+int mtimeset;
+time_t mtime;
+time_t mtime2;
+};
+
+
+
+
+struct zfs_filesystem *zfsget_fs(void);
+int init_fs(block_dev_desc_t *dev_desc);
+void deinit_fs(block_dev_desc_t *dev_desc);
+int zfs_open(zfs_file_t, const char *filename);
+uint64_t zfs_read(zfs_file_t, char *buf, uint64_t len);
+struct grub_zfs_data *zfs_mount(device_t);
+int zfs_close(zfs_file_t);
+int zfs_ls(device_t dev, const char *path,
+   int (*hook) (const char *, const struct zfs_dirhook_info *));
+int zfs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part);
+void zfs_unmount(struct grub_zfs_data *data);
+int lzjb_decompress(void *, void *, uint32_t, uint32_t);
+#endif
&lt;/pre&gt;</description>
    <dc:creator>Jorgen Lundman</dc:creator>
    <dc:date>2012-05-24T01:12:00</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132146">
    <title>Re: [PATCH] net: sh_eth: Add support SH7734 Ethernet device</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132146</link>
    <description>&lt;pre&gt;Joe Hershberger さんは書きました:

sorry and thanks!

Best regards,
   Nobuhiro
_______________________________________________
U-Boot mailing list
U-Boot&amp;lt; at &amp;gt;lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
&lt;/pre&gt;</description>
    <dc:creator>Nobuhiro Iwamatsu</dc:creator>
    <dc:date>2012-05-24T00:41:12</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132145">
    <title>[PATCH V5 RESEND 3/3] mtd/NAND: Remove obsolete SPEArspecific NAND drivers</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132145</link>
    <description>&lt;pre&gt;From: Vipin KUMAR &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;

Since, SPEAr platform uses generic FSMC driver now, so spear specific files
drivers/mtd/nand/spr_nand.c, arch/arm/include/asm/arch-spear/spr_nand.h are
removed

Signed-off-by: Vipin Kumar &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;
Signed-off-by: Amit Virdi &amp;lt;amit.virdi&amp;lt; at &amp;gt;st.com&amp;gt;
---
 arch/arm/include/asm/arch-spear/spr_nand.h |   57 -------------
 drivers/mtd/nand/spr_nand.c                |  124 ----------------------------
 2 files changed, 0 insertions(+), 181 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_nand.h
 delete mode 100644 drivers/mtd/nand/spr_nand.c

diff --git a/arch/arm/include/asm/arch-spear/spr_nand.h b/arch/arm/include/asm/arch-spear/spr_nand.h
deleted file mode 100644
index 2b63dc7..0000000
--- a/arch/arm/include/asm/arch-spear/spr_nand.h
+++ /dev/null
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,57 +0,0 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar&amp;lt; at &amp;gt;st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __SPR_NAND_H__
-#define __SPR_NAND_H__
-
-struct fsmc_regs {
-u32 reserved_1[0x10];
-u32 genmemctrl_pc;
-u32 reserved_2;
-u32 genmemctrl_comm;
-u32 genmemctrl_attrib;
-u32 reserved_3;
-u32 genmemctrl_ecc;
-};
-
-/* genmemctrl_pc register definitions */
-#define FSMC_RESET(1 &amp;lt;&amp;lt; 0)
-#define FSMC_WAITON(1 &amp;lt;&amp;lt; 1)
-#define FSMC_ENABLE(1 &amp;lt;&amp;lt; 2)
-#define FSMC_DEVTYPE_NAND(1 &amp;lt;&amp;lt; 3)
-#define FSMC_DEVWID_8(0 &amp;lt;&amp;lt; 4)
-#define FSMC_DEVWID_16(1 &amp;lt;&amp;lt; 4)
-#define FSMC_ECCEN(1 &amp;lt;&amp;lt; 6)
-#define FSMC_ECCPLEN_512(0 &amp;lt;&amp;lt; 7)
-#define FSMC_ECCPLEN_256(1 &amp;lt;&amp;lt; 7)
-#define FSMC_TCLR_1(1 &amp;lt;&amp;lt; 9)
-#define FSMC_TAR_1(1 &amp;lt;&amp;lt; 13)
-
-/* genmemctrl_comm register definitions */
-#define FSMC_TSET_0(0 &amp;lt;&amp;lt; 0)
-#define FSMC_TWAIT_6(6 &amp;lt;&amp;lt; 8)
-#define FSMC_THOLD_4(4 &amp;lt;&amp;lt; 16)
-#define FSMC_THIZ_1(1 &amp;lt;&amp;lt; 24)
-
-extern int spear_nand_init(struct nand_chip *nand);
-#endif
diff --git a/drivers/mtd/nand/spr_nand.c b/drivers/mtd/nand/spr_nand.c
deleted file mode 100644
index 097d0c6..0000000
--- a/drivers/mtd/nand/spr_nand.c
+++ /dev/null
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1,124 +0,0 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
-/*
- * (C) Copyright 2009
- * Vipin Kumar, ST Micoelectronics, vipin.kumar&amp;lt; at &amp;gt;st.com.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include &amp;lt;common.h&amp;gt;
-#include &amp;lt;nand.h&amp;gt;
-#include &amp;lt;linux/mtd/nand_ecc.h&amp;gt;
-#include &amp;lt;asm/io.h&amp;gt;
-#include &amp;lt;asm/arch/hardware.h&amp;gt;
-#include &amp;lt;asm/arch/spr_nand.h&amp;gt;
-
-static struct fsmc_regs *const fsmc_regs_p =
-    (struct fsmc_regs *)CONFIG_SPEAR_FSMCBASE;
-
-static struct nand_ecclayout spear_nand_ecclayout = {
-.eccbytes = 24,
-.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
-   66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
-.oobfree = {
-    {.offset = 8, .length = 8},
-    {.offset = 24, .length = 8},
-    {.offset = 40, .length = 8},
-    {.offset = 56, .length = 8},
-    {.offset = 72, .length = 8},
-    {.offset = 88, .length = 8},
-    {.offset = 104, .length = 8},
-    {.offset = 120, .length = 8}
-    }
-};
-
-static void spear_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl)
-{
-struct nand_chip *this = mtd-&amp;gt;priv;
-ulong IO_ADDR_W;
-
-if (ctrl &amp;amp; NAND_CTRL_CHANGE) {
-IO_ADDR_W = (ulong)this-&amp;gt;IO_ADDR_W;
-
-IO_ADDR_W &amp;amp;= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE);
-if (ctrl &amp;amp; NAND_CLE)
-IO_ADDR_W |= CONFIG_SYS_NAND_CLE;
-if (ctrl &amp;amp; NAND_ALE)
-IO_ADDR_W |= CONFIG_SYS_NAND_ALE;
-
-if (ctrl &amp;amp; NAND_NCE) {
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) |
-       FSMC_ENABLE, &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-} else {
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) &amp;amp;
-       ~FSMC_ENABLE, &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-}
-this-&amp;gt;IO_ADDR_W = (void *)IO_ADDR_W;
-}
-
-if (cmd != NAND_CMD_NONE)
-writeb(cmd, this-&amp;gt;IO_ADDR_W);
-}
-
-static int spear_read_hwecc(struct mtd_info *mtd,
-    const u_char *data, u_char ecc[3])
-{
-u_int ecc_tmp;
-
-/* read the h/w ECC */
-ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_ecc);
-
-ecc[0] = (u_char) (ecc_tmp &amp;amp; 0xFF);
-ecc[1] = (u_char) ((ecc_tmp &amp;amp; 0xFF00) &amp;gt;&amp;gt; 8);
-ecc[2] = (u_char) ((ecc_tmp &amp;amp; 0xFF0000) &amp;gt;&amp;gt; 16);
-
-return 0;
-}
-
-void spear_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) &amp;amp; ~0x80,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) &amp;amp; ~FSMC_ECCEN,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) | FSMC_ECCEN,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-}
-
-int spear_nand_init(struct nand_chip *nand)
-{
-writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc) | FSMC_TCLR_1 | FSMC_TAR_1,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_pc);
-writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_comm);
-writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
-       &amp;amp;fsmc_regs_p-&amp;gt;genmemctrl_attrib);
-
-nand-&amp;gt;options = 0;
-nand-&amp;gt;ecc.mode = NAND_ECC_HW;
-nand-&amp;gt;ecc.layout = &amp;amp;spear_nand_ecclayout;
-nand-&amp;gt;ecc.size = 512;
-nand-&amp;gt;ecc.bytes = 3;
-nand-&amp;gt;ecc.calculate = spear_read_hwecc;
-nand-&amp;gt;ecc.hwctl = spear_enable_hwecc;
-nand-&amp;gt;ecc.correct = nand_correct_data;
-nand-&amp;gt;cmd_ctrl = spear_nand_hwcontrol;
-return 0;
-}
&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T05:28:12</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132144">
    <title>[PATCH V5 RESEND 1/3] mtd/NAND: Add FSMC driver support</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132144</link>
    <description>&lt;pre&gt;From: Vipin KUMAR &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;

Flexible static memory controller is a peripheral provided by ST,
which controls the access to NAND chips along with many other
memory device chips eg NOR, SRAM.

This patch adds the driver support for FSMC controller interfacing
with NAND memory.

Signed-off-by: Vipin Kumar &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;
Signed-off-by: Amit Virdi &amp;lt;amit.virdi&amp;lt; at &amp;gt;st.com&amp;gt;
---
 drivers/mtd/nand/Makefile     |    1 +
 drivers/mtd/nand/fsmc_nand.c  |  487 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/fsmc_nand.h |  101 +++++++++
 3 files changed, 589 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/fsmc_nand.c
 create mode 100644 include/linux/mtd/fsmc_nand.h

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1d1b628..29dc20e 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -49,6 +49,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; COBJS-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
 COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
 COBJS-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
 COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
+COBJS-$(CONFIG_NAND_FSMC) += fsmc_nand.o
 COBJS-$(CONFIG_NAND_JZ4740) += jz4740_nand.o
 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
new file mode 100644
index 0000000..292fa8c
--- /dev/null
+++ b/drivers/mtd/nand/fsmc_nand.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,487 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar&amp;lt; at &amp;gt;st.com.
+ *
+ * (C) Copyright 2012
+ * Amit Virdi, ST Micoelectronics, amit.virdi&amp;lt; at &amp;gt;st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include &amp;lt;common.h&amp;gt;
+#include &amp;lt;nand.h&amp;gt;
+#include &amp;lt;asm/io.h&amp;gt;
+#include &amp;lt;linux/bitops.h&amp;gt;
+#include &amp;lt;linux/err.h&amp;gt;
+#include &amp;lt;linux/mtd/nand_ecc.h&amp;gt;
+#include &amp;lt;linux/mtd/fsmc_nand.h&amp;gt;
+#include &amp;lt;asm/arch/hardware.h&amp;gt;
+
+static u32 fsmc_version;
+static struct fsmc_regs *const fsmc_regs_p = (struct fsmc_regs *)
+CONFIG_SYS_FSMC_BASE;
+
+/*
+ * ECC4 and ECC1 have 13 bytes and 3 bytes of ecc respectively for 512 bytes of
+ * data. ECC4 can correct up to 8 bits in 512 bytes of data while ECC1 can
+ * correct 1 bit in 512 bytes
+ */
+
+static struct nand_ecclayout fsmc_ecc4_lp_layout = {
+.eccbytes = 104,
+.eccpos = {  2,   3,   4,   5,   6,   7,   8,
+9,  10,  11,  12,  13,  14,
+18,  19,  20,  21,  22,  23,  24,
+25,  26,  27,  28,  29,  30,
+34,  35,  36,  37,  38,  39,  40,
+41,  42,  43,  44,  45,  46,
+50,  51,  52,  53,  54,  55,  56,
+57,  58,  59,  60,  61,  62,
+66,  67,  68,  69,  70,  71,  72,
+73,  74,  75,  76,  77,  78,
+82,  83,  84,  85,  86,  87,  88,
+89,  90,  91,  92,  93,  94,
+98,  99, 100, 101, 102, 103, 104,
+105, 106, 107, 108, 109, 110,
+114, 115, 116, 117, 118, 119, 120,
+121, 122, 123, 124, 125, 126
+},
+.oobfree = {
+{.offset = 15, .length = 3},
+{.offset = 31, .length = 3},
+{.offset = 47, .length = 3},
+{.offset = 63, .length = 3},
+{.offset = 79, .length = 3},
+{.offset = 95, .length = 3},
+{.offset = 111, .length = 3},
+{.offset = 127, .length = 1}
+}
+};
+
+/*
+ * ECC4 layout for NAND of pagesize 4096 bytes &amp;amp; OOBsize 224 bytes. 13*8 bytes
+ * of OOB size is reserved for ECC, Byte no. 0 &amp;amp; 1 reserved for bad block &amp;amp; 118
+ * bytes are free for use.
+ */
+static struct nand_ecclayout fsmc_ecc4_224_layout = {
+.eccbytes = 104,
+.eccpos = {  2,   3,   4,   5,   6,   7,   8,
+9,  10,  11,  12,  13,  14,
+18,  19,  20,  21,  22,  23,  24,
+25,  26,  27,  28,  29,  30,
+34,  35,  36,  37,  38,  39,  40,
+41,  42,  43,  44,  45,  46,
+50,  51,  52,  53,  54,  55,  56,
+57,  58,  59,  60,  61,  62,
+66,  67,  68,  69,  70,  71,  72,
+73,  74,  75,  76,  77,  78,
+82,  83,  84,  85,  86,  87,  88,
+89,  90,  91,  92,  93,  94,
+98,  99, 100, 101, 102, 103, 104,
+105, 106, 107, 108, 109, 110,
+114, 115, 116, 117, 118, 119, 120,
+121, 122, 123, 124, 125, 126
+},
+.oobfree = {
+{.offset = 15, .length = 3},
+{.offset = 31, .length = 3},
+{.offset = 47, .length = 3},
+{.offset = 63, .length = 3},
+{.offset = 79, .length = 3},
+{.offset = 95, .length = 3},
+{.offset = 111, .length = 3},
+{.offset = 127, .length = 97}
+}
+};
+
+/*
+ * ECC placement definitions in oobfree type format
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data
+ * Managing the ecc bytes in the following way makes it easier for software to
+ * read ecc bytes consecutive to data bytes. This way is similar to
+ * oobfree structure maintained already in u-boot nand driver
+ */
+static struct fsmc_eccplace fsmc_eccpl_lp = {
+.eccplace = {
+{.offset = 2, .length = 13},
+{.offset = 18, .length = 13},
+{.offset = 34, .length = 13},
+{.offset = 50, .length = 13},
+{.offset = 66, .length = 13},
+{.offset = 82, .length = 13},
+{.offset = 98, .length = 13},
+{.offset = 114, .length = 13}
+}
+};
+
+static struct nand_ecclayout fsmc_ecc4_sp_layout = {
+.eccbytes = 13,
+.eccpos = { 0,  1,  2,  3,  6,  7, 8,
+9, 10, 11, 12, 13, 14
+},
+.oobfree = {
+{.offset = 15, .length = 1},
+}
+};
+
+static struct fsmc_eccplace fsmc_eccpl_sp = {
+.eccplace = {
+{.offset = 0, .length = 4},
+{.offset = 6, .length = 9}
+}
+};
+
+static struct nand_ecclayout fsmc_ecc1_layout = {
+.eccbytes = 24,
+.eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
+66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
+.oobfree = {
+{.offset = 8, .length = 8},
+{.offset = 24, .length = 8},
+{.offset = 40, .length = 8},
+{.offset = 56, .length = 8},
+{.offset = 72, .length = 8},
+{.offset = 88, .length = 8},
+{.offset = 104, .length = 8},
+{.offset = 120, .length = 8}
+}
+};
+
+/* Count the number of 0's in buff upto a max of max_bits */
+static int count_written_bits(uint8_t *buff, int size, int max_bits)
+{
+int k, written_bits = 0;
+
+for (k = 0; k &amp;lt; size; k++) {
+written_bits += hweight8(~buff[k]);
+if (written_bits &amp;gt; max_bits)
+break;
+}
+
+return written_bits;
+}
+
+static void fsmc_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl)
+{
+struct nand_chip *this = mtd-&amp;gt;priv;
+ulong IO_ADDR_W;
+
+if (ctrl &amp;amp; NAND_CTRL_CHANGE) {
+IO_ADDR_W = (ulong)this-&amp;gt;IO_ADDR_W;
+
+IO_ADDR_W &amp;amp;= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE);
+if (ctrl &amp;amp; NAND_CLE)
+IO_ADDR_W |= CONFIG_SYS_NAND_CLE;
+if (ctrl &amp;amp; NAND_ALE)
+IO_ADDR_W |= CONFIG_SYS_NAND_ALE;
+
+if (ctrl &amp;amp; NAND_NCE) {
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) |
+FSMC_ENABLE, &amp;amp;fsmc_regs_p-&amp;gt;pc);
+} else {
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) &amp;amp;
+~FSMC_ENABLE, &amp;amp;fsmc_regs_p-&amp;gt;pc);
+}
+this-&amp;gt;IO_ADDR_W = (void *)IO_ADDR_W;
+}
+
+if (cmd != NAND_CMD_NONE)
+writeb(cmd, this-&amp;gt;IO_ADDR_W);
+}
+
+static int fsmc_bch8_correct_data(struct mtd_info *mtd, u_char *dat,
+u_char *read_ecc, u_char *calc_ecc)
+{
+/* The calculated ecc is actually the correction index in data */
+u32 err_idx[8];
+u32 num_err, i;
+u32 ecc1, ecc2, ecc3, ecc4;
+
+num_err = (readl(&amp;amp;fsmc_regs_p-&amp;gt;sts) &amp;gt;&amp;gt; 10) &amp;amp; 0xF;
+
+if (likely(num_err == 0))
+return 0;
+
+if (unlikely(num_err &amp;gt; 8)) {
+/*
+ * This is a temporary erase check. A newly erased page read
+ * would result in an ecc error because the oob data is also
+ * erased to FF and the calculated ecc for an FF data is not
+ * FF..FF.
+ * This is a workaround to skip performing correction in case
+ * data is FF..FF
+ *
+ * Logic:
+ * For every page, each bit written as 0 is counted until these
+ * number of bits are greater than 8 (the maximum correction
+ * capability of FSMC for each 512 + 13 bytes)
+ */
+
+int bits_ecc = count_written_bits(read_ecc, 13, 8);
+int bits_data = count_written_bits(dat, 512, 8);
+
+if ((bits_ecc + bits_data) &amp;lt;= 8) {
+if (bits_data)
+memset(dat, 0xff, 512);
+return bits_data + bits_ecc;
+}
+
+return -EBADMSG;
+}
+
+ecc1 = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc1);
+ecc2 = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc2);
+ecc3 = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc3);
+ecc4 = readl(&amp;amp;fsmc_regs_p-&amp;gt;sts);
+
+err_idx[0] = (ecc1 &amp;gt;&amp;gt; 0) &amp;amp; 0x1FFF;
+err_idx[1] = (ecc1 &amp;gt;&amp;gt; 13) &amp;amp; 0x1FFF;
+err_idx[2] = (((ecc2 &amp;gt;&amp;gt; 0) &amp;amp; 0x7F) &amp;lt;&amp;lt; 6) | ((ecc1 &amp;gt;&amp;gt; 26) &amp;amp; 0x3F);
+err_idx[3] = (ecc2 &amp;gt;&amp;gt; 7) &amp;amp; 0x1FFF;
+err_idx[4] = (((ecc3 &amp;gt;&amp;gt; 0) &amp;amp; 0x1) &amp;lt;&amp;lt; 12) | ((ecc2 &amp;gt;&amp;gt; 20) &amp;amp; 0xFFF);
+err_idx[5] = (ecc3 &amp;gt;&amp;gt; 1) &amp;amp; 0x1FFF;
+err_idx[6] = (ecc3 &amp;gt;&amp;gt; 14) &amp;amp; 0x1FFF;
+err_idx[7] = (((ecc4 &amp;gt;&amp;gt; 16) &amp;amp; 0xFF) &amp;lt;&amp;lt; 5) | ((ecc3 &amp;gt;&amp;gt; 27) &amp;amp; 0x1F);
+
+i = 0;
+while (i &amp;lt; num_err) {
+err_idx[i] ^= 3;
+
+if (err_idx[i] &amp;lt; 512 * 8) {
+u8 *p = dat + err_idx[i] / 8;
+*p = *p ^ (1 &amp;lt;&amp;lt; (err_idx[i] % 8));
+}
+i++;
+}
+
+return num_err;
+}
+
+static int fsmc_read_hwecc(struct mtd_info *mtd,
+const u_char *data, u_char *ecc)
+{
+u_int ecc_tmp;
+int timeout = CONFIG_SYS_HZ;
+ulong start;
+
+switch (fsmc_version) {
+case FSMC_VER8:
+start = get_timer(0);
+while (get_timer(start) &amp;lt; timeout) {
+/*
+ * Busy waiting for ecc computation
+ * to finish for 512 bytes
+ */
+if (readl(&amp;amp;fsmc_regs_p-&amp;gt;sts) &amp;amp; FSMC_CODE_RDY)
+break;
+}
+
+ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc1);
+ecc[0] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 0);
+ecc[1] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 8);
+ecc[2] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 16);
+ecc[3] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 24);
+
+ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc2);
+ecc[4] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 0);
+ecc[5] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 8);
+ecc[6] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 16);
+ecc[7] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 24);
+
+ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc3);
+ecc[8] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 0);
+ecc[9] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 8);
+ecc[10] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 16);
+ecc[11] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 24);
+
+ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;sts);
+ecc[12] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 16);
+break;
+
+default:
+ecc_tmp = readl(&amp;amp;fsmc_regs_p-&amp;gt;ecc1);
+ecc[0] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 0);
+ecc[1] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 8);
+ecc[2] = (u_char) (ecc_tmp &amp;gt;&amp;gt; 16);
+break;
+}
+
+return 0;
+}
+
+void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) &amp;amp; ~FSMC_ECCPLEN_256,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) &amp;amp; ~FSMC_ECCEN,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) | FSMC_ECCEN,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+}
+
+/*
+ * fsmc_read_page_hwecc
+ * &amp;lt; at &amp;gt;mtd:mtd info structure
+ * &amp;lt; at &amp;gt;chip:nand chip info structure
+ * &amp;lt; at &amp;gt;buf:buffer to store read data
+ * &amp;lt; at &amp;gt;page:page number to read
+ *
+ * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
+ * performed in a strict sequence as follows:
+ * data(512 byte) -&amp;gt; ecc(13 byte)
+ * After this read, fsmc hardware generates and reports error data bits(upto a
+ * max of 8 bits)
+ */
+static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf, int page)
+{
+struct fsmc_eccplace *fsmc_eccpl;
+int i, j, s, stat, eccsize = chip-&amp;gt;ecc.size;
+int eccbytes = chip-&amp;gt;ecc.bytes;
+int eccsteps = chip-&amp;gt;ecc.steps;
+uint8_t *p = buf;
+uint8_t *ecc_calc = chip-&amp;gt;buffers-&amp;gt;ecccalc;
+uint8_t *ecc_code = chip-&amp;gt;buffers-&amp;gt;ecccode;
+int off, len, group = 0;
+uint8_t oob[13] __attribute__((aligned(2)));
+
+/* Differentiate between small and large page ecc place definitions */
+if (mtd-&amp;gt;writesize == 512)
+fsmc_eccpl = &amp;amp;fsmc_eccpl_sp;
+else
+fsmc_eccpl = &amp;amp;fsmc_eccpl_lp;
+
+for (i = 0, s = 0; s &amp;lt; eccsteps; s++, i += eccbytes, p += eccsize) {
+
+chip-&amp;gt;cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
+chip-&amp;gt;ecc.hwctl(mtd, NAND_ECC_READ);
+chip-&amp;gt;read_buf(mtd, p, eccsize);
+
+for (j = 0; j &amp;lt; eccbytes;) {
+off = fsmc_eccpl-&amp;gt;eccplace[group].offset;
+len = fsmc_eccpl-&amp;gt;eccplace[group].length;
+group++;
+
+/*
+ * length is intentionally kept a higher multiple of 2
+ * to read at least 13 bytes even in case of 16 bit NAND
+ * devices
+ */
+if (chip-&amp;gt;options &amp;amp; NAND_BUSWIDTH_16)
+len = roundup(len, 2);
+chip-&amp;gt;cmdfunc(mtd, NAND_CMD_READOOB, off, page);
+chip-&amp;gt;read_buf(mtd, oob + j, len);
+j += len;
+}
+
+memcpy(&amp;amp;ecc_code[i], oob, 13);
+chip-&amp;gt;ecc.calculate(mtd, p, &amp;amp;ecc_calc[i]);
+
+stat = chip-&amp;gt;ecc.correct(mtd, p, &amp;amp;ecc_code[i],
+&amp;amp;ecc_calc[i]);
+if (stat &amp;lt; 0)
+mtd-&amp;gt;ecc_stats.failed++;
+else
+mtd-&amp;gt;ecc_stats.corrected += stat;
+}
+
+return 0;
+}
+
+int fsmc_nand_init(struct nand_chip *nand)
+{
+static int chip_nr;
+struct mtd_info *mtd;
+int i;
+u32 peripid2 = readl(&amp;amp;fsmc_regs_p-&amp;gt;peripid2);
+
+fsmc_version = (peripid2 &amp;gt;&amp;gt; FSMC_REVISION_SHFT) &amp;amp;
+FSMC_REVISION_MSK;
+
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;ctrl) | FSMC_WP, &amp;amp;fsmc_regs_p-&amp;gt;ctrl);
+
+#if defined(CONFIG_SYS_FSMC_NAND_16BIT)
+writel(FSMC_DEVWID_16 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+#elif defined(CONFIG_SYS_FSMC_NAND_8BIT)
+writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+#else
+#error Please define CONFIG_SYS_FSMC_NAND_16BIT or CONFIG_SYS_FSMC_NAND_8BIT
+#endif
+writel(readl(&amp;amp;fsmc_regs_p-&amp;gt;pc) | FSMC_TCLR_1 | FSMC_TAR_1,
+&amp;amp;fsmc_regs_p-&amp;gt;pc);
+writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+&amp;amp;fsmc_regs_p-&amp;gt;comm);
+writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+&amp;amp;fsmc_regs_p-&amp;gt;attrib);
+
+nand-&amp;gt;options = 0;
+#if defined(CONFIG_SYS_FSMC_NAND_16BIT)
+nand-&amp;gt;options |= NAND_BUSWIDTH_16;
+#endif
+nand-&amp;gt;ecc.mode = NAND_ECC_HW;
+nand-&amp;gt;ecc.size = 512;
+nand-&amp;gt;ecc.calculate = fsmc_read_hwecc;
+nand-&amp;gt;ecc.hwctl = fsmc_enable_hwecc;
+nand-&amp;gt;cmd_ctrl = fsmc_nand_hwcontrol;
+nand-&amp;gt;IO_ADDR_R = nand-&amp;gt;IO_ADDR_W =
+(void  __iomem *)CONFIG_SYS_NAND_BASE;
+nand-&amp;gt;badblockbits = 7;
+
+mtd = &amp;amp;nand_info[chip_nr++];
+mtd-&amp;gt;priv = nand;
+
+switch (fsmc_version) {
+case FSMC_VER8:
+nand-&amp;gt;ecc.bytes = 13;
+nand-&amp;gt;ecc.correct = fsmc_bch8_correct_data;
+nand-&amp;gt;ecc.read_page = fsmc_read_page_hwecc;
+if (mtd-&amp;gt;writesize == 512)
+nand-&amp;gt;ecc.layout = &amp;amp;fsmc_ecc4_sp_layout;
+else {
+if (mtd-&amp;gt;oobsize == 224)
+nand-&amp;gt;ecc.layout = &amp;amp;fsmc_ecc4_224_layout;
+else
+nand-&amp;gt;ecc.layout = &amp;amp;fsmc_ecc4_lp_layout;
+}
+
+break;
+default:
+nand-&amp;gt;ecc.bytes = 3;
+nand-&amp;gt;ecc.layout = &amp;amp;fsmc_ecc1_layout;
+nand-&amp;gt;ecc.correct = nand_correct_data;
+break;
+}
+
+/* Detect NAND chips */
+if (nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_DEVICE, NULL))
+return -ENXIO;
+
+if (nand_scan_tail(mtd))
+return -ENXIO;
+
+for (i = 0; i &amp;lt; CONFIG_SYS_MAX_NAND_DEVICE; i++)
+if (nand_register(i))
+return -ENXIO;
+
+return 0;
+}
diff --git a/include/linux/mtd/fsmc_nand.h b/include/linux/mtd/fsmc_nand.h
new file mode 100644
index 0000000..3a61cea
--- /dev/null
+++ b/include/linux/mtd/fsmc_nand.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,101 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar&amp;lt; at &amp;gt;st.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FSMC_NAND_H__
+#define __FSMC_NAND_H__
+
+#include &amp;lt;linux/mtd/nand.h&amp;gt;
+
+struct fsmc_regs {
+u32 ctrl;/* 0x00 */
+u8 reserved_1[0x40 - 0x04];
+u32 pc;/* 0x40 */
+u32 sts;/* 0x44 */
+u32 comm;/* 0x48 */
+u32 attrib;/* 0x4c */
+u32 ioata;/* 0x50 */
+u32 ecc1;/* 0x54 */
+u32 ecc2;/* 0x58 */
+u32 ecc3;/* 0x5c */
+u8 reserved_2[0xfe0 - 0x60];
+u32 peripid0;/* 0xfe0 */
+u32 peripid1;/* 0xfe4 */
+u32 peripid2;/* 0xfe8 */
+u32 peripid3;/* 0xfec */
+u32 pcellid0;/* 0xff0 */
+u32 pcellid1;/* 0xff4 */
+u32 pcellid2;/* 0xff8 */
+u32 pcellid3;/* 0xffc */
+};
+
+/* ctrl register definitions */
+#define FSMC_WP(1 &amp;lt;&amp;lt; 7)
+
+/* pc register definitions */
+#define FSMC_RESET(1 &amp;lt;&amp;lt; 0)
+#define FSMC_WAITON(1 &amp;lt;&amp;lt; 1)
+#define FSMC_ENABLE(1 &amp;lt;&amp;lt; 2)
+#define FSMC_DEVTYPE_NAND(1 &amp;lt;&amp;lt; 3)
+#define FSMC_DEVWID_8(0 &amp;lt;&amp;lt; 4)
+#define FSMC_DEVWID_16(1 &amp;lt;&amp;lt; 4)
+#define FSMC_ECCEN(1 &amp;lt;&amp;lt; 6)
+#define FSMC_ECCPLEN_512(0 &amp;lt;&amp;lt; 7)
+#define FSMC_ECCPLEN_256(1 &amp;lt;&amp;lt; 7)
+#define FSMC_TCLR_1(1 &amp;lt;&amp;lt; 9)
+#define FSMC_TAR_1(1 &amp;lt;&amp;lt; 13)
+
+/* sts register definitions */
+#define FSMC_CODE_RDY(1 &amp;lt;&amp;lt; 15)
+
+/* comm register definitions */
+#define FSMC_TSET_0(0 &amp;lt;&amp;lt; 0)
+#define FSMC_TWAIT_6(6 &amp;lt;&amp;lt; 8)
+#define FSMC_THOLD_4(4 &amp;lt;&amp;lt; 16)
+#define FSMC_THIZ_1(1 &amp;lt;&amp;lt; 24)
+
+/* peripid2 register definitions */
+#define FSMC_REVISION_MSK(0xf)
+#define FSMC_REVISION_SHFT(0x4)
+
+#define FSMC_VER80x8
+
+/*
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets
+ * Managing the ecc bytes in the following way is easier. This way is similar to
+ * oobfree structure maintained already in u-boot nand driver
+ */
+#define FSMC_MAX_ECCPLACE_ENTRIES32
+
+struct fsmc_nand_eccplace {
+u32 offset;
+u32 length;
+};
+
+struct fsmc_eccplace {
+struct fsmc_nand_eccplace eccplace[FSMC_MAX_ECCPLACE_ENTRIES];
+};
+
+extern int fsmc_nand_init(struct nand_chip *nand);
+#endif
&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T05:28:10</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132143">
    <title>[PATCH V5 RESEND 2/3] SPEAr: Configure FSMC driver forNAND interface</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132143</link>
    <description>&lt;pre&gt;From: Vipin KUMAR &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;

Since FSMC is a standard IP and it supports different memory interfaces, it
is supported independent of spear platform and spear is configured to use that
driver for interfacing with the NAND device

Signed-off-by: Vipin Kumar &amp;lt;vipin.kumar&amp;lt; at &amp;gt;st.com&amp;gt;
Signed-off-by: Amit Virdi &amp;lt;amit.virdi&amp;lt; at &amp;gt;st.com&amp;gt;
---
 arch/arm/include/asm/arch-spear/hardware.h |    8 ++++----
 board/spear/spear300/spear300.c            |   14 +++++++++-----
 board/spear/spear310/spear310.c            |   14 +++++++++-----
 board/spear/spear320/spear320.c            |   13 +++++++++----
 board/spear/spear600/spear600.c            |   14 +++++++++-----
 include/configs/spear-common.h             |    3 ++-
 include/configs/spear3xx.h                 |    4 ++++
 include/configs/spear6xx.h                 |    3 +++
 8 files changed, 49 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/arch-spear/hardware.h b/arch/arm/include/asm/arch-spear/hardware.h
index 818f36c..a6517b2 100644
--- a/arch/arm/include/asm/arch-spear/hardware.h
+++ b/arch/arm/include/asm/arch-spear/hardware.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -37,15 +37,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #if defined(CONFIG_SPEAR600)
 #define CONFIG_SYS_I2C_BASE(0xD0200000)
-#define CONFIG_SPEAR_FSMCBASE(0xD1800000)
+#define CONFIG_SYS_FSMC_BASE(0xD1800000)
 
 #elif defined(CONFIG_SPEAR300)
 #define CONFIG_SYS_I2C_BASE(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE(0x94000000)
+#define CONFIG_SYS_FSMC_BASE(0x94000000)
 
 #elif defined(CONFIG_SPEAR310)
 #define CONFIG_SYS_I2C_BASE(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE(0x44000000)
+#define CONFIG_SYS_FSMC_BASE(0x44000000)
 
 #undef CONFIG_SYS_NAND_CLE
 #undef CONFIG_SYS_NAND_ALE
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -57,7 +57,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #elif defined(CONFIG_SPEAR320)
 #define CONFIG_SYS_I2C_BASE(0xD0180000)
-#define CONFIG_SPEAR_FSMCBASE(0x4C000000)
+#define CONFIG_SYS_FSMC_BASE(0x4C000000)
 
 #define CONFIG_SPEAR_EMIBASE(0x40000000)
 #define CONFIG_SPEAR_RASBASE(0xB3000000)
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index 60ee544..72a3631 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -24,10 +24,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;common.h&amp;gt;
 #include &amp;lt;nand.h&amp;gt;
 #include &amp;lt;asm/io.h&amp;gt;
+#include &amp;lt;linux/mtd/fsmc_nand.h&amp;gt;
 #include &amp;lt;asm/arch/hardware.h&amp;gt;
 #include &amp;lt;asm/arch/spr_defs.h&amp;gt;
 #include &amp;lt;asm/arch/spr_misc.h&amp;gt;
-#include &amp;lt;asm/arch/spr_nand.h&amp;gt;
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 
 int board_init(void)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -41,18 +43,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int board_init(void)
  * Called by nand_init_chip to initialize the board specific functions
  */
 
-int board_nand_init(struct nand_chip *nand)
+void board_nand_init()
 {
 struct misc_regs *const misc_regs_p =
     (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+struct nand_chip *nand = &amp;amp;nand_chip[0];
 
+#if defined(CONFIG_NAND_FSMC)
 if (((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG30) ||
     ((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG31)) {
 
-return spear_nand_init(nand);
+fsmc_nand_init(nand);
 }
-
-return -1;
+#endif
+return;
 }
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index 03dfe16..14e666d 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -25,10 +25,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;common.h&amp;gt;
 #include &amp;lt;nand.h&amp;gt;
 #include &amp;lt;asm/io.h&amp;gt;
+#include &amp;lt;linux/mtd/fsmc_nand.h&amp;gt;
 #include &amp;lt;asm/arch/hardware.h&amp;gt;
 #include &amp;lt;asm/arch/spr_defs.h&amp;gt;
 #include &amp;lt;asm/arch/spr_misc.h&amp;gt;
-#include &amp;lt;asm/arch/spr_nand.h&amp;gt;
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 
 int board_init(void)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -42,18 +44,20 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int board_init(void)
  * Called by nand_init_chip to initialize the board specific functions
  */
 
-int board_nand_init(struct nand_chip *nand)
+void board_nand_init()
 {
 struct misc_regs *const misc_regs_p =
     (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+struct nand_chip *nand = &amp;amp;nand_chip[0];
 
+#if defined(CONFIG_NAND_FSMC)
 if (((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG30) ||
     ((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG31)) {
 
-return spear_nand_init(nand);
+fsmc_nand_init(nand);
 }
-
-return -1;
+#endif
+return;
 }
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index 2ba2dbb..994eb2b 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -25,10 +25,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;common.h&amp;gt;
 #include &amp;lt;nand.h&amp;gt;
 #include &amp;lt;asm/io.h&amp;gt;
+#include &amp;lt;linux/mtd/fsmc_nand.h&amp;gt;
 #include &amp;lt;asm/arch/hardware.h&amp;gt;
 #include &amp;lt;asm/arch/spr_defs.h&amp;gt;
 #include &amp;lt;asm/arch/spr_misc.h&amp;gt;
-#include &amp;lt;asm/arch/spr_nand.h&amp;gt;
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 
 int board_init(void)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -42,18 +44,21 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int board_init(void)
  * Called by nand_init_chip to initialize the board specific functions
  */
 
-int board_nand_init(struct nand_chip *nand)
+void board_nand_init()
 {
 struct misc_regs *const misc_regs_p =
     (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+struct nand_chip *nand = &amp;amp;nand_chip[0];
 
+#if defined(CONFIG_NAND_FSMC)
 if (((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG30) ||
     ((readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_SOCCFGMSK) ==
      MISC_SOCCFG31)) {
 
-return spear_nand_init(nand);
+fsmc_nand_init(nand);
 }
+#endif
 
-return -1;
+return;
 }
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index eef9a37..ab0f760 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -24,10 +24,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include &amp;lt;common.h&amp;gt;
 #include &amp;lt;nand.h&amp;gt;
 #include &amp;lt;asm/io.h&amp;gt;
+#include &amp;lt;linux/mtd/fsmc_nand.h&amp;gt;
 #include &amp;lt;asm/arch/hardware.h&amp;gt;
 #include &amp;lt;asm/arch/spr_defs.h&amp;gt;
 #include &amp;lt;asm/arch/spr_misc.h&amp;gt;
-#include &amp;lt;asm/arch/spr_nand.h&amp;gt;
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 
 int board_init(void)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -41,13 +43,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int board_init(void)
  * Called by nand_init_chip to initialize the board specific functions
  */
 
-int board_nand_init(struct nand_chip *nand)
+void board_nand_init()
 {
 struct misc_regs *const misc_regs_p =
     (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+struct nand_chip *nand = &amp;amp;nand_chip[0];
 
+#if defined(CONFIG_NAND_FSMC)
 if (!(readl(&amp;amp;misc_regs_p-&amp;gt;auto_cfg_reg) &amp;amp; MISC_NANDDIS))
-return spear_nand_init(nand);
-
-return -1;
+fsmc_nand_init(nand);
+#endif
+return;
 }
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index fa71590..14011af 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -88,9 +88,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define CONFIG_SYS_LOADS_BAUD_CHANGE
 
 /* NAND FLASH Configuration */
+#define CONFIG_SYS_NAND_SELF_INIT
 #define CONFIG_MTD_DEVICE
 #define CONFIG_MTD_PARTITIONS
-#define CONFIG_NAND_SPEAR1
+#define CONFIG_NAND_FSMC
 #define CONFIG_SYS_MAX_NAND_DEVICE1
 #define CONFIG_MTD_NAND_VERIFY_WRITE1
 
diff --git a/include/configs/spear3xx.h b/include/configs/spear3xx.h
index 37bdebb..2a86c21 100644
--- a/include/configs/spear3xx.h
+++ b/include/configs/spear3xx.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -117,6 +117,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #endif
 
+/* NAND flash configuration */
+#define CONFIG_SYS_FSMC_NAND_SP
+#define CONFIG_SYS_FSMC_NAND_8BIT
+
 #if defined(CONFIG_SPEAR300)
 #define CONFIG_SYS_NAND_BASE(0x80000000)
 
diff --git a/include/configs/spear6xx.h b/include/configs/spear6xx.h
index 2ad5beb..c5bcc30 100644
--- a/include/configs/spear6xx.h
+++ b/include/configs/spear6xx.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #define CONFIG_PL01x_PORTS{ (void *)CONFIG_SYS_SERIAL0, \
 (void *)CONFIG_SYS_SERIAL1 }
 
+/* NAND flash configuration */
+#define CONFIG_SYS_FSMC_NAND_SP
+#define CONFIG_SYS_FSMC_NAND_8BIT
 #define CONFIG_SYS_NAND_BASE(0xD2000000)
 
 #endif  /* __CONFIG_H */
&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T05:28:11</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132142">
    <title>[PATCH V5 RESEND 0/3] mtd/NAND: Support for FSMC controller</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132142</link>
    <description>&lt;pre&gt;This patchset adds support for ST's FSMC controller. In the current u-boot, a
SPEAr specific driver exists for FSMC controller.  This patchset adds a full
fledged driver that can be used across multiple platforms and removes the
obsolete SPEAr specific driver.

V4 -&amp;gt; V5
 - Dropped the patch that defined change_bit as wrapper over __change_bit and,
   instead, defined logic to correct bit errors without using __change_bit

V3 -&amp;gt; V4
 - Removed local_irq_save and local_irq_restore calls from change_bit wrapper
 - Report the total bit flips, including that of ECC, to the upper layers
 - Replace change_bit calls for err_idx's 0th and 1st bit with "^= 3" operation

V2 -&amp;gt; V3
 - Implemented timeout during hardware ecc read
 - Used __attribute__ ((aligned(2))) instead of using array of U16
 - Removed unnecessary enum

V1 -&amp;gt; V2
 - Defined CONFIG_SYS_NAND_SELF_INIT and did the related changes
 - Modified the error index calculation process
 - Modified newly erased page read algorithm
 - Initialized the badblockbits index to 7
 - Improved fsmc_bch8_correct_data() implementation

Vipin KUMAR (3):
  mtd/NAND: Add FSMC driver support
  SPEAr: Configure FSMC driver for NAND interface
  mtd/NAND: Remove obsolete SPEAr specific NAND drivers

 arch/arm/include/asm/arch-spear/hardware.h |    8 +-
 arch/arm/include/asm/arch-spear/spr_nand.h |   57 ----
 board/spear/spear300/spear300.c            |   14 +-
 board/spear/spear310/spear310.c            |   14 +-
 board/spear/spear320/spear320.c            |   13 +-
 board/spear/spear600/spear600.c            |   14 +-
 drivers/mtd/nand/Makefile                  |    1 +
 drivers/mtd/nand/fsmc_nand.c               |  487 ++++++++++++++++++++++++++++
 drivers/mtd/nand/spr_nand.c                |  124 -------
 include/configs/spear-common.h             |    3 +-
 include/configs/spear3xx.h                 |    4 +
 include/configs/spear6xx.h                 |    3 +
 include/linux/mtd/fsmc_nand.h              |  101 ++++++
 13 files changed, 638 insertions(+), 205 deletions(-)
 delete mode 100644 arch/arm/include/asm/arch-spear/spr_nand.h
 create mode 100644 drivers/mtd/nand/fsmc_nand.c
 delete mode 100644 drivers/mtd/nand/spr_nand.c
 create mode 100644 include/linux/mtd/fsmc_nand.h

&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T05:28:09</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132141">
    <title>Re: [PATCH v5 5/5] Kirkwood: add lschlv2 and lsxhl boardsupport</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132141</link>
    <description>&lt;pre&gt;


I will do it on this weekend

Regards..
Prafulla . . .
&lt;/pre&gt;</description>
    <dc:creator>Prafulla Wadaskar</dc:creator>
    <dc:date>2012-05-24T04:50:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132140">
    <title>Re: [PATCH] config.mk:Update DBGFLAGS with dwarfinformation</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132140</link>
    <description>&lt;pre&gt;Hi Prabhakar,

On Thu, May 24, 2012 at 2:43 PM, Prabhakar Kushwaha
&amp;lt;prabhakar&amp;lt; at &amp;gt;freescale.com&amp;gt; wrote:

Mike Frysinger posted a comment on May 14, 2012:

[quote]
no real information here as to what is going wrong.  the -g flag provides debug
information and many people (myself included) have found this sufficient.

please describe your actual problem in detail and how this actually fixes
things for you.
-mike

[/quote]

Regards,

Graeme
&lt;/pre&gt;</description>
    <dc:creator>Graeme Russ</dc:creator>
    <dc:date>2012-05-24T04:47:16</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132139">
    <title>Re: [PATCH V5 0/3] mtd/NAND: Support for FSMC controller</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132139</link>
    <description>&lt;pre&gt;

On 5/22/2012 3:45 PM, Amit VIRDI wrote:

Please ignore this patchset. I'll be resending the same with a little 
modification.

Thanks
Amit Virdi
&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T04:46:17</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132138">
    <title>Re: [PATCH] config.mk:Update DBGFLAGS with dwarfinformation</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132138</link>
    <description>&lt;pre&gt;Hi Wolfgang,

This patch has been pending for a very long time.  No review comments 
has been provided.

Can you please review/accept this patch.


Regards,
Prabhakar


On 04/25/2012 09:41 AM, Prabhakar Kushwaha wrote:
&lt;/pre&gt;</description>
    <dc:creator>Prabhakar Kushwaha</dc:creator>
    <dc:date>2012-05-24T04:43:25</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132137">
    <title>Re: [PATCH v5 1/5] lib: add rand() function</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132137</link>
    <description>&lt;pre&gt;


If I consider the files being checked in, those are generic, I would suggest if Wolfgang can pull them.

Regards..
Prafulla . . .
&lt;/pre&gt;</description>
    <dc:creator>Prafulla Wadaskar</dc:creator>
    <dc:date>2012-05-24T04:32:07</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132136">
    <title>Re: EFI/GPT support in U-Boot : real-world tests</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132136</link>
    <description>&lt;pre&gt;


Hi Dave

At least I have not used it so far, so I am sorry about that :-(

Regards..
Prafulla . . .
&lt;/pre&gt;</description>
    <dc:creator>Prafulla Wadaskar</dc:creator>
    <dc:date>2012-05-24T04:28:36</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132135">
    <title>Re: [PATCH V4 1/4] ARM: Define change_bit routine</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132135</link>
    <description>&lt;pre&gt;Hi Wolfgang,

On 5/22/2012 9:21 PM, Wolfgang Denk wrote:

Ok. I have understood your point. I would resend V5 excluding any call 
to __change_bit.

Thanks
Amit Virdi
&lt;/pre&gt;</description>
    <dc:creator>Amit Virdi</dc:creator>
    <dc:date>2012-05-24T04:18:14</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132134">
    <title>Re: [PATCH 1/2] powerpc/p1022ds: add support for SPI and SD boot</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132134</link>
    <description>&lt;pre&gt;
My best guess on a patch from months ago is just trying to keep things
in sync with other boards.

-M
&lt;/pre&gt;</description>
    <dc:creator>McClintock Matthew-B29882</dc:creator>
    <dc:date>2012-05-24T02:35:25</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132133">
    <title>[PATCH v3 0/1] zfs: Add ZFS filesystem support</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132133</link>
    <description>&lt;pre&gt;Patch to add ZFS filesystem support to u-boot, based on GRUB sources.
Thank you for your patience.

Jorgen Lundman (1):
  Add ZFS filesystem support

 Makefile                     |    2 +-
 common/Makefile              |    1 +
 common/cmd_zfs.c             |  236 +++++
 fs/Makefile                  |    3 +-
 fs/{ =&amp;gt; zfs}/Makefile        |   39 +-
 fs/zfs/dev.c                 |  137 +++
 fs/zfs/zfs.c                 | 2396 ++++++++++++++++++++++++++++++++++++++++++
 fs/zfs/zfs_fletcher.c        |   84 ++
 fs/zfs/zfs_lzjb.c            |   94 ++
 fs/zfs/zfs_sha256.c          |  145 +++
 include/config_cmd_all.h     |    1 +
 include/zfs/dmu.h            |  119 +++
 include/zfs/dmu_objset.h     |   43 +
 include/zfs/dnode.h          |   80 ++
 include/zfs/dsl_dataset.h    |   52 +
 include/zfs/dsl_dir.h        |   48 +
 include/zfs/sa_impl.h        |   34 +
 include/zfs/spa.h            |  311 ++++++
 include/zfs/uberblock_impl.h |   57 +
 include/zfs/vdev_impl.h      |   69 ++
 include/zfs/zap_impl.h       |  112 ++
 include/zfs/zap_leaf.h       |  103 ++
 include/zfs/zfs.h            |  122 +++
 include/zfs/zfs_acl.h        |   55 +
 include/zfs/zfs_znode.h      |   70 ++
 include/zfs/zil.h            |   56 +
 include/zfs/zio.h            |   92 ++
 include/zfs/zio_checksum.h   |   49 +
 include/zfs_common.h         |   94 ++
 29 files changed, 4687 insertions(+), 17 deletions(-)
 create mode 100644 common/cmd_zfs.c
 copy fs/{ =&amp;gt; zfs}/Makefile (56%)
 create mode 100644 fs/zfs/dev.c
 create mode 100644 fs/zfs/zfs.c
 create mode 100644 fs/zfs/zfs_fletcher.c
 create mode 100644 fs/zfs/zfs_lzjb.c
 create mode 100644 fs/zfs/zfs_sha256.c
 create mode 100644 include/zfs/dmu.h
 create mode 100644 include/zfs/dmu_objset.h
 create mode 100644 include/zfs/dnode.h
 create mode 100644 include/zfs/dsl_dataset.h
 create mode 100644 include/zfs/dsl_dir.h
 create mode 100644 include/zfs/sa_impl.h
 create mode 100644 include/zfs/spa.h
 create mode 100644 include/zfs/uberblock_impl.h
 create mode 100644 include/zfs/vdev_impl.h
 create mode 100644 include/zfs/zap_impl.h
 create mode 100644 include/zfs/zap_leaf.h
 create mode 100644 include/zfs/zfs.h
 create mode 100644 include/zfs/zfs_acl.h
 create mode 100644 include/zfs/zfs_znode.h
 create mode 100644 include/zfs/zil.h
 create mode 100644 include/zfs/zio.h
 create mode 100644 include/zfs/zio_checksum.h
 create mode 100644 include/zfs_common.h
&lt;/pre&gt;</description>
    <dc:creator>Jorgen Lundman</dc:creator>
    <dc:date>2012-05-24T01:11:59</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132132">
    <title>Re: undefined reference to `net_set_upd_handler'</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132132</link>
    <description>&lt;pre&gt;Hi Joe,

thanks, now it compiles without error, tftpput works too.

br,
Stephan

Am Mittwoch, den 23.05.2012, 17:54 -0500 schrieb Joe Hershberger: 

&lt;/pre&gt;</description>
    <dc:creator>Stephan Linz</dc:creator>
    <dc:date>2012-05-23T23:20:08</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132131">
    <title>EFI/GPT support in U-Boot : real-world tests</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132131</link>
    <description>&lt;pre&gt;Hi folks,

I'm hoping that a few of you (perhaps Kirkwood users in particular)
can tell me of their own personal experiences (hopefully all good)
when using EFI/GPT partitions w/ U-Boot.

Does it work as advertised?

Is it just a matter of setting CONFIG_EFI_PARTITION in the config?

Any unexpected/counterintuitive/gottcha issues to think about?  (other
that proper kernel suppport)

thanks,

Dave
&lt;/pre&gt;</description>
    <dc:creator>David Purdy</dc:creator>
    <dc:date>2012-05-23T23:13:50</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132130">
    <title>Re: [U-Boot-Users] U-Boot WinCE booting support?</title>
    <link>http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/132130</link>
    <description>&lt;pre&gt;
Dear Luc

AFAIK, it has not been integrated in u-boot. In fact the patch was "ugly 
&amp;amp; dirty" but it works, at least on out Zefeer platform with WinCE 6.0 
(it work with previous versions too). We also ported it with ease on 
other platform (e.g. out Qong, which is an iMX31 based platform).

It can be find as attachment to the thread you already mention, here:

http://lists.denx.de/pipermail/u-boot/2008-February/029523.html

I hope you can find it useful and maybe clean it up and let it be more 
flexible and generic.

Best Regards,

Andrea

Il 23/05/2012 15:32, Luc Dechamp ha scritto:
&lt;/pre&gt;</description>
    <dc:creator>Andrea Scian</dc:creator>
    <dc:date>2012-05-23T15:09:37</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.comp.boot-loaders.u-boot">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.comp.boot-loaders.u-boot</link>
  </textinput>
</rdf:RDF>

