devopen.c revision 1.6 1 /* $NetBSD: devopen.c,v 1.6 2003/11/21 19:44:53 tsutsui Exp $ */
2
3 /*-
4 * Copyright (C) 1999 Tsubai Masanari. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <lib/libkern/libkern.h>
30 #include <lib/libsa/stand.h>
31 #include <lib/libsa/ufs.h>
32 #include <lib/libsa/ustarfs.h>
33 #include <netinet/in.h>
34 #include <lib/libsa/nfs.h>
35
36 #include <machine/apcall.h>
37 #include <machine/romcall.h>
38 #include <promdev.h>
39
40 #ifdef BOOT_DEBUG
41 # define DPRINTF printf
42 #else
43 # define DPRINTF while (0) printf
44 #endif
45
46 int dkopen __P((struct open_file *, ...));
47 int dkclose __P((struct open_file *));
48 int dkstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
49 #ifdef HAVE_CHANGEDISK_HOOK
50 void changedisk_hook __P((struct open_file *));
51 #endif
52
53 struct devsw devsw[] = {
54 { "dk", dkstrategy, dkopen, dkclose, noioctl }
55 };
56 int ndevs = sizeof(devsw) / sizeof(devsw[0]);
57
58 struct fs_ops file_system_ufs = {
59 ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat
60 };
61 struct fs_ops file_system_nfs = {
62 nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat
63 };
64 #ifdef SUPPORT_USTARFS
65 struct fs_ops file_system_ustarfs = {
66 ustarfs_open, ustarfs_close, ustarfs_read, ustarfs_write,
67 ustarfs_seek, ustarfs_stat
68 };
69 struct fs_ops file_system[2];
70 #else
71 struct fs_ops file_system[1];
72 #endif
73 int nfsys;
74
75 struct romdev romdev;
76
77 extern int apbus;
78
79 int
80 devopen(f, fname, file)
81 struct open_file *f;
82 const char *fname;
83 char **file; /* out */
84 {
85 int fd;
86 char *cp;
87 int error = 0;
88
89 DPRINTF("devopen: %s\n", fname);
90
91 strcpy(romdev.devname, fname);
92 cp = strchr(romdev.devname, ')') + 1;
93 *cp = 0;
94 if (apbus)
95 fd = apcall_open(romdev.devname, 2);
96 else
97 fd = rom_open(romdev.devname, 2);
98
99 DPRINTF("devname = %s, fd = %d\n", romdev.devname, fd);
100 if (fd == -1)
101 return -1;
102
103 romdev.fd = fd;
104 if (strncmp(romdev.devname, "sonic", 5) == 0)
105 romdev.devtype = DT_NET;
106 else
107 romdev.devtype = DT_BLOCK;
108
109 f->f_dev = devsw;
110 f->f_devdata = &romdev;
111 *file = strchr(fname, ')') + 1;
112
113 if (romdev.devtype == DT_BLOCK) {
114 file_system[0] = file_system_ufs;
115 #ifdef SUPPORT_USTARFS
116 file_system[1] = file_system_ustarfs;
117 nfsys = 2;
118 #else
119 nfsys = 1;
120 #endif
121 } else { /* DT_NET */
122 file_system[0] = file_system_nfs;
123 nfsys = 1;
124
125 if ((error = net_open(&romdev)) != 0) {
126 printf("Can't open NFS network connection on `%s'\n",
127 romdev.devname);
128 return error;
129 }
130 }
131
132 return 0;
133 }
134
135 int
136 dkopen(struct open_file *f, ...)
137 {
138 DPRINTF("dkopen\n");
139 return 0;
140 }
141
142 int
143 dkclose(f)
144 struct open_file *f;
145 {
146 struct romdev *dev = f->f_devdata;
147
148 DPRINTF("dkclose\n");
149 if (apbus)
150 apcall_close(dev->fd);
151 else
152 rom_close(dev->fd);
153
154 return 0;
155 }
156
157 int
158 dkstrategy(devdata, rw, blk, size, buf, rsize)
159 void *devdata;
160 int rw;
161 daddr_t blk;
162 size_t size;
163 void *buf;
164 size_t *rsize; /* out: number of bytes transfered */
165 {
166 struct romdev *dev = devdata;
167
168 /* XXX should use partition offset */
169
170 if (apbus) {
171 apcall_lseek(dev->fd, blk * 512, 0);
172 apcall_read(dev->fd, buf, size);
173 } else {
174 rom_lseek(dev->fd, blk * 512, 0);
175 rom_read(dev->fd, buf, size);
176 }
177 *rsize = size; /* XXX */
178 return 0;
179 }
180
181 #ifdef HAVE_CHANGEDISK_HOOK
182 void
183 changedisk_hook(f)
184 struct open_file *f;
185 {
186 struct romdev *dev = f->f_devdata;
187
188 if (apbus) {
189 apcall_ioctl(dev->fd, APIOCEJECT, NULL);
190 apcall_close(dev->fd);
191 getchar();
192 dev->fd = apcall_open(dev->devname, 2);
193 } else {
194 rom_ioctl(dev->fd, SYSIOCEJECT, NULL);
195 rom_close(dev->fd);
196 getchar();
197 dev->fd = rom_open(dev->devname, 2);
198 }
199
200 }
201 #endif
202