1 /* $OpenBSD: devopen.c,v 1.4 2007/07/27 17:48:01 tom 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", "mcd", 46 "", "", "", "", "", "", "", "scd", "", "hd", "" 47 }; 48 const int nbdevs = NENTS(bdevs); 49 50 const char cdevs[][4] = { 51 "cn", "", "", "", "", "", "", "", 52 "com", "", "", "", "pc" 53 }; 54 const int ncdevs = NENTS(cdevs); 55 56 /* pass dev_t to the open routines */ 57 int 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 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 int pch_pos = 0; 148 149 void 150 putchar(int c) 151 { 152 switch (c) { 153 case '\177': /* DEL erases */ 154 cnputc('\b'); 155 cnputc(' '); 156 case '\b': 157 cnputc('\b'); 158 if (pch_pos) 159 pch_pos--; 160 break; 161 case '\t': 162 do 163 cnputc(' '); 164 while (++pch_pos % 8); 165 break; 166 case '\n': 167 case '\r': 168 cnputc(c); 169 pch_pos=0; 170 break; 171 default: 172 cnputc(c); 173 pch_pos++; 174 break; 175 } 176 } 177 178 int 179 getchar(void) 180 { 181 register int c = cngetc(); 182 183 if (c == '\r') 184 c = '\n'; 185 186 if ((c < ' ' && c != '\n') || c == '\177') 187 return c; 188 189 putchar(c); 190 191 return c; 192 } 193 194 char ttyname_buf[8]; 195 196 char * 197 ttyname(int fd) 198 { 199 snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d", 200 cdevs[major(cn_tab->cn_dev)], minor(cn_tab->cn_dev)); 201 202 return ttyname_buf; 203 } 204 205 dev_t 206 ttydev(char *name) 207 { 208 int i, unit = -1; 209 char *no = name + strlen(name) - 1; 210 211 while (no >= name && *no >= '0' && *no <= '9') 212 unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0'; 213 if (no < name || unit < 0) 214 return NODEV; 215 for (i = 0; i < ncdevs; i++) 216 if (strncmp(name, cdevs[i], no - name + 1) == 0) 217 return (makedev(i, unit)); 218 return NODEV; 219 } 220 221 int 222 cnspeed(dev_t dev, int sp) 223 { 224 if (major(dev) == 8) /* comN */ 225 return (comspeed(dev, sp)); 226 227 /* pc0 and anything else */ 228 return 9600; 229 } 230