diff --git a/fmc-bus b/fmc-bus
index 29f077e42c420f596d05b51fdc356505cc42edb1..b2ca26a566e978dc8426a0cebe8dba40cadac2ac 160000
--- a/fmc-bus
+++ b/fmc-bus
@@ -1 +1 @@
-Subproject commit 29f077e42c420f596d05b51fdc356505cc42edb1
+Subproject commit b2ca26a566e978dc8426a0cebe8dba40cadac2ac
diff --git a/kernel/spec-fmc.c b/kernel/spec-fmc.c
index 3de6bf1c658f176757d177b6351abc66fa4437f9..ec8ad67d89961b2f970e339c4439a13962018541 100644
--- a/kernel/spec-fmc.c
+++ b/kernel/spec-fmc.c
@@ -7,6 +7,7 @@
  * This work is part of the White Rabbit project, a research effort led
  * by CERN, the European Institute for Nuclear Research.
  */
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/fmc.h>
 #include <linux/interrupt.h>
@@ -256,7 +257,7 @@ static int spec_read_ee(struct fmc_device *fmc, int pos, void *data, int len)
 {
 	if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
 		return -ENOTSUPP;
-	return spec_eeprom_read(fmc, SPEC_I2C_EEPROM_ADDR, pos, data, len);
+	return spec_eeprom_read(fmc, pos, data, len);
 }
 
 static int spec_write_ee(struct fmc_device *fmc, int pos,
@@ -264,7 +265,7 @@ static int spec_write_ee(struct fmc_device *fmc, int pos,
 {
 	if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
 		return -ENOTSUPP;
-	return spec_eeprom_write(fmc, SPEC_I2C_EEPROM_ADDR, pos, data, len);
+	return spec_eeprom_write(fmc, pos, data, len);
 }
 
 static struct fmc_operations spec_fmc_operations = {
@@ -391,6 +392,7 @@ static int check_golden(struct fmc_device *fmc)
 int spec_fmc_create(struct spec_dev *spec)
 {
 	struct fmc_device *fmc;
+        struct pci_dev *pdev;
 	int ret;
 
 	fmc = kzalloc(sizeof(*fmc), GFP_KERNEL);
@@ -398,14 +400,27 @@ int spec_fmc_create(struct spec_dev *spec)
 		return -ENOMEM;
 
 	fmc->version = FMC_VERSION;
+	fmc->owner = THIS_MODULE;
 	fmc->carrier_name = "SPEC";
 	fmc->carrier_data = spec;
-	fmc->base = spec->remap[0]; /* 1M window at offset 0 */
+
+	/* 1M window at offset 0 */
+	fmc->fpga_base = spec->remap[0];
+	fmc->memlen = 1 << 20;
+
 	fmc->irq = spec->pdev->irq;
 	fmc->op = &spec_fmc_operations;
 	fmc->hwdev = &spec->pdev->dev; /* for messages */
 	spec->fmc = fmc;
 
+	/* We have one slot only, and the i2c address is mandated */
+	fmc->slot_id = 0;
+	fmc->eeprom_addr = SPEC_I2C_EEPROM_ADDR;
+
+	/* The device id is needed to build mezzanine unique names */
+	pdev = spec->pdev;
+	fmc->device_id = (pdev->bus->number << 8) | pdev->devfn;
+
 	/* Check that the golden binary is actually correct */
 	ret = check_golden(fmc);
 	if (ret)
diff --git a/kernel/spec-i2c.c b/kernel/spec-i2c.c
index a99650f459fe6e213c2358d5bf2c750f0dbc4e56..e2aedb59a94c2278c1153a06408d163792a16e69 100644
--- a/kernel/spec-i2c.c
+++ b/kernel/spec-i2c.c
@@ -139,7 +139,7 @@ int mi2c_scan(struct fmc_device *fmc)
 }
 
 /* FIXME: this is very inefficient: read several bytes in a row instead */
-int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
+int spec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
 		void *buf, size_t size)
 {
 	int i;
@@ -148,7 +148,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
 
 	for(i = 0; i < size; i++) {
 		mi2c_start(fmc);
-		if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) {
+		if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
 			mi2c_stop(fmc);
 			return -EIO;
 		}
@@ -158,7 +158,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
 		offset++;
 		mi2c_stop(fmc);
 		mi2c_start(fmc);
-		mi2c_put_byte(fmc, (i2c_addr << 1) | 1);
+		mi2c_put_byte(fmc, (fmc->eeprom_addr << 1) | 1);
 		mi2c_get_byte(fmc, &c, 0);
 		*buf8++ = c;
 		mi2c_stop(fmc);
@@ -166,7 +166,7 @@ int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
 	return size;
 }
 
-int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
+int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
 		 const void *buf, size_t size)
 {
 	int i, busy;
@@ -175,7 +175,7 @@ int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
 	for(i = 0; i < size; i++) {
 		mi2c_start((fmc));
 
-		if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) {
+		if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
 			mi2c_stop(fmc);
 			return -1;
 		}
@@ -187,7 +187,7 @@ int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset,
 
 		do { /* wait until the chip becomes ready */
 			mi2c_start(fmc);
-			busy = mi2c_put_byte(fmc, i2c_addr << 1);
+			busy = mi2c_put_byte(fmc, fmc->eeprom_addr << 1);
 			mi2c_stop(fmc);
 		} while(busy);
 	}
@@ -210,12 +210,12 @@ int spec_i2c_init(struct fmc_device *fmc)
 	if (!buf)
 		return -ENOMEM;
 
-	i = spec_eeprom_read(fmc, SPEC_I2C_EEPROM_ADDR, 0, buf,
-			     SPEC_I2C_EEPROM_SIZE);
+	i = spec_eeprom_read(fmc, 0, buf, SPEC_I2C_EEPROM_SIZE);
 	if (i != SPEC_I2C_EEPROM_SIZE) {
-		dev_err(&spec->pdev->dev, "EEPROM read error: retval is %i\n",
-			i);
+		dev_err(&spec->pdev->dev, "EEPROM read error %i\n", i);
 		kfree(buf);
+		fmc->eeprom = NULL;
+		fmc->eeprom_len = 0;
 		return -EIO;
 	}
 	fmc->eeprom = buf;
diff --git a/kernel/spec.h b/kernel/spec.h
index 3fdbe6e9fb0452b461e6b131df67e71e32ba0a65..9ec90bebc7cd84386aab182c435ef997e320d19a 100644
--- a/kernel/spec.h
+++ b/kernel/spec.h
@@ -125,10 +125,10 @@ extern void spec_fmc_destroy(struct spec_dev *spec);
 /* Functions in spec-i2c.c, used by spec-fmc.c */
 extern int spec_i2c_init(struct fmc_device *fmc);
 extern void spec_i2c_exit(struct fmc_device *fmc);
-extern int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr,
-			    uint32_t offset, void *buf, size_t size);
-extern int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr,
-			     uint32_t offset, const void *buf, size_t size);
+extern int spec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
+			    void *buf, size_t size);
+extern int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
+			     const void *buf, size_t size);
 
 /* The eeprom is at address 0x50 */
 #define SPEC_I2C_EEPROM_ADDR 0x50
diff --git a/kernel/wr-nic-core.c b/kernel/wr-nic-core.c
index 8a470102fabb1146c30a880a71c554c6fa88ef50..00de69fa42496fd4cd62d2180aa9f539fde453a7 100644
--- a/kernel/wr-nic-core.c
+++ b/kernel/wr-nic-core.c
@@ -88,9 +88,9 @@ int wrn_fmc_probe(struct fmc_device *fmc)
 	 * global name
 	 */
 	if (wrn_drv.gw_n)
-		ret = fmc->op->reprogram(fmc, &wrn_drv, "");
+		ret = fmc_reprogram(fmc, &wrn_drv, "", 0x630000 /* SDB */);
 	else
-		ret = fmc->op->reprogram(fmc, &wrn_drv, wrn_filename);
+		ret = fmc_reprogram(fmc, &wrn_drv, wrn_filename, 0x63000);
 	if (ret <0) {
 		if (ret == -ESRCH) {
 			dev_info(fmc->hwdev, "%s: no gateware at index %i\n",
@@ -102,19 +102,9 @@ int wrn_fmc_probe(struct fmc_device *fmc)
 			wrn_filename, ret);
 		return ret;
 	}
-
-	/* Verify that we have SDB at offset WRN_SDB_ADDR (0x63000) */
-	if (fmc_readl(fmc, WRN_SDB_ADDR) != 0x5344422d) {
-		dev_err(dev, "Can't find SDB magic\n");
-		ret = -ENODEV;
-		goto out;
-	}
 	dev_info(dev, "Gateware successfully loaded\n");
 
-	if ( (ret = fmc_scan_sdb_tree(fmc, WRN_SDB_ADDR)) < 0) {
-		dev_err(dev, "scan fmc failed %i\n", ret);
-		goto out;
-	}
+	/* FIXME: remove this parameter, fmc.ko shows it already */
 	if (wrn_show_sdb)
 		fmc_show_sdb_tree(fmc);
 
diff --git a/kernel/wr-nic-eth.c b/kernel/wr-nic-eth.c
index 14633ed69bc15cb1739c636eb3a6c96bd21e140d..4d1ce875a1d611d74c26214f17992eb71e7a271b 100644
--- a/kernel/wr-nic-eth.c
+++ b/kernel/wr-nic-eth.c
@@ -223,7 +223,8 @@ int wrn_eth_init(struct fmc_device *fmc)
 			continue;
 		}
 		/* use c->offset to copy and already-remapped value */
-		*((void **)((u8 *)drvdata + c->offset)) = fmc->base + start;
+		*((void **)((u8 *)drvdata + c->offset)) =
+			fmc->fpga_base + start;
 	}
 	pdev->resource = resarr;
 	pdev->num_resources = ARRAY_SIZE(wrn_cores);