Commit 8bb2021d authored by David Hendricks's avatar David Hendricks Committed by David Hendricks
Browse files

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)

Corresponding to flashrom svn r1338.
Signed-off-by: default avatarDavid Hendricks <dhendrix@google.com>
Acked-by: default avatarCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
parent 9d9a1042
......@@ -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;
}
......
......@@ -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)
{
......
......@@ -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);
}
......
......@@ -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;
}
......@@ -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));
......
......@@ -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);
......
......@@ -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,
......
......@@ -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));
......
......@@ -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) \
......
......@@ -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;
}
......
......@@ -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));
......
......@@ -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;
}
......@@ -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;
}
......
......@@ -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) \
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment