diff options
-rw-r--r-- | atahpt.c | 18 | ||||
-rw-r--r-- | buspirate_spi.c | 73 | ||||
-rw-r--r-- | cli_classic.c | 1 | ||||
-rw-r--r-- | dediprog.c | 41 | ||||
-rw-r--r-- | drkaiser.c | 23 | ||||
-rw-r--r-- | dummyflasher.c | 38 | ||||
-rw-r--r-- | flash.h | 2 | ||||
-rw-r--r-- | flashrom.c | 28 | ||||
-rw-r--r-- | gfxnvidia.c | 30 | ||||
-rw-r--r-- | hwaccess.c | 3 | ||||
-rw-r--r-- | internal.c | 15 | ||||
-rw-r--r-- | it85spi.c | 18 | ||||
-rw-r--r-- | nic3com.c | 32 | ||||
-rw-r--r-- | nicintel.c | 29 | ||||
-rw-r--r-- | nicintel_spi.c | 41 | ||||
-rw-r--r-- | nicnatsemi.c | 16 | ||||
-rw-r--r-- | nicrealtek.c | 18 | ||||
-rw-r--r-- | ogp_spi.c | 21 | ||||
-rw-r--r-- | pcidev.c | 3 | ||||
-rw-r--r-- | programmer.h | 21 | ||||
-rw-r--r-- | satamv.c | 19 | ||||
-rw-r--r-- | satasii.c | 22 | ||||
-rw-r--r-- | serial.c | 2 | ||||
-rw-r--r-- | serprog.c | 12 |
24 files changed, 284 insertions, 242 deletions
@@ -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; } @@ -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) @@ -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 @@ -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; } @@ -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; -} @@ -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); @@ -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. @@ -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; } @@ -180,7 +180,7 @@ void sp_flush_incoming(void) return; } -int serialport_shutdown(void) +int serialport_shutdown(void *data) { #ifdef _WIN32 CloseHandle(sp_fd); @@ -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)) |