Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / libc / diskio.c
1 /*
2  *   Creation Date: <2003/12/07 19:36:00 samuel>
3  *   Time-stamp: <2004/01/07 19:28:43 samuel>
4  *
5  *      <diskio.c>
6  *
7  *      I/O wrappers
8  *
9  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
10  *
11  *   This program is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU General Public License
13  *   version 2
14  *
15  */
16
17 #include "config.h"
18 #include "libopenbios/bindings.h"
19 #include "libc/diskio.h"
20
21 //#define CONFIG_DEBUG_DISKIO
22 #ifdef CONFIG_DEBUG_DISKIO
23 #define DPRINTF(fmt, args...)                   \
24     do { printk(fmt , ##args); } while (0)
25 #else
26 #define DPRINTF(fmt, args...)
27 #endif
28
29 typedef struct {
30         ihandle_t ih;
31         int     do_close;
32         xt_t    read_xt;
33         xt_t    seek_xt;
34
35         xt_t    reopen_xt;
36         xt_t    tell_xt;
37         xt_t    get_path_xt;
38         xt_t    get_fstype_xt;
39         xt_t    open_nwrom_xt;
40         xt_t    volume_name_xt;
41 } priv_fd_t;
42
43 #define MAX_FD 32
44 static priv_fd_t *file_descriptors[MAX_FD];
45
46 static int
47 lookup_xt( ihandle_t ih, const char *method, xt_t *xt )
48 {
49         if( *xt )
50                 return 0;
51         *xt = find_ih_method( method, ih );
52         return (*xt) ? 0:1;
53 }
54
55 int
56 open_ih( ihandle_t ih )
57 {
58         xt_t read_xt=0, seek_xt=0;
59         priv_fd_t *fdp;
60         int fd;
61
62         if( !ih || lookup_xt(ih, "read", &read_xt) )
63                 return -1;
64         if( lookup_xt(ih, "seek", &seek_xt) )
65                 return -1;
66
67         for (fd=0; fd<MAX_FD; fd++)
68                 if(file_descriptors[fd]==NULL)
69                         break;
70         if(fd==MAX_FD)
71                 return -1;
72
73         fdp = malloc( sizeof(*fdp) );
74         /* Better clear the fd, as it
75          * contains valuable information
76          */
77         memset(fdp, 0, sizeof(*fdp));
78         fdp->ih = ih;
79         fdp->read_xt = read_xt;
80         fdp->seek_xt = seek_xt;
81         fdp->do_close = 0;
82
83         file_descriptors[fd]=fdp;
84         DPRINTF("%s(0x%lx) = %d\n", __func__, (unsigned long)ih, fd);
85         return fd;
86 }
87
88 int
89 open_io( const char *spec )
90 {
91         int fd;
92         ihandle_t ih = open_dev( spec );
93         priv_fd_t *fdp;
94
95         DPRINTF("%s(%s)\n", __func__, spec);
96         if( !ih )
97                 return -1;
98
99         if( (fd=open_ih(ih)) == -1 ) {
100                 close_dev( ih );
101                 return -1;
102         }
103
104         fdp = file_descriptors[fd];
105         fdp->do_close = 1;
106
107         return fd;
108 }
109
110 int
111 reopen( int fd, const char *filename )
112 {
113         priv_fd_t *fdp = file_descriptors[fd];
114         int ret;
115
116         if( lookup_xt(fdp->ih, "reopen", &fdp->reopen_xt) )
117                 return -1;
118
119         push_str( filename );
120         call_package( fdp->reopen_xt, fdp->ih );
121         ret = (POP() == (ucell)-1)? 0 : -1;
122
123         DPRINTF("%s(%d, %s) = %d\n", __func__, fd, filename, ret);
124         return ret;
125 }
126
127 int
128 reopen_nwrom( int fd )
129 {
130         priv_fd_t *fdp = file_descriptors[fd];
131
132         DPRINTF("%s(%d)\n", __func__, fd);
133         if( lookup_xt(fdp->ih, "open-nwrom", &fdp->open_nwrom_xt) )
134                 return -1;
135         call_package( fdp->open_nwrom_xt, fdp->ih );
136         return (POP() == (ucell)-1)? 0 : -1;
137 }
138
139 ihandle_t
140 get_ih_from_fd( int fd )
141 {
142         priv_fd_t *fdp = file_descriptors[fd];
143         return fdp->ih;
144 }
145
146 const char *
147 get_file_path( int fd )
148 {
149         priv_fd_t *fdp = file_descriptors[fd];
150         if( lookup_xt(fdp->ih, "get-path", &fdp->get_path_xt) )
151                 return NULL;
152         call_package( fdp->get_path_xt, fdp->ih );
153         return (char*)cell2pointer(POP());
154 }
155
156 const char *
157 get_volume_name( int fd )
158 {
159         priv_fd_t *fdp = file_descriptors[fd];
160         if( lookup_xt(fdp->ih, "volume-name", &fdp->volume_name_xt) )
161                 return NULL;
162         call_package( fdp->volume_name_xt, fdp->ih );
163         return (char*)cell2pointer(POP());
164 }
165
166 const char *
167 get_fstype( int fd )
168 {
169         priv_fd_t *fdp = file_descriptors[fd];
170         if( lookup_xt(fdp->ih, "get-fstype", &fdp->get_fstype_xt) )
171                 return NULL;
172         call_package( fdp->get_fstype_xt, fdp->ih );
173         return (char*)cell2pointer(POP());
174 }
175
176 int
177 read_io( int fd, void *buf, size_t cnt )
178 {
179         priv_fd_t *fdp;
180         ucell ret;
181
182         DPRINTF("%s(%d, %p, %u)\n", __func__, fd, buf, cnt);
183         if (fd != -1) {
184                 fdp = file_descriptors[fd];
185
186                 PUSH( pointer2cell(buf) );
187                 PUSH( cnt );
188                 call_package( fdp->read_xt, fdp->ih );
189                 ret = POP();
190
191                 if( !ret && cnt )
192                         ret = -1;
193         } else {
194                 ret = -1;
195         }
196
197         return ret;
198 }
199
200 int
201 seek_io( int fd, long long offs )
202 {
203         priv_fd_t *fdp;
204
205         DPRINTF("%s(%d, %lld)\n", __func__, fd, offs);
206         if (fd != -1) {
207                 fdp = file_descriptors[fd];
208                 
209                 DPUSH( offs );
210                 call_package( fdp->seek_xt, fdp->ih );
211                 return ((((cell)POP()) >= 0)? 0 : -1);
212         } else {
213                 return -1;
214         }
215 }
216
217 long long
218 tell( int fd )
219 {
220         priv_fd_t *fdp = file_descriptors[fd];
221         long long offs;
222
223         if( lookup_xt(fdp->ih, "tell", &fdp->tell_xt) )
224                 return -1;
225         call_package( fdp->tell_xt, fdp->ih );
226         offs = DPOP();
227         DPRINTF("%s(%d) = %lld\n", __func__, fd, offs);
228         return offs;
229 }
230
231 int
232 close_io( int fd )
233 {
234         priv_fd_t *fdp;
235
236         DPRINTF("%s(%d)\n", __func__, fd);
237         if (fd != -1) {
238                 fdp = file_descriptors[fd];
239
240                 if( fdp->do_close )
241                         close_dev( fdp->ih );
242                 free( fdp );
243
244                 file_descriptors[fd]=NULL;
245         }
246
247         return 0;
248 }