Luc Verhaegen has uploaded this change for review. ( https://review.coreboot.org/29081
Change subject: pci2: add device enable/disable ......................................................................
pci2: add device enable/disable
Change-Id: I79bbc5c4b0f571df692e0992f43b46da7ab3bf01 Signed-off-by: Luc Verhaegen libv@skynet.be --- M pcidev.c M programmer.h 2 files changed, 120 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/81/29081/1
diff --git a/pcidev.c b/pcidev.c index da4e2a3..7680e78 100644 --- a/pcidev.c +++ b/pcidev.c @@ -420,6 +420,115 @@ /* * */ +int +flashrom_pci_device_enable(struct flashrom_pci_device *device) +{ + char filename[1024]; + int fd, ret; + char enable; + + if (device->enabled) + return 0; + + snprintf(filename, sizeof(filename) - 1, + "%senable", device->sysfs_path); + + fd = open(filename, O_RDWR); + if (fd == -1) { + msg_perr("%s: failed to open %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + + ret = read(fd, &enable, 1); + if (ret != 1) { + close(fd); + msg_perr("%s: failed to read %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + + if (enable == '0') { + device->was_disabled = true; + ret = write(fd, "1", 1); + if (ret != 1) { + close(fd); + msg_perr("%s: failed to write %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + } else if (enable != '1') { + close(fd); + msg_perr("%s: invalid value read from %s: %c\n", + __func__, filename, enable); + return EINVAL; + } + + close(fd); + + device->enabled = true; + + return 0; +} + +/* + * + */ +int +flashrom_pci_device_disable(struct flashrom_pci_device *device) +{ + char filename[1024]; + int fd, ret; + char enable; + + /* We do not want to disable the device if we did not enable it */ + if (!device->enabled || !device->was_disabled) + return 0; + + snprintf(filename, sizeof(filename) - 1, + "%senable", device->sysfs_path); + + fd = open(filename, O_RDWR); + if (fd == -1) { + msg_perr("%s: failed to open %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + + ret = read(fd, &enable, 1); + if (ret != 1) { + close(fd); + msg_perr("%s: failed to read %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + + if (enable == '1') { + ret = write(fd, "0", 1); + if (ret != 1) { + close(fd); + msg_perr("%s: failed to write %s: %s\n", + __func__, filename, strerror(errno)); + return errno; + } + } else if (enable != '0') { + close(fd); + msg_perr("%s: invalid value read from %s: %c\n", + __func__, filename, enable); + return EINVAL; + } + + close(fd); + + device->enabled = false; + + return 0; +} + + +/* + * + */ static int flashrom_pci_device_shutdown(void *data) { @@ -433,6 +542,8 @@
flashrom_pci_mmio_unmap(device);
+ flashrom_pci_device_disable(device); + free(device->sysfs_path); device->sysfs_path = NULL;
@@ -533,6 +644,9 @@
register_shutdown(flashrom_pci_device_shutdown, device);
+ if (flashrom_pci_device_enable(device)) + return NULL; + return device; }
diff --git a/programmer.h b/programmer.h index 1a7af7a..7ec4291 100644 --- a/programmer.h +++ b/programmer.h @@ -872,9 +872,15 @@ size_t mmio_size;
const void *private; /* programmer specific hook */ + + /* housekeeping */ + bool enabled; + bool was_disabled; };
struct flashrom_pci_device *flashrom_pci_init(const struct flashrom_pci_match *matches); +int flashrom_pci_device_enable(struct flashrom_pci_device *device); +int flashrom_pci_device_disable(struct flashrom_pci_device *device); int flashrom_pci_mmio_map(struct flashrom_pci_device *device, int bar); void flashrom_pci_mmio_unmap(struct flashrom_pci_device *device);