wdc_isa.c revision 1.7 1 /* $NetBSD: wdc_isa.c,v 1.7 1998/06/09 00:05:46 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
5 *
6 * DMA and multi-sector PIO handling are derived from code contributed by
7 * Onno van der Linden.
8 *
9 * ISA attachment created by Christopher G. Demetriou.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Charles M. Hannum.
22 * 4. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41
42 #include <machine/bus.h>
43 #include <machine/intr.h>
44
45 #include <dev/isa/isavar.h>
46 #include <dev/isa/isadmavar.h>
47
48 #include <dev/ic/wdcvar.h>
49
50 #define WDC_ISA_REG_NPORTS 8
51 #define WDC_ISA_AUXREG_OFFSET 0x206
52 #define WDC_ISA_AUXREG_NPORTS 1 /* XXX "fdc" owns ports 0x3f7/0x377 */
53
54 /*
55 * XXX This code currently doesn't even try to allow 32-bit data port use.
56 */
57
58 struct wdc_isa_softc {
59 struct wdc_softc sc_wdcdev;
60 struct wdc_attachment_data sc_ad;
61 isa_chipset_tag_t sc_ic;
62 void *sc_ih;
63 int sc_drq;
64 };
65
66 #ifdef __BROKEN_INDIRECT_CONFIG
67 int wdc_isa_probe __P((struct device *, void *, void *));
68 #else
69 int wdc_isa_probe __P((struct device *, struct cfdata *, void *));
70 #endif
71 void wdc_isa_attach __P((struct device *, struct device *, void *));
72
73 struct cfattach wdc_isa_ca = {
74 sizeof(struct wdc_isa_softc), wdc_isa_probe, wdc_isa_attach
75 };
76
77 static void wdc_isa_dma_setup __P((void *));
78 static void wdc_isa_dma_start __P((void *, void *, size_t, int));
79 static void wdc_isa_dma_finish __P((void *));
80
81 int
82 wdc_isa_probe(parent, match, aux)
83 struct device *parent;
84 #ifdef __BROKEN_INDIRECT_CONFIG
85 void *match;
86 #else
87 struct cfdata *match;
88 #endif
89 void *aux;
90 {
91 #if 0 /* XXX memset */
92 struct wdc_attachment_data ad = { 0 };
93 #else /* XXX memset */
94 struct wdc_attachment_data ad;
95 #endif /* XXX memset */
96 struct isa_attach_args *ia = aux;
97 int result = 0;
98
99 #if 0 /* XXX memset */
100 #else /* XXX memset */
101 bzero(&ad, sizeof ad);
102 #endif /* XXX memset */
103 ad.iot = ia->ia_iot;
104 if (bus_space_map(ad.iot, ia->ia_iobase, WDC_ISA_REG_NPORTS, 0,
105 &ad.ioh))
106 goto out;
107
108 ad.auxiot = ia->ia_iot;
109 if (bus_space_map(ad.auxiot, ia->ia_iobase + WDC_ISA_AUXREG_OFFSET,
110 WDC_ISA_AUXREG_NPORTS, 0, &ad.auxioh))
111 goto outunmap;
112
113 result = wdcprobe(&ad);
114 if (result) {
115 ia->ia_iosize = WDC_ISA_REG_NPORTS;
116 ia->ia_msize = 0;
117 }
118
119 bus_space_unmap(ad.auxiot, ad.auxioh, WDC_ISA_AUXREG_NPORTS);
120 outunmap:
121 bus_space_unmap(ad.iot, ad.ioh, WDC_ISA_REG_NPORTS);
122 out:
123 return (result);
124 }
125
126 void
127 wdc_isa_attach(parent, self, aux)
128 struct device *parent, *self;
129 void *aux;
130 {
131 struct wdc_isa_softc *sc = (void *)self;
132 struct isa_attach_args *ia = aux;
133
134 printf("\n");
135
136 sc->sc_ad.iot = ia->ia_iot;
137 sc->sc_ad.auxiot = ia->ia_iot;
138 sc->sc_ic = ia->ia_ic;
139 if (bus_space_map(sc->sc_ad.iot, ia->ia_iobase, WDC_ISA_REG_NPORTS, 0,
140 &sc->sc_ad.ioh) ||
141 bus_space_map(sc->sc_ad.auxiot,
142 ia->ia_iobase + WDC_ISA_AUXREG_OFFSET, WDC_ISA_AUXREG_NPORTS,
143 0, &sc->sc_ad.auxioh)) {
144 printf("%s: couldn't map registers\n",
145 sc->sc_wdcdev.sc_dev.dv_xname);
146 }
147
148 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
149 IPL_BIO, wdcintr, sc);
150
151 if (ia->ia_drq != DRQUNK) {
152 sc->sc_drq = ia->ia_drq;
153
154 sc->sc_ad.cap |= WDC_CAPABILITY_DMA;
155 sc->sc_ad.dma_arg = sc;
156 sc->sc_ad.dma_setup = &wdc_isa_dma_setup;
157 sc->sc_ad.dma_start = &wdc_isa_dma_start;
158 sc->sc_ad.dma_finish = &wdc_isa_dma_finish;
159 }
160
161 wdcattach(&sc->sc_wdcdev, &sc->sc_ad);
162 }
163
164 static void
165 wdc_isa_dma_setup(scv)
166 void *scv;
167 {
168 struct wdc_isa_softc *sc = scv;
169
170 if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
171 MAXPHYS, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
172 printf("%s: can't create map for drq %d\n",
173 sc->sc_wdcdev.sc_dev.dv_xname, sc->sc_drq);
174 sc->sc_ad.cap &= ~WDC_CAPABILITY_DMA;
175 }
176 }
177
178 static void
179 wdc_isa_dma_start(scv, buf, size, read)
180 void *scv, *buf;
181 size_t size;
182 int read;
183 {
184 struct wdc_isa_softc *sc = scv;
185
186 isa_dmastart(sc->sc_ic, sc->sc_drq, buf,
187 size, NULL, read ? DMAMODE_READ : DMAMODE_WRITE,
188 BUS_DMA_NOWAIT);
189 }
190
191 static void
192 wdc_isa_dma_finish(scv)
193 void *scv;
194 {
195 struct wdc_isa_softc *sc = scv;
196
197 isa_dmadone(sc->sc_ic, sc->sc_drq);
198 }
199