1 /* $OpenBSD: dev_i386.c,v 1.30 2007/06/27 20:29:37 mk Exp $ */
2
3 /*
4 * Copyright (c) 1996-1999 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "libsa.h"
30 #include "biosdev.h"
31 #include <sys/param.h>
32 #include <dev/cons.h>
33
34 extern int debug;
35
36 /* XXX use slot for 'rd' for 'hd' pseudo-device */
37 const char bdevs[][4] = {
38 "wd", "", "fd", "", "sd", "st", "cd", "mcd",
39 "", "", "", "", "", "", "", "scd", "", "hd", ""
40 };
41 const int nbdevs = NENTS(bdevs);
42
43 const char cdevs[][4] = {
44 "cn", "", "", "", "", "", "", "",
45 "com", "", "", "", "pc"
46 };
47 const int ncdevs = NENTS(cdevs);
48
49 /* pass dev_t to the open routines */
50 int
51 devopen(struct open_file *f, const char *fname, char **file)
52 {
53 struct devsw *dp = devsw;
54 register int i, rc = 1;
55
56 *file = (char *)fname;
57
58 #ifdef DEBUG
59 if (debug)
60 printf("devopen:");
61 #endif
62
63 for (i = 0; i < ndevs && rc != 0; dp++, i++) {
64 #ifdef DEBUG
65 if (debug)
66 printf(" %s: ", dp->dv_name);
67 #endif
68 if ((rc = (*dp->dv_open)(f, file)) == 0) {
69 f->f_dev = dp;
70 return 0;
71 }
72 #ifdef DEBUG
73 else if (debug)
74 printf("%d", rc);
75 #endif
76
77 }
78 #ifdef DEBUG
79 if (debug)
80 putchar('\n');
81 #endif
82
83 if ((f->f_flags & F_NODEV) == 0)
84 f->f_dev = dp;
85
86 return rc;
87 }
88
89 void
90 devboot(dev_t bootdev, char *p)
91 {
92 #ifdef _TEST
93 *p++ = '/';
94 *p++ = 'd';
95 *p++ = 'e';
96 *p++ = 'v';
97 *p++ = '/';
98 *p++ = 'r';
99 #endif
100 if (bootdev & 0x100) {
101 *p++ = 'c';
102 *p++ = 'd';
103 *p++ = '0';
104 } else {
105 if (bootdev & 0x80)
106 *p++ = 'h';
107 else
108 *p++ = 'f';
109 *p++ = 'd';
110 *p++ = '0' + (bootdev & 0x7f);
111 }
112 *p++ = 'a';
113 *p = '\0';
114 }
115
116 int pch_pos = 0;
117
118 void
119 putchar(int c)
120 {
121 switch (c) {
122 case '\177': /* DEL erases */
123 cnputc('\b');
124 cnputc(' ');
125 case '\b':
126 cnputc('\b');
127 if (pch_pos)
128 pch_pos--;
129 break;
130 case '\t':
131 do
132 cnputc(' ');
133 while (++pch_pos % 8);
134 break;
135 case '\n':
136 case '\r':
137 cnputc(c);
138 pch_pos=0;
139 break;
140 default:
141 cnputc(c);
142 pch_pos++;
143 break;
144 }
145 }
146
147 int
148 getchar(void)
149 {
150 register int c = cngetc();
151
152 if (c == '\r')
153 c = '\n';
154
155 if ((c < ' ' && c != '\n') || c == '\177')
156 return c;
157
158 putchar(c);
159
160 return c;
161 }
162
163 char ttyname_buf[8];
164
165 char *
166 ttyname(int fd)
167 {
168 snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
169 cdevs[major(cn_tab->cn_dev)], minor(cn_tab->cn_dev));
170
171 return ttyname_buf;
172 }
173
174 dev_t
175 ttydev(char *name)
176 {
177 int i, unit = -1;
178 char *no = name + strlen(name) - 1;
179
180 while (no >= name && *no >= '0' && *no <= '9')
181 unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
182 if (no < name || unit < 0)
183 return NODEV;
184 for (i = 0; i < ncdevs; i++)
185 if (strncmp(name, cdevs[i], no - name + 1) == 0)
186 return (makedev(i, unit));
187 return NODEV;
188 }
189
190 int
191 cnspeed(dev_t dev, int sp)
192 {
193 if (major(dev) == 8) /* comN */
194 return (comspeed(dev, sp));
195
196 /* pc0 and anything else */
197 return 9600;
198 }