Signed-off-by: Niklas Söderlund niso@kth.se --- hwaccess.c | 57 +++++++++++++++++++++++++++++++++------------------------ ichspi.c | 53 +++++++++++++++++++++++++++++++++++------------------ nicintel.c | 3 ++- programmer.h | 18 +++++++++--------- satamv.c | 6 ++++-- sb600spi.c | 8 +++++--- 6 files changed, 88 insertions(+), 57 deletions(-)
diff --git a/hwaccess.c b/hwaccess.c index 5b18c32..e2951d3 100644 --- a/hwaccess.c +++ b/hwaccess.c @@ -213,18 +213,18 @@ int undo_mmio_write(void *p) mmio_writel(data->ldata, data->addr); break; } - /* p was allocated in register_undo_mmio_write. */ + /* p was allocated in register_undo_mmio_write_or_return. */ free(p); return 0; }
-#define register_undo_mmio_write(a, c) \ +#define register_undo_mmio_write_or_return(a, c) \ { \ struct undo_mmio_write_data *undo_mmio_write_data; \ undo_mmio_write_data = malloc(sizeof(struct undo_mmio_write_data)); \ if (!undo_mmio_write_data) { \ msg_gerr("Out of memory!\n"); \ - exit(1); \ + return 1; \ } \ undo_mmio_write_data->addr = a; \ undo_mmio_write_data->type = mmio_write_type_##c; \ @@ -232,57 +232,66 @@ int undo_mmio_write(void *p) register_shutdown(undo_mmio_write, undo_mmio_write_data); \ }
-#define register_undo_mmio_writeb(a) register_undo_mmio_write(a, b) -#define register_undo_mmio_writew(a) register_undo_mmio_write(a, w) -#define register_undo_mmio_writel(a) register_undo_mmio_write(a, l) +#define register_undo_mmio_writeb_or_return(a) register_undo_mmio_write_or_return(a, b) +#define register_undo_mmio_writew_or_return(a) register_undo_mmio_write_or_return(a, w) +#define register_undo_mmio_writel_or_return(a) register_undo_mmio_write_or_return(a, l)
-void rmmio_writeb(uint8_t val, void *addr) +int rmmio_writeb(uint8_t val, void *addr) { - register_undo_mmio_writeb(addr); + register_undo_mmio_writeb_or_return(addr); mmio_writeb(val, addr); + return 0; }
-void rmmio_writew(uint16_t val, void *addr) +int rmmio_writew(uint16_t val, void *addr) { - register_undo_mmio_writew(addr); + register_undo_mmio_writew_or_return(addr); mmio_writew(val, addr); + return 0; }
-void rmmio_writel(uint32_t val, void *addr) +int rmmio_writel(uint32_t val, void *addr) { - register_undo_mmio_writel(addr); + register_undo_mmio_writel_or_return(addr); mmio_writel(val, addr); + return 0; }
-void rmmio_le_writeb(uint8_t val, void *addr) +int rmmio_le_writeb(uint8_t val, void *addr) { - register_undo_mmio_writeb(addr); + register_undo_mmio_writeb_or_return(addr); mmio_le_writeb(val, addr); + return 0; }
-void rmmio_le_writew(uint16_t val, void *addr) +int rmmio_le_writew(uint16_t val, void *addr) { - register_undo_mmio_writew(addr); + register_undo_mmio_writew_or_return(addr); mmio_le_writew(val, addr); + return 0; }
-void rmmio_le_writel(uint32_t val, void *addr) +int rmmio_le_writel(uint32_t val, void *addr) { - register_undo_mmio_writel(addr); + register_undo_mmio_writel_or_return(addr); mmio_le_writel(val, addr); + return 0; }
-void rmmio_valb(void *addr) +int rmmio_valb(void *addr) { - register_undo_mmio_writeb(addr); + register_undo_mmio_writeb_or_return(addr); + return 0; }
-void rmmio_valw(void *addr) +int rmmio_valw(void *addr) { - register_undo_mmio_writew(addr); + register_undo_mmio_writew_or_return(addr); + return 0; }
-void rmmio_vall(void *addr) +int rmmio_vall(void *addr) { - register_undo_mmio_writel(addr); + register_undo_mmio_writel_or_return(addr); + return 0; } diff --git a/ichspi.c b/ichspi.c index 6c394db..4feada1 100644 --- a/ichspi.c +++ b/ichspi.c @@ -544,10 +544,14 @@ static int program_opcodes(OPCODES *op, int enable_undo) case CHIPSET_CENTERTON: /* Register undo only for enable_undo=1, i.e. first call. */ if (enable_undo) { - rmmio_valw(ich_spibar + ICH7_REG_PREOP); - rmmio_valw(ich_spibar + ICH7_REG_OPTYPE); - rmmio_vall(ich_spibar + ICH7_REG_OPMENU); - rmmio_vall(ich_spibar + ICH7_REG_OPMENU + 4); + if (rmmio_valw(ich_spibar + ICH7_REG_PREOP)) + return 1; + if (rmmio_valw(ich_spibar + ICH7_REG_OPTYPE)) + return 1; + if (rmmio_vall(ich_spibar + ICH7_REG_OPMENU)) + return 1; + if (rmmio_vall(ich_spibar + ICH7_REG_OPMENU + 4)) + return 1; } mmio_writew(preop, ich_spibar + ICH7_REG_PREOP); mmio_writew(optype, ich_spibar + ICH7_REG_OPTYPE); @@ -558,10 +562,14 @@ static int program_opcodes(OPCODES *op, int enable_undo) default: /* Future version might behave the same */ /* Register undo only for enable_undo=1, i.e. first call. */ if (enable_undo) { - rmmio_valw(ich_spibar + ICH9_REG_PREOP); - rmmio_valw(ich_spibar + ICH9_REG_OPTYPE); - rmmio_vall(ich_spibar + ICH9_REG_OPMENU); - rmmio_vall(ich_spibar + ICH9_REG_OPMENU + 4); + if (rmmio_valw(ich_spibar + ICH9_REG_PREOP)) + return 1; + if (rmmio_valw(ich_spibar + ICH9_REG_OPTYPE)) + return 1; + if (rmmio_vall(ich_spibar + ICH9_REG_OPMENU)) + return 1; + if (rmmio_vall(ich_spibar + ICH9_REG_OPMENU + 4)) + return 1; } mmio_writew(preop, ich_spibar + ICH9_REG_PREOP); mmio_writew(optype, ich_spibar + ICH9_REG_OPTYPE); @@ -602,7 +610,7 @@ static int ich_missing_opcodes() * Try to set BBAR (BIOS Base Address Register), but read back the value in case * it didn't stick. */ -static void ich_set_bbar(uint32_t min_addr) +static int ich_set_bbar(uint32_t min_addr) { int bbar_off; switch (ich_generation) { @@ -613,7 +621,7 @@ static void ich_set_bbar(uint32_t min_addr) break; case CHIPSET_ICH8: msg_perr("BBAR offset is unknown on ICH8!\n"); - return; + return 1; case CHIPSET_ICH9: default: /* Future version might behave the same */ bbar_off = ICH9_REG_BBAR; @@ -627,7 +635,8 @@ static void ich_set_bbar(uint32_t min_addr) } min_addr &= BBAR_MASK; ichspi_bbar |= min_addr; - rmmio_writel(ichspi_bbar, ich_spibar + bbar_off); + if (rmmio_writel(ichspi_bbar, ich_spibar + bbar_off)) + return 1; ichspi_bbar = mmio_readl(ich_spibar + bbar_off) & BBAR_MASK;
/* We don't have any option except complaining. And if the write @@ -636,6 +645,7 @@ static void ich_set_bbar(uint32_t min_addr) if (ichspi_bbar != min_addr) msg_perr("Setting BBAR to 0x%08x failed! New value: 0x%08x.\n", min_addr, ichspi_bbar); + return 0; }
/* Read len bytes from the fdata/spid register into the data array. @@ -1501,7 +1511,7 @@ static int ich9_handle_pr(int i)
/* Set/Clear the read and write protection enable bits of PR register @i * according to @read_prot and @write_prot. */ -static void ich9_set_pr(int i, int read_prot, int write_prot) +static int ich9_set_pr(int i, int read_prot, int write_prot) { void *addr = ich_spibar + ICH9_REG_PR0 + (i * 4); uint32_t old = mmio_readl(addr); @@ -1515,11 +1525,14 @@ static void ich9_set_pr(int i, int read_prot, int write_prot) new |= (1 << PR_WP_OFF); if (old == new) { msg_gspew(" already.\n"); - return; + return 0; } msg_gspew(", trying to set it to 0x%08x ", new); - rmmio_writel(new, addr); + if (rmmio_writel(new, addr)) + return 1; msg_gspew("resulted in 0x%08x.\n", mmio_readl(addr)); + + return 0; }
static const struct spi_programmer spi_programmer_ich7 = { @@ -1604,7 +1617,8 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) ichspi_lock = 1; } ich_init_opcodes(); - ich_set_bbar(0); + if (ich_set_bbar(0)) + return 1; register_spi_programmer(&spi_programmer_ich7); break; case CHIPSET_ICH8: @@ -1692,7 +1706,8 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) for (i = 0; i < 5; i++) { /* if not locked down try to disable PR locks first */ if (!ichspi_lock) - ich9_set_pr(i, 0, 0); + if (ich9_set_pr(i, 0, 0)) + return 1; ich_spi_rw_restricted |= ich9_handle_pr(i); }
@@ -1750,7 +1765,8 @@ int ich_init_spi(struct pci_dev *dev, void *spibar, enum ich_chipset ich_gen) tmp = mmio_readl(ich_spibar + ICH9_REG_FPB); msg_pdbg("0xD0: 0x%08x (FPB)\n", tmp); } - ich_set_bbar(0); + if (ich_set_bbar(0)) + return 1; }
msg_pdbg("\n"); @@ -1851,7 +1867,8 @@ int via_init_spi(struct pci_dev *dev, uint32_t mmio_base) ichspi_lock = 1; }
- ich_set_bbar(0); + if (ich_set_bbar(0)) + return 1; ich_init_opcodes();
return 0; diff --git a/nicintel.c b/nicintel.c index 98ba29f..b3126a7 100644 --- a/nicintel.c +++ b/nicintel.c @@ -100,7 +100,8 @@ int nicintel_init(void) * what we should do with it. Write 0x0001 because we have nothing * better to do with our time. */ - pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR); + if (pci_rmmio_writew(0x0001, nicintel_control_bar + CSR_FCR)) + return 1;
max_rom_decode.parallel = NICINTEL_MEMMAP_SIZE; register_par_programmer(&par_programmer_nicintel, BUS_PARALLEL); diff --git a/programmer.h b/programmer.h index 0c51f58..1e129ad 100644 --- a/programmer.h +++ b/programmer.h @@ -347,18 +347,18 @@ uint32_t mmio_le_readl(void *addr); #define pci_mmio_readb mmio_le_readb #define pci_mmio_readw mmio_le_readw #define pci_mmio_readl mmio_le_readl -void rmmio_writeb(uint8_t val, void *addr); -void rmmio_writew(uint16_t val, void *addr); -void rmmio_writel(uint32_t val, void *addr); -void rmmio_le_writeb(uint8_t val, void *addr); -void rmmio_le_writew(uint16_t val, void *addr); -void rmmio_le_writel(uint32_t val, void *addr); +int rmmio_writeb(uint8_t val, void *addr); +int rmmio_writew(uint16_t val, void *addr); +int rmmio_writel(uint32_t val, void *addr); +int rmmio_le_writeb(uint8_t val, void *addr); +int rmmio_le_writew(uint16_t val, void *addr); +int rmmio_le_writel(uint32_t val, void *addr); #define pci_rmmio_writeb rmmio_le_writeb #define pci_rmmio_writew rmmio_le_writew #define pci_rmmio_writel rmmio_le_writel -void rmmio_valb(void *addr); -void rmmio_valw(void *addr); -void rmmio_vall(void *addr); +int rmmio_valb(void *addr); +int rmmio_valw(void *addr); +int rmmio_vall(void *addr);
/* dummyflasher.c */ #if CONFIG_DUMMY == 1 diff --git a/satamv.c b/satamv.c index 3065f0c..ecfbead 100644 --- a/satamv.c +++ b/satamv.c @@ -124,7 +124,8 @@ int satamv_init(void) msg_pspew("BAR2Sz=0x%01x\n", (tmp >> 19) & 0x7); tmp &= 0xffffffc0; tmp |= 0x0000001f; - pci_rmmio_writel(tmp, mv_bar + PCI_BAR2_CONTROL); + if (pci_rmmio_writel(tmp, mv_bar + PCI_BAR2_CONTROL)) + return 1;
/* Enable flash: GPIO Port Control Register 0x104f0 */ tmp = pci_mmio_readl(mv_bar + GPIO_PORT_CONTROL); @@ -135,7 +136,8 @@ int satamv_init(void) "values!\n"); tmp &= 0xfffffffc; tmp |= 0x2; - pci_rmmio_writel(tmp, mv_bar + GPIO_PORT_CONTROL); + if (pci_rmmio_writel(tmp, mv_bar + GPIO_PORT_CONTROL)) + return 1;
/* Get I/O BAR location. */ tmp = pcidev_readbar(dev, PCI_BASE_ADDRESS_2); diff --git a/sb600spi.c b/sb600spi.c index 9523591..05752c9 100644 --- a/sb600spi.c +++ b/sb600spi.c @@ -291,7 +291,8 @@ static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed)
msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed); if (amd_gen != CHIPSET_YANGTZE) { - rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd); + if (rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd)) + return 1; success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3)); }
@@ -318,8 +319,9 @@ static int handle_speed(struct pci_dev *dev) msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis"); if (fast_read) { msg_pdbg("Disabling them temporarily.\n"); - rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18), - sb600_spibar + 0x00); + if (rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18), + sb600_spibar + 0x00)) + return 1; } } tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;