1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratory. 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 * @(#)sbus.c 8.1 (Berkeley) 6/11/93 43 * 44 * from: Header: sbus.c,v 1.10 92/11/26 02:28:13 torek Exp (LBL) 45 * $Id: sbus.c,v 1.1 1993/10/02 10:23:55 deraadt Exp $ 46 */ 47 48 /* 49 * Sbus stuff. 50 */ 51 52 #include <sys/param.h> 53 #include <sys/device.h> 54 55 #include <machine/autoconf.h> 56 57 #include <sparc/sbus/sbusreg.h> 58 #include <sparc/sbus/sbusvar.h> 59 60 /* autoconfiguration driver */ 61 void sbus_attach __P((struct device *, struct device *, void *)); 62 struct cfdriver sbuscd = 63 { NULL, "sbus", matchbyname, sbus_attach, 64 DV_DULL, sizeof(struct sbus_softc) }; 65 66 /* 67 * Print the location of some sbus-attached device (called just 68 * before attaching that device). If `sbus' is not NULL, the 69 * device was found but not configured; print the sbus as well. 70 * Return UNCONF (config_find ignores this if the device was configured). 71 */ 72 int 73 sbus_print(args, sbus) 74 void *args; 75 char *sbus; 76 { 77 register struct sbus_attach_args *sa = args; 78 79 if (sbus) 80 printf("%s at %s", sa->sa_ra.ra_name, sbus); 81 printf(" slot %d offset 0x%x", sa->sa_slot, sa->sa_offset); 82 return (UNCONF); 83 } 84 85 /* 86 * Attach an Sbus. 87 */ 88 void 89 sbus_attach(parent, self, aux) 90 struct device *parent; 91 struct device *self; 92 void *aux; 93 { 94 register struct sbus_softc *sc = (struct sbus_softc *)self; 95 register int base, node, slot; 96 register char *name; 97 struct sbus_attach_args sa; 98 register struct romaux *ra; 99 100 /* 101 * XXX there is only one Sbus, for now -- do not know how to 102 * address children on others 103 */ 104 if (sc->sc_dev.dv_unit > 0) { 105 printf(" unsupported\n"); 106 return; 107 } 108 109 /* 110 * Record clock frequency for synchronous SCSI. 111 * IS THIS THE CORRECT DEFAULT?? 112 */ 113 ra = aux; 114 node = ra->ra_node; 115 sc->sc_clockfreq = getpropint(node, "clock-frequency", 25*1000*1000); 116 printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq)); 117 118 if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "sbus") == 0) 119 sa.sa_ra.ra_bp = ra->ra_bp + 1; 120 else 121 sa.sa_ra.ra_bp = NULL; 122 123 /* 124 * Loop through ROM children, fixing any relative addresses 125 * and then configuring each device. 126 */ 127 for (node = firstchild(node); node; node = nextsibling(node)) { 128 name = getpropstring(node, "name"); 129 if (!romprop(&sa.sa_ra, name, node)) 130 continue; 131 base = (int)sa.sa_ra.ra_paddr; 132 if (SBUS_ABS(base)) { 133 sa.sa_slot = SBUS_ABS_TO_SLOT(base); 134 sa.sa_offset = SBUS_ABS_TO_OFFSET(base); 135 } else { 136 sa.sa_slot = slot = sa.sa_ra.ra_iospace; 137 sa.sa_offset = base; 138 sa.sa_ra.ra_paddr = (void *)SBUS_ADDR(slot, base); 139 } 140 (void) config_found(&sc->sc_dev, (void *)&sa, sbus_print); 141 } 142 } 143 144 /* 145 * Each attached device calls sbus_establish after it initializes 146 * its sbusdev portion. 147 */ 148 void 149 sbus_establish(sd, dev) 150 register struct sbusdev *sd; 151 register struct device *dev; 152 { 153 register struct sbus_softc *sc = (struct sbus_softc *)dev->dv_parent; 154 155 sd->sd_dev = dev; 156 sd->sd_bchain = sc->sc_sbdev; 157 sc->sc_sbdev = sd; 158 } 159 160 /* 161 * Reset the given sbus. (???) 162 */ 163 void 164 sbusreset(sbus) 165 int sbus; 166 { 167 register struct sbusdev *sd; 168 struct sbus_softc *sc = sbuscd.cd_devs[sbus]; 169 struct device *dev; 170 171 printf("reset %s:", sc->sc_dev.dv_xname); 172 for (sd = sc->sc_sbdev; sd != NULL; sd = sd->sd_bchain) { 173 if (sd->sd_reset) { 174 dev = sd->sd_dev; 175 (*sd->sd_reset)(dev); 176 printf(" %s", dev->dv_xname); 177 } 178 } 179 } 180