183364Sdfr/*-
283364Sdfr * Copyright (c) 2001 Doug Rabson
383364Sdfr * All rights reserved.
483364Sdfr *
583364Sdfr * Redistribution and use in source and binary forms, with or without
683364Sdfr * modification, are permitted provided that the following conditions
783364Sdfr * are met:
883364Sdfr * 1. Redistributions of source code must retain the above copyright
983364Sdfr *    notice, this list of conditions and the following disclaimer.
1083364Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1183364Sdfr *    notice, this list of conditions and the following disclaimer in the
1283364Sdfr *    documentation and/or other materials provided with the distribution.
1383364Sdfr *
1483364Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1583364Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1683364Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1783364Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1883364Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1983364Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2083364Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2183364Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2283364Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2383364Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2483364Sdfr * SUCH DAMAGE.
2583364Sdfr */
2683364Sdfr
27119880Sobrien#include <sys/cdefs.h>
28119880Sobrien__FBSDID("$FreeBSD$");
29119880Sobrien
3083364Sdfr#include <sys/param.h>
3183364Sdfr#include <sys/time.h>
3283364Sdfr#include <stddef.h>
3383364Sdfr#include <stand.h>
3483364Sdfr#include <stdarg.h>
3583364Sdfr
36164010Smarcel#include <bootstrap.h>
3783364Sdfr#include "libski.h"
3883364Sdfr
3983364Sdfrstruct disk_req {
4083364Sdfr	unsigned long addr;
4183364Sdfr	unsigned len;
4283364Sdfr};
4383364Sdfr
4483364Sdfrstruct disk_stat {
4583364Sdfr	int fd;
4683364Sdfr	unsigned count;
4783364Sdfr};
4883364Sdfr
4983364Sdfrstatic int
5083364Sdfrskifs_open(const char *path, struct open_file *f)
5183364Sdfr{
5283364Sdfr	int fd;
5383364Sdfr
5483364Sdfr	/*
5583364Sdfr	 * Skip leading '/' so that our pretend filesystem starts in
5683364Sdfr	 * the current working directory.
5783364Sdfr	 */
5883364Sdfr	while (*path == '/')
5983364Sdfr		path++;
6083364Sdfr
6183364Sdfr	fd = ssc((u_int64_t) path, 1, 0, 0, SSC_OPEN);
6283364Sdfr	if (fd > 0) {
6383364Sdfr		f->f_fsdata = (void*)(u_int64_t) fd;
6483364Sdfr		return 0;
6583364Sdfr	}
6683364Sdfr	return ENOENT;
6783364Sdfr}
6883364Sdfr
6983364Sdfrstatic int
7083364Sdfrskifs_close(struct open_file *f)
7183364Sdfr{
7283364Sdfr	ssc((u_int64_t) f->f_fsdata, 0, 0, 0, SSC_CLOSE);
7383364Sdfr	return 0;
7483364Sdfr}
7583364Sdfr
7683364Sdfrstatic int
7783364Sdfrskifs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
7883364Sdfr{
7983364Sdfr	struct disk_req req;
8083364Sdfr	struct disk_stat stat;
8183364Sdfr
8283364Sdfr	req.len = size;
8383364Sdfr	req.addr = (u_int64_t) buf;
8483364Sdfr	ssc((u_int64_t) f->f_fsdata, 1, (u_int64_t) &req, f->f_offset, SSC_READ);
8583364Sdfr	stat.fd = (u_int64_t) f->f_fsdata;
8683364Sdfr	ssc((u_int64_t)&stat, 0, 0, 0, SSC_WAIT_COMPLETION);
8783364Sdfr
8883364Sdfr	*resid = size - stat.count;
8983364Sdfr	f->f_offset += stat.count;
9083364Sdfr	return 0;
9183364Sdfr}
9283364Sdfr
9383364Sdfrstatic off_t
9483364Sdfrskifs_seek(struct open_file *f, off_t offset, int where)
9583364Sdfr{
9683364Sdfr	u_int64_t base;
9783364Sdfr
9883364Sdfr	switch (where) {
9983364Sdfr	case SEEK_SET:
10083364Sdfr		base = 0;
10183364Sdfr		break;
10283364Sdfr
10383364Sdfr	case SEEK_CUR:
10483364Sdfr		base = f->f_offset;
10583364Sdfr		break;
10683364Sdfr
10783364Sdfr	case SEEK_END:
10883364Sdfr		printf("can't find end of file in SKI\n");
10983364Sdfr		base = f->f_offset;
11083364Sdfr		break;
11183364Sdfr	}
11283364Sdfr
11383364Sdfr	f->f_offset = base + offset;
11483364Sdfr	return base;
11583364Sdfr}
11683364Sdfr
11783364Sdfrstatic int
11883364Sdfrskifs_stat(struct open_file *f, struct stat *sb)
11983364Sdfr{
12083364Sdfr	bzero(sb, sizeof(*sb));
12183364Sdfr	sb->st_mode = S_IFREG | S_IRUSR;
12283364Sdfr	return 0;
12383364Sdfr}
12483364Sdfr
12583364Sdfrstatic int
12683364Sdfrskifs_readdir(struct open_file *f, struct dirent *d)
12783364Sdfr{
12883364Sdfr	return ENOENT;
12983364Sdfr}
13083364Sdfr
13183364Sdfrstruct fs_ops ski_fsops = {
13283364Sdfr	"fs",
13383364Sdfr	skifs_open,
13483364Sdfr	skifs_close,
13583364Sdfr	skifs_read,
13683364Sdfr	null_write,
13783364Sdfr	skifs_seek,
13883364Sdfr	skifs_stat,
13983364Sdfr	skifs_readdir
14083364Sdfr};
14183364Sdfr
14283364Sdfrstatic int
14383364Sdfrskifs_dev_init(void)
14483364Sdfr{
14583364Sdfr	return 0;
14683364Sdfr}
14783364Sdfr
14883364Sdfr/*
14983364Sdfr * Print information about disks
15083364Sdfr */
15183364Sdfrstatic void
15283364Sdfrskifs_dev_print(int verbose)
15383364Sdfr{
15483364Sdfr}
15583364Sdfr
15683364Sdfr/*
15783364Sdfr * Attempt to open the disk described by (dev) for use by (f).
15883364Sdfr *
15983364Sdfr * Note that the philosophy here is "give them exactly what
16083364Sdfr * they ask for".  This is necessary because being too "smart"
16183364Sdfr * about what the user might want leads to complications.
16283364Sdfr * (eg. given no slice or partition value, with a disk that is
16383364Sdfr *  sliced - are they after the first BSD slice, or the DOS
16483364Sdfr *  slice before it?)
16583364Sdfr */
16683364Sdfrstatic int
16783364Sdfrskifs_dev_open(struct open_file *f, ...)
16883364Sdfr{
16983364Sdfr	return 0;
17083364Sdfr}
17183364Sdfr
17283364Sdfrstatic int
17383364Sdfrskifs_dev_close(struct open_file *f)
17483364Sdfr{
17583364Sdfr
17683364Sdfr	return 0;
17783364Sdfr}
17883364Sdfr
17983364Sdfrstatic int
18083364Sdfrskifs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
18183364Sdfr{
18283364Sdfr	return 0;
18383364Sdfr}
18483364Sdfr
18583364Sdfrstruct devsw skifs_dev = {
18683364Sdfr	"fs",
18783364Sdfr	DEVT_DISK,
18883364Sdfr	skifs_dev_init,
18983364Sdfr	skifs_dev_strategy,
19083364Sdfr	skifs_dev_open,
19183364Sdfr	skifs_dev_close,
19283364Sdfr	noioctl,
19383364Sdfr	skifs_dev_print
19483364Sdfr};
195