Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / libc / diskio.c
diff --git a/qemu/roms/openbios/libc/diskio.c b/qemu/roms/openbios/libc/diskio.c
new file mode 100644 (file)
index 0000000..23f38eb
--- /dev/null
@@ -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;
+}