1 /* $NetBSD: autoconf.c,v 1.41 2002/10/04 01:50:55 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Leo Weppelman 5 * Copyright (c) 1994 Christian E. Hopps 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 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Christian E. Hopps. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/reboot.h> 36 #include <sys/conf.h> 37 #include <sys/buf.h> 38 #include <sys/device.h> 39 #include <sys/disklabel.h> 40 #include <sys/disk.h> 41 #include <machine/disklabel.h> 42 #include <machine/cpu.h> 43 #include <atari/atari/device.h> 44 45 static void findroot __P((void)); 46 void mbattach __P((struct device *, struct device *, void *)); 47 int mbprint __P((void *, const char *)); 48 int mbmatch __P((struct device *, struct cfdata *, void *)); 49 50 struct device *booted_device; 51 int booted_partition; 52 53 int atari_realconfig; 54 #include <sys/kernel.h> 55 56 /* 57 * called at boot time, configure all devices on system 58 */ 59 void 60 cpu_configure() 61 { 62 extern int atari_realconfig; 63 64 atari_realconfig = 1; 65 66 if (config_rootfound("mainbus", "mainbus") == NULL) 67 panic("no mainbus found"); 68 } 69 70 void 71 cpu_rootconf() 72 { 73 findroot(); 74 setroot(booted_device, booted_partition); 75 } 76 77 /*ARGSUSED*/ 78 int 79 simple_devprint(auxp, pnp) 80 void *auxp; 81 const char *pnp; 82 { 83 return(QUIET); 84 } 85 86 /* 87 * use config_search to find appropriate device, then call that device 88 * directly with NULL device variable storage. A device can then 89 * always tell the difference between the real and console init 90 * by checking for NULL. 91 */ 92 int 93 atari_config_found(pcfp, pdp, auxp, pfn) 94 struct cfdata *pcfp; 95 struct device *pdp; 96 void *auxp; 97 cfprint_t pfn; 98 { 99 struct device temp; 100 struct cfdata *cf; 101 const struct cfattach *ca; 102 extern int atari_realconfig; 103 104 if (atari_realconfig) 105 return(config_found(pdp, auxp, pfn) != NULL); 106 107 if (pdp == NULL) 108 pdp = &temp; 109 110 pdp->dv_cfdata = pcfp; 111 if ((cf = config_search((cfmatch_t)NULL, pdp, auxp)) != NULL) { 112 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname); 113 if (ca != NULL) { 114 (*ca->ca_attach)(pdp, NULL, auxp); 115 pdp->dv_cfdata = NULL; 116 return(1); 117 } 118 } 119 pdp->dv_cfdata = NULL; 120 return(0); 121 } 122 123 /* 124 * this function needs to get enough configured to do a console 125 * basically this means start attaching the grfxx's that support 126 * the console. Kinda hacky but it works. 127 */ 128 void 129 config_console() 130 { 131 struct cfdata *cf; 132 133 config_init(); 134 135 /* 136 * we need mainbus' cfdata. 137 */ 138 cf = config_rootsearch(NULL, "mainbus", "mainbus"); 139 if (cf == NULL) 140 panic("no mainbus"); 141 142 /* 143 * Note: The order of the 'atari_config_found()' calls is 144 * important! On the Hades, the 'pci-side' of the config does 145 * some setup for the 'grf-side'. This make it possible to use 146 * a PCI card for both wscons and grfabs. 147 */ 148 atari_config_found(cf, NULL, "pcibus", NULL); 149 atari_config_found(cf, NULL, "isabus", NULL); 150 atari_config_found(cf, NULL, "grfbus", NULL); 151 } 152 153 /* 154 * The system will assign the "booted device" indicator (and thus 155 * rootdev if rootspec is wildcarded) to the first partition 'a' 156 * in preference of boot. 157 */ 158 #include <sys/fcntl.h> /* XXXX and all that uses it */ 159 #include <sys/proc.h> /* XXXX and all that uses it */ 160 161 #include "fd.h" 162 #include "sd.h" 163 #include "cd.h" 164 #include "wd.h" 165 166 #if NWD > 0 167 extern struct cfdriver wd_cd; 168 #endif 169 #if NSD > 0 170 extern struct cfdriver sd_cd; 171 #endif 172 #if NCD > 0 173 extern struct cfdriver cd_cd; 174 #endif 175 #if NFD > 0 176 extern struct cfdriver fd_cd; 177 #endif 178 179 struct cfdriver *genericconf[] = { 180 #if NWD > 0 181 &wd_cd, 182 #endif 183 #if NSD > 0 184 &sd_cd, 185 #endif 186 #if NCD > 0 187 &cd_cd, 188 #endif 189 #if NFD > 0 190 &fd_cd, 191 #endif 192 NULL, 193 }; 194 195 void 196 findroot(void) 197 { 198 struct disk *dkp; 199 struct partition *pp; 200 struct device **devs; 201 const struct bdevsw *bdev; 202 int i, maj, unit; 203 204 if (boothowto & RB_ASKNAME) 205 return; /* Don't bother looking */ 206 207 for (i = 0; genericconf[i] != NULL; i++) { 208 for (unit = 0; unit < genericconf[i]->cd_ndevs; unit++) { 209 if (genericconf[i]->cd_devs[unit] == NULL) 210 continue; 211 212 /* 213 * Find the disk structure corresponding to the 214 * current device. 215 */ 216 devs = (struct device **)genericconf[i]->cd_devs; 217 if ((dkp = disk_find(devs[unit]->dv_xname)) == NULL) 218 continue; 219 220 if (dkp->dk_driver == NULL || 221 dkp->dk_driver->d_strategy == NULL) 222 continue; 223 224 maj = devsw_name2blk(genericconf[i]->cd_name, NULL, 0); 225 if (maj == -1) 226 continue; 227 bdev = bdevsw_lookup(makedev(maj, 0)); 228 #ifdef DIAGNOSTIC 229 if (bdev == NULL) 230 panic("findroot: impossible"); 231 #endif 232 if (bdev == NULL || 233 bdev->d_strategy != dkp->dk_driver->d_strategy) 234 continue; 235 236 /* Open disk; forces read of disklabel. */ 237 if ((*bdev->d_open)(MAKEDISKDEV(maj, 238 unit, 0), FREAD|FNONBLOCK, 0, &proc0)) 239 continue; 240 (void)(*bdev->d_close)(MAKEDISKDEV(maj, 241 unit, 0), FREAD|FNONBLOCK, 0, &proc0); 242 243 pp = &dkp->dk_label->d_partitions[booted_partition]; 244 if (pp->p_size != 0 && pp->p_fstype == FS_BSDFFS) { 245 booted_device = devs[unit]; 246 return; 247 } 248 } 249 } 250 } 251 252 /* 253 * mainbus driver 254 */ 255 CFATTACH_DECL(mainbus, sizeof(struct device), 256 mbmatch, mbattach, NULL, NULL); 257 258 int 259 mbmatch(pdp, cfp, auxp) 260 struct device *pdp; 261 struct cfdata *cfp; 262 void *auxp; 263 { 264 if (cfp->cf_unit > 0) 265 return(0); 266 /* 267 * We are always here 268 */ 269 return(1); 270 } 271 272 /* 273 * "find" all the things that should be there. 274 */ 275 void 276 mbattach(pdp, dp, auxp) 277 struct device *pdp, *dp; 278 void *auxp; 279 { 280 printf ("\n"); 281 config_found(dp, "clock" , simple_devprint); 282 config_found(dp, "grfbus" , simple_devprint); 283 config_found(dp, "kbd" , simple_devprint); 284 config_found(dp, "fdc" , simple_devprint); 285 config_found(dp, "ser" , simple_devprint); 286 config_found(dp, "zs" , simple_devprint); 287 config_found(dp, "ncrscsi", simple_devprint); 288 config_found(dp, "nvr" , simple_devprint); 289 config_found(dp, "lpt" , simple_devprint); 290 config_found(dp, "wdc" , simple_devprint); 291 config_found(dp, "isabus" , simple_devprint); 292 config_found(dp, "pcibus" , simple_devprint); 293 config_found(dp, "avmebus" , simple_devprint); 294 } 295 296 int 297 mbprint(auxp, pnp) 298 void *auxp; 299 const char *pnp; 300 { 301 if (pnp) 302 printf("%s at %s", (char *)auxp, pnp); 303 return(UNCONF); 304 } 305