From e643a494d46c571711ccba361ad20faaf6f6503c Mon Sep 17 00:00:00 2001 From: Steve Marple Date: Sat, 25 Jun 2022 17:02:14 +0100 Subject: [PATCH] drivers/bcm2835gpio: Release resources on error and when quitting The /dev/mem file descriptor can be closed without invalidating the mappings so close as soon as possible. munmap() all memory, either on error or from quit. Signed-off-by: Steve Marple Change-Id: I2b6a8365f554e332520fa77ccf076188083a932f Reviewed-on: https://review.openocd.org/c/openocd/+/7122 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/bcm2835gpio.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 11d9a8020..0bbbc6fce 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -37,7 +37,8 @@ uint32_t bcm2835_peri_base = 0x20000000; #define GPIO_LEV (*(pio_base+13)) /* current level of the pin */ static int dev_mem_fd; -static volatile uint32_t *pio_base; +static volatile uint32_t *pio_base = MAP_FAILED; +static volatile uint32_t *pads_base = MAP_FAILED; static bb_value_t bcm2835gpio_read(void); static int bcm2835gpio_write(int tck, int tms, int tdi); @@ -479,6 +480,19 @@ static bool bcm2835gpio_swd_mode_possible(void) return 1; } +static void bcm2835gpio_munmap(void) +{ + if (pio_base != MAP_FAILED) { + munmap((void *)pio_base, sysconf(_SC_PAGE_SIZE)); + pio_base = MAP_FAILED; + } + + if (pads_base != MAP_FAILED) { + munmap((void *)pads_base, sysconf(_SC_PAGE_SIZE)); + pads_base = MAP_FAILED; + } +} + static int bcm2835gpio_init(void) { bitbang_interface = &bcm2835gpio_bitbang; @@ -514,16 +528,18 @@ static int bcm2835gpio_init(void) return ERROR_JTAG_INIT_FAILED; } - static volatile uint32_t *pads_base; pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27); if (pads_base == MAP_FAILED) { LOG_ERROR("mmap: %s", strerror(errno)); + bcm2835gpio_munmap(); close(dev_mem_fd); return ERROR_JTAG_INIT_FAILED; } + close(dev_mem_fd); + /* set 4mA drive strength, slew rate limited, hysteresis on */ pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1; @@ -605,5 +621,7 @@ static int bcm2835gpio_quit(void) if (is_gpio_valid(swdio_dir_gpio)) SET_MODE_GPIO(swdio_dir_gpio, swdio_dir_gpio_mode); + bcm2835gpio_munmap(); + return ERROR_OK; }