diff --git a/Kconfig b/Kconfig
index 24a4fcefbf349baccd6e483fed1955990f7f4d71..f8f2cf02091c2ef17146a9acbb64daa93b8c2736 100644
--- a/Kconfig
+++ b/Kconfig
@@ -216,3 +216,13 @@ config W1
 config SOCKITOWM
        boolean
        default !W1
+
+config SDB_EEPROM
+	depends on DEVELOPER && W1
+	boolean "Use SDB to manage EEPROM (instead of legacy code)"
+	help
+	  New experimental code to unify W1 and EEPROM storage
+
+config LEGACY_EEPROM
+	boolean
+	default !SDB_EEPROM
diff --git a/dev/dev.mk b/dev/dev.mk
index 9f09998a2d2b1b5c6749b82cfb5dc31f8736cfbd..af67206640524cc5b4c15f4443ab7739d6e94c42 100644
--- a/dev/dev.mk
+++ b/dev/dev.mk
@@ -1,5 +1,4 @@
 obj-y += \
-	dev/eeprom.o \
 	dev/endpoint.o \
 	dev/ep_pfilter.o \
 	dev/i2c.o \
@@ -10,6 +9,9 @@ obj-y += \
 	dev/sdb.o \
 	dev/rxts_calibrator.o
 
+obj-$(CONFIG_LEGACY_EEPROM) += dev/eeprom.o
+obj-$(CONFIG_SDB_EEPROM) += dev/sdb-eeprom.o
+
 obj-$(CONFIG_SOCKITOWM) +=	dev/onewire.o
 obj-$(CONFIG_W1) +=		dev/w1.o	dev/w1-hw.o
 obj-$(CONFIG_W1) +=		dev/w1-temp.o	dev/w1-eeprom.o
diff --git a/dev/sdb-eeprom.c b/dev/sdb-eeprom.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b0ef02589f3d61095a394ac85db996cbcb0cbc8
--- /dev/null
+++ b/dev/sdb-eeprom.c
@@ -0,0 +1,397 @@
+/*
+ * This work is part of the White Rabbit project
+ *
+ * Copyright (C) 2012, 2013 CERN (www.cern.ch)
+ * Author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ */
+//#include <string.h>
+#include <wrc.h>
+#include <w1.h>
+#include <eeprom.h>
+
+//#include "types.h"
+//#include "i2c.h"
+//#include "eeprom.h"
+//#include "board.h"
+//#include "syscon.h"
+#include <sdb.h>
+
+#define SDBFS_BIG_ENDIAN
+#include <libsdbfs.h>
+
+/*
+ * This source file is a drop-in replacement of the legacy one: it manages
+ * both i2c and w1 devices even if the interface is the old i2c-based one
+ */
+#define SDB_VENDOR	0x46696c6544617461LL /* "FileData" */
+#define SDB_DEV_INIT	0x77722d69 /* wr-i (nit) */
+#define SDB_DEV_MAC	0x6d61632d /* mac- (address) */
+#define SDB_DEV_SFP	0x7366702d /* sfp- (database) */
+#define SDB_DEV_CALIB	0x63616c69 /* cali (bration) */
+
+/* The methods for W1 access */
+static int sdb_w1_read(struct sdbfs *fs, int offset, void *buf, int count)
+{
+	return w1_read_eeprom_bus(fs->drvdata, offset, buf, count);
+}
+
+static int sdb_w1_write(struct sdbfs *fs, int offset, void *buf, int count)
+{
+	return w1_write_eeprom_bus(fs->drvdata, offset, buf, count);
+}
+
+/* The methods for I2C access -- FIXME */
+
+
+/*
+ * A trivial dumper, just to show what's up in there
+ */
+static void eeprom_sdb_list(struct sdbfs *fs)
+{
+	struct sdb_device *d;
+	int new = 1;
+	while ( (d = sdbfs_scan(fs, new)) != NULL) {
+		d->sdb_component.product.record_type = '\0';
+		pp_printf("file 0x%08x @ %4i, name %s\n",
+			  (int)(d->sdb_component.product.device_id),
+			  (int)(d->sdb_component.addr_first),
+			  (char *)(d->sdb_component.product.name));
+		new = 0;
+	}
+}
+/* The sdb filesystem itself */
+static struct sdbfs wrc_sdb = {
+	.name = "wrpc-storage",
+	.blocksize = 1, /* Not currently used */
+	/* .read and .write according to device type */
+};
+
+uint8_t has_eeprom = 0; /* modified at init time */
+
+/*
+ * Init: returns 0 for success; it changes has_eeprom above
+ *
+ * This is called by wrc_main, after initializing both w1 and i2c
+ */
+uint8_t eeprom_present(uint8_t i2cif, uint8_t i2c_addr)
+{
+	uint32_t magic = 0;
+	static unsigned entry_points[] = {0, 64, 128, 256, 512, 1024};
+	int i, ret;
+
+	/* Look for w1 first: if there is no eeprom if fails fast */
+	for (i = 0; i < ARRAY_SIZE(entry_points); i++) {
+		ret = w1_read_eeprom_bus(&wrpc_w1_bus, entry_points[i],
+					 (void *)&magic, sizeof(magic));
+		if (ret != sizeof(magic))
+			break;
+		if (magic == SDB_MAGIC)
+			break;
+	}
+	if (magic == SDB_MAGIC) {
+		pp_printf("sdbfs: found at %i in W1\n", entry_points[i]);
+		wrc_sdb.drvdata = &wrpc_w1_bus;
+		wrc_sdb.read = sdb_w1_read;
+		wrc_sdb.write = sdb_w1_write;
+		has_eeprom = 1;
+		eeprom_sdb_list(&wrc_sdb);
+		return 0;
+	}
+
+	/*
+	 * If w1 failed, look for i2c: start from high offsets by now.
+	 * FIXME: this is a hack, until we have subdirectory support
+	 */
+	for (i = ARRAY_SIZE(entry_points) - i; i >= 0; i--) {
+		/* FIXME: i2c */
+	}
+	return 0;
+}
+
+
+/*
+ * The SFP section is placed somewhere inside EEPROM (W1 or I2C), using sdbfs.
+ *
+ * Initially we have a count of SFP records
+ *
+ * For each sfp we have
+ *
+ * - part number (16 bytes)
+ * - alpha (4 bytes)
+ * - deltaTx (4 bytes)
+ * - delta Rx (4 bytes)
+ * - checksum (1 byte)  (low order 8 bits of the sum of all bytes)
+ *
+ * the total is 29 bytes for each sfp (ugly, but we are byte-oriented anyways
+ */
+
+
+/* Just a dummy function that writes '0' to sfp count field of the SFP DB */
+int32_t eeprom_sfpdb_erase(uint8_t i2cif, uint8_t i2c_addr)
+{
+	uint8_t sfpcount = 0;
+	int ret;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0)
+		return -1;
+	ret = sdbfs_fwrite(&wrc_sdb, 0, (char *)&sfpcount, 1);
+	sdbfs_close(&wrc_sdb);
+	return ret == 1 ? 0 : -1;
+}
+
+int32_t eeprom_get_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo * sfp,
+		       uint8_t add, uint8_t pos)
+{
+	static uint8_t sfpcount = 0;
+	int ret = -1;
+	uint8_t i, chksum = 0;
+	uint8_t *ptr;
+
+	if (pos >= SFPS_MAX)
+		return EE_RET_POSERR;	//position outside the range
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0)
+		return -1;
+
+	//read how many SFPs are in the database, but only in the first call
+	if (!pos
+	    && sdbfs_fread(&wrc_sdb, 0, &sfpcount, sizeof(sfpcount))
+	    != sizeof(sfpcount))
+		goto out;
+
+	if (add && sfpcount == SFPS_MAX)	//no more space to add new SFPs
+		return EE_RET_DBFULL;
+	if (!pos && !add && sfpcount == 0)	// no SFPs in the database
+		return 0;
+
+	if (!add) {
+		if (sdbfs_fread(&wrc_sdb, sizeof(sfpcount) + pos * sizeof(*sfp),
+				sfp, sizeof(*sfp))
+		    != sizeof(*sfp))
+			goto out;
+
+		ptr = (uint8_t *)sfp;
+		/* read sizeof() - 1 because we don't include checksum */
+		for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i)
+			chksum = chksum + *(ptr++);
+		if (chksum != sfp->chksum) {
+			pp_printf("sfp: corrupted checksum\n");
+			goto out;
+		}
+	} else {
+		/*count checksum */
+		ptr = (uint8_t *)sfp;
+		/* use sizeof() - 1 because we don't include checksum */
+		for (i = 0; i < sizeof(struct s_sfpinfo) - 1; ++i)
+			chksum = chksum + *(ptr++);
+		sfp->chksum = chksum;
+		/* add SFP at the end of DB */
+		if (sdbfs_fwrite(&wrc_sdb, sizeof(sfpcount)
+				  + sfpcount * sizeof(*sfp), sfp, sizeof(*sfp))
+		    != sizeof(*sfp))
+			goto out;
+		sfpcount++;
+		if (sdbfs_fwrite(&wrc_sdb, 0, &sfpcount, sizeof(sfpcount))
+		    != sizeof(sfpcount))
+			goto out;
+	}
+	ret = sfpcount;
+out:
+	sdbfs_close(&wrc_sdb);
+	return ret;
+	return 0;
+}
+
+int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo * sfp)
+{
+	uint8_t sfpcount = 1;
+	int8_t i, temp;
+	struct s_sfpinfo dbsfp;
+
+	for (i = 0; i < sfpcount; ++i) {
+		temp = eeprom_get_sfp(i2cif, i2c_addr,
+				      &dbsfp, 0, i);
+		if (!i) {
+			// first round: valid sfpcount is returned
+			sfpcount = temp;
+			if (sfpcount == 0 || sfpcount == 0xFF)
+				return 0;
+			else if (sfpcount < 0)
+				return sfpcount;
+		}
+		if (!strncmp(dbsfp.pn, sfp->pn, 16)) {
+			sfp->dTx = dbsfp.dTx;
+			sfp->dRx = dbsfp.dRx;
+			sfp->alpha = dbsfp.alpha;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Phase transition ("calibration" file)
+ */
+int8_t eeprom_phtrans(uint8_t i2cif, uint8_t i2c_addr, uint32_t * val,
+		      uint8_t write)
+{
+	int ret = -1;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_CALIB) < 0)
+		return -1;
+	if (write) {
+		*val |= (1 << 31);
+		if (sdbfs_fwrite(&wrc_sdb, 0, val, sizeof(*val))
+		    != sizeof(*val))
+			goto out;
+		ret = 1;
+	} else {
+		if (sdbfs_fread(&wrc_sdb, 0, val, sizeof(*val))
+		    != sizeof(*val))
+			goto out;
+		if (!(*val & (1 << 31)))
+			ret = 0;
+		*val &= 0x7fffffff;	/*  ph_trans value without valid bit */
+		ret= 1;
+	}
+out:
+	sdbfs_close(&wrc_sdb);
+	return ret;
+}
+
+/*
+ * The init script area consist of 2-byte size field and a set of
+ * shell commands separated with '\n' character.
+ *
+ * -------------------
+ * | bytes used (2B) |
+ * ------------------------------------------------
+ * | shell commands separated with '\n'.....      |
+ * |                                              |
+ * |                                              |
+ * ------------------------------------------------
+ */
+
+int8_t eeprom_init_erase(uint8_t i2cif, uint8_t i2c_addr)
+{
+	uint16_t used = 0;
+	int ret;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
+		return -1;
+	ret = sdbfs_fwrite(&wrc_sdb, 0, &used, sizeof(used));
+	sdbfs_close(&wrc_sdb);
+	return ret == sizeof(used) ? 0 : -1;
+}
+
+/*
+ * Appends a new shell command at the end of boot script
+ */
+int8_t eeprom_init_add(uint8_t i2cif, uint8_t i2c_addr, const char *args[])
+{
+	int len, i = 1; /* args[0] is "add" */
+	uint8_t separator = ' ';
+	uint16_t used, readback;
+	int ret = -1;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
+		return -1;
+	if (sdbfs_fread(&wrc_sdb, 0, &used, sizeof(used)) != sizeof(used))
+		goto out;
+	if (used > 256 /* 0xffff or wrong */)
+		used = 0;
+
+	while (args[i] != NULL) {
+		len = strlen(args[i]);
+		if (sdbfs_fwrite(&wrc_sdb, sizeof(used) + used,
+				 (void *)args[i], len) != len)
+			goto out;
+		used += len;
+		if (sdbfs_fwrite(&wrc_sdb, sizeof(used) + used,
+				&separator, sizeof(separator))
+		    != sizeof(separator))
+			goto out;
+		++used;
+		++i;
+	}
+	/*  At end of command, replace last separator with '\n' */
+	separator = '\n';
+	if (sdbfs_fwrite(&wrc_sdb, sizeof(used) + used - 1,
+			&separator, sizeof(separator)) != sizeof(separator))
+		goto out;
+	/* and finally update the size of the script */
+	if (sdbfs_fwrite(&wrc_sdb, 0, &used, sizeof(used)) != sizeof(used))
+		goto out;
+
+	if (sdbfs_fread(&wrc_sdb, 0, &readback, sizeof(readback))
+	    != sizeof(readback))
+		goto out;
+
+	ret = 0;
+out:
+	sdbfs_close(&wrc_sdb);
+	return ret;
+}
+
+int32_t eeprom_init_show(uint8_t i2cif, uint8_t i2c_addr)
+{
+	int i, ret = -1;
+	uint16_t used;
+	uint8_t byte;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
+		return -1;
+	i = sdbfs_fread(&wrc_sdb, 0, &used, sizeof(used));
+	if (i != sizeof(used))
+		goto out;
+	/* sdbfs configuration sets it to 256: if insanely large refuse it */
+	if (used == 0 || used > 256 /* 0xffff or wrong */) {
+		pp_printf("Empty init script...\n");
+		goto out_ok;
+	}
+
+	/* Just read and print to the screen char after char */
+	for (i = 0; i < used; ++i) {
+		if (sdbfs_fread(&wrc_sdb, -1 /* sequentially */, &byte, 1) != 1)
+			goto out;
+		pp_printf("%c", byte);
+	}
+out_ok:
+	ret = 0;
+out:
+	sdbfs_close(&wrc_sdb);
+	return ret;
+}
+
+int8_t eeprom_init_readcmd(uint8_t i2cif, uint8_t i2c_addr, uint8_t *buf,
+			   uint8_t bufsize, uint8_t next)
+{
+	int i = 0, ret = -1;
+	uint16_t used;
+	static uint16_t ptr;
+
+	if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_INIT) < 0)
+		return -1;
+	if (sdbfs_fread(&wrc_sdb, 0, &used, sizeof(used)) != sizeof(used))
+		goto out;
+
+	if (next == 0)
+		ptr = sizeof(used);
+	if (ptr - sizeof(used) >= used)
+		return 0;
+	do {
+		if (ptr - sizeof(used) > bufsize)
+			goto out;
+		if (sdbfs_fread(&wrc_sdb, (ptr++),
+				&buf[i], sizeof(char)) != sizeof(char))
+			goto out;
+	} while (buf[i++] != '\n');
+	ret = i;
+out:
+	sdbfs_close(&wrc_sdb);
+	return ret;
+}