[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