Index: hwaccess.c
===================================================================
--- hwaccess.c	(revision 1299)
+++ hwaccess.c	(working copy)
@@ -202,7 +202,7 @@
 	};
 };
 
-void undo_mmio_write(void *p)
+int undo_mmio_write(void *p)
 {
 	struct undo_mmio_write_data *data = p;
 	msg_pdbg("Restoring MMIO space at %p\n", data->addr);
@@ -219,6 +219,7 @@
 	}
 	/* p was allocated in register_undo_mmio_write. */
 	free(p);
+	return 0;
 }
 
 #define register_undo_mmio_write(a, c)					\
Index: ogp_spi.c
===================================================================
--- ogp_spi.c	(revision 1299)
+++ ogp_spi.c	(working copy)
@@ -93,6 +93,15 @@
 	.release_bus = ogp_release_spibus,
 };
 
+static int ogp_spi_shutdown(void *data)
+{
+	physunmap(ogp_spibar, 4096);
+	pci_cleanup(pacc);
+	release_io_perms();
+
+	return 0;
+}
+
 int ogp_spi_init(void)
 {
 	char *type;
@@ -120,6 +129,9 @@
 
 	get_io_perms();
 
+	if (register_shutdown(ogp_spi_shutdown, NULL))
+		return 1;
+
 	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);
 
 	ogp_spibar = physmap("OGP registers", io_base_addr, 4096);
@@ -130,12 +142,3 @@
 
 	return 0;
 }
-
-int ogp_spi_shutdown(void)
-{
-	physunmap(ogp_spibar, 4096);
-	pci_cleanup(pacc);
-	release_io_perms();
-
-	return 0;
-}
Index: flash.h
===================================================================
--- flash.h	(revision 1299)
+++ flash.h	(working copy)
@@ -40,7 +40,7 @@
 
 typedef unsigned long chipaddr;
 
-int register_shutdown(void (*function) (void *data), void *data);
+int register_shutdown(int (*function) (void *data), void *data);
 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
 				  size_t len);
 void programmer_unmap_flash_region(void *virt_addr, size_t len);
Index: drkaiser.c
===================================================================
--- drkaiser.c	(revision 1299)
+++ drkaiser.c	(working copy)
@@ -37,6 +37,14 @@
 
 static uint8_t *drkaiser_bar;
 
+static int drkaiser_shutdown(void *data)
+{
+	/* Flash write is disabled automatically by PCI restore. */
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+};
+
 int drkaiser_init(void)
 {
 	uint32_t addr;
@@ -55,17 +63,11 @@
 
 	buses_supported = CHIP_BUSTYPE_PARALLEL;
 
+	if (register_shutdown(drkaiser_shutdown, NULL))
+		return 1;
 	return 0;
 }
 
-int drkaiser_shutdown(void)
-{
-	/* Flash write is disabled automatically by PCI restore. */
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-};
-
 void drkaiser_chip_writeb(uint8_t val, chipaddr addr)
 {
 	pci_mmio_writeb(val, drkaiser_bar + (addr & DRKAISER_MEMMAP_MASK));
Index: pcidev.c
===================================================================
--- pcidev.c	(revision 1299)
+++ pcidev.c	(working copy)
@@ -270,7 +270,7 @@
 	};
 };
 
-void undo_pci_write(void *p)
+int undo_pci_write(void *p)
 {
 	struct undo_pci_write_data *data = p;
 	msg_pdbg("Restoring PCI config space for %02x:%02x:%01x reg 0x%02x\n",
@@ -288,6 +288,7 @@
 	}
 	/* p was allocated in register_undo_pci_write. */
 	free(p);
+	return 0;
 }
 
 #define register_undo_pci_write(a, b, c) 				\
Index: gfxnvidia.c
===================================================================
--- gfxnvidia.c	(revision 1299)
+++ gfxnvidia.c	(working copy)
@@ -60,12 +60,26 @@
 	{},
 };
 
+static int gfxnvidia_shutdown(void *data)
+{
+	/* Flash interface access is disabled (and screen enabled) automatically
+	 * by PCI restore.
+	 */
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int gfxnvidia_init(void)
 {
 	uint32_t reg32;
 
 	get_io_perms();
 
+	/* must be done before rpci calls */
+	if (register_shutdown(gfxnvidia_shutdown, NULL))
+		return 1;
+
 	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, gfx_nvidia);
 
 	io_base_addr += 0x300000;
@@ -86,16 +100,6 @@
 	return 0;
 }
 
-int gfxnvidia_shutdown(void)
-{
-	/* Flash interface access is disabled (and screen enabled) automatically
-	 * by PCI restore.
-	 */
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void gfxnvidia_chip_writeb(uint8_t val, chipaddr addr)
 {
 	pci_mmio_writeb(val, nvidia_bar + (addr & GFXNVIDIA_MEMMAP_MASK));
Index: serprog.c
===================================================================
--- serprog.c	(revision 1299)
+++ serprog.c	(working copy)
@@ -295,6 +295,190 @@
 	return 0;
 }
 
+/* Move an in flashrom buffer existing write-n operation to	*
+ * the on-device operation buffer.				*/
+static void sp_pass_writen(void)
+{
+	unsigned char header[7];
+	msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
+		     sp_write_n_bytes, sp_write_n_addr);
+	if (sp_streamed_transmit_bytes >=
+	    (7 + sp_write_n_bytes + sp_device_serbuf_size))
+		sp_flush_stream();
+	/* In case it's just a single byte send it as a single write. */
+	if (sp_write_n_bytes == 1) {
+		sp_write_n_bytes = 0;
+		header[0] = (sp_write_n_addr >> 0) & 0xFF;
+		header[1] = (sp_write_n_addr >> 8) & 0xFF;
+		header[2] = (sp_write_n_addr >> 16) & 0xFF;
+		header[3] = sp_write_n_buf[0];
+		sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
+		sp_opbuf_usage += 5;
+		return;
+	}
+	header[0] = S_CMD_O_WRITEN;
+	header[1] = (sp_write_n_bytes >> 0) & 0xFF;
+	header[2] = (sp_write_n_bytes >> 8) & 0xFF;
+	header[3] = (sp_write_n_bytes >> 16) & 0xFF;
+	header[4] = (sp_write_n_addr >> 0) & 0xFF;
+	header[5] = (sp_write_n_addr >> 8) & 0xFF;
+	header[6] = (sp_write_n_addr >> 16) & 0xFF;
+	if (write(sp_fd, header, 7) != 7)
+		sp_die("Error: cannot write write-n command\n");
+	if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
+	    sp_write_n_bytes)
+		sp_die("Error: cannot write write-n data");
+	sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
+	sp_streamed_transmit_ops += 1;
+	sp_opbuf_usage += 7 + sp_write_n_bytes;
+	sp_write_n_bytes = 0;
+	sp_prev_was_write = 0;
+}
+
+static void sp_execute_opbuf_noflush(void)
+{
+	if ((sp_max_write_n) && (sp_write_n_bytes))
+		sp_pass_writen();
+	sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
+	msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
+		     sp_opbuf_usage);
+	sp_opbuf_usage = 0;
+	sp_prev_was_write = 0;
+	return;
+}
+
+static void sp_execute_opbuf(void)
+{
+	sp_execute_opbuf_noflush();
+	sp_flush_stream();
+}
+
+static void sp_check_opbuf_usage(int bytes_to_be_added)
+{
+	if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
+		sp_execute_opbuf();
+		/* If this happens in the mid of an page load the page load *
+		 * will probably fail.					    */
+		msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
+	}
+}
+
+void serprog_chip_writeb(uint8_t val, chipaddr addr)
+{
+	msg_pspew("%s\n", __func__);
+	if (sp_max_write_n) {
+		if ((sp_prev_was_write)
+		    && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
+			sp_write_n_buf[sp_write_n_bytes++] = val;
+		} else {
+			if ((sp_prev_was_write) && (sp_write_n_bytes))
+				sp_pass_writen();
+			sp_prev_was_write = 1;
+			sp_write_n_addr = addr;
+			sp_write_n_bytes = 1;
+			sp_write_n_buf[0] = val;
+		}
+		sp_check_opbuf_usage(7 + sp_write_n_bytes);
+		if (sp_write_n_bytes >= sp_max_write_n)
+			sp_pass_writen();
+	} else {
+		/* We will have to do single writeb ops. */
+		unsigned char writeb_parm[4];
+		sp_check_opbuf_usage(6);
+		writeb_parm[0] = (addr >> 0) & 0xFF;
+		writeb_parm[1] = (addr >> 8) & 0xFF;
+		writeb_parm[2] = (addr >> 16) & 0xFF;
+		writeb_parm[3] = val;
+		sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
+		sp_opbuf_usage += 5;
+	}
+}
+
+uint8_t serprog_chip_readb(const chipaddr addr)
+{
+	unsigned char c;
+	unsigned char buf[3];
+	/* Will stream the read operation - eg. add it to the stream buffer, *
+	 * then flush the buffer, then read the read answer.		     */
+	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
+		sp_execute_opbuf_noflush();
+	buf[0] = ((addr >> 0) & 0xFF);
+	buf[1] = ((addr >> 8) & 0xFF);
+	buf[2] = ((addr >> 16) & 0xFF);
+	sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
+	sp_flush_stream();
+	if (read(sp_fd, &c, 1) != 1)
+		sp_die("readb byteread");
+	msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
+	return c;
+}
+
+/* Local version that really does the job, doesn't care of max_read_n. */
+static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
+{
+	int rd_bytes = 0;
+	unsigned char sbuf[6];
+	msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
+	/* Stream the read-n -- as above. */
+	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
+		sp_execute_opbuf_noflush();
+	sbuf[0] = ((addr >> 0) & 0xFF);
+	sbuf[1] = ((addr >> 8) & 0xFF);
+	sbuf[2] = ((addr >> 16) & 0xFF);
+	sbuf[3] = ((len >> 0) & 0xFF);
+	sbuf[4] = ((len >> 8) & 0xFF);
+	sbuf[5] = ((len >> 16) & 0xFF);
+	sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
+	sp_flush_stream();
+	do {
+		int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
+		if (r <= 0)
+			sp_die("Error: cannot read read-n data");
+		rd_bytes += r;
+	} while (rd_bytes != len);
+	return;
+}
+
+/* The externally called version that makes sure that max_read_n is obeyed. */
+void serprog_chip_readn(uint8_t * buf, const chipaddr addr, size_t len)
+{
+	size_t lenm = len;
+	chipaddr addrm = addr;
+	while ((sp_max_read_n)&&(lenm > sp_max_read_n)) {
+		sp_do_read_n(&(buf[addrm-addr]),addrm,sp_max_read_n);
+		addrm += sp_max_read_n;
+		lenm -= sp_max_read_n;
+	}
+	if (lenm) sp_do_read_n(&(buf[addrm-addr]),addrm,lenm);
+}
+
+void serprog_delay(int delay)
+{
+	unsigned char buf[4];
+	msg_pspew("%s\n", __func__);
+	if ((sp_max_write_n) && (sp_write_n_bytes))
+		sp_pass_writen();
+	sp_check_opbuf_usage(5);
+	buf[0] = ((delay >> 0) & 0xFF);
+	buf[1] = ((delay >> 8) & 0xFF);
+	buf[2] = ((delay >> 16) & 0xFF);
+	buf[3] = ((delay >> 24) & 0xFF);
+	sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
+	sp_opbuf_usage += 5;
+	sp_prev_was_write = 0;
+}
+
+static int serprog_shutdown(void *data)
+{
+	msg_pspew("%s\n", __func__);
+	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
+		sp_execute_opbuf();
+	close(sp_fd);
+	if (sp_max_write_n)
+		free(sp_write_n_buf);
+	return 0;
+}
+
 int serprog_init(void)
 {
 	uint16_t iface;
@@ -373,6 +557,9 @@
 		return 1;
 	}
 
+	if (register_shutdown(serprog_shutdown, NULL))
+		return 1;
+
 	msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
 
 	sp_check_avail_automatic = 0;
@@ -494,189 +681,7 @@
 	sp_streamed_transmit_ops = 0;
 	sp_streamed_transmit_bytes = 0;
 	sp_opbuf_usage = 0;
-	return 0;
-}
 
-/* Move an in flashrom buffer existing write-n operation to	*
- * the on-device operation buffer.				*/
-static void sp_pass_writen(void)
-{
-	unsigned char header[7];
-	msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
-		     sp_write_n_bytes, sp_write_n_addr);
-	if (sp_streamed_transmit_bytes >=
-	    (7 + sp_write_n_bytes + sp_device_serbuf_size))
-		sp_flush_stream();
-	/* In case it's just a single byte send it as a single write. */
-	if (sp_write_n_bytes == 1) {
-		sp_write_n_bytes = 0;
-		header[0] = (sp_write_n_addr >> 0) & 0xFF;
-		header[1] = (sp_write_n_addr >> 8) & 0xFF;
-		header[2] = (sp_write_n_addr >> 16) & 0xFF;
-		header[3] = sp_write_n_buf[0];
-		sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
-		sp_opbuf_usage += 5;
-		return;
-	}
-	header[0] = S_CMD_O_WRITEN;
-	header[1] = (sp_write_n_bytes >> 0) & 0xFF;
-	header[2] = (sp_write_n_bytes >> 8) & 0xFF;
-	header[3] = (sp_write_n_bytes >> 16) & 0xFF;
-	header[4] = (sp_write_n_addr >> 0) & 0xFF;
-	header[5] = (sp_write_n_addr >> 8) & 0xFF;
-	header[6] = (sp_write_n_addr >> 16) & 0xFF;
-	if (write(sp_fd, header, 7) != 7)
-		sp_die("Error: cannot write write-n command\n");
-	if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
-	    sp_write_n_bytes)
-		sp_die("Error: cannot write write-n data");
-	sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
-	sp_streamed_transmit_ops += 1;
-	sp_opbuf_usage += 7 + sp_write_n_bytes;
-	sp_write_n_bytes = 0;
-	sp_prev_was_write = 0;
-}
-
-static void sp_execute_opbuf_noflush(void)
-{
-	if ((sp_max_write_n) && (sp_write_n_bytes))
-		sp_pass_writen();
-	sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
-	msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
-		     sp_opbuf_usage);
-	sp_opbuf_usage = 0;
-	sp_prev_was_write = 0;
-	return;
-}
-
-static void sp_execute_opbuf(void)
-{
-	sp_execute_opbuf_noflush();
-	sp_flush_stream();
-}
-
-int serprog_shutdown(void)
-{
-	msg_pspew("%s\n", __func__);
-	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
-		sp_execute_opbuf();
-	close(sp_fd);
-	if (sp_max_write_n)
-		free(sp_write_n_buf);
 	return 0;
 }
 
-static void sp_check_opbuf_usage(int bytes_to_be_added)
-{
-	if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
-		sp_execute_opbuf();
-		/* If this happens in the mid of an page load the page load *
-		 * will probably fail.					    */
-		msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
-	}
-}
-
-void serprog_chip_writeb(uint8_t val, chipaddr addr)
-{
-	msg_pspew("%s\n", __func__);
-	if (sp_max_write_n) {
-		if ((sp_prev_was_write)
-		    && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
-			sp_write_n_buf[sp_write_n_bytes++] = val;
-		} else {
-			if ((sp_prev_was_write) && (sp_write_n_bytes))
-				sp_pass_writen();
-			sp_prev_was_write = 1;
-			sp_write_n_addr = addr;
-			sp_write_n_bytes = 1;
-			sp_write_n_buf[0] = val;
-		}
-		sp_check_opbuf_usage(7 + sp_write_n_bytes);
-		if (sp_write_n_bytes >= sp_max_write_n)
-			sp_pass_writen();
-	} else {
-		/* We will have to do single writeb ops. */
-		unsigned char writeb_parm[4];
-		sp_check_opbuf_usage(6);
-		writeb_parm[0] = (addr >> 0) & 0xFF;
-		writeb_parm[1] = (addr >> 8) & 0xFF;
-		writeb_parm[2] = (addr >> 16) & 0xFF;
-		writeb_parm[3] = val;
-		sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
-		sp_opbuf_usage += 5;
-	}
-}
-
-uint8_t serprog_chip_readb(const chipaddr addr)
-{
-	unsigned char c;
-	unsigned char buf[3];
-	/* Will stream the read operation - eg. add it to the stream buffer, *
-	 * then flush the buffer, then read the read answer.		     */
-	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
-		sp_execute_opbuf_noflush();
-	buf[0] = ((addr >> 0) & 0xFF);
-	buf[1] = ((addr >> 8) & 0xFF);
-	buf[2] = ((addr >> 16) & 0xFF);
-	sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
-	sp_flush_stream();
-	if (read(sp_fd, &c, 1) != 1)
-		sp_die("readb byteread");
-	msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
-	return c;
-}
-
-/* Local version that really does the job, doesn't care of max_read_n. */
-static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
-{
-	int rd_bytes = 0;
-	unsigned char sbuf[6];
-	msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
-	/* Stream the read-n -- as above. */
-	if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
-		sp_execute_opbuf_noflush();
-	sbuf[0] = ((addr >> 0) & 0xFF);
-	sbuf[1] = ((addr >> 8) & 0xFF);
-	sbuf[2] = ((addr >> 16) & 0xFF);
-	sbuf[3] = ((len >> 0) & 0xFF);
-	sbuf[4] = ((len >> 8) & 0xFF);
-	sbuf[5] = ((len >> 16) & 0xFF);
-	sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
-	sp_flush_stream();
-	do {
-		int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
-		if (r <= 0)
-			sp_die("Error: cannot read read-n data");
-		rd_bytes += r;
-	} while (rd_bytes != len);
-	return;
-}
-
-/* The externally called version that makes sure that max_read_n is obeyed. */
-void serprog_chip_readn(uint8_t * buf, const chipaddr addr, size_t len)
-{
-	size_t lenm = len;
-	chipaddr addrm = addr;
-	while ((sp_max_read_n)&&(lenm > sp_max_read_n)) {
-		sp_do_read_n(&(buf[addrm-addr]),addrm,sp_max_read_n);
-		addrm += sp_max_read_n;
-		lenm -= sp_max_read_n;
-	}
-	if (lenm) sp_do_read_n(&(buf[addrm-addr]),addrm,lenm);
-}
-
-void serprog_delay(int delay)
-{
-	unsigned char buf[4];
-	msg_pspew("%s\n", __func__);
-	if ((sp_max_write_n) && (sp_write_n_bytes))
-		sp_pass_writen();
-	sp_check_opbuf_usage(5);
-	buf[0] = ((delay >> 0) & 0xFF);
-	buf[1] = ((delay >> 8) & 0xFF);
-	buf[2] = ((delay >> 16) & 0xFF);
-	buf[3] = ((delay >> 24) & 0xFF);
-	sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
-	sp_opbuf_usage += 5;
-	sp_prev_was_write = 0;
-}
Index: nicrealtek.c
===================================================================
--- nicrealtek.c	(revision 1299)
+++ nicrealtek.c	(working copy)
@@ -36,6 +36,14 @@
 	{},
 };
 
+static int nicrealtek_shutdown(void *data)
+{
+	/* FIXME: We forgot to disable software access again. */
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int nicrealtek_init(void)
 {
 	get_io_perms();
@@ -44,17 +52,11 @@
 
 	buses_supported = CHIP_BUSTYPE_PARALLEL;
 
+	if (register_shutdown(nicrealtek_shutdown, NULL))
+		return 1;
 	return 0;
 }
 
-int nicrealtek_shutdown(void)
-{
-	/* FIXME: We forgot to disable software access again. */
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void nicrealtek_chip_writeb(uint8_t val, chipaddr addr)
 {
 	/* Output addr and data, set WE to 0, set OE to 1, set CS to 0,
Index: satamv.c
===================================================================
--- satamv.c	(revision 1299)
+++ satamv.c	(working copy)
@@ -40,6 +40,14 @@
 #define PCI_BAR2_CONTROL		0x00c08
 #define GPIO_PORT_CONTROL		0x104f0
 
+static int satamv_shutdown(void *data)
+{
+	physunmap(mv_bar, 0x20000);
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 /*
  * Random notes:
  * FCE#		Flash Chip Enable
@@ -73,6 +81,9 @@
 	if (mv_bar == ERROR_PTR)
 		goto error_out;
 
+	if (register_shutdown(satamv_shutdown, NULL))
+		return 1;
+
 	tmp = pci_mmio_readl(mv_bar + FLASH_PARAM);
 	msg_pspew("Flash Parameters:\n");
 	msg_pspew("TurnOff=0x%01x\n", (tmp >> 0) & 0x7);
@@ -139,14 +150,6 @@
 	return 1;
 }
 
-int satamv_shutdown(void)
-{
-	physunmap(mv_bar, 0x20000);
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 /* BAR2 (MEM) can map NVRAM and flash. We set it to flash in the init function.
  * If BAR2 is disabled, it still can be accessed indirectly via BAR1 (I/O).
  * This code only supports indirect accesses for now.
Index: dummyflasher.c
===================================================================
--- dummyflasher.c	(revision 1299)
+++ dummyflasher.c	(working copy)
@@ -73,6 +73,23 @@
 	.read = default_spi_read,
 	.write_256 = dummy_spi_write_256,
 };
+
+static int dummy_shutdown(void *data)
+{
+	msg_pspew("%s\n", __func__);
+#if EMULATE_CHIP
+	if (emu_chip != EMULATE_NONE) {
+		if (emu_persistent_image) {
+			msg_pdbg("Writing %s\n", emu_persistent_image);
+			write_buf_to_file(flashchip_contents, emu_chip_size,
+					  emu_persistent_image);
+		}
+		free(flashchip_contents);
+	}
+#endif
+	return 0;
+}
+
 int dummy_init(void)
 {
 	char *bustext = NULL;
@@ -180,6 +197,11 @@
 		msg_perr("Out of memory!\n");
 		return 1;
 	}
+
+	/* shutdown will free the flashchip contents */
+	if (register_shutdown(dummy_shutdown, NULL))
+		return 1;
+
 	msg_pdbg("Filling fake flash chip with 0xff, size %i\n", emu_chip_size);
 	memset(flashchip_contents, 0xff, emu_chip_size);
 
@@ -204,22 +226,6 @@
 	return 0;
 }
 
-int dummy_shutdown(void)
-{
-	msg_pspew("%s\n", __func__);
-#if EMULATE_CHIP
-	if (emu_chip != EMULATE_NONE) {
-		if (emu_persistent_image) {
-			msg_pdbg("Writing %s\n", emu_persistent_image);
-			write_buf_to_file(flashchip_contents, emu_chip_size,
-					  emu_persistent_image);
-		}
-		free(flashchip_contents);
-	}
-#endif
-	return 0;
-}
-
 void *dummy_map(const char *descr, unsigned long phys_addr, size_t len)
 {
 	msg_pspew("%s: Mapping %s, 0x%lx bytes at 0x%08lx\n",
Index: internal.c
===================================================================
--- internal.c	(revision 1299)
+++ internal.c	(working copy)
@@ -127,6 +127,12 @@
 int is_laptop = 0;
 int laptop_ok = 0;
 
+static int internal_shutdown(void *data)
+{
+	release_io_perms();
+	return 0;
+}
+
 int internal_init(void)
 {
 #if __FLASHROM_LITTLE_ENDIAN__
@@ -178,6 +184,8 @@
 	free(arg);
 
 	get_io_perms();
+	if (register_shutdown(internal_shutdown, NULL))
+		return 1;
 
 	/* Default to Parallel/LPC/FWH flash devices. If a known host controller
 	 * is found, the init routine sets the buses_supported bitfield.
@@ -287,13 +295,6 @@
 	return 1;
 #endif
 }
-
-int internal_shutdown(void)
-{
-	release_io_perms();
-
-	return 0;
-}
 #endif
 
 void internal_chip_writeb(uint8_t val, chipaddr addr)
Index: nicintel_spi.c
===================================================================
--- nicintel_spi.c	(revision 1299)
+++ nicintel_spi.c	(working copy)
@@ -138,12 +138,34 @@
 	.release_bus = nicintel_release_spibus,
 };
 
+static int nicintel_spi_shutdown(void *data)
+{
+	uint32_t tmp;
+
+	/* Disable writes manually. See the comment about EECD in
+	 * nicintel_spi_init() for details.
+	 */
+	tmp = pci_mmio_readl(nicintel_spibar + EECD);
+	tmp &= ~FLASH_WRITES_ENABLED;
+	tmp |= FLASH_WRITES_DISABLED;
+	pci_mmio_writel(tmp, nicintel_spibar + EECD);
+
+	physunmap(nicintel_spibar, 4096);
+	pci_cleanup(pacc);
+	release_io_perms();
+
+	return 0;
+}
+
 int nicintel_spi_init(void)
 {
 	uint32_t tmp;
 
 	get_io_perms();
 
+	if (register_shutdown(nicintel_spi_shutdown, NULL))
+		return 1;
+
 	io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, nics_intel_spi);
 
 	nicintel_spibar = physmap("Intel Gigabit NIC w/ SPI flash",
@@ -164,22 +186,3 @@
 
 	return 0;
 }
-
-int nicintel_spi_shutdown(void)
-{
-	uint32_t tmp;
-
-	/* Disable writes manually. See the comment about EECD in
-	 * nicintel_spi_init() for details.
-	 */
-	tmp = pci_mmio_readl(nicintel_spibar + EECD);
-	tmp &= ~FLASH_WRITES_ENABLED;
-	tmp |= FLASH_WRITES_DISABLED;
-	pci_mmio_writel(tmp, nicintel_spibar + EECD);
-
-	physunmap(nicintel_spibar, 4096);
-	pci_cleanup(pacc);
-	release_io_perms();
-
-	return 0;
-}
Index: nicnatsemi.c
===================================================================
--- nicnatsemi.c	(revision 1299)
+++ nicnatsemi.c	(working copy)
@@ -35,6 +35,13 @@
 	{},
 };
 
+static int nicnatsemi_shutdown(void)
+{
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int nicnatsemi_init(void)
 {
 	get_io_perms();
@@ -51,16 +58,11 @@
 	 */
 	max_rom_decode.parallel = 131072;
 
+	if (register_shutdown(nicnatsemi_shutdown, NULL))
+		return -1;
 	return 0;
 }
 
-int nicnatsemi_shutdown(void)
-{
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr)
 {
 	OUTL((uint32_t)addr & 0x0001FFFF, io_base_addr + BOOT_ROM_ADDR);
Index: dediprog.c
===================================================================
--- dediprog.c	(revision 1299)
+++ dediprog.c	(working copy)
@@ -536,6 +536,25 @@
 	.write_256 = dediprog_spi_write_256,
 };
 
+static static int dediprog_shutdown(void *data)
+{
+	msg_pspew("%s\n", __func__);
+
+	/* URB 28. Command Set SPI Voltage to 0. */
+	if (dediprog_set_spi_voltage(0x0))
+		return 1;
+
+	if (usb_release_interface(dediprog_handle, 0)) {
+		msg_perr("Could not release USB interface!\n");
+		return 1;
+	}
+	if (usb_close(dediprog_handle)) {
+		msg_perr("Could not close USB device!\n");
+		return 1;
+	}
+	return 0;
+}
+
 /* URB numbers refer to the first log ever captured. */
 int dediprog_init(void)
 {
@@ -587,6 +606,9 @@
 	}
 	dediprog_endpoint = 2;
 	
+	if (register_shutdown(dediprog_shutdown, NULL))
+		return 1;
+
 	dediprog_set_leds(PASS_ON|BUSY_ON|ERROR_ON);
 
 	/* URB 6. Command A. */
@@ -681,22 +703,3 @@
 	return 0;
 }
 #endif	
-
-int dediprog_shutdown(void)
-{
-	msg_pspew("%s\n", __func__);
-
-	/* URB 28. Command Set SPI Voltage to 0. */
-	if (dediprog_set_spi_voltage(0x0))
-		return 1;
-
-	if (usb_release_interface(dediprog_handle, 0)) {
-		msg_perr("Could not release USB interface!\n");
-		return 1;
-	}
-	if (usb_close(dediprog_handle)) {
-		msg_perr("Could not close USB device!\n");
-		return 1;
-	}
-	return 0;
-}
Index: it85spi.c
===================================================================
--- it85spi.c	(revision 1299)
+++ it85spi.c	(working copy)
@@ -226,6 +226,14 @@
 #endif
 }
 
+static int it85xx_shutdown(void *data)
+{
+	msg_pdbg("%s():%d\n", __func__, __LINE__);
+	it85xx_exit_scratch_rom();
+
+	return 0;	/* FIXME: Should probably return something meaningful */
+}
+
 static int it85xx_spi_common_init(struct superio s)
 {
 	chipaddr base;
@@ -233,6 +241,9 @@
 	msg_pdbg("%s():%d superio.vendor=0x%02x\n", __func__, __LINE__,
 	         s.vendor);
 
+	if (register_shutdown(it85xx_shutdown, NULL))
+		return 1;
+
 #ifdef LPC_IO
 	/* Get LPCPNP of SHM. That's big-endian */
 	sio_write(s.port, LDNSEL, 0x0F); /* Set LDN to SHM (0x0F) */
@@ -300,13 +311,6 @@
 	return ret;
 }
 
-int it85xx_shutdown(void)
-{
-	msg_pdbg("%s():%d\n", __func__, __LINE__);
-	it85xx_exit_scratch_rom();
-	return 0;
-}
-
 /* According to ITE 8502 document, the procedure to follow mode is following:
  *   1. write 0x00 to LPC/FWH address 0xffff_fexxh (drive CE# high)
  *   2. write data to LPC/FWH address 0xffff_fdxxh (drive CE# low and MOSI
Index: buspirate_spi.c
===================================================================
--- buspirate_spi.c	(revision 1299)
+++ buspirate_spi.c	(working copy)
@@ -106,6 +106,41 @@
 	{NULL,		0x0}
 };
 
+static int buspirate_spi_shutdown(void *data)
+{
+	unsigned char buf[5];
+	int ret = 0;
+
+	/* Exit raw SPI mode (enter raw bitbang mode) */
+	buf[0] = 0x00;
+	ret = buspirate_sendrecv(buf, 1, 5);
+	if (ret)
+		return ret;
+	if (memcmp(buf, "BBIO", 4)) {
+		msg_perr("Entering raw bitbang mode failed!\n");
+		return 1;
+	}
+	msg_pdbg("Raw bitbang mode version %c\n", buf[4]);
+	if (buf[4] != '1') {
+		msg_perr("Can't handle raw bitbang mode version %c!\n",
+			buf[4]);
+		return 1;
+	}
+	/* Reset Bus Pirate (return to user terminal) */
+	buf[0] = 0x0f;
+	ret = buspirate_sendrecv(buf, 1, 0);
+	if (ret)
+		return ret;
+
+	/* Shut down serial port communication */
+	ret = serialport_shutdown(NULL);
+	if (ret)
+		return ret;
+	msg_pdbg("Bus Pirate shutdown completed.\n");
+
+	return 0;
+}
+
 int buspirate_spi_init(void)
 {
 	unsigned char buf[512];
@@ -143,6 +178,9 @@
 		return ret;
 	free(dev);
 
+	if (register_shutdown(buspirate_spi_shutdown, NULL))
+		return 1;
+
 	/* This is the brute force version, but it should work. */
 	for (i = 0; i < 19; i++) {
 		/* Enter raw bitbang mode */
@@ -248,41 +286,6 @@
 	return 0;
 }
 
-int buspirate_spi_shutdown(void)
-{
-	unsigned char buf[5];
-	int ret = 0;
-
-	/* Exit raw SPI mode (enter raw bitbang mode) */
-	buf[0] = 0x00;
-	ret = buspirate_sendrecv(buf, 1, 5);
-	if (ret)
-		return ret;
-	if (memcmp(buf, "BBIO", 4)) {
-		msg_perr("Entering raw bitbang mode failed!\n");
-		return 1;
-	}
-	msg_pdbg("Raw bitbang mode version %c\n", buf[4]);
-	if (buf[4] != '1') {
-		msg_perr("Can't handle raw bitbang mode version %c!\n",
-			buf[4]);
-		return 1;
-	}
-	/* Reset Bus Pirate (return to user terminal) */
-	buf[0] = 0x0f;
-	ret = buspirate_sendrecv(buf, 1, 0);
-	if (ret)
-		return ret;
-
-	/* Shut down serial port communication */
-	ret = serialport_shutdown();
-	if (ret)
-		return ret;
-	msg_pdbg("Bus Pirate shutdown completed.\n");
-
-	return 0;
-}
-
 static int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		const unsigned char *writearr, unsigned char *readarr)
 {
Index: serial.c
===================================================================
--- serial.c	(revision 1299)
+++ serial.c	(working copy)
@@ -180,7 +180,7 @@
 	return;
 }
 
-int serialport_shutdown(void)
+int serialport_shutdown(void *data)
 {
 #ifdef _WIN32
 	CloseHandle(sp_fd);
Index: atahpt.c
===================================================================
--- atahpt.c	(revision 1299)
+++ atahpt.c	(working copy)
@@ -38,6 +38,14 @@
 	{},
 };
 
+static int atahpt_shutdown(void *data)
+{
+	/* Flash access is disabled automatically by PCI restore. */
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int atahpt_init(void)
 {
 	uint32_t reg32;
@@ -53,17 +61,11 @@
 
 	buses_supported = CHIP_BUSTYPE_PARALLEL;
 
+	if (register_shutdown(atahpt_shutdown, NULL))
+		return 1;
 	return 0;
 }
 
-int atahpt_shutdown(void)
-{
-	/* Flash access is disabled automatically by PCI restore. */
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void atahpt_chip_writeb(uint8_t val, chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
Index: nic3com.c
===================================================================
--- nic3com.c	(revision 1299)
+++ nic3com.c	(working copy)
@@ -55,6 +55,21 @@
 	{},
 };
 
+static int nic3com_shutdown(void *data)
+{
+	/* 3COM 3C90xB cards need a special fixup. */
+	if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
+	    || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
+		/* Select register window 3 and restore the receiver status. */
+		OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
+		OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG);
+	}
+
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int nic3com_init(void)
 {
 	get_io_perms();
@@ -84,24 +99,9 @@
 	buses_supported = CHIP_BUSTYPE_PARALLEL;
 	max_rom_decode.parallel = 128 * 1024;
 
-	return 0;
+	return register_shutdown(nic3com_shutdown, NULL);
 }
 
-int nic3com_shutdown(void)
-{
-	/* 3COM 3C90xB cards need a special fixup. */
-	if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
-	    || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
-		/* Select register window 3 and restore the receiver status. */
-		OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
-		OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG);
-	}
-
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void nic3com_chip_writeb(uint8_t val, chipaddr addr)
 {
 	OUTL((uint32_t)addr, io_base_addr + BIOS_ROM_ADDR);
Index: satasii.c
===================================================================
--- satasii.c	(revision 1299)
+++ satasii.c	(working copy)
@@ -40,6 +40,13 @@
 	{},
 };
 
+static int satasii_shutdown(void *data)
+{
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int satasii_init(void)
 {
 	uint32_t addr;
@@ -67,16 +74,11 @@
 
 	buses_supported = CHIP_BUSTYPE_PARALLEL;
 
+	if (register_shutdown(satasii_shutdown, NULL))
+		return 1;
 	return 0;
 }
 
-int satasii_shutdown(void)
-{
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void satasii_chip_writeb(uint8_t val, chipaddr addr)
 {
 	uint32_t ctrl_reg, data_reg;
Index: nicintel.c
===================================================================
--- nicintel.c	(revision 1299)
+++ nicintel.c	(working copy)
@@ -41,6 +41,14 @@
 
 #define CSR_FCR 0x0c
 
+static int nicintel_shutdown(void *data)
+{
+	physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE);
+	pci_cleanup(pacc);
+	release_io_perms();
+	return 0;
+}
+
 int nicintel_init(void)
 {
 	uintptr_t addr;
@@ -60,6 +68,9 @@
 	if (nicintel_bar == ERROR_PTR)
 		goto error_out;
 
+	if (register_shutdown(nicintel_shutdown, NULL))
+		return 1;
+
 	/* FIXME: Using pcidev_dev _will_ cause pretty explosions in the future. */
 	addr = pcidev_validate(pcidev_dev, PCI_BASE_ADDRESS_0, nics_intel);
 	/* FIXME: This is not an aligned mapping. Use 4k? */
@@ -90,14 +101,6 @@
 	return 1;
 }
 
-int nicintel_shutdown(void)
-{
-	physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE);
-	pci_cleanup(pacc);
-	release_io_perms();
-	return 0;
-}
-
 void nicintel_chip_writeb(uint8_t val, chipaddr addr)
 {
 	pci_mmio_writeb(val, nicintel_bar + (addr & NICINTEL_MEMMAP_MASK));
Index: flashrom.c
===================================================================
--- flashrom.c	(revision 1299)
+++ flashrom.c	(working copy)
@@ -129,7 +129,6 @@
 	{
 		.name			= "internal",
 		.init			= internal_init,
-		.shutdown		= internal_shutdown,
 		.map_flash_region	= physmap,
 		.unmap_flash_region	= physunmap,
 		.chip_readb		= internal_chip_readb,
@@ -148,7 +147,6 @@
 	{
 		.name			= "dummy",
 		.init			= dummy_init,
-		.shutdown		= dummy_shutdown,
 		.map_flash_region	= dummy_map,
 		.unmap_flash_region	= dummy_unmap,
 		.chip_readb		= dummy_chip_readb,
@@ -167,7 +165,6 @@
 	{
 		.name			= "nic3com",
 		.init			= nic3com_init,
-		.shutdown		= nic3com_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= nic3com_chip_readb,
@@ -188,7 +185,6 @@
 		.name                   = "nicrealtek",
 		//.name                   = "nicsmc1211",
 		.init                   = nicrealtek_init,
-		.shutdown               = nicrealtek_shutdown,
 		.map_flash_region       = fallback_map,
 		.unmap_flash_region     = fallback_unmap,
 		.chip_readb             = nicrealtek_chip_readb,
@@ -207,7 +203,6 @@
 	{
 		.name                   = "nicnatsemi",
 		.init                   = nicnatsemi_init,
-		.shutdown               = nicnatsemi_shutdown,
 		.map_flash_region       = fallback_map,
 		.unmap_flash_region     = fallback_unmap,
 		.chip_readb             = nicnatsemi_chip_readb,
@@ -226,7 +221,6 @@
 	{
 		.name			= "gfxnvidia",
 		.init			= gfxnvidia_init,
-		.shutdown		= gfxnvidia_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= gfxnvidia_chip_readb,
@@ -245,7 +239,6 @@
 	{
 		.name			= "drkaiser",
 		.init			= drkaiser_init,
-		.shutdown		= drkaiser_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= drkaiser_chip_readb,
@@ -264,7 +257,6 @@
 	{
 		.name			= "satasii",
 		.init			= satasii_init,
-		.shutdown		= satasii_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= satasii_chip_readb,
@@ -283,7 +275,6 @@
 	{
 		.name			= "atahpt",
 		.init			= atahpt_init,
-		.shutdown		= atahpt_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= atahpt_chip_readb,
@@ -302,7 +293,6 @@
 	{
 		.name			= "ft2232_spi",
 		.init			= ft2232_spi_init,
-		.shutdown		= noop_shutdown, /* Missing shutdown */
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= noop_chip_readb,
@@ -321,7 +311,6 @@
 	{
 		.name			= "serprog",
 		.init			= serprog_init,
-		.shutdown		= serprog_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= serprog_chip_readb,
@@ -340,7 +329,6 @@
 	{
 		.name			= "buspirate_spi",
 		.init			= buspirate_spi_init,
-		.shutdown		= buspirate_spi_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= noop_chip_readb,
@@ -359,7 +347,6 @@
 	{
 		.name			= "dediprog",
 		.init			= dediprog_init,
-		.shutdown		= dediprog_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= noop_chip_readb,
@@ -378,7 +365,6 @@
 	{
 		.name			= "rayer_spi",
 		.init			= rayer_spi_init,
-		.shutdown		= noop_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= noop_chip_readb,
@@ -397,7 +383,6 @@
 	{
 		.name			= "nicintel",
 		.init			= nicintel_init,
-		.shutdown		= nicintel_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= nicintel_chip_readb,
@@ -416,7 +401,6 @@
 	{
 		.name = "nicintel_spi",
 		.init = nicintel_spi_init,
-		.shutdown = nicintel_spi_shutdown,
 		.map_flash_region = fallback_map,
 		.unmap_flash_region = fallback_unmap,
 		.chip_readb = noop_chip_readb,
@@ -435,7 +419,6 @@
 	{
 		.name = "ogp_spi",
 		.init = ogp_spi_init,
-		.shutdown = ogp_spi_shutdown,
 		.map_flash_region = fallback_map,
 		.unmap_flash_region = fallback_unmap,
 		.chip_readb = noop_chip_readb,
@@ -454,7 +437,6 @@
 	{
 		.name			= "satamv",
 		.init			= satamv_init,
-		.shutdown		= satamv_shutdown,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
 		.chip_readb		= satamv_chip_readb,
@@ -475,7 +457,7 @@
 #define SHUTDOWN_MAXFN 32
 static int shutdown_fn_count = 0;
 struct shutdown_func_data {
-	void (*func) (void *data);
+	int (*func) (void *data);
 	void *data;
 } static shutdown_fn[SHUTDOWN_MAXFN];
 /* Initialize to 0 to make sure nobody registers a shutdown function before
@@ -491,7 +473,7 @@
  * Please note that the first (void *data) belongs to the function signature of
  * the function passed as first parameter.
  */
-int register_shutdown(void (*function) (void *data), void *data)
+int register_shutdown(int (*function) (void *data), void *data)
 {
 	if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
 		msg_perr("Tried to register more than %i shutdown functions.\n",
@@ -543,13 +525,15 @@
 
 int programmer_shutdown(void)
 {
+	int rc = 0;
+
 	/* Registering shutdown functions is no longer allowed. */
 	may_register_shutdown = 0;
 	while (shutdown_fn_count > 0) {
 		int i = --shutdown_fn_count;
-		shutdown_fn[i].func(shutdown_fn[i].data);
+		rc |= shutdown_fn[i].func(shutdown_fn[i].data);
 	}
-	return programmer_table[programmer].shutdown();
+	return rc;
 }
 
 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
Index: programmer.h
===================================================================
--- programmer.h	(revision 1299)
+++ programmer.h	(working copy)
@@ -89,7 +89,6 @@
 	const char *name;
 
 	int (*init) (void);
-	int (*shutdown) (void);
 
 	void * (*map_flash_region) (const char *descr, unsigned long phys_addr,
 				    size_t len);
@@ -303,7 +302,6 @@
 void probe_superio(void);
 int register_superio(struct superio s);
 int internal_init(void);
-int internal_shutdown(void);
 void internal_chip_writeb(uint8_t val, chipaddr addr);
 void internal_chip_writew(uint16_t val, chipaddr addr);
 void internal_chip_writel(uint32_t val, chipaddr addr);
@@ -361,7 +359,6 @@
 /* dummyflasher.c */
 #if CONFIG_DUMMY == 1
 int dummy_init(void);
-int dummy_shutdown(void);
 void *dummy_map(const char *descr, unsigned long phys_addr, size_t len);
 void dummy_unmap(void *virt_addr, size_t len);
 void dummy_chip_writeb(uint8_t val, chipaddr addr);
@@ -377,7 +374,6 @@
 /* nic3com.c */
 #if CONFIG_NIC3COM == 1
 int nic3com_init(void);
-int nic3com_shutdown(void);
 void nic3com_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t nic3com_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_3com[];
@@ -386,7 +382,6 @@
 /* gfxnvidia.c */
 #if CONFIG_GFXNVIDIA == 1
 int gfxnvidia_init(void);
-int gfxnvidia_shutdown(void);
 void gfxnvidia_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t gfxnvidia_chip_readb(const chipaddr addr);
 extern const struct pcidev_status gfx_nvidia[];
@@ -395,7 +390,6 @@
 /* drkaiser.c */
 #if CONFIG_DRKAISER == 1
 int drkaiser_init(void);
-int drkaiser_shutdown(void);
 void drkaiser_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t drkaiser_chip_readb(const chipaddr addr);
 extern const struct pcidev_status drkaiser_pcidev[];
@@ -404,7 +398,6 @@
 /* nicrealtek.c */
 #if CONFIG_NICREALTEK == 1
 int nicrealtek_init(void);
-int nicrealtek_shutdown(void);
 void nicrealtek_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t nicrealtek_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_realtek[];
@@ -413,7 +406,6 @@
 /* nicnatsemi.c */
 #if CONFIG_NICNATSEMI == 1
 int nicnatsemi_init(void);
-int nicnatsemi_shutdown(void);
 void nicnatsemi_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t nicnatsemi_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_natsemi[];
@@ -422,7 +414,6 @@
 /* nicintel.c */
 #if CONFIG_NICINTEL == 1
 int nicintel_init(void);
-int nicintel_shutdown(void);
 void nicintel_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t nicintel_chip_readb(const chipaddr addr);
 extern const struct pcidev_status nics_intel[];
@@ -431,7 +422,6 @@
 /* nicintel_spi.c */
 #if CONFIG_NICINTEL_SPI == 1
 int nicintel_spi_init(void);
-int nicintel_spi_shutdown(void);
 int nicintel_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 	const unsigned char *writearr, unsigned char *readarr);
 void nicintel_spi_chip_writeb(uint8_t val, chipaddr addr);
@@ -441,14 +431,12 @@
 /* ogp_spi.c */
 #if CONFIG_OGP_SPI == 1
 int ogp_spi_init(void);
-int ogp_spi_shutdown(void);
 extern const struct pcidev_status ogp_spi[];
 #endif
 
 /* satamv.c */
 #if CONFIG_SATAMV == 1
 int satamv_init(void);
-int satamv_shutdown(void);
 void satamv_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t satamv_chip_readb(const chipaddr addr);
 extern const struct pcidev_status satas_mv[];
@@ -457,7 +445,6 @@
 /* satasii.c */
 #if CONFIG_SATASII == 1
 int satasii_init(void);
-int satasii_shutdown(void);
 void satasii_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t satasii_chip_readb(const chipaddr addr);
 extern const struct pcidev_status satas_sii[];
@@ -466,7 +453,6 @@
 /* atahpt.c */
 #if CONFIG_ATAHPT == 1
 int atahpt_init(void);
-int atahpt_shutdown(void);
 void atahpt_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t atahpt_chip_readb(const chipaddr addr);
 extern const struct pcidev_status ata_hpt[];
@@ -508,11 +494,9 @@
 	const int speed;
 };
 int buspirate_spi_init(void);
-int buspirate_spi_shutdown(void);
 
 /* dediprog.c */
 int dediprog_init(void);
-int dediprog_shutdown(void);
 
 /* flashrom.c */
 struct decode_sizes {
@@ -597,7 +581,6 @@
 
 /* it85spi.c */
 int it85xx_spi_init(struct superio s);
-int it85xx_shutdown(void);
 
 /* it87spi.c */
 void enter_conf_mode_ite(uint16_t port);
@@ -617,7 +600,6 @@
 
 /* serprog.c */
 int serprog_init(void);
-int serprog_shutdown(void);
 void serprog_chip_writeb(uint8_t val, chipaddr addr);
 uint8_t serprog_chip_readb(const chipaddr addr);
 void serprog_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
@@ -634,7 +616,8 @@
 fdtype sp_openserport(char *dev, unsigned int baud);
 void __attribute__((noreturn)) sp_die(char *msg);
 extern fdtype sp_fd;
-int serialport_shutdown(void);
+/* expose serialport_shutdown as it's currently used by buspirate */
+int serialport_shutdown(void *data);
 int serialport_write(unsigned char *buf, unsigned int writecnt);
 int serialport_read(unsigned char *buf, unsigned int readcnt);
 
