1 1.1 thorpej /* $NetBSD: pci_bootdev.c,v 1.1 2025/03/09 01:06:42 thorpej Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /* 4 1.1 thorpej * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * Author: Chris G. Demetriou 8 1.1 thorpej * 9 1.1 thorpej * Permission to use, copy, modify and distribute this software and 10 1.1 thorpej * its documentation is hereby granted, provided that both the copyright 11 1.1 thorpej * notice and this permission notice appear in all copies of the 12 1.1 thorpej * software, derivative works or modified versions, and any portions 13 1.1 thorpej * thereof, and that both notices appear in supporting documentation. 14 1.1 thorpej * 15 1.1 thorpej * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 1.1 thorpej * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 1.1 thorpej * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 1.1 thorpej * 19 1.1 thorpej * Carnegie Mellon requests users of this software to return to 20 1.1 thorpej * 21 1.1 thorpej * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 22 1.1 thorpej * School of Computer Science 23 1.1 thorpej * Carnegie Mellon University 24 1.1 thorpej * Pittsburgh PA 15213-3890 25 1.1 thorpej * 26 1.1 thorpej * any improvements or extensions that they make and grant Carnegie the 27 1.1 thorpej * rights to redistribute these changes. 28 1.1 thorpej */ 29 1.1 thorpej 30 1.1 thorpej #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 1.1 thorpej 32 1.1 thorpej __KERNEL_RCSID(0, "$NetBSD: pci_bootdev.c,v 1.1 2025/03/09 01:06:42 thorpej Exp $"); 33 1.1 thorpej 34 1.1 thorpej #include <sys/systm.h> 35 1.1 thorpej #include <sys/device.h> 36 1.1 thorpej 37 1.1 thorpej #include <machine/alpha.h> 38 1.1 thorpej #include <machine/autoconf.h> 39 1.1 thorpej 40 1.1 thorpej #include <dev/ata/atavar.h> 41 1.1 thorpej #include <dev/pci/pcivar.h> 42 1.1 thorpej #include <dev/scsipi/scsiconf.h> 43 1.1 thorpej 44 1.1 thorpej #include <dev/ic/mlxio.h> /* XXX */ 45 1.1 thorpej #include <dev/ic/mlxvar.h> /* XXX */ 46 1.1 thorpej 47 1.1 thorpej #include <dev/i2o/i2o.h> /* XXX */ 48 1.1 thorpej #include <dev/i2o/iopio.h> /* XXX */ 49 1.1 thorpej #include <dev/i2o/iopvar.h> /* XXX */ 50 1.1 thorpej 51 1.1 thorpej #define DPRINTF(x) if (bootdev_debug) printf x 52 1.1 thorpej 53 1.1 thorpej void 54 1.1 thorpej pci_find_bootdev(device_t hosedev, device_t dev, void *aux) 55 1.1 thorpej { 56 1.1 thorpej static device_t pcidev, ctrlrdev; 57 1.1 thorpej struct bootdev_data *b = bootdev_data; 58 1.1 thorpej device_t parent = device_parent(dev); 59 1.1 thorpej 60 1.1 thorpej if (booted_device != NULL || b == NULL) { 61 1.1 thorpej return; 62 1.1 thorpej } 63 1.1 thorpej 64 1.1 thorpej if (pcidev == NULL) { 65 1.1 thorpej if (device_is_a(dev, "pci")) { 66 1.1 thorpej struct pcibus_attach_args *pba = aux; 67 1.1 thorpej 68 1.1 thorpej /* 69 1.1 thorpej * If a hose device was specified, ensure that 70 1.1 thorpej * this PCI instance has that device as an ancestor. 71 1.1 thorpej */ 72 1.1 thorpej if (hosedev) { 73 1.1 thorpej while (parent) { 74 1.1 thorpej if (parent == hosedev) { 75 1.1 thorpej break; 76 1.1 thorpej } 77 1.1 thorpej parent = device_parent(parent); 78 1.1 thorpej } 79 1.1 thorpej if (!parent) { 80 1.1 thorpej return; 81 1.1 thorpej } 82 1.1 thorpej } 83 1.1 thorpej if ((b->slot / 1000) == pba->pba_bus) { 84 1.1 thorpej pcidev = dev; 85 1.1 thorpej DPRINTF(("\npcidev = %s\n", device_xname(dev))); 86 1.1 thorpej } 87 1.1 thorpej } 88 1.1 thorpej return; 89 1.1 thorpej } 90 1.1 thorpej 91 1.1 thorpej if (ctrlrdev == NULL) { 92 1.1 thorpej if (parent == pcidev) { 93 1.1 thorpej struct pci_attach_args *pa = aux; 94 1.1 thorpej int slot = pa->pa_bus * 1000 + pa->pa_function * 100 + 95 1.1 thorpej pa->pa_device; 96 1.1 thorpej 97 1.1 thorpej if (b->slot == slot) { 98 1.1 thorpej if (bootdev_is_net) { 99 1.1 thorpej goto foundit; 100 1.1 thorpej } else { 101 1.1 thorpej ctrlrdev = dev; 102 1.1 thorpej DPRINTF(("\nctrlrdev = %s\n", 103 1.1 thorpej device_xname(dev))); 104 1.1 thorpej } 105 1.1 thorpej } 106 1.1 thorpej } 107 1.1 thorpej return; 108 1.1 thorpej } 109 1.1 thorpej 110 1.1 thorpej if (!bootdev_is_disk) { 111 1.1 thorpej return; 112 1.1 thorpej } 113 1.1 thorpej 114 1.1 thorpej if (device_is_a(dev, "sd") || 115 1.1 thorpej device_is_a(dev, "st") || 116 1.1 thorpej device_is_a(dev, "cd")) { 117 1.1 thorpej struct scsipibus_attach_args *sa = aux; 118 1.1 thorpej struct scsipi_periph *periph = sa->sa_periph; 119 1.1 thorpej int unit; 120 1.1 thorpej 121 1.1 thorpej if (device_parent(parent) != ctrlrdev) { 122 1.1 thorpej return; 123 1.1 thorpej } 124 1.1 thorpej 125 1.1 thorpej unit = periph->periph_target * 100 + periph->periph_lun; 126 1.1 thorpej if (b->unit != unit || 127 1.1 thorpej b->channel != periph->periph_channel->chan_channel) { 128 1.1 thorpej return; 129 1.1 thorpej } 130 1.1 thorpej goto foundit; 131 1.1 thorpej } 132 1.1 thorpej 133 1.1 thorpej if (device_is_a(dev, "wd")) { 134 1.1 thorpej struct ata_device *adev = aux; 135 1.1 thorpej 136 1.1 thorpej if (!device_is_a(parent, "atabus")) { 137 1.1 thorpej return; 138 1.1 thorpej } 139 1.1 thorpej if (device_parent(parent) != ctrlrdev) { 140 1.1 thorpej return; 141 1.1 thorpej } 142 1.1 thorpej 143 1.1 thorpej DPRINTF(("\natapi info: drive %d, channel %d\n", 144 1.1 thorpej adev->adev_drv_data->drive, adev->adev_channel)); 145 1.1 thorpej DPRINTF(("bootdev info: unit: %d, channel: %d\n", 146 1.1 thorpej b->unit, b->channel)); 147 1.1 thorpej if (b->unit != adev->adev_drv_data->drive || 148 1.1 thorpej b->channel != adev->adev_channel) { 149 1.1 thorpej return; 150 1.1 thorpej } 151 1.1 thorpej goto foundit; 152 1.1 thorpej } 153 1.1 thorpej 154 1.1 thorpej if (device_is_a(dev, "ld")) { 155 1.1 thorpej /* 156 1.1 thorpej * XXX Attach arguments for ld devices is not consistent, 157 1.1 thorpej * XXX so we have to special-case each supported RAID 158 1.1 thorpej * XXX controller. 159 1.1 thorpej */ 160 1.1 thorpej if (parent != ctrlrdev) { 161 1.1 thorpej return; 162 1.1 thorpej } 163 1.1 thorpej 164 1.1 thorpej if (device_is_a(parent, "mlx")) { 165 1.1 thorpej struct mlx_attach_args *mlxa = aux; 166 1.1 thorpej 167 1.1 thorpej if (b->unit != mlxa->mlxa_unit) { 168 1.1 thorpej return; 169 1.1 thorpej } 170 1.1 thorpej goto foundit; 171 1.1 thorpej } 172 1.1 thorpej 173 1.1 thorpej if (device_is_a(parent, "iop")) { 174 1.1 thorpej struct iop_attach_args *iopa = aux; 175 1.1 thorpej 176 1.1 thorpej if (b->unit != iopa->ia_tid) { 177 1.1 thorpej return; 178 1.1 thorpej } 179 1.1 thorpej goto foundit; 180 1.1 thorpej } 181 1.1 thorpej } 182 1.1 thorpej 183 1.1 thorpej return; 184 1.1 thorpej 185 1.1 thorpej foundit: 186 1.1 thorpej booted_device = dev; 187 1.1 thorpej DPRINTF(("\nbooted_device = %s\n", device_xname(dev))); 188 1.1 thorpej } 189