[Pdbg] [PATCH v2 1/7] libpdbg: Store fsi_fd state information in fsi structure
Alistair Popple
alistair at popple.id.au
Mon Jun 15 17:22:31 AEST 2020
On Wednesday, 10 June 2020 3:24:20 PM AEST Amitay Isaacs wrote:
> This allows to have different fd for different fsi targets. Also, we
> can close the fd cleanly in release procedure.
>
> Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
> ---
> libpdbg/hwunit.h | 1 +
> libpdbg/kernel.c | 87 +++++++++++++++++++++++-------------------------
> 2 files changed, 43 insertions(+), 45 deletions(-)
>
> diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h
> index 61aea0f..e3a8426 100644
> --- a/libpdbg/hwunit.h
> +++ b/libpdbg/hwunit.h
> @@ -112,6 +112,7 @@ struct fsi {
> int (*read)(struct fsi *, uint32_t, uint32_t *);
> int (*write)(struct fsi *, uint32_t, uint32_t);
> enum chip_type chip_type;
> + int fd;
> };
> #define target_to_fsi(x) container_of(x, struct fsi, target)
>
> diff --git a/libpdbg/kernel.c b/libpdbg/kernel.c
> index c4637a7..7914e50 100644
> --- a/libpdbg/kernel.c
> +++ b/libpdbg/kernel.c
> @@ -33,7 +33,6 @@
> #define OPENFSI_LEGACY_PATH "/sys/bus/platform/devices/gpio-fsi/"
> #define OPENFSI_PATH "/sys/class/fsi-master/"
>
> -int fsi_fd;
> const char *fsi_base;
>
> const char *kernel_get_fsi_path(void)
> @@ -66,14 +65,14 @@ static int kernel_fsi_getcfam(struct fsi *fsi, uint32_t
addr64, uint32_t *value)
> int rc;
> uint32_t tmp, addr = (addr64 & 0x7ffc00) | ((addr64 & 0x3ff) << 2);
>
> - rc = lseek(fsi_fd, addr, SEEK_SET);
> + rc = lseek(fsi->fd, addr, SEEK_SET);
> if (rc < 0) {
> rc = errno;
> PR_WARNING("seek failed: %s\n", strerror(errno));
> return rc;
> }
>
> - rc = read(fsi_fd, &tmp, 4);
> + rc = read(fsi->fd, &tmp, 4);
> if (rc < 0) {
> rc = errno;
> if ((addr64 & 0xfff) != 0xc09)
> @@ -93,7 +92,7 @@ static int kernel_fsi_putcfam(struct fsi *fsi, uint32_t
addr64, uint32_t data)
> int rc;
> uint32_t tmp, addr = (addr64 & 0x7ffc00) | ((addr64 & 0x3ff) << 2);
>
> - rc = lseek(fsi_fd, addr, SEEK_SET);
> + rc = lseek(fsi->fd, addr, SEEK_SET);
> if (rc < 0) {
> rc = errno;
> PR_WARNING("seek failed: %s\n", strerror(errno));
> @@ -101,7 +100,7 @@ static int kernel_fsi_putcfam(struct fsi *fsi, uint32_t
addr64, uint32_t data)
> }
>
> tmp = htobe32(data);
> - rc = write(fsi_fd, &tmp, 4);
> + rc = write(fsi->fd, &tmp, 4);
> if (rc < 0) {
> rc = errno;
> PR_ERROR("Failed to write to 0x%08" PRIx32 " (%016" PRIx32 ")\n",
addr, addr64);
> @@ -111,16 +110,6 @@ static int kernel_fsi_putcfam(struct fsi *fsi, uint32_t
addr64, uint32_t data)
> return 0;
> }
>
> -#if 0
> -/* TODO: At present we don't have a generic destroy method as there aren't
many
> - * use cases for it. So for the moment we can just let the OS close the file
> - * descriptor on exit. */
> -static void kernel_fsi_destroy(struct pdbg_target *target)
> -{
> - close(fsi_fd);
> -}
> -#endif
> -
> static void kernel_fsi_scan_devices(void)
> {
> const char one = '1';
> @@ -154,51 +143,59 @@ static void kernel_fsi_scan_devices(void)
>
> int kernel_fsi_probe(struct pdbg_target *target)
> {
> - if (!fsi_fd) {
> - int tries = 5;
> - int rc;
> - const char *kernel_path = kernel_get_fsi_path();
> - char *path;
> -
> - if (!kernel_path)
> - return -1;
> -
> - rc = asprintf(&path, "%s/fsi0/slave at 00:00/raw",
kernel_get_fsi_path());
> - if (rc < 0) {
> - PR_ERROR("Unable create fsi path\n");
> - return rc;
> - }
> + struct fsi *fsi = target_to_fsi(target);
> + int tries = 5;
> + int rc;
> + const char *kernel_path = kernel_get_fsi_path();
> + char *path;
>
> - while (tries) {
> - /* Open first raw device */
> - fsi_fd = open(path, O_RDWR | O_SYNC);
> - if (fsi_fd >= 0) {
> - free(path);
> - return 0;
> - }
> - tries--;
> -
> - /* Scan */
> - kernel_fsi_scan_devices();
> - sleep(1);
> - }
> - if (fsi_fd < 0) {
> - PR_ERROR("Unable to open %s\n", path);
> + if (!kernel_path)
> + return -1;
> +
> + rc = asprintf(&path, "%s/fsi0/slave at 00:00/raw", kernel_get_fsi_path());
> + if (rc < 0) {
> + PR_ERROR("Unable create fsi path\n");
> + return rc;
> + }
> +
> + while (tries) {
> + /* Open first raw device */
> + fsi->fd = open(path, O_RDWR | O_SYNC);
> + if (fsi->fd >= 0) {
> free(path);
> - return -1;
> + return 0;
Minor nit that doesn't need fixing but IMHO it would probably have been clearer
to make this a for loop and break out rather than return.
> }
> + tries--;
>
> + /* Scan */
> + kernel_fsi_scan_devices();
> + sleep(1);
> + }
> + if (fsi->fd < 0) {
> + PR_ERROR("Unable to open %s\n", path);
> + free(path);
> }
>
> return -1;
> }
>
> +static void kernel_fsi_release(struct pdbg_target *target)
> +{
> + struct fsi *fsi = target_to_fsi(target);
> +
> + if (fsi->fd != -1) {
In theory I think generic pdbg logic should prevent this from ever being false
as release should only get called on a successful probe.
Reviewed-by: Alistair Popple <alistair at popple.id.au>
> + close(fsi->fd);
> + fsi->fd = -1;
> + }
> +}
> +
> static struct fsi kernel_fsi = {
> .target = {
> .name = "Kernel based FSI master",
> .compatible = "ibm,kernel-fsi",
> .class = "fsi",
> .probe = kernel_fsi_probe,
> + .release = kernel_fsi_release,
> },
> .read = kernel_fsi_getcfam,
> .write = kernel_fsi_putcfam,
>
More information about the Pdbg
mailing list