aboutsummaryrefslogtreecommitdiffstats
path: root/roms/openbios/libc/diskio.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/openbios/libc/diskio.c')
-rw-r--r--roms/openbios/libc/diskio.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/roms/openbios/libc/diskio.c b/roms/openbios/libc/diskio.c
new file mode 100644
index 00000000..23f38ebb
--- /dev/null
+++ b/roms/openbios/libc/diskio.c
@@ -0,0 +1,248 @@
+/*
+ * Creation Date: <2003/12/07 19:36:00 samuel>
+ * Time-stamp: <2004/01/07 19:28:43 samuel>
+ *
+ * <diskio.c>
+ *
+ * I/O wrappers
+ *
+ * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2
+ *
+ */
+
+#include "config.h"
+#include "libopenbios/bindings.h"
+#include "libc/diskio.h"
+
+//#define CONFIG_DEBUG_DISKIO
+#ifdef CONFIG_DEBUG_DISKIO
+#define DPRINTF(fmt, args...) \
+ do { printk(fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
+typedef struct {
+ ihandle_t ih;
+ int do_close;
+ xt_t read_xt;
+ xt_t seek_xt;
+
+ xt_t reopen_xt;
+ xt_t tell_xt;
+ xt_t get_path_xt;
+ xt_t get_fstype_xt;
+ xt_t open_nwrom_xt;
+ xt_t volume_name_xt;
+} priv_fd_t;
+
+#define MAX_FD 32
+static priv_fd_t *file_descriptors[MAX_FD];
+
+static int
+lookup_xt( ihandle_t ih, const char *method, xt_t *xt )
+{
+ if( *xt )
+ return 0;
+ *xt = find_ih_method( method, ih );
+ return (*xt) ? 0:1;
+}
+
+int
+open_ih( ihandle_t ih )
+{
+ xt_t read_xt=0, seek_xt=0;
+ priv_fd_t *fdp;
+ int fd;
+
+ if( !ih || lookup_xt(ih, "read", &read_xt) )
+ return -1;
+ if( lookup_xt(ih, "seek", &seek_xt) )
+ return -1;
+
+ for (fd=0; fd<MAX_FD; fd++)
+ if(file_descriptors[fd]==NULL)
+ break;
+ if(fd==MAX_FD)
+ return -1;
+
+ fdp = malloc( sizeof(*fdp) );
+ /* Better clear the fd, as it
+ * contains valuable information
+ */
+ memset(fdp, 0, sizeof(*fdp));
+ fdp->ih = ih;
+ fdp->read_xt = read_xt;
+ fdp->seek_xt = seek_xt;
+ fdp->do_close = 0;
+
+ file_descriptors[fd]=fdp;
+ DPRINTF("%s(0x%lx) = %d\n", __func__, (unsigned long)ih, fd);
+ return fd;
+}
+
+int
+open_io( const char *spec )
+{
+ int fd;
+ ihandle_t ih = open_dev( spec );
+ priv_fd_t *fdp;
+
+ DPRINTF("%s(%s)\n", __func__, spec);
+ if( !ih )
+ return -1;
+
+ if( (fd=open_ih(ih)) == -1 ) {
+ close_dev( ih );
+ return -1;
+ }
+
+ fdp = file_descriptors[fd];
+ fdp->do_close = 1;
+
+ return fd;
+}
+
+int
+reopen( int fd, const char *filename )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ int ret;
+
+ if( lookup_xt(fdp->ih, "reopen", &fdp->reopen_xt) )
+ return -1;
+
+ push_str( filename );
+ call_package( fdp->reopen_xt, fdp->ih );
+ ret = (POP() == (ucell)-1)? 0 : -1;
+
+ DPRINTF("%s(%d, %s) = %d\n", __func__, fd, filename, ret);
+ return ret;
+}
+
+int
+reopen_nwrom( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+
+ DPRINTF("%s(%d)\n", __func__, fd);
+ if( lookup_xt(fdp->ih, "open-nwrom", &fdp->open_nwrom_xt) )
+ return -1;
+ call_package( fdp->open_nwrom_xt, fdp->ih );
+ return (POP() == (ucell)-1)? 0 : -1;
+}
+
+ihandle_t
+get_ih_from_fd( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ return fdp->ih;
+}
+
+const char *
+get_file_path( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ if( lookup_xt(fdp->ih, "get-path", &fdp->get_path_xt) )
+ return NULL;
+ call_package( fdp->get_path_xt, fdp->ih );
+ return (char*)cell2pointer(POP());
+}
+
+const char *
+get_volume_name( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ if( lookup_xt(fdp->ih, "volume-name", &fdp->volume_name_xt) )
+ return NULL;
+ call_package( fdp->volume_name_xt, fdp->ih );
+ return (char*)cell2pointer(POP());
+}
+
+const char *
+get_fstype( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ if( lookup_xt(fdp->ih, "get-fstype", &fdp->get_fstype_xt) )
+ return NULL;
+ call_package( fdp->get_fstype_xt, fdp->ih );
+ return (char*)cell2pointer(POP());
+}
+
+int
+read_io( int fd, void *buf, size_t cnt )
+{
+ priv_fd_t *fdp;
+ ucell ret;
+
+ DPRINTF("%s(%d, %p, %u)\n", __func__, fd, buf, cnt);
+ if (fd != -1) {
+ fdp = file_descriptors[fd];
+
+ PUSH( pointer2cell(buf) );
+ PUSH( cnt );
+ call_package( fdp->read_xt, fdp->ih );
+ ret = POP();
+
+ if( !ret && cnt )
+ ret = -1;
+ } else {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+int
+seek_io( int fd, long long offs )
+{
+ priv_fd_t *fdp;
+
+ DPRINTF("%s(%d, %lld)\n", __func__, fd, offs);
+ if (fd != -1) {
+ fdp = file_descriptors[fd];
+
+ DPUSH( offs );
+ call_package( fdp->seek_xt, fdp->ih );
+ return ((((cell)POP()) >= 0)? 0 : -1);
+ } else {
+ return -1;
+ }
+}
+
+long long
+tell( int fd )
+{
+ priv_fd_t *fdp = file_descriptors[fd];
+ long long offs;
+
+ if( lookup_xt(fdp->ih, "tell", &fdp->tell_xt) )
+ return -1;
+ call_package( fdp->tell_xt, fdp->ih );
+ offs = DPOP();
+ DPRINTF("%s(%d) = %lld\n", __func__, fd, offs);
+ return offs;
+}
+
+int
+close_io( int fd )
+{
+ priv_fd_t *fdp;
+
+ DPRINTF("%s(%d)\n", __func__, fd);
+ if (fd != -1) {
+ fdp = file_descriptors[fd];
+
+ if( fdp->do_close )
+ close_dev( fdp->ih );
+ free( fdp );
+
+ file_descriptors[fd]=NULL;
+ }
+
+ return 0;
+}