1 /* $NetBSD: devopen.c,v 1.2 2011/03/06 18:22:13 phx Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Tohru Nishimura. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 34 #include <netinet/in.h> 35 36 #include <lib/libsa/stand.h> 37 #include <lib/libsa/nfs.h> 38 #include <lib/libsa/ufs.h> 39 #include <lib/libsa/tftp.h> 40 #include <lib/libkern/libkern.h> 41 42 #include "globals.h" 43 #include "memfs.h" 44 45 struct devsw devnet = { "net", net_strategy, net_open, net_close, noioctl }; 46 struct devsw devdsk = { "dsk", dsk_strategy, dsk_open, dsk_close, noioctl }; 47 48 struct fs_ops file_system[1] = { FS_OPS(null) }; 49 int nfsys = 1; 50 struct fs_ops fs_nfs = FS_OPS(nfs); 51 struct fs_ops fs_tftp = FS_OPS(tftp); 52 struct fs_ops fs_ffsv2 = FS_OPS(ffsv2); 53 struct fs_ops fs_ffsv1 = FS_OPS(ffsv1); 54 struct fs_ops fs_mem = FS_OPS(mem); 55 extern char *fsmod; 56 57 static void parseunit(const char *, int *, int *, char **); 58 59 int 60 devopen(struct open_file *of, const char *name, char **file) 61 { 62 int error; 63 int unit, part; 64 extern char bootfile[]; /* handed by DHCP */ 65 66 if (of->f_flags != F_READ) 67 return EPERM; 68 69 if (strncmp("mem:", name, 4) == 0) { 70 of->f_dev = NULL; 71 of->f_flags |= F_NODEV; 72 file_system[0] = fs_mem; 73 *file = (char *)&name[4]; 74 return 0; /* MEM */ 75 } 76 if (strncmp("net:", name, 4) == 0 || strncmp("nfs:", name, 4) == 0) { 77 of->f_dev = &devnet; 78 if ((error = net_open(of, &name[4], "nfs")) != 0) 79 return error; 80 file_system[0] = fs_nfs; 81 *file = bootfile; /* resolved fname */ 82 return 0; /* NFS */ 83 } 84 if (strncmp("tftp:", name, 5) == 0) { 85 of->f_dev = &devnet; 86 if ((error = net_open(of, &name[5], "tftp")) != 0) 87 return error; 88 file_system[0] = fs_tftp; 89 *file = bootfile; /* resolved fname */ 90 return 0; /* TFTP */ 91 } 92 if (name[0] == 'w' && name[1] == 'd') { 93 parseunit(&name[2], &unit, &part, file); 94 of->f_dev = &devdsk; 95 if (*file == NULL || **file <= ' ') 96 *file = "netbsd"; 97 if ((error = dsk_open(of, unit, part, *file)) != 0) 98 return error; 99 file_system[0] = *dsk_fsops(of); 100 return 0; /* FFS */ 101 } 102 return ENOENT; 103 } 104 105 static void 106 parseunit(const char *name, int *unitp, int *partp, char **pathp) 107 { 108 const char *p = name; 109 int unit, part; 110 111 unit = part = -1; 112 while (*p != ':' && *p != '\0') { 113 if (unit == -1 && *p >= '0' && *p <= '9') 114 unit = *p - '0'; 115 if (part == -1 && *p >= 'a' && *p < 'a' + 16) 116 part = *p - 'a'; 117 p += 1; 118 } 119 *unitp = (unit == -1) ? 0 : unit; 120 *partp = (part == -1) ? 0 : part; 121 *pathp = (*p == ':') ? (char *)p + 1 : NULL; 122 } 123 124 /* ARGSUSED */ 125 int 126 noioctl(struct open_file *f, u_long cmd, void *data) 127 { 128 129 return EINVAL; 130 } 131