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.fat...@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


Reply via email to