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
35extern int debug;
36
37extern char *fs_name[];
38extern int nfsname;
39extern struct devsw netsw[];
40
41extern char *bootmac;		/* Gets passed to kernel for network boot */
42
43/* XXX use slot for 'rd' for 'hd' pseudo-device */
44const char bdevs[][4] = {
45	"wd", "", "fd", "", "sd", "st", "cd", "",
46	"", "", "", "", "", "", "", "", "", "hd", ""
47};
48const int nbdevs = nitems(bdevs);
49
50const char cdevs[][4] = {
51	"cn", "", "", "", "", "", "", "",
52	"com", "", "", "", "pc"
53};
54const int ncdevs = nitems(cdevs);
55
56/* pass dev_t to the open routines */
57int
58devopen(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
137void
138devboot(dev_t bootdev, char *p)
139{
140	*p++ = 't';
141	*p++ = 'f';
142	*p++ = 't';
143	*p++ = 'p';
144	*p = '\0';
145}
146
147char ttyname_buf[8];
148
149char *
150ttyname(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
158dev_t
159ttydev(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
174int
175cnspeed(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