1*a62d1016Stsutsui /* $NetBSD: devopen.c,v 1.10 2008/02/21 14:30:41 tsutsui Exp $ */
295faaaecStsubai
395faaaecStsubai /*-
495faaaecStsubai * Copyright (C) 1999 Tsubai Masanari. All rights reserved.
595faaaecStsubai *
695faaaecStsubai * Redistribution and use in source and binary forms, with or without
795faaaecStsubai * modification, are permitted provided that the following conditions
895faaaecStsubai * are met:
995faaaecStsubai * 1. Redistributions of source code must retain the above copyright
1095faaaecStsubai * notice, this list of conditions and the following disclaimer.
1195faaaecStsubai * 2. Redistributions in binary form must reproduce the above copyright
1295faaaecStsubai * notice, this list of conditions and the following disclaimer in the
1395faaaecStsubai * documentation and/or other materials provided with the distribution.
1495faaaecStsubai * 3. The name of the author may not be used to endorse or promote products
1595faaaecStsubai * derived from this software without specific prior written permission.
1695faaaecStsubai *
1795faaaecStsubai * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1895faaaecStsubai * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1995faaaecStsubai * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2095faaaecStsubai * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2195faaaecStsubai * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2295faaaecStsubai * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2395faaaecStsubai * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2495faaaecStsubai * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2595faaaecStsubai * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2695faaaecStsubai * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2795faaaecStsubai */
2895faaaecStsubai
2995faaaecStsubai #include <lib/libkern/libkern.h>
3095faaaecStsubai #include <lib/libsa/stand.h>
3195faaaecStsubai #include <lib/libsa/ufs.h>
32b29a3326Stsutsui #include <lib/libsa/ustarfs.h>
33c594e4d0Stsubai #include <netinet/in.h>
34c594e4d0Stsubai #include <lib/libsa/nfs.h>
3595faaaecStsubai
36c594e4d0Stsubai #include <machine/apcall.h>
3795faaaecStsubai #include <machine/romcall.h>
38c594e4d0Stsubai #include <promdev.h>
3995faaaecStsubai
4095faaaecStsubai #ifdef BOOT_DEBUG
413fb3c2b5Stsutsui # define DPRINTF printf
4295faaaecStsubai #else
433fb3c2b5Stsutsui # define DPRINTF while (0) printf
4495faaaecStsubai #endif
4595faaaecStsubai
46fd4afa03Stsutsui int dkopen(struct open_file *, ...);
47fd4afa03Stsutsui int dkclose(struct open_file *);
48fd4afa03Stsutsui int dkstrategy(void *, int, daddr_t, size_t, void *, size_t *);
49fdeaca44Stsutsui #ifdef HAVE_CHANGEDISK_HOOK
50fd4afa03Stsutsui void changedisk_hook(struct open_file *);
51fdeaca44Stsutsui #endif
5295faaaecStsubai
5395faaaecStsubai struct devsw devsw[] = {
5495faaaecStsubai { "dk", dkstrategy, dkopen, dkclose, noioctl }
5595faaaecStsubai };
56*a62d1016Stsutsui int ndevs = __arraycount(devsw);
5795faaaecStsubai
5817670568Sjunyoung struct fs_ops file_system_ufs = FS_OPS(ufs);
5917670568Sjunyoung struct fs_ops file_system_nfs = FS_OPS(nfs);
60b29a3326Stsutsui #ifdef SUPPORT_USTARFS
6117670568Sjunyoung struct fs_ops file_system_ustarfs = FS_OPS(ustarfs);
62b29a3326Stsutsui struct fs_ops file_system[2];
63b29a3326Stsutsui #else
64c594e4d0Stsubai struct fs_ops file_system[1];
65b29a3326Stsutsui #endif
66b29a3326Stsutsui int nfsys;
6795faaaecStsubai
68c594e4d0Stsubai struct romdev romdev;
69c594e4d0Stsubai
70c594e4d0Stsubai extern int apbus;
7195faaaecStsubai
7295faaaecStsubai int
devopen(struct open_file * f,const char * fname,char ** file)73fd4afa03Stsutsui devopen(struct open_file *f, const char *fname, char **file)
7495faaaecStsubai {
7595faaaecStsubai int fd;
7695faaaecStsubai char *cp;
77c594e4d0Stsubai int error = 0;
7895faaaecStsubai
793fb3c2b5Stsutsui DPRINTF("devopen: %s\n", fname);
8095faaaecStsubai
81b29a3326Stsutsui strcpy(romdev.devname, fname);
82b29a3326Stsutsui cp = strchr(romdev.devname, ')') + 1;
8395faaaecStsubai *cp = 0;
84c594e4d0Stsubai if (apbus)
85b29a3326Stsutsui fd = apcall_open(romdev.devname, 2);
86c594e4d0Stsubai else
87b29a3326Stsutsui fd = rom_open(romdev.devname, 2);
8895faaaecStsubai
893fb3c2b5Stsutsui DPRINTF("devname = %s, fd = %d\n", romdev.devname, fd);
9095faaaecStsubai if (fd == -1)
9195faaaecStsubai return -1;
9295faaaecStsubai
9395faaaecStsubai romdev.fd = fd;
94b29a3326Stsutsui if (strncmp(romdev.devname, "sonic", 5) == 0)
95c594e4d0Stsubai romdev.devtype = DT_NET;
96c594e4d0Stsubai else
97c594e4d0Stsubai romdev.devtype = DT_BLOCK;
9895faaaecStsubai
9995faaaecStsubai f->f_dev = devsw;
10095faaaecStsubai f->f_devdata = &romdev;
10195faaaecStsubai *file = strchr(fname, ')') + 1;
10295faaaecStsubai
103b29a3326Stsutsui if (romdev.devtype == DT_BLOCK) {
104b29a3326Stsutsui file_system[0] = file_system_ufs;
105b29a3326Stsutsui #ifdef SUPPORT_USTARFS
106b29a3326Stsutsui file_system[1] = file_system_ustarfs;
107b29a3326Stsutsui nfsys = 2;
108b29a3326Stsutsui #else
109b29a3326Stsutsui nfsys = 1;
110b29a3326Stsutsui #endif
111b29a3326Stsutsui } else { /* DT_NET */
112b29a3326Stsutsui file_system[0] = file_system_nfs;
113b29a3326Stsutsui nfsys = 1;
114c594e4d0Stsubai
115c594e4d0Stsubai if ((error = net_open(&romdev)) != 0) {
116c594e4d0Stsubai printf("Can't open NFS network connection on `%s'\n",
117b29a3326Stsutsui romdev.devname);
118c594e4d0Stsubai return error;
119c594e4d0Stsubai }
120c594e4d0Stsubai }
121c594e4d0Stsubai
12295faaaecStsubai return 0;
12395faaaecStsubai }
12495faaaecStsubai
12595faaaecStsubai int
dkopen(struct open_file * f,...)12695faaaecStsubai dkopen(struct open_file *f, ...)
12795faaaecStsubai {
128fd4afa03Stsutsui
1293fb3c2b5Stsutsui DPRINTF("dkopen\n");
13095faaaecStsubai return 0;
13195faaaecStsubai }
13295faaaecStsubai
13395faaaecStsubai int
dkclose(struct open_file * f)134fd4afa03Stsutsui dkclose(struct open_file *f)
13595faaaecStsubai {
13695faaaecStsubai struct romdev *dev = f->f_devdata;
13795faaaecStsubai
1383fb3c2b5Stsutsui DPRINTF("dkclose\n");
139c594e4d0Stsubai if (apbus)
140c594e4d0Stsubai apcall_close(dev->fd);
141c594e4d0Stsubai else
14295faaaecStsubai rom_close(dev->fd);
143c594e4d0Stsubai
14495faaaecStsubai return 0;
14595faaaecStsubai }
14695faaaecStsubai
14795faaaecStsubai int
dkstrategy(void * devdata,int rw,daddr_t blk,size_t size,void * buf,size_t * rsize)148fd4afa03Stsutsui dkstrategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
149fd4afa03Stsutsui size_t *rsize)
15095faaaecStsubai {
15195faaaecStsubai struct romdev *dev = devdata;
15295faaaecStsubai
15395faaaecStsubai /* XXX should use partition offset */
15495faaaecStsubai
155c594e4d0Stsubai if (apbus) {
156c594e4d0Stsubai apcall_lseek(dev->fd, blk * 512, 0);
157c594e4d0Stsubai apcall_read(dev->fd, buf, size);
158c594e4d0Stsubai } else {
15995faaaecStsubai rom_lseek(dev->fd, blk * 512, 0);
16095faaaecStsubai rom_read(dev->fd, buf, size);
161c594e4d0Stsubai }
162c594e4d0Stsubai *rsize = size; /* XXX */
16395faaaecStsubai return 0;
16495faaaecStsubai }
165b29a3326Stsutsui
166b29a3326Stsutsui #ifdef HAVE_CHANGEDISK_HOOK
167b29a3326Stsutsui void
changedisk_hook(struct open_file * f)168fd4afa03Stsutsui changedisk_hook(struct open_file *f)
169b29a3326Stsutsui {
170b29a3326Stsutsui struct romdev *dev = f->f_devdata;
171b29a3326Stsutsui
172b29a3326Stsutsui if (apbus) {
173b29a3326Stsutsui apcall_ioctl(dev->fd, APIOCEJECT, NULL);
174b29a3326Stsutsui apcall_close(dev->fd);
175b29a3326Stsutsui getchar();
176b29a3326Stsutsui dev->fd = apcall_open(dev->devname, 2);
177b29a3326Stsutsui } else {
178b29a3326Stsutsui rom_ioctl(dev->fd, SYSIOCEJECT, NULL);
179b29a3326Stsutsui rom_close(dev->fd);
180b29a3326Stsutsui getchar();
181b29a3326Stsutsui dev->fd = rom_open(dev->devname, 2);
182b29a3326Stsutsui }
183b29a3326Stsutsui }
184b29a3326Stsutsui #endif
185