1 /* $NetBSD: sbus.c,v 1.5 1994/11/23 07:02:19 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratory. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)sbus.c 8.1 (Berkeley) 6/11/93 45 */ 46 47 /* 48 * Sbus stuff. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/device.h> 53 54 #include <machine/autoconf.h> 55 56 #include <sparc/dev/sbusreg.h> 57 #include <sparc/dev/sbusvar.h> 58 59 /* autoconfiguration driver */ 60 void sbus_attach __P((struct device *, struct device *, void *)); 61 int sbus_match __P((struct device *, void *, void *)); 62 struct cfdriver sbuscd = { 63 NULL, "sbus", sbus_match, sbus_attach, 64 DV_DULL, sizeof(struct sbus_softc) 65 }; 66 67 /* 68 * Print the location of some sbus-attached device (called just 69 * before attaching that device). If `sbus' is not NULL, the 70 * device was found but not configured; print the sbus as well. 71 * Return UNCONF (config_find ignores this if the device was configured). 72 */ 73 int 74 sbus_print(args, sbus) 75 void *args; 76 char *sbus; 77 { 78 register struct confargs *ca = args; 79 80 if (sbus) 81 printf("%s at %s", ca->ca_ra.ra_name, sbus); 82 printf(" slot %d offset 0x%x", ca->ca_slot, ca->ca_offset); 83 return (UNCONF); 84 } 85 86 int 87 sbus_match(parent, vcf, aux) 88 struct device *parent; 89 void *vcf, *aux; 90 { 91 struct cfdata *cf = vcf; 92 register struct confargs *ca = aux; 93 register struct romaux *ra = &ca->ca_ra; 94 95 if (cputyp==CPU_SUN4) 96 return (0); 97 return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0); 98 } 99 100 /* 101 * Attach an Sbus. 102 */ 103 void 104 sbus_attach(parent, self, aux) 105 struct device *parent; 106 struct device *self; 107 void *aux; 108 { 109 register struct sbus_softc *sc = (struct sbus_softc *)self; 110 struct confargs *ca = aux; 111 register struct romaux *ra = &ca->ca_ra; 112 register int base, node, slot; 113 register char *name; 114 struct confargs oca; 115 116 /* 117 * XXX there is only one Sbus, for now -- do not know how to 118 * address children on others 119 */ 120 if (sc->sc_dev.dv_unit > 0) { 121 printf(" unsupported\n"); 122 return; 123 } 124 125 /* 126 * Record clock frequency for synchronous SCSI. 127 * IS THIS THE CORRECT DEFAULT?? 128 */ 129 node = ra->ra_node; 130 sc->sc_clockfreq = getpropint(node, "clock-frequency", 25*1000*1000); 131 printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq)); 132 133 if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "sbus") == 0) 134 oca.ca_ra.ra_bp = ra->ra_bp + 1; 135 else 136 oca.ca_ra.ra_bp = NULL; 137 138 /* 139 * Loop through ROM children, fixing any relative addresses 140 * and then configuring each device. 141 */ 142 for (node = firstchild(node); node; node = nextsibling(node)) { 143 name = getpropstring(node, "name"); 144 if (!romprop(&oca.ca_ra, name, node)) 145 continue; 146 base = (int)oca.ca_ra.ra_paddr; 147 if (SBUS_ABS(base)) { 148 oca.ca_slot = SBUS_ABS_TO_SLOT(base); 149 oca.ca_offset = SBUS_ABS_TO_OFFSET(base); 150 } else { 151 oca.ca_slot = slot = oca.ca_ra.ra_iospace; 152 oca.ca_offset = base; 153 oca.ca_ra.ra_paddr = (void *)SBUS_ADDR(slot, base); 154 } 155 oca.ca_bustype = BUS_SBUS; 156 (void) config_found(&sc->sc_dev, (void *)&oca, sbus_print); 157 } 158 } 159 160 /* 161 * Each attached device calls sbus_establish after it initializes 162 * its sbusdev portion. 163 */ 164 void 165 sbus_establish(sd, dev) 166 register struct sbusdev *sd; 167 register struct device *dev; 168 { 169 register struct sbus_softc *sc = (struct sbus_softc *)dev->dv_parent; 170 171 sd->sd_dev = dev; 172 sd->sd_bchain = sc->sc_sbdev; 173 sc->sc_sbdev = sd; 174 } 175 176 /* 177 * Reset the given sbus. (???) 178 */ 179 void 180 sbusreset(sbus) 181 int sbus; 182 { 183 register struct sbusdev *sd; 184 struct sbus_softc *sc = sbuscd.cd_devs[sbus]; 185 struct device *dev; 186 187 printf("reset %s:", sc->sc_dev.dv_xname); 188 for (sd = sc->sc_sbdev; sd != NULL; sd = sd->sd_bchain) { 189 if (sd->sd_reset) { 190 dev = sd->sd_dev; 191 (*sd->sd_reset)(dev); 192 printf(" %s", dev->dv_xname); 193 } 194 } 195 } 196