Author: dhendrix Date: Tue Jun 14 03:35:36 2011 New Revision: 1338 URL: http://flashrom.org/trac/flashrom/changeset/1338
Log: Use shutdown callback mechanism to shutdown programmers
This patch attempts to resolve some programmer shutdown ordering issues by having the programmer init functions register shutdown callbacks explicitly wherever it makes most sense. Before, assumptions were made that could lead to the internal programmer's state changing before the external programmer could be shut down properly. Now, each programmer cleans up after itself and (hopefully) performs each operation in the correct order.
As a side-effect, this patch gives us a better usage model for reverse operations such as rpci_* and rmmio_*. In the long-run, this should make reversing the initialization process easier to understand, less tedious, and less error-prone.
In short, this patch does the following: - Registers a shutdown callback during initialization for each programmer. - Kills the .shutdown function pointer from programmer_entry struct. Also, make most shutdown functions static. - Adds a few minor clean-ups and corrections (e.g. missing physunmap() calls).
TODO: Remove forward declaration of serprog_shutdown() (added to simplify diff)
Signed-off-by: David Hendricks dhendrix@google.com Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Modified: trunk/atahpt.c trunk/buspirate_spi.c trunk/cli_classic.c trunk/dediprog.c trunk/drkaiser.c trunk/dummyflasher.c trunk/flash.h trunk/flashrom.c trunk/gfxnvidia.c trunk/hwaccess.c trunk/internal.c trunk/it85spi.c trunk/nic3com.c trunk/nicintel.c trunk/nicintel_spi.c trunk/nicnatsemi.c trunk/nicrealtek.c trunk/ogp_spi.c trunk/pcidev.c trunk/programmer.h trunk/satamv.c trunk/satasii.c trunk/serial.c trunk/serprog.c
Modified: trunk/atahpt.c ============================================================================== --- trunk/atahpt.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/atahpt.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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,14 +61,8 @@
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; }
Modified: trunk/buspirate_spi.c ============================================================================== --- trunk/buspirate_spi.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/buspirate_spi.c Tue Jun 14 03:35:36 2011 (r1338) @@ -111,6 +111,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]; @@ -148,6 +183,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 */ @@ -252,41 +290,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)
Modified: trunk/cli_classic.c ============================================================================== --- trunk/cli_classic.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/cli_classic.c Tue Jun 14 03:35:36 2011 (r1338) @@ -360,6 +360,7 @@
if (programmer_init(pparam)) { fprintf(stderr, "Error: Programmer initialization failed.\n"); + programmer_shutdown(); exit(1); }
Modified: trunk/dediprog.c ============================================================================== --- trunk/dediprog.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/dediprog.c Tue Jun 14 03:35:36 2011 (r1338) @@ -536,6 +536,25 @@ .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 @@ } 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; -}
Modified: trunk/drkaiser.c ============================================================================== --- trunk/drkaiser.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/drkaiser.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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 @@
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 @@
/* 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));
Modified: trunk/dummyflasher.c ============================================================================== --- trunk/dummyflasher.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/dummyflasher.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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; @@ -126,7 +143,7 @@ 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 @@ 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 @@ } } #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; }
Modified: trunk/flash.h ============================================================================== --- trunk/flash.h Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/flash.h Tue Jun 14 03:35:36 2011 (r1338) @@ -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);
Modified: trunk/flashrom.c ============================================================================== --- trunk/flashrom.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/flashrom.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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 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,
Modified: trunk/gfxnvidia.c ============================================================================== --- trunk/gfxnvidia.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/gfxnvidia.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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 @@ {}, };
+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 @@ 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 @@ 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));
Modified: trunk/hwaccess.c ============================================================================== --- trunk/hwaccess.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/hwaccess.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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) \
Modified: trunk/internal.c ============================================================================== --- trunk/internal.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/internal.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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)
Modified: trunk/it85spi.c ============================================================================== --- trunk/it85spi.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/it85spi.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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
Modified: trunk/nic3com.c ============================================================================== --- trunk/nic3com.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/nic3com.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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,21 +99,8 @@ 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; }
Modified: trunk/nicintel.c ============================================================================== --- trunk/nicintel.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/nicintel.c Tue Jun 14 03:35:36 2011 (r1338) @@ -39,8 +39,19 @@ #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 @@
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 @@
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));
Modified: trunk/nicintel_spi.c ============================================================================== --- trunk/nicintel_spi.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/nicintel_spi.c Tue Jun 14 03:35:36 2011 (r1338) @@ -139,6 +139,25 @@ .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 @@ 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; -}
Modified: trunk/nicnatsemi.c ============================================================================== --- trunk/nicnatsemi.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/nicnatsemi.c Tue Jun 14 03:35:36 2011 (r1338) @@ -35,6 +35,13 @@ {}, };
+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 @@ */ 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; }
Modified: trunk/nicrealtek.c ============================================================================== --- trunk/nicrealtek.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/nicrealtek.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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,14 +52,8 @@
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; }
Modified: trunk/ogp_spi.c ============================================================================== --- trunk/ogp_spi.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/ogp_spi.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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; @@ -124,18 +133,12 @@
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; -}
Modified: trunk/pcidev.c ============================================================================== --- trunk/pcidev.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/pcidev.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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) \
Modified: trunk/programmer.h ============================================================================== --- trunk/programmer.h Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/programmer.h Tue Jun 14 03:35:36 2011 (r1338) @@ -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); @@ -305,7 +304,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); @@ -363,7 +361,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); @@ -379,7 +376,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[]; @@ -388,7 +384,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[]; @@ -397,7 +392,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[]; @@ -406,7 +400,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[]; @@ -415,7 +408,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[]; @@ -424,7 +416,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[]; @@ -433,7 +424,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); @@ -443,14 +433,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[]; @@ -459,7 +447,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[]; @@ -468,7 +455,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[]; @@ -500,13 +486,11 @@ /* 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 @@
/* 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 @@ /* 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 @@ 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);
Modified: trunk/satamv.c ============================================================================== --- trunk/satamv.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/satamv.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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.
Modified: trunk/satasii.c ============================================================================== --- trunk/satasii.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/satasii.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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 @@ {}, };
+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 @@ 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 @@
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; }
Modified: trunk/serial.c ============================================================================== --- trunk/serial.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/serial.c Tue Jun 14 03:35:36 2011 (r1338) @@ -180,7 +180,7 @@ return; }
-int serialport_shutdown(void) +int serialport_shutdown(void *data) { #ifdef _WIN32 CloseHandle(sp_fd);
Modified: trunk/serprog.c ============================================================================== --- trunk/serprog.c Mon Jun 13 18:59:01 2011 (r1337) +++ trunk/serprog.c Tue Jun 14 03:35:36 2011 (r1338) @@ -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 @@ 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 @@ 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))