[PATCH 4/6] firmware: semihosting: translate return values in wrappers
Ahmad Fatoum
a.fatoum at pengutronix.de
Mon Jun 10 23:59:21 PDT 2024
It's needlessly verbose to expect callers of the semihosting wrappers to
call semihosting_errno() on error, so let's just do that inside the
wrappers so they behave like other functions.
While at it, also have semihosting_read() and semihosting_write() return
the number of bytes sent. The semihosting API returns the number of
bytes that were _not_ sent instead, so a return value of 0 is success.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
drivers/firmware/semihosting.c | 36 ++++++++++++++++++++++------------
fs/smhfs.c | 33 +++++++++----------------------
2 files changed, 33 insertions(+), 36 deletions(-)
diff --git a/drivers/firmware/semihosting.c b/drivers/firmware/semihosting.c
index 1dfbdf219727..9663959aa49f 100644
--- a/drivers/firmware/semihosting.c
+++ b/drivers/firmware/semihosting.c
@@ -43,6 +43,12 @@ enum {
long semihosting_trap(ulong sysnum, void *addr);
+static long semihosting_call(ulong sysnum, void *addr)
+{
+ long ret = semihosting_trap(sysnum, addr);
+ return ret >= 0 ? ret : -semihosting_errno();
+}
+
static ulong semihosting_flags_to_mode(int flags)
{
static const int semihosting_open_modeflags[12] = {
@@ -81,13 +87,13 @@ int semihosting_open(const char *fname, int flags)
.mode = semihosting_flags_to_mode(flags),
};
- return semihosting_trap(SEMIHOSTING_SYS_OPEN, &open);
+ return semihosting_call(SEMIHOSTING_SYS_OPEN, &open);
}
EXPORT_SYMBOL(semihosting_open);
int semihosting_close(int fd)
{
- return semihosting_trap(SEMIHOSTING_SYS_CLOSE, &fd);
+ return semihosting_call(SEMIHOSTING_SYS_CLOSE, &fd);
}
EXPORT_SYMBOL(semihosting_close);
@@ -111,37 +117,43 @@ struct __packed semihosting_file_io {
ssize_t semihosting_write(int fd, const void *buf, size_t count)
{
+ ssize_t ret;
struct semihosting_file_io write = {
.fd = fd,
.memp = virt_to_phys(buf),
.len = count,
};
- return semihosting_trap(SEMIHOSTING_SYS_WRITE, &write);
+ ret = semihosting_call(SEMIHOSTING_SYS_WRITE, &write);
+
+ return ret >= 0 ? count - ret : ret;
}
EXPORT_SYMBOL(semihosting_write);
ssize_t semihosting_read(int fd, void *buf, size_t count)
{
+ ssize_t ret;
struct semihosting_file_io read = {
.fd = fd,
.memp = virt_to_phys(buf),
.len = count,
};
- return semihosting_trap(SEMIHOSTING_SYS_READ, &read);
+ ret = semihosting_call(SEMIHOSTING_SYS_READ, &read);
+
+ return ret >= 0 ? count - ret : ret;
}
EXPORT_SYMBOL(semihosting_read);
int semihosting_readc(void)
{
- return semihosting_trap(SEMIHOSTING_SYS_READC, NULL);
+ return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
}
EXPORT_SYMBOL(semihosting_readc);
int semihosting_isatty(int fd)
{
- return semihosting_trap(SEMIHOSTING_SYS_ISATTY, &fd);
+ return semihosting_call(SEMIHOSTING_SYS_ISATTY, &fd);
}
EXPORT_SYMBOL(semihosting_isatty);
@@ -155,12 +167,12 @@ off_t semihosting_seek(int fd, off_t pos)
.pos = pos,
};
- return semihosting_trap(SEMIHOSTING_SYS_SEEK, &seek);
+ return semihosting_call(SEMIHOSTING_SYS_SEEK, &seek);
}
EXPORT_SYMBOL(semihosting_seek);
off_t semihosting_flen(int fd)
{
- return semihosting_trap(SEMIHOSTING_SYS_FLEN, &fd);
+ return semihosting_call(SEMIHOSTING_SYS_FLEN, &fd);
}
EXPORT_SYMBOL(semihosting_flen);
@@ -174,7 +186,7 @@ int semihosting_remove(const char *fname)
.fname_length = strlen(fname),
};
- return semihosting_trap(SEMIHOSTING_SYS_REMOVE, &remove);
+ return semihosting_call(SEMIHOSTING_SYS_REMOVE, &remove);
}
EXPORT_SYMBOL(semihosting_remove);
@@ -192,13 +204,13 @@ int semihosting_rename(const char *fname1, const char *fname2)
.fname2_length = strlen(fname2),
};
- return semihosting_trap(SEMIHOSTING_SYS_RENAME, &rename);
+ return semihosting_call(SEMIHOSTING_SYS_RENAME, &rename);
}
EXPORT_SYMBOL(semihosting_rename);
int semihosting_errno(void)
{
- return semihosting_trap(SEMIHOSTING_SYS_ERRNO, NULL);
+ return semihosting_call(SEMIHOSTING_SYS_ERRNO, NULL);
}
EXPORT_SYMBOL(semihosting_errno);
@@ -213,6 +225,6 @@ int semihosting_system(const char *command)
.cmd_len = strlen(command),
};
- return semihosting_trap(SEMIHOSTING_SYS_SYSTEM, &system);
+ return semihosting_call(SEMIHOSTING_SYS_SYSTEM, &system);
}
EXPORT_SYMBOL(semihosting_system);
diff --git a/fs/smhfs.c b/fs/smhfs.c
index da285b5be52f..ce027f203e23 100644
--- a/fs/smhfs.c
+++ b/fs/smhfs.c
@@ -48,10 +48,7 @@ static int smhfs_rm(struct device __always_unused *dev,
/* Get rid of leading '/' */
pathname = &pathname[1];
- if (semihosting_remove(pathname) != 0)
- return -semihosting_errno();
- else
- return 0;
+ return semihosting_remove(pathname);
}
static int smhfs_truncate(struct device __always_unused *dev,
@@ -70,52 +67,40 @@ static int smhfs_open(struct device __always_unused *dev,
fd = semihosting_open(filename, file->flags);
if (fd < 0)
- goto error;
+ return fd;
file->priv = (void *)(uintptr_t)fd;
file->size = semihosting_flen(fd);
if (file->size < 0)
- goto error;
+ return file->size;
return 0;
-error:
- return -semihosting_errno();
}
static int smhfs_close(struct device __always_unused *dev,
FILE *f)
{
- if (semihosting_close(file_to_fd(f)))
- return -semihosting_errno();
- else
- return 0;
+ return semihosting_close(file_to_fd(f));
}
static int smhfs_write(struct device __always_unused *dev,
FILE *f, const void *inbuf, size_t insize)
{
- if (semihosting_write(file_to_fd(f), inbuf, insize))
- return -semihosting_errno();
- else
- return insize;
+ long ret = semihosting_write(file_to_fd(f), inbuf, insize);
+ return ret < 0 ? ret : insize;
}
static int smhfs_read(struct device __always_unused *dev,
FILE *f, void *buf, size_t insize)
{
- if (!semihosting_read(file_to_fd(f), buf, insize))
- return insize;
- else
- return -semihosting_errno();
+ long ret = semihosting_read(file_to_fd(f), buf, insize);
+ return ret < 0 ? ret : insize;
}
static int smhfs_lseek(struct device __always_unused *dev,
FILE *f, loff_t pos)
{
- if (semihosting_seek(file_to_fd(f), pos))
- return -semihosting_errno();
-
- return 0;
+ return semihosting_seek(file_to_fd(f), pos);
}
static DIR* smhfs_opendir(struct device __always_unused *dev,
--
2.39.2
More information about the barebox
mailing list