summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--atahpt.c18
-rw-r--r--buspirate_spi.c73
-rw-r--r--cli_classic.c1
-rw-r--r--dediprog.c41
-rw-r--r--drkaiser.c23
-rw-r--r--dummyflasher.c38
-rw-r--r--flash.h2
-rw-r--r--flashrom.c28
-rw-r--r--gfxnvidia.c30
-rw-r--r--hwaccess.c3
-rw-r--r--internal.c15
-rw-r--r--it85spi.c18
-rw-r--r--nic3com.c32
-rw-r--r--nicintel.c29
-rw-r--r--nicintel_spi.c41
-rw-r--r--nicnatsemi.c16
-rw-r--r--nicrealtek.c18
-rw-r--r--ogp_spi.c21
-rw-r--r--pcidev.c3
-rw-r--r--programmer.h21
-rw-r--r--satamv.c19
-rw-r--r--satasii.c22
-rw-r--r--serial.c2
-rw-r--r--serprog.c12
24 files changed, 284 insertions, 242 deletions
diff --git a/atahpt.c b/atahpt.c
index 82b430d44..2bf4a1143 100644
--- a/atahpt.c
+++ b/atahpt.c
@@ -38,6 +38,14 @@ const struct pcidev_status ata_hpt[] = {
{},
};
+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,14 +61,8 @@ int atahpt_init(void)
buses_supported = CHIP_BUSTYPE_PARALLEL;
- return 0;
-}
-
-int atahpt_shutdown(void)
-{
- /* Flash access is disabled automatically by PCI restore. */
- pci_cleanup(pacc);
- release_io_perms();
+ if (register_shutdown(atahpt_shutdown, NULL))
+ return 1;
return 0;
}
diff --git a/buspirate_spi.c b/buspirate_spi.c
index 3ac0929b6..3b9f48707 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -111,6 +111,41 @@ static const struct buspirate_spispeeds spispeeds[] = {
{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];
@@ -148,6 +183,9 @@ int buspirate_spi_init(void)
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 */
@@ -253,41 +291,6 @@ int buspirate_spi_init(void)
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)
{
diff --git a/cli_classic.c b/cli_classic.c
index d1b468644..59096a02d 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -360,6 +360,7 @@ int cli_classic(int argc, char *argv[])
if (programmer_init(pparam)) {
fprintf(stderr, "Error: Programmer initialization failed.\n");
+ programmer_shutdown();
exit(1);
}
diff --git a/dediprog.c b/dediprog.c
index 1c54c668d..1cbde18b3 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -536,6 +536,25 @@ static const struct spi_programmer spi_programmer_dediprog = {
.write_256 = dediprog_spi_write_256,
};
+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 @@ int dediprog_init(void)
}
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 @@ static int dediprog_do_stuff(void)
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;
-}
diff --git a/drkaiser.c b/drkaiser.c
index c2938ddb2..db4be60ac 100644
--- a/drkaiser.c
+++ b/drkaiser.c
@@ -27,6 +27,8 @@
#define PCI_MAGIC_DRKAISER_ADDR 0x50
#define PCI_MAGIC_DRKAISER_VALUE 0xa971
+#define DRKAISER_MEMMAP_SIZE (1024 * 128)
+
/* Mask to restrict flash accesses to the 128kB memory window. */
#define DRKAISER_MEMMAP_MASK ((1 << 17) - 1)
@@ -37,6 +39,15 @@ const struct pcidev_status drkaiser_pcidev[] = {
static uint8_t *drkaiser_bar;
+static int drkaiser_shutdown(void *data)
+{
+ physunmap(drkaiser_bar, DRKAISER_MEMMAP_SIZE);
+ /* Flash write is disabled automatically by PCI restore. */
+ pci_cleanup(pacc);
+ release_io_perms();
+ return 0;
+};
+
int drkaiser_init(void)
{
uint32_t addr;
@@ -51,21 +62,15 @@ int drkaiser_init(void)
/* Map 128kB flash memory window. */
drkaiser_bar = physmap("Dr. Kaiser PC-Waechter flash memory",
- addr, 128 * 1024);
+ addr, DRKAISER_MEMMAP_SIZE);
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));
diff --git a/dummyflasher.c b/dummyflasher.c
index fdb4f2a6d..fca228cfb 100644
--- a/dummyflasher.c
+++ b/dummyflasher.c
@@ -73,6 +73,23 @@ static const struct spi_programmer spi_programmer_dummyflasher = {
.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;
@@ -126,7 +143,7 @@ int dummy_init(void)
if (!tmp) {
msg_pdbg("Not emulating any flash chip.\n");
/* Nothing else to do. */
- return 0;
+ goto dummy_init_out;
}
#if EMULATE_SPI_CHIP
if (!strcmp(tmp, "M25P10.RES")) {
@@ -180,13 +197,14 @@ int dummy_init(void)
msg_perr("Out of memory!\n");
return 1;
}
+
msg_pdbg("Filling fake flash chip with 0xff, size %i\n", emu_chip_size);
memset(flashchip_contents, 0xff, emu_chip_size);
emu_persistent_image = extract_programmer_param("image");
if (!emu_persistent_image) {
/* Nothing else to do. */
- return 0;
+ goto dummy_init_out;
}
if (!stat(emu_persistent_image, &image_stat)) {
msg_pdbg("Found persistent image %s, size %li ",
@@ -201,22 +219,12 @@ int dummy_init(void)
}
}
#endif
- 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);
- }
+dummy_init_out:
+ if (register_shutdown(dummy_shutdown, NULL)) {
free(flashchip_contents);
+ return 1;
}
-#endif
return 0;
}
diff --git a/flash.h b/flash.h
index ec248d9d0..f87510257 100644
--- a/flash.h
+++ b/flash.h
@@ -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);
diff --git a/flashrom.c b/flashrom.c
index e9e6a7751..663b56b7f 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -129,7 +129,6 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
{
.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 @@ const struct programmer_entry programmer_table[] = {
#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 @@ static int may_register_shutdown = 0;
* 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_init(char *param)
int programmer_shutdown(void)
{
+ int ret = 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);
+ ret |= shutdown_fn[i].func(shutdown_fn[i].data);
}
- return programmer_table[programmer].shutdown();
+ return ret;
}
void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
diff --git a/gfxnvidia.c b/gfxnvidia.c
index 60498b11f..3f67c72ea 100644
--- a/gfxnvidia.c
+++ b/gfxnvidia.c
@@ -29,6 +29,7 @@
* FIXME: Is this size a one-fits-all or card dependent?
*/
#define GFXNVIDIA_MEMMAP_MASK ((1 << 17) - 1)
+#define GFXNVIDIA_MEMMAP_SIZE (16 * 1024 * 1024)
uint8_t *nvidia_bar;
@@ -60,6 +61,17 @@ const struct pcidev_status gfx_nvidia[] = {
{},
};
+static int gfxnvidia_shutdown(void *data)
+{
+ physunmap(nvidia_bar, GFXNVIDIA_MEMMAP_SIZE);
+ /* 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;
@@ -71,13 +83,17 @@ int gfxnvidia_init(void)
io_base_addr += 0x300000;
msg_pinfo("Detected NVIDIA I/O base address: 0x%x.\n", io_base_addr);
+ nvidia_bar = physmap("NVIDIA", io_base_addr, GFXNVIDIA_MEMMAP_SIZE);
+
+ /* must be done before rpci calls */
+ if (register_shutdown(gfxnvidia_shutdown, NULL))
+ return 1;
+
/* Allow access to flash interface (will disable screen). */
reg32 = pci_read_long(pcidev_dev, 0x50);
reg32 &= ~(1 << 0);
rpci_write_long(pcidev_dev, 0x50, reg32);
- nvidia_bar = physmap("NVIDIA", io_base_addr, 16 * 1024 * 1024);
-
buses_supported = CHIP_BUSTYPE_PARALLEL;
/* Write/erase doesn't work. */
@@ -86,16 +102,6 @@ int gfxnvidia_init(void)
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));
diff --git a/hwaccess.c b/hwaccess.c
index 3c4f07a8c..efe8bb0e9 100644
--- a/hwaccess.c
+++ b/hwaccess.c
@@ -202,7 +202,7 @@ struct undo_mmio_write_data {
};
};
-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 @@ void undo_mmio_write(void *p)
}
/* p was allocated in register_undo_mmio_write. */
free(p);
+ return 0;
}
#define register_undo_mmio_write(a, c) \
diff --git a/internal.c b/internal.c
index c9f62c161..32bfb3a88 100644
--- a/internal.c
+++ b/internal.c
@@ -127,6 +127,12 @@ int register_superio(struct superio s)
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 @@ int internal_init(void)
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 @@ int internal_init(void)
return 1;
#endif
}
-
-int internal_shutdown(void)
-{
- release_io_perms();
-
- return 0;
-}
#endif
void internal_chip_writeb(uint8_t val, chipaddr addr)
diff --git a/it85spi.c b/it85spi.c
index c6c945b8c..d4ca13b0f 100644
--- a/it85spi.c
+++ b/it85spi.c
@@ -226,6 +226,14 @@ void it85xx_exit_scratch_rom()
#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 @@ static int it85xx_spi_common_init(struct superio s)
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 @@ int it85xx_spi_init(struct superio s)
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
diff --git a/nic3com.c b/nic3com.c
index d39ee715c..bcc63e0bd 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -55,6 +55,21 @@ const struct pcidev_status nics_3com[] = {
{},
};
+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,21 +99,8 @@ int nic3com_init(void)
buses_supported = CHIP_BUSTYPE_PARALLEL;
max_rom_decode.parallel = 128 * 1024;
- return 0;
-}
-
-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();
+ if (register_shutdown(nic3com_shutdown, NULL))
+ return 1;
return 0;
}
diff --git a/nicintel.c b/nicintel.c
index 3d53ec85e..2e6e46a24 100644
--- a/nicintel.c
+++ b/nicintel.c
@@ -39,8 +39,19 @@ const struct pcidev_status nics_intel[] = {
#define NICINTEL_MEMMAP_SIZE (128 * 1024)
#define NICINTEL_MEMMAP_MASK (NICINTEL_MEMMAP_SIZE - 1)
+#define NICINTEL_CONTROL_MEMMAP_SIZE 0x10
+
#define CSR_FCR 0x0c
+static int nicintel_shutdown(void *data)
+{
+ physunmap(nicintel_control_bar, NICINTEL_CONTROL_MEMMAP_SIZE);
+ physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE);
+ pci_cleanup(pacc);
+ release_io_perms();
+ return 0;
+}
+
int nicintel_init(void)
{
uintptr_t addr;
@@ -58,15 +69,19 @@ int nicintel_init(void)
nicintel_bar = physmap("Intel NIC flash", addr, NICINTEL_MEMMAP_SIZE);
if (nicintel_bar == ERROR_PTR)
- goto error_out;
+ goto error_out_unmap;
/* 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? */
- nicintel_control_bar = physmap("Intel NIC control/status reg", addr, 0x10);
+ nicintel_control_bar = physmap("Intel NIC control/status reg",
+ addr, NICINTEL_CONTROL_MEMMAP_SIZE);
if (nicintel_control_bar == ERROR_PTR)
goto error_out;
+ if (register_shutdown(nicintel_shutdown, NULL))
+ return 1;
+
/* FIXME: This register is pretty undocumented in all publicly available
* documentation from Intel. Let me quote the complete info we have:
* "Flash Control Register: The Flash Control register allows the CPU to
@@ -84,20 +99,14 @@ int nicintel_init(void)
return 0;
+error_out_unmap:
+ physunmap(nicintel_bar, NICINTEL_MEMMAP_SIZE);
error_out:
pci_cleanup(pacc);
release_io_perms();
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));
diff --git a/nicintel_spi.c b/nicintel_spi.c
index 574735fb2..aacd68c72 100644
--- a/nicintel_spi.c
+++ b/nicintel_spi.c
@@ -139,6 +139,25 @@ static const struct bitbang_spi_master bitbang_spi_master_nicintel = {
.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;
@@ -159,28 +178,12 @@ int nicintel_spi_init(void)
tmp |= FLASH_WRITES_ENABLED;
pci_mmio_writel(tmp, nicintel_spibar + EECD);
+ if (register_shutdown(nicintel_spi_shutdown, NULL))
+ return 1;
+
/* 1 usec halfperiod delay for now. */
if (bitbang_spi_init(&bitbang_spi_master_nicintel, 1))
return 1;
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;
-}
diff --git a/nicnatsemi.c b/nicnatsemi.c
index 3cae25366..ac37cf0cd 100644
--- a/nicnatsemi.c
+++ b/nicnatsemi.c
@@ -35,6 +35,13 @@ const struct pcidev_status nics_natsemi[] = {
{},
};
+static int nicnatsemi_shutdown(void *data)
+{
+ pci_cleanup(pacc);
+ release_io_perms();
+ return 0;
+}
+
int nicnatsemi_init(void)
{
get_io_perms();
@@ -51,13 +58,8 @@ int nicnatsemi_init(void)
*/
max_rom_decode.parallel = 131072;
- return 0;
-}
-
-int nicnatsemi_shutdown(void)
-{
- pci_cleanup(pacc);
- release_io_perms();
+ if (register_shutdown(nicnatsemi_shutdown, NULL))
+ return 1;
return 0;
}
diff --git a/nicrealtek.c b/nicrealtek.c
index d97deb1e5..4566e50c6 100644
--- a/nicrealtek.c
+++ b/nicrealtek.c
@@ -36,6 +36,14 @@ const struct pcidev_status nics_realtek[] = {
{},
};
+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,14 +52,8 @@ int nicrealtek_init(void)
buses_supported = CHIP_BUSTYPE_PARALLEL;
- return 0;
-}
-
-int nicrealtek_shutdown(void)
-{
- /* FIXME: We forgot to disable software access again. */
- pci_cleanup(pacc);
- release_io_perms();
+ if (register_shutdown(nicrealtek_shutdown, NULL))
+ return 1;
return 0;
}
diff --git a/ogp_spi.c b/ogp_spi.c
index 2916ae1f9..dbaa57a0e 100644
--- a/ogp_spi.c
+++ b/ogp_spi.c
@@ -93,6 +93,15 @@ static const struct bitbang_spi_master bitbang_spi_master_ogp = {
.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;
@@ -124,18 +133,12 @@ int ogp_spi_init(void)
ogp_spibar = physmap("OGP registers", io_base_addr, 4096);
+ if (register_shutdown(ogp_spi_shutdown, NULL))
+ return 1;
+
/* no delay for now. */
if (bitbang_spi_init(&bitbang_spi_master_ogp, 0))
return 1;
return 0;
}
-
-int ogp_spi_shutdown(void)
-{
- physunmap(ogp_spibar, 4096);
- pci_cleanup(pacc);
- release_io_perms();
-
- return 0;
-}
diff --git a/pcidev.c b/pcidev.c
index e4980141d..1f9a5cc8d 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -270,7 +270,7 @@ struct undo_pci_write_data {
};
};
-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 @@ void undo_pci_write(void *p)
}
/* p was allocated in register_undo_pci_write. */
free(p);
+ return 0;
}
#define register_undo_pci_write(a, b, c) \
diff --git a/programmer.h b/programmer.h
index 83cf5e1b9..ce0ffa171 100644
--- a/programmer.h
+++ b/programmer.h
@@ -89,7 +89,6 @@ struct programmer_entry {
const char *name;
int (*init) (void);
- int (*shutdown) (void);
void * (*map_flash_region) (const char *descr, unsigned long phys_addr,
size_t len);
@@ -305,7 +304,6 @@ extern int force_boardmismatch;
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);
@@ -363,7 +361,6 @@ void fallback_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
/* 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);
@@ -379,7 +376,6 @@ void dummy_chip_readn(uint8_t *buf, const chipaddr addr, size_t len);
/* 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[];
@@ -388,7 +384,6 @@ extern const struct pcidev_status nics_3com[];
/* 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[];
@@ -397,7 +392,6 @@ extern const struct pcidev_status gfx_nvidia[];
/* 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[];
@@ -406,7 +400,6 @@ extern const struct pcidev_status drkaiser_pcidev[];
/* 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[];
@@ -415,7 +408,6 @@ extern const struct pcidev_status nics_realtek[];
/* 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[];
@@ -424,7 +416,6 @@ extern const struct pcidev_status nics_natsemi[];
/* 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[];
@@ -433,7 +424,6 @@ extern const struct pcidev_status nics_intel[];
/* 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);
@@ -443,14 +433,12 @@ extern const struct pcidev_status nics_intel_spi[];
/* 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[];
@@ -459,7 +447,6 @@ extern const struct pcidev_status satas_mv[];
/* 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[];
@@ -468,7 +455,6 @@ extern const struct pcidev_status satas_sii[];
/* 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[];
@@ -500,13 +486,11 @@ int bitbang_spi_shutdown(const struct bitbang_spi_master *master);
/* buspirate_spi.c */
#if CONFIG_BUSPIRATE_SPI == 1
int buspirate_spi_init(void);
-int buspirate_spi_shutdown(void);
#endif
/* dediprog.c */
#if CONFIG_DEDIPROG == 1
int dediprog_init(void);
-int dediprog_shutdown(void);
#endif
/* flashrom.c */
@@ -591,7 +575,6 @@ int via_init_spi(struct pci_dev *dev);
/* it85spi.c */
int it85xx_spi_init(struct superio s);
-int it85xx_shutdown(void);
/* it87spi.c */
void enter_conf_mode_ite(uint16_t port);
@@ -612,7 +595,6 @@ int wbsio_check_for_spi(void);
/* serprog.c */
#if CONFIG_SERPROG == 1
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);
@@ -630,7 +612,8 @@ void sp_flush_incoming(void);
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);
diff --git a/satamv.c b/satamv.c
index 0c0daceb0..01919d068 100644
--- a/satamv.c
+++ b/satamv.c
@@ -40,6 +40,14 @@ const struct pcidev_status satas_mv[] = {
#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 @@ int satamv_init(void)
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 @@ error_out:
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.
diff --git a/satasii.c b/satasii.c
index 9d05b2d84..dbc4f4f51 100644
--- a/satasii.c
+++ b/satasii.c
@@ -26,6 +26,8 @@
#define PCI_VENDOR_ID_SII 0x1095
+#define SATASII_MEMMAP_SIZE 0x100
+
uint8_t *sii_bar;
static uint16_t id;
@@ -40,6 +42,14 @@ const struct pcidev_status satas_sii[] = {
{},
};
+static int satasii_shutdown(void *data)
+{
+ physunmap(sii_bar, SATASII_MEMMAP_SIZE);
+ pci_cleanup(pacc);
+ release_io_perms();
+ return 0;
+}
+
int satasii_init(void)
{
uint32_t addr;
@@ -59,7 +69,8 @@ int satasii_init(void)
reg_offset = 0x50;
}
- sii_bar = physmap("SATA SIL registers", addr, 0x100) + reg_offset;
+ sii_bar = physmap("SATA SIL registers", addr, SATASII_MEMMAP_SIZE) +
+ reg_offset;
/* Check if ROM cycle are OK. */
if ((id != 0x0680) && (!(pci_mmio_readl(sii_bar) & (1 << 26))))
@@ -67,13 +78,8 @@ int satasii_init(void)
buses_supported = CHIP_BUSTYPE_PARALLEL;
- return 0;
-}
-
-int satasii_shutdown(void)
-{
- pci_cleanup(pacc);
- release_io_perms();
+ if (register_shutdown(satasii_shutdown, NULL))
+ return 1;
return 0;
}
diff --git a/serial.c b/serial.c
index a04a1386b..37ea4222d 100644
--- a/serial.c
+++ b/serial.c
@@ -180,7 +180,7 @@ void sp_flush_incoming(void)
return;
}
-int serialport_shutdown(void)
+int serialport_shutdown(void *data)
{
#ifdef _WIN32
CloseHandle(sp_fd);
diff --git a/serprog.c b/serprog.c
index f869b076e..b91e37674 100644
--- a/serprog.c
+++ b/serprog.c
@@ -39,6 +39,13 @@
#define MSGHEADER "serprog:"
+/*
+ * FIXME: This prototype was added to help reduce diffs for the shutdown
+ * registration patch, which shifted many lines of code to place
+ * serprog_shutdown() before serprog_init(). It should be removed soon.
+ */
+static int serprog_shutdown(void *data);
+
#define S_ACK 0x06
#define S_NAK 0x15
#define S_CMD_NOP 0x00 /* No operation */
@@ -373,6 +380,9 @@ int serprog_init(void)
return 1;
}
+ if (register_shutdown(serprog_shutdown, NULL))
+ return 1;
+
msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
sp_check_avail_automatic = 0;
@@ -555,7 +565,7 @@ static void sp_execute_opbuf(void)
sp_flush_stream();
}
-int serprog_shutdown(void)
+static int serprog_shutdown(void *data)
{
msg_pspew("%s\n", __func__);
if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))