1 /* $NetBSD: autoconf.c,v 1.16 2001/06/13 14:36:34 soda Exp $ */ 2 /* $OpenBSD: autoconf.c,v 1.9 1997/05/18 13:45:20 pefo Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Per Fogelstrom 6 * Copyright (c) 1988 University of Utah. 7 * Copyright (c) 1992, 1993 8 * The Regents of the University of California. All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * the Systems Programming Group of the University of Utah Computer 12 * Science Department and Ralph Campbell. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the University of 25 * California, Berkeley and its contributors. 26 * 4. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * from: Utah Hdr: autoconf.c 1.31 91/01/21 43 * 44 * from: @(#)autoconf.c 8.1 (Berkeley) 6/10/93 45 */ 46 47 /* 48 * Setup the system to run on the current machine. 49 * 50 * Configure() is called at boot time. Available 51 * devices are determined (from possibilities mentioned in ioconf.c), 52 * and the drivers are initialized. 53 */ 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/buf.h> 58 #include <sys/disklabel.h> 59 #include <sys/conf.h> 60 #include <sys/reboot.h> 61 #include <sys/device.h> 62 63 #include <machine/cpu.h> 64 #include <machine/autoconf.h> 65 66 #include <dev/scsipi/scsi_all.h> 67 #include <dev/scsipi/scsipi_all.h> 68 #include <dev/scsipi/scsiconf.h> 69 70 struct bootdev_data { 71 char *dev_type; 72 int bus; 73 int unit; 74 int partition; 75 }; 76 77 int getpno __P((char **, int *)); 78 79 /* 80 * The following several variables are related to 81 * the configuration process, and are used in initializing 82 * the machine. 83 */ 84 struct device *booted_device; 85 struct bootdev_data *bootdev_data; 86 87 /* 88 * Configure all devices found that we know about. 89 * This is done at boot time. 90 */ 91 void 92 cpu_configure() 93 { 94 (void)splhigh(); /* To be really sure.. */ 95 if (config_rootfound("mainbus", "mainbus") == NULL) 96 panic("no mainbus found"); 97 98 /* Configuration is finished, turn on interrupts. */ 99 _splnone(); /* enable all source forcing SOFT_INTs cleared */ 100 } 101 102 #if defined(NFS_BOOT_BOOTP) || defined(NFS_BOOT_DHCP) 103 int nfs_boot_rfc951 = 1; 104 #endif 105 106 void 107 cpu_rootconf() 108 { 109 printf("boot device: %s\n", 110 booted_device ? booted_device->dv_xname : "<unknown>"); 111 112 setroot(booted_device, booted_device ? bootdev_data->partition : 0); 113 } 114 115 struct devmap { 116 char *attachment; 117 char *dev; 118 }; 119 120 /* 121 * Look at the string 'cp' and decode the boot device. 122 * Boot names look like: scsi()disk(n)rdisk()partition(1)\bsd 123 * (beware for empty scsi id's...) 124 */ 125 void 126 makebootdev(cp) 127 char *cp; 128 { 129 int ok, junk; 130 static struct devmap devmap[] = { 131 { "multi", "fd" }, 132 { "eisa", "wd" }, 133 { "scsi", "sd" }, 134 { NULL, NULL } 135 }; 136 struct devmap *dp = &devmap[0]; 137 static struct bootdev_data bd; 138 139 /* "scsi()" */ 140 while (dp->attachment) { 141 if (strncmp (cp, dp->attachment, strlen(dp->attachment)) == 0) 142 break; 143 dp++; 144 } 145 if (!dp->attachment) { 146 printf("Warning: boot device unrecognized: %s\n", cp); 147 return; 148 } 149 bd.dev_type = dp->dev; 150 ok = getpno(&cp, &bd.bus); 151 152 /* "multi(2)scsi(0)disk(0)rdisk(0)partition(1)" case */ 153 if (ok && strcmp(dp->attachment, "multi") == 0 && 154 memcmp(cp, "scsi", 4) == 0) { 155 bd.dev_type = "sd"; 156 ok = getpno(&cp, &bd.bus); 157 } 158 159 /* "disk(N)" */ 160 if (ok) 161 ok = getpno(&cp, &bd.unit); 162 else 163 bd.unit = 0; 164 165 /* "rdisk()" */ 166 if (*cp++ == ')') 167 ok = getpno(&cp, &junk); 168 169 /* "partition(1)" */ 170 #if 0 /* ignore partition number */ 171 if (ok && getpno(&cp, &bd.partition)) 172 --bd.partition; 173 else 174 #endif 175 bd.partition = 0; 176 177 bootdev_data = &bd; 178 } 179 180 int 181 getpno(cp, np) 182 char **cp; 183 int *np; 184 { 185 int val = 0; 186 char *s = *cp; 187 int got = 0; 188 189 *np = 0; 190 191 while (*s && *s != '(') 192 s++; 193 if (*s == '(') { 194 for (s++; *s; s++) { 195 if (*s == ')') { 196 s++; 197 got = 1; 198 *np = val; 199 break; 200 } 201 val = val * 10 + *s - '0'; 202 } 203 } 204 *cp = s; 205 return (got); 206 } 207 208 /* 209 * Attempt to find the device from which we were booted. 210 */ 211 void 212 device_register(dev, aux) 213 struct device *dev; 214 void *aux; 215 { 216 struct bootdev_data *b = bootdev_data; 217 struct device *parent = dev->dv_parent; 218 struct cfdata *cf = dev->dv_cfdata; 219 struct cfdriver *cd = cf->cf_driver; 220 221 static int found = 0, initted = 0, scsiboot = 0; 222 static struct device *scsibusdev = NULL; 223 224 if (b == NULL) 225 return; /* There is no hope. */ 226 if (found) 227 return; 228 229 if (!initted) { 230 if (strcmp(b->dev_type, "sd") == 0) 231 scsiboot = 1; 232 initted = 1; 233 } 234 235 if (scsiboot && strcmp(cd->cd_name, "scsibus") == 0) { 236 if (dev->dv_unit == b->bus) { 237 scsibusdev = dev; 238 #if 0 239 printf("\nscsibus = %s\n", dev->dv_xname); 240 #endif 241 } 242 return; 243 } 244 245 if (strcmp(b->dev_type, cd->cd_name) != 0) 246 return; 247 248 if (strcmp(cd->cd_name, "sd") == 0) { 249 struct scsipibus_attach_args *sa = aux; 250 251 if (scsiboot && scsibusdev && parent == scsibusdev && 252 sa->sa_periph->periph_target == b->unit) { 253 booted_device = dev; 254 #if 0 255 printf("\nbooted_device = %s\n", dev->dv_xname); 256 #endif 257 found = 1; 258 } 259 return; 260 } 261 if (dev->dv_unit == b->unit) { 262 booted_device = dev; 263 #if 0 264 printf("\nbooted_device = %s\n", dev->dv_xname); 265 #endif 266 found = 1; 267 } 268 } 269