1 1.41 thorpej /* $NetBSD: wdc_ofisa.c,v 1.41 2022/09/25 17:29:22 thorpej Exp $ */ 2 1.1 cgd 3 1.1 cgd /* 4 1.1 cgd * Copyright 1997, 1998 5 1.1 cgd * Digital Equipment Corporation. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This software is furnished under license and may be used and 8 1.1 cgd * copied only in accordance with the following terms and conditions. 9 1.1 cgd * Subject to these conditions, you may download, copy, install, 10 1.1 cgd * use, modify and distribute this software in source and/or binary 11 1.1 cgd * form. No title or ownership is transferred hereby. 12 1.1 cgd * 13 1.1 cgd * 1) Any source code used, modified or distributed must reproduce 14 1.1 cgd * and retain this copyright notice and list of conditions as 15 1.1 cgd * they appear in the source file. 16 1.1 cgd * 17 1.1 cgd * 2) No right is granted to use any trade name, trademark, or logo of 18 1.1 cgd * Digital Equipment Corporation. Neither the "Digital Equipment 19 1.1 cgd * Corporation" name nor any trademark or logo of Digital Equipment 20 1.1 cgd * Corporation may be used to endorse or promote products derived 21 1.1 cgd * from this software without the prior written permission of 22 1.1 cgd * Digital Equipment Corporation. 23 1.1 cgd * 24 1.1 cgd * 3) This software is provided "AS-IS" and any express or implied 25 1.1 cgd * warranties, including but not limited to, any implied warranties 26 1.1 cgd * of merchantability, fitness for a particular purpose, or 27 1.1 cgd * non-infringement are disclaimed. In no event shall DIGITAL be 28 1.1 cgd * liable for any damages whatsoever, and in particular, DIGITAL 29 1.1 cgd * shall not be liable for special, indirect, consequential, or 30 1.1 cgd * incidental damages or damages for lost profits, loss of 31 1.1 cgd * revenue or loss of use, whether such damages arise in contract, 32 1.1 cgd * negligence, tort, under statute, in equity, at law or otherwise, 33 1.1 cgd * even if advised of the possibility of such damage. 34 1.1 cgd */ 35 1.1 cgd 36 1.1 cgd /* 37 1.1 cgd * OFW Attachment for 'wdc' disk controller driver 38 1.1 cgd */ 39 1.7 lukem 40 1.7 lukem #include <sys/cdefs.h> 41 1.41 thorpej __KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.41 2022/09/25 17:29:22 thorpej Exp $"); 42 1.1 cgd 43 1.1 cgd #include <sys/param.h> 44 1.1 cgd #include <sys/device.h> 45 1.2 cgd #include <sys/systm.h> 46 1.1 cgd #include <sys/tty.h> 47 1.1 cgd 48 1.29 ad #include <sys/intr.h> 49 1.29 ad #include <sys/bus.h> 50 1.1 cgd 51 1.1 cgd #include <dev/ofw/openfirm.h> 52 1.1 cgd #include <dev/isa/isavar.h> 53 1.1 cgd #include <dev/ofisa/ofisavar.h> 54 1.1 cgd 55 1.1 cgd #include <dev/ic/wdcreg.h> /* ??? */ 56 1.3 bouyer #include <dev/ata/atavar.h> 57 1.1 cgd #include <dev/ic/wdcvar.h> 58 1.1 cgd 59 1.1 cgd struct wdc_ofisa_softc { 60 1.3 bouyer struct wdc_softc sc_wdcdev; 61 1.25 perry struct ata_channel *sc_chanlist[1]; 62 1.21 thorpej struct ata_channel sc_channel; 63 1.21 thorpej struct wdc_regs wdc_regs; 64 1.1 cgd void *sc_ih; 65 1.1 cgd }; 66 1.1 cgd 67 1.30 cube static int wdc_ofisa_probe(device_t, cfdata_t, void *); 68 1.30 cube static void wdc_ofisa_attach(device_t, device_t, void *); 69 1.1 cgd 70 1.30 cube CFATTACH_DECL_NEW(wdc_ofisa, sizeof(struct wdc_ofisa_softc), 71 1.11 thorpej wdc_ofisa_probe, wdc_ofisa_attach, NULL, NULL); 72 1.1 cgd 73 1.37 thorpej static const struct device_compatible_entry compat_data[] = { 74 1.37 thorpej { .compat = "pnpPNP,600" }, 75 1.39 thorpej DEVICE_COMPAT_EOL 76 1.37 thorpej }; 77 1.37 thorpej 78 1.22 thorpej static int 79 1.30 cube wdc_ofisa_probe(device_t parent, cfdata_t cf, void *aux) 80 1.1 cgd { 81 1.1 cgd struct ofisa_attach_args *aa = aux; 82 1.37 thorpej int rv; 83 1.1 cgd 84 1.40 thorpej rv = of_compatible_match(aa->oba.oba_phandle, compat_data) ? 5 : 0; 85 1.1 cgd #ifdef _WDC_OFISA_MD_MATCH 86 1.1 cgd if (!rv) 87 1.1 cgd rv = wdc_ofisa_md_match(parent, cf, aux); 88 1.1 cgd #endif 89 1.1 cgd return (rv); 90 1.1 cgd } 91 1.1 cgd 92 1.22 thorpej static void 93 1.30 cube wdc_ofisa_attach(device_t parent, device_t self, void *aux) 94 1.1 cgd { 95 1.28 thorpej struct wdc_ofisa_softc *sc = device_private(self); 96 1.21 thorpej struct wdc_regs *wdr; 97 1.1 cgd struct ofisa_attach_args *aa = aux; 98 1.1 cgd struct ofisa_reg_desc reg[2]; 99 1.1 cgd struct ofisa_intr_desc intr; 100 1.1 cgd int n; 101 1.16 fvdl bus_space_handle_t ioh; 102 1.1 cgd 103 1.1 cgd /* 104 1.1 cgd * We're living on an ofw. We have to ask the OFW what our 105 1.1 cgd * registers and interrupts properties look like. 106 1.1 cgd * 107 1.1 cgd * We expect exactly two register regions and one interrupt. 108 1.1 cgd */ 109 1.1 cgd 110 1.30 cube sc->sc_wdcdev.sc_atac.atac_dev = self; 111 1.21 thorpej sc->sc_wdcdev.regs = wdr = &sc->wdc_regs; 112 1.21 thorpej 113 1.2 cgd n = ofisa_reg_get(aa->oba.oba_phandle, reg, 2); 114 1.1 cgd #ifdef _WDC_OFISA_MD_REG_FIXUP 115 1.1 cgd n = wdc_ofisa_md_reg_fixup(parent, self, aux, reg, 2, n); 116 1.1 cgd #endif 117 1.1 cgd if (n != 2) { 118 1.30 cube aprint_error(": error getting register data\n"); 119 1.1 cgd return; 120 1.1 cgd } 121 1.1 cgd if (reg[0].len != 8 || reg[1].len != 2) { 122 1.30 cube aprint_error(": weird register size (%lu/%lu, expected 8/2)\n", 123 1.2 cgd (unsigned long)reg[0].len, (unsigned long)reg[1].len); 124 1.1 cgd return; 125 1.1 cgd } 126 1.1 cgd 127 1.2 cgd n = ofisa_intr_get(aa->oba.oba_phandle, &intr, 1); 128 1.1 cgd #ifdef _WDC_OFISA_MD_INTR_FIXUP 129 1.1 cgd n = wdc_ofisa_md_intr_fixup(parent, self, aux, &intr, 1, n); 130 1.1 cgd #endif 131 1.1 cgd if (n != 1) { 132 1.30 cube aprint_error(": error getting interrupt data\n"); 133 1.1 cgd return; 134 1.1 cgd } 135 1.1 cgd 136 1.21 thorpej wdr->cmd_iot = (reg[0].type == OFISA_REG_TYPE_IO) ? aa->iot : aa->memt; 137 1.21 thorpej wdr->ctl_iot = (reg[1].type == OFISA_REG_TYPE_IO) ? aa->iot : aa->memt; 138 1.21 thorpej if (bus_space_map(wdr->cmd_iot, reg[0].addr, 8, 0, &ioh) || 139 1.21 thorpej bus_space_map(wdr->ctl_iot, reg[1].addr, 1, 0, 140 1.21 thorpej &wdr->ctl_ioh)) { 141 1.30 cube aprint_error(": can't map register spaces\n"); 142 1.1 cgd return; 143 1.1 cgd } 144 1.21 thorpej wdr->cmd_baseioh = ioh; 145 1.16 fvdl 146 1.16 fvdl for (n = 0; n < WDC_NREG; n++) { 147 1.21 thorpej if (bus_space_subregion(wdr->cmd_iot, ioh, n, 148 1.21 thorpej n == 0 ? 4 : 1, &wdr->cmd_iohs[n]) != 0) { 149 1.30 cube aprint_error(": can't subregion register space\n"); 150 1.16 fvdl return; 151 1.16 fvdl } 152 1.16 fvdl } 153 1.1 cgd 154 1.3 bouyer sc->sc_ih = isa_intr_establish(aa->ic, intr.irq, intr.share, 155 1.21 thorpej IPL_BIO, wdcintr, &sc->sc_channel); 156 1.1 cgd 157 1.30 cube aprint_normal("\n"); 158 1.23 thorpej sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16; 159 1.21 thorpej sc->sc_chanlist[0] = &sc->sc_channel; 160 1.23 thorpej sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist; 161 1.23 thorpej sc->sc_wdcdev.sc_atac.atac_nchannels = 1; 162 1.33 bouyer sc->sc_wdcdev.wdc_maxdrives = 2; 163 1.21 thorpej sc->sc_channel.ch_channel = 0; 164 1.23 thorpej sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac; 165 1.36 jdolecek 166 1.35 jdolecek wdc_init_shadow_regs(wdr); 167 1.24 reinoud 168 1.21 thorpej wdcattach(&sc->sc_channel); 169 1.1 cgd 170 1.1 cgd #if 0 171 1.30 cube aprint_verbose_dev(self, "registers: "); 172 1.1 cgd ofisa_reg_print(reg, 2); 173 1.30 cube aprint_verbose("\n"); 174 1.30 cube aprint_verbose_dev(self, "interrupts: "); 175 1.1 cgd ofisa_intr_print(&intr, 1); 176 1.30 cube aprint_verbose("\n"); 177 1.1 cgd #endif 178 1.1 cgd } 179