]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/alpha/boot1/sys.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / boot / alpha / boot1 / sys.c
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  *
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  *
16  * Carnegie Mellon requests users of this software to return to
17  *
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  *
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:36:34  rpd
27  *      fromL Id: sys.c,v 1.21 1997/06/09 05:10:56 bde Exp
28  * $FreeBSD$
29  */
30
31 #include <string.h>
32 #include <sys/param.h>
33 #include <sys/time.h>
34
35 #include <ufs/ffs/fs.h>
36 #include <ufs/ufs/quota.h>
37 #include <ufs/ufs/inode.h>
38
39 #include <sys/dirent.h>
40
41 #define COMPAT_UFS
42
43 struct fs *fs;
44 struct inode inode;
45 int boff = 0;
46
47 #if 0
48 /* #define BUFSIZE 4096 */
49 #define BUFSIZE MAXBSIZE
50
51 static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
52 #endif
53
54 #define BUFSIZE 8192
55 #define MAPBUFSIZE BUFSIZE
56 static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
57
58 static char mapbuf[MAPBUFSIZE];
59 static int mapblock;
60
61 int poff;
62
63 #ifdef RAWBOOT
64 #define STARTBYTE       8192    /* Where on the media the kernel starts */
65 #endif
66
67 static int block_map(int file_block);
68 static int find(char *path);
69
70 int
71 readit(char *buffer, int count)
72 {
73     int logno, off, size;
74     int cnt2, bnum2;
75     struct fs *fs_copy;
76     int n = 0;
77
78     if (poff + count > inode.i_size)
79         count = inode.i_size - poff;
80     while (count > 0 && poff < inode.i_size) {
81         fs_copy = fs;
82         off = blkoff(fs_copy, poff);
83         logno = lblkno(fs_copy, poff);
84         cnt2 = size = blksize(fs_copy, &inode, logno);
85         bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
86         if (    (!off)  && (size <= count)) {
87             devread(buffer, bnum2, cnt2);
88         } else {
89             size -= off;
90             if (size > count)
91                 size = count;
92             devread(iobuf, bnum2, cnt2);
93             bcopy(iobuf+off, buffer, size);
94         }
95         buffer += size;
96         count -= size;
97         poff += size;
98         n += size;
99     }
100     return n;
101 }
102
103 static int
104 find(char *path)
105 {
106     char *rest, ch;
107     int block, off, loc, ino = ROOTINO;
108     struct dirent *dp;
109     char list_only;
110
111     list_only = (path[0] == '?' && path[1] == '\0');
112  loop:
113     devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
114     bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
115           (void *)&inode.i_din,
116           sizeof (struct dinode));
117     if (!*path)
118         return 1;
119     while (*path == '/')
120         path++;
121     if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
122         return 0;
123     for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
124     *rest = 0;
125     loc = 0;
126     do {
127         if (loc >= inode.i_size) {
128             if (list_only) {
129                 putchar('\n');
130                 return -1;
131             } else {
132                 return 0;
133             }
134         }
135         if (!(off = blkoff(fs, loc))) {
136             block = lblkno(fs, loc);
137             devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
138                     blksize(fs, &inode, block));
139         }
140         dp = (struct dirent *)(iobuf + off);
141         loc += dp->d_reclen;
142         if (dp->d_fileno && list_only) {
143             puts(dp->d_name);
144             putchar(' ');
145         }
146     } while (!dp->d_fileno || strcmp(path, dp->d_name));
147     ino = dp->d_fileno;
148     *(path = rest) = ch;
149     goto loop;
150 }
151
152
153 static int
154 block_map(int file_block)
155 {
156         int bnum;
157         if (file_block < NDADDR)
158                 return(inode.i_db[file_block]);
159         if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
160                 devread(mapbuf, bnum, fs->fs_bsize);
161                 mapblock = bnum;
162         }
163         return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
164 }
165
166 #ifdef COMPAT_UFS
167
168 #define max(a, b)       ((a) > (b) ? (a) : (b))
169
170 /*
171  * Sanity checks for old file systems.
172  *
173  * XXX - goes away some day.
174  */
175 static void
176 ffs_oldfscompat(fs)
177         struct fs *fs;
178 {
179         int i;
180
181         fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect);       /* XXX */
182         fs->fs_interleave = max(fs->fs_interleave, 1);          /* XXX */
183         if (fs->fs_postblformat == FS_42POSTBLFMT)              /* XXX */
184                 fs->fs_nrpos = 8;                               /* XXX */
185         if (fs->fs_inodefmt < FS_44INODEFMT) {                  /* XXX */
186                 quad_t sizepb = fs->fs_bsize;                   /* XXX */
187                                                                 /* XXX */
188                 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
189                 for (i = 0; i < NIADDR; i++) {                  /* XXX */
190                         sizepb *= NINDIR(fs);                   /* XXX */
191                         fs->fs_maxfilesize += sizepb;           /* XXX */
192                 }                                               /* XXX */
193                 fs->fs_qbmask = ~fs->fs_bmask;                  /* XXX */
194                 fs->fs_qfmask = ~fs->fs_fmask;                  /* XXX */
195         }                                                       /* XXX */
196 }
197 #endif
198
199 int
200 openrd(char *name)
201 {
202     int ret;
203     char namecopy[128];
204
205     if (devopen())
206         return 1;
207
208     /*
209      * Load Filesystem info (mount the device).
210      */
211     devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
212
213 #ifdef COMPAT_UFS
214     ffs_oldfscompat(fs);
215 #endif
216
217     /*
218      * Find the actual FILE on the mounted device.
219      * Make a copy of the name since find() is destructive.
220      */
221     strcpy(namecopy, name);
222     ret = find(namecopy);
223     if (ret == 0)
224         return 1;
225     if (ret < 0)
226         return -1;
227     poff = 0;
228     return 0;
229 }