1 /* $NetBSD: autoconf.c,v 1.69 2024/01/07 07:58:35 isaki 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/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.69 2024/01/07 07:58:35 isaki Exp $"); 35 36 #include "opt_compat_netbsd.h" 37 #include "scsibus.h" 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/reboot.h> 42 #include <sys/conf.h> 43 #include <sys/device.h> 44 #include <sys/disk.h> 45 #include <sys/disklabel.h> 46 #include <machine/cpu.h> 47 #include <machine/bootinfo.h> 48 #include <machine/autoconf.h> 49 50 #include <dev/scsipi/scsi_all.h> 51 #include <dev/scsipi/scsipi_all.h> 52 #include <dev/scsipi/scsiconf.h> 53 54 static void findroot(void); 55 static device_t scsi_find(dev_t); 56 57 int x68k_realconfig; 58 59 /* 60 * called at boot time, configure all devices on system 61 */ 62 void 63 cpu_configure(void) 64 { 65 x68k_realconfig = 1; 66 67 if (config_rootfound("mainbus", NULL) == NULL) 68 panic("no mainbus found"); 69 70 /* Turn on interrupts */ 71 printf("enabling interrupts\n"); 72 (void) spl0(); 73 } 74 75 void 76 cpu_rootconf(void) 77 { 78 findroot(); 79 80 printf("boot device: %s\n", 81 booted_device ? device_xname(booted_device) : "<unknown>"); 82 83 rootconf(); 84 } 85 86 void 87 config_console(void) 88 { 89 mfp_config_console(); 90 grf_config_console(); 91 ite_config_console(); 92 } 93 94 uint32_t bootdev = 0; 95 96 static void 97 findroot(void) 98 { 99 int majdev, unit, part; 100 const char *name; 101 102 if (booted_device) 103 return; 104 105 if (boothowto & RB_ASKNAME) 106 return; /* Don't bother looking */ 107 108 if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 109 return; 110 111 majdev = B_TYPE(bootdev); 112 if (X68K_BOOT_DEV_IS_SCSI(majdev)) { 113 /* 114 * SCSI device 115 */ 116 if ((booted_device = scsi_find(bootdev)) != NULL) 117 booted_partition = B_X68K_SCSI_PART(bootdev); 118 return; 119 } 120 name = devsw_blk2name(majdev); 121 if (name == NULL) 122 return; 123 124 part = B_PARTITION(bootdev); 125 unit = B_UNIT(bootdev); 126 127 if ((booted_device = device_find_by_driver_unit(name, unit)) != NULL) 128 booted_partition = part; 129 } 130 131 static const char *const name_netif[] = { X68K_BOOT_NETIF_STRINGS }; 132 133 void 134 device_register(device_t dev, void *aux) 135 { 136 int majdev; 137 char tname[16]; 138 139 /* 140 * Handle network interfaces here, the attachment information is 141 * not available driver independently later. 142 * For disks, there is nothing useful available at attach time. 143 */ 144 if (device_class(dev) == DV_IFNET) { 145 majdev = B_TYPE(bootdev); 146 if (X68K_BOOT_DEV_IS_NETIF(majdev)) { 147 snprintf(tname, sizeof(tname), "%s%d", 148 name_netif[255 - majdev], B_UNIT(bootdev)); 149 if (!strcmp(tname, device_xname(dev))) 150 goto found; 151 } 152 } 153 return; 154 155 found: 156 if (booted_device) { 157 /* XXX should be a "panic()" */ 158 printf("warning: double match for boot device (%s, %s)\n", 159 device_xname(booted_device), device_xname(dev)); 160 return; 161 } 162 booted_device = dev; 163 } 164 165 static const char *const name_scsiif[] = { X68K_BOOT_SCSIIF_STRINGS }; 166 167 static device_t 168 scsi_find(dev_t bdev) 169 { 170 #if defined(NSCSIBUS) && NSCSIBUS > 0 171 int ifid; 172 char tname[16]; 173 device_t scsibus; 174 deviter_t di; 175 struct scsibus_softc *sbsc; 176 struct scsipi_periph *periph; 177 178 ifid = B_X68K_SCSI_IF(bdev); 179 if (ifid >= sizeof name_scsiif/sizeof name_scsiif[0] || 180 !name_scsiif[ifid]) { 181 #ifdef COMPAT_13 182 /* 183 * old boot didn't pass interface type 184 * try "scsibus0" 185 */ 186 printf("warning: scsi_find: can't get boot interface -- " 187 "update boot loader\n"); 188 scsibus = device_find_by_xname("scsibus0"); 189 #else 190 /* can't determine interface type */ 191 return NULL; 192 #endif 193 } else { 194 /* 195 * search for the scsibus whose parent is 196 * the specified SCSI interface 197 */ 198 snprintf(tname, sizeof(tname), "%s%" PRIu64, 199 name_scsiif[ifid], B_X68K_SCSI_IF_UN(bdev)); 200 201 for (scsibus = deviter_first(&di, DEVITER_F_ROOT_FIRST); 202 scsibus != NULL; 203 scsibus = deviter_next(&di)) { 204 if (device_parent(scsibus) 205 && strcmp(tname, device_xname(device_parent(scsibus))) == 0) 206 break; 207 } 208 deviter_release(&di); 209 } 210 if (scsibus == NULL) 211 return NULL; 212 sbsc = device_private(scsibus); 213 periph = scsipi_lookup_periph(sbsc->sc_channel, 214 B_X68K_SCSI_ID(bdev), B_X68K_SCSI_LUN(bdev)); 215 216 return periph ? periph->periph_dev : NULL; 217 #else 218 return NULL; 219 #endif /* NSCSIBUS > 0 */ 220 } 221