1 /* $OpenBSD: devopen.c,v 1.11 2014/07/13 09:26:08 jasper Exp $ */
2
3 /*
4 * Copyright (c) 2004 Tom Cosgrove
5 * Copyright (c) 1996-1999 Michael Shalayeff
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
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 OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "libsa.h"
31 #include "biosdev.h"
32 #include <sys/param.h>
33 #include <dev/cons.h>
34
35 extern int debug;
36
37 extern char *fs_name[];
38 extern int nfsname;
39 extern struct devsw netsw[];
40
41 extern char *bootmac; /* Gets passed to kernel for network boot */
42
43 /* XXX use slot for 'rd' for 'hd' pseudo-device */
44 const char bdevs[][4] = {
45 "wd", "", "fd", "", "sd", "st", "cd", "",
46 "", "", "", "", "", "", "", "", "", "hd", ""
47 };
48 const int nbdevs = nitems(bdevs);
49
50 const char cdevs[][4] = {
51 "cn", "", "", "", "", "", "", "",
52 "com", "", "", "", "pc"
53 };
54 const int ncdevs = nitems(cdevs);
55
56 /* pass dev_t to the open routines */
57 int
devopen(struct open_file * f,const char * fname,char ** file)58 devopen(struct open_file *f, const char *fname, char **file)
59 {
60 struct devsw *dp = devsw;
61 char *p;
62 char *stripdev;
63 int i, l;
64 int rc = 1;
65
66 *file = (char *)fname;
67
68 #ifdef DEBUG
69 if (debug)
70 printf("devopen(%s):", fname);
71 #endif
72
73 /* Make sure we have a prefix, e.g. hd0a: or tftp:. */
74 for (p = (char *)fname; *p != ':' && *p != '\0'; ) p++;
75 if (*p != ':')
76 return 1;
77 stripdev = p + 1;
78
79 l = p - fname; /* Length of device prefix. */
80 for (i = 0; i < nfsname; i++) {
81 if ((fs_name[i] != NULL) &&
82 (strncmp(fname, fs_name[i], l) == 0)) {
83
84 /* Force oopen() etc to use this filesystem. */
85 f->f_ops = &file_system[i];
86 f->f_dev = dp = &netsw[0];
87
88 rc = (*dp->dv_open)(f, NULL);
89 if (rc == 0)
90 *file = stripdev;
91 else
92 f->f_dev = NULL;
93 #ifdef DEBUG
94 if (debug)
95 putchar('\n');
96 #endif
97 return rc;
98 }
99 }
100
101 /*
102 * Assume that any network filesystems would be caught by the
103 * code above, so that the next phase of devopen() is only for
104 * local devices.
105 *
106 * Clear bootmac, to signal that we loaded this file from a
107 * non-network device.
108 */
109 bootmac = NULL;
110
111 for (i = 0; i < ndevs && rc != 0; dp++, i++) {
112 #ifdef DEBUG
113 if (debug)
114 printf(" %s: ", dp->dv_name);
115 #endif
116 if ((rc = (*dp->dv_open)(f, file)) == 0) {
117 f->f_dev = dp;
118 return 0;
119 }
120 #ifdef DEBUG
121 else if (debug)
122 printf("%d", rc);
123 #endif
124
125 }
126 #ifdef DEBUG
127 if (debug)
128 putchar('\n');
129 #endif
130
131 if ((f->f_flags & F_NODEV) == 0)
132 f->f_dev = dp;
133
134 return rc;
135 }
136
137 void
devboot(dev_t bootdev,char * p)138 devboot(dev_t bootdev, char *p)
139 {
140 *p++ = 't';
141 *p++ = 'f';
142 *p++ = 't';
143 *p++ = 'p';
144 *p = '\0';
145 }
146
147 char ttyname_buf[8];
148
149 char *
ttyname(int fd)150 ttyname(int fd)
151 {
152 snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
153 cdevs[major(cn_tab->cn_dev)], minor(cn_tab->cn_dev));
154
155 return ttyname_buf;
156 }
157
158 dev_t
ttydev(char * name)159 ttydev(char *name)
160 {
161 int i, unit = -1;
162 char *no = name + strlen(name) - 1;
163
164 while (no >= name && *no >= '0' && *no <= '9')
165 unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
166 if (no < name || unit < 0)
167 return NODEV;
168 for (i = 0; i < ncdevs; i++)
169 if (strncmp(name, cdevs[i], no - name + 1) == 0)
170 return (makedev(i, unit));
171 return NODEV;
172 }
173
174 int
cnspeed(dev_t dev,int sp)175 cnspeed(dev_t dev, int sp)
176 {
177 if (major(dev) == 8) /* comN */
178 return (comspeed(dev, sp));
179
180 /* pc0 and anything else */
181 return 9600;
182 }
183