/* $NetBSD: devopen.c,v 1.5 2011/12/25 06:09:09 tsutsui Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <netinet/in.h>
#include <lib/libsa/dev_net.h>
#include <lib/libsa/ufs.h>
#include <lib/libsa/nfs.h>
#include <lib/libsa/dev_net.h>
#include <machine/sbd.h>
#include "local.h"
extern uint8_t kernel_binary[];
extern int kernel_binary_size;
extern struct fs_ops datafs_ops;
extern struct fs_ops bfs_ops;
struct fs_ops ufs_ops = FS_OPS(ufs);
struct fs_ops nfs_ops = FS_OPS(nfs);
extern struct devsw netdevsw;
extern struct devsw dkdevsw;
char fname[16];
/* Referenced by libsa/open.c */
struct fs_ops file_system[1];
int nfsys = 1;
struct devsw devsw[1];
int ndevs = 1;
int
devopen(struct open_file *f, const char *request, char **file)
{
char *p, *filename;
int disk, partition;
void *addr;
size_t size;
strcpy(fname, request);
filename = 0;
for (p = fname; *p; p++) {
if (*p == ':') {
filename = p + 1;
*p = '\0';
break;
}
}
if (filename == 0) { /* not a loader's request. probably ufs_ls() */
printf("request=%s\n", request);
f->f_dev = &dkdevsw;
file_system[0] = ufs_ops;
devsw[0] = dkdevsw;
*file = "/";
return 0;
}
/* Data section */
if (strcmp(fname, "mem") == 0) {
data_attach(kernel_binary, kernel_binary_size);
*file = "noname";
f->f_flags |= F_NODEV;
file_system[0] = datafs_ops;
printf("data(compiled):noname\n");
return 0;
}
/* NFS boot */
if (strcmp(fname, "nfs") == 0) {
if (!DEVICE_CAPABILITY.network_enabled) {
printf("Network disabled.\n");
return -1;
}
try_bootp = true;
file_system[0] = nfs_ops;
f->f_dev = &netdevsw;
if (*filename == '\0') {
printf("set kernel filename. ex.) nfs:netbsd\n");
return 1;
}
*--filename = '/';
*file = filename;
printf("nfs:/%s\n", filename);
net_open(f);
return 0;
}
/* FD boot */
if (strcmp(fname, "fd") == 0) {
printf("floppy(boot):/%s (ustarfs)\n", filename);
f->f_dev = &dkdevsw;
file_system[0] = datafs_ops;
devsw[0] = dkdevsw;
device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1);
if (!ustarfs_load(filename, &addr, &size))
return -1;
data_attach(addr, size);
*file = filename;
return 0;
}
/* Disk boot */
if (strncmp(fname, "sd", 2) == 0) {
enum fstype fs;
if (!DEVICE_CAPABILITY.disk_enabled) {
printf("Disk disabled.\n");
return -1;
}
disk = fname[2] - '0';
partition = fname[3] - 'a';
if (disk < 0 || disk > 9 || partition < 0 || partition > 15) {
fs = FSTYPE_USTARFS;
printf("disk(boot):%s ", filename);
device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1);
} else {
fs = fstype(partition);
printf("disk(%d,%d):/%s ",
disk, partition, filename);
device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition);
}
switch (fs) {
case FSTYPE_UFS:
printf(" (ufs)\n");
f->f_dev = &dkdevsw;
file_system[0] = ufs_ops;
devsw[0] = dkdevsw;
break;
case FSTYPE_BFS:
printf(" (bfs)\n");
f->f_flags |= F_NODEV;
file_system[0] = bfs_ops;
break;
case FSTYPE_USTARFS:
printf(" (ustarfs)\n");
f->f_dev = &dkdevsw;
file_system[0] = datafs_ops;
devsw[0] = dkdevsw;
if (!ustarfs_load(filename, &addr, &size))
return -1;
data_attach(addr, size);
break;
}
*file = filename;
return 0;
}
printf("%s invalid.\n", fname);
return -1;
}