1/* $NetBSD: p5bus.c,v 1.2 2012/01/19 00:14:08 rkujawa Exp $ */ 2 3/*- 4 * Copyright (c) 2011, 2012 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Radoslaw Kujawa. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* Driver for internal BlizzardPPC, CyberStorm Mk-III/PPC bus. */ 33 34#include <sys/cdefs.h> 35 36#include <sys/systm.h> 37#include <sys/types.h> 38#include <sys/device.h> 39#include <sys/kmem.h> 40 41#include <amiga/dev/zbusvar.h> 42#include <amiga/dev/p5busvar.h> 43 44#define ZORRO_MANID_P5 8512 45#define ZORRO_PRODID_CSPPC 100 46#define ZORRO_PRODID_BPPC 110 47 48#define P5_ROM_OFF 0xF00010 49#define P5_SN_LEN 7 50 51static int p5bus_match(struct device *pdp, struct cfdata *cfp, void *auxp); 52static void p5bus_attach(device_t parent, device_t self, void *aux); 53static char* p5bus_cardsn(void); 54static int p5bus_print(void *aux, const char *str); 55static void p5bus_callback(device_t self); 56 57struct p5bus_softc { 58 device_t sc_dev; 59 uint8_t sc_cardtype; 60 uint8_t sc_has_scsi; 61#define P5BUS_SCSI_NONE 0 62#define P5BUS_SCSI_710 1 /* NCR 53C710 */ 63#define P5BUS_SCSI_770 2 /* NCR 53C770 */ 64 uint8_t sc_has_ppc; 65#define P5BUS_PPC_NONE 0 /* CS Mk-III only */ 66#define P5BUS_PPC_OK 1 /* has working PPC CPU */ 67}; 68 69CFATTACH_DECL_NEW(p5bus, sizeof(struct p5bus_softc), 70 p5bus_match, p5bus_attach, NULL, NULL); 71 72static int 73p5bus_match(struct device *pdp, struct cfdata *cfp, void *auxp) 74{ 75 struct zbus_args *zap; 76 77 zap = auxp; 78 79 if (zap->manid != ZORRO_MANID_P5) 80 return 0; 81 82 83 if ((zap->prodid != ZORRO_PRODID_BPPC) && 84 (zap->prodid != ZORRO_PRODID_CSPPC)) 85 return 0; 86 87 return 1; 88} 89 90static void 91p5bus_attach(device_t parent, device_t self, void *aux) 92{ 93 struct p5bus_softc *sc; 94 struct zbus_args *zap; 95 struct p5bus_attach_args p5baa; 96 char *sn; 97 98 zap = aux; 99 sc = device_private(self); 100 sc->sc_dev = self; 101 102 sn = p5bus_cardsn(); 103 104 aprint_normal(": Phase5 PowerUP on-board bus\n"); 105 106 /* "Detect" what devices are present and attach the right drivers. */ 107 108 if (zap->prodid == ZORRO_PRODID_CSPPC) { 109 110 if (sn[0] == 'F') { 111 aprint_normal_dev(sc->sc_dev, 112 "CyberStorm Mk-III (sn %s)\n", sn); 113 sc->sc_has_ppc = P5BUS_PPC_NONE; 114 } else { 115 aprint_normal_dev(sc->sc_dev, 116 "CyberStorm PPC 604e (sn %s)\n", sn); 117 sc->sc_has_ppc = P5BUS_PPC_OK; 118 } 119 120 sc->sc_cardtype = P5_CARDTYPE_CS; 121 sc->sc_has_scsi = P5BUS_SCSI_770; 122 123 } else if (zap->prodid == ZORRO_PRODID_BPPC) { 124 125 if (sn[0] != 'I') { /* only "+" model has SCSI */ 126 aprint_normal_dev(sc->sc_dev, 127 "BlizzardPPC 603e (sn %s)\n", sn); 128 sc->sc_has_scsi = P5BUS_SCSI_NONE; 129 } else { 130 aprint_normal_dev(sc->sc_dev, 131 "BlizzardPPC 603e+ (sn %s)\n", sn); 132 sc->sc_has_scsi = P5BUS_SCSI_710; 133 } 134 135 sc->sc_cardtype = P5_CARDTYPE_BPPC; 136 sc->sc_has_ppc = P5BUS_PPC_OK; 137 138 } 139 140 p5baa.p5baa_cardtype = sc->sc_cardtype; 141 142 /* Attach the SCSI host adapters. */ 143 switch (sc->sc_has_scsi) { 144 case P5BUS_SCSI_710: 145 strcpy(p5baa.p5baa_name, "bppcsc"); 146 config_found_ia(sc->sc_dev, "p5bus", &p5baa, p5bus_print); 147 break; 148 case P5BUS_SCSI_770: 149 strcpy(p5baa.p5baa_name, "cbiiisc"); 150 config_found_ia(sc->sc_dev, "p5bus", &p5baa, p5bus_print); 151 break; 152 default: 153 break; 154 } 155 156 /* 157 * We need to wait for possible p5membar attachments. Defer the rest 158 * until parent (zbus) is completely configured. 159 */ 160 config_defer(self, p5bus_callback); 161 162} 163 164/* Continue the attachment. */ 165static void 166p5bus_callback(device_t self) { 167 168 struct p5bus_attach_args p5baa; 169 struct p5bus_softc *sc; 170 171 sc = device_private(self); 172 p5baa.p5baa_cardtype = sc->sc_cardtype; 173 174 /* p5pb is always found, probe is inside of p5pb driver */ 175 strcpy(p5baa.p5baa_name, "p5pb"); 176 config_found_ia(sc->sc_dev, "p5bus", &p5baa, p5bus_print); 177} 178 179/* Get serial number of the card. */ 180static char * 181p5bus_cardsn(void) 182{ 183 char *snr, *sn; 184 185 sn = kmem_zalloc(P5_SN_LEN + 1, KM_SLEEP); 186 snr = (char *)__UNVOLATILE(ztwomap(P5_ROM_OFF)); 187 188 memcpy(sn, snr, P5_SN_LEN); 189 return sn; 190} 191 192static int 193p5bus_print(void *aux, const char *str) 194{ 195 if (str == NULL) 196 return 0; 197 198 printf("%s ", str); 199 200 return 0; 201} 202 203