wdc_isa.c revision 1.3 1 /* $NetBSD: wdc_isa.c,v 1.3 1998/01/22 23:42:39 mycroft 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 2
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 void *sc_ih;
62 int sc_drq;
63 };
64
65 #ifdef __BROKEN_INDIRECT_CONFIG
66 int wdc_isa_probe __P((struct device *, void *, void *));
67 #else
68 int wdc_isa_probe __P((struct device *, struct cfdata *, void *));
69 #endif
70 void wdc_isa_attach __P((struct device *, struct device *, void *));
71
72 struct cfattach wdc_isa_ca = {
73 sizeof(struct wdc_isa_softc), wdc_isa_probe, wdc_isa_attach
74 };
75
76 static void wdc_isa_dma_setup __P((void *));
77 static void wdc_isa_dma_start __P((void *, void *, size_t, int));
78 static void wdc_isa_dma_finish __P((void *));
79
80 int
81 wdc_isa_probe(parent, match, aux)
82 struct device *parent;
83 #ifdef __BROKEN_INDIRECT_CONFIG
84 void *match;
85 #else
86 struct cfdata *match;
87 #endif
88 void *aux;
89 {
90 #if 0 /* XXX memset */
91 struct wdc_attachment_data ad = { 0 };
92 #else /* XXX memset */
93 struct wdc_attachment_data ad;
94 #endif /* XXX memset */
95 struct isa_attach_args *ia = aux;
96 int result = 0;
97
98 #if 0 /* XXX memset */
99 #else /* XXX memset */
100 bzero(&ad, sizeof ad);
101 #endif /* XXX memset */
102 ad.iot = ia->ia_iot;
103 if (bus_space_map(ad.iot, ia->ia_iobase, WDC_ISA_REG_NPORTS, 0,
104 &ad.ioh))
105 goto out;
106
107 ad.auxiot = ia->ia_iot;
108 if (bus_space_map(ad.auxiot, ia->ia_iobase + WDC_ISA_AUXREG_OFFSET,
109 WDC_ISA_AUXREG_NPORTS, 0, &ad.auxioh))
110 goto outunmap;
111
112 result = wdcprobe(&ad);
113 if (result) {
114 ia->ia_iosize = WDC_ISA_REG_NPORTS;
115 ia->ia_msize = 0;
116 }
117
118 bus_space_unmap(ad.auxiot, ad.auxioh, WDC_ISA_AUXREG_NPORTS);
119 outunmap:
120 bus_space_unmap(ad.iot, ad.ioh, WDC_ISA_REG_NPORTS);
121 out:
122 return (result);
123 }
124
125 void
126 wdc_isa_attach(parent, self, aux)
127 struct device *parent, *self;
128 void *aux;
129 {
130 struct wdc_isa_softc *sc = (struct wdc_isa_softc *)self;
131 struct isa_attach_args *ia = aux;
132
133 bzero(&sc->sc_ad, sizeof sc->sc_ad);
134 sc->sc_ad.iot = ia->ia_iot;
135 sc->sc_ad.auxiot = ia->ia_iot;
136 if (bus_space_map(sc->sc_ad.iot, ia->ia_iobase, WDC_ISA_REG_NPORTS, 0,
137 &sc->sc_ad.ioh) ||
138 bus_space_map(sc->sc_ad.auxiot,
139 ia->ia_iobase + WDC_ISA_AUXREG_OFFSET, WDC_ISA_AUXREG_NPORTS,
140 0, &sc->sc_ad.auxioh)) {
141 printf(": couldn't map registers\n");
142 panic("wdc_isa_attach: couldn't map registers\n");
143 }
144
145 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
146 IPL_BIO, wdcintr, sc);
147
148 if (ia->ia_drq != DRQUNK) {
149 sc->sc_drq = ia->ia_drq;
150
151 sc->sc_ad.cap |= WDC_CAPABILITY_DMA;
152 sc->sc_ad.dma_setup = &wdc_isa_dma_setup;
153 sc->sc_ad.dma_start = &wdc_isa_dma_start;
154 sc->sc_ad.dma_finish = &wdc_isa_dma_finish;
155 }
156
157 wdcattach(&sc->sc_wdcdev, &sc->sc_ad);
158 }
159
160 static void
161 wdc_isa_dma_setup(scv)
162 void *scv;
163 {
164 struct wdc_isa_softc *sc = scv;
165
166 if (isa_dmamap_create(sc->sc_wdcdev.sc_dev.dv_parent, sc->sc_drq,
167 MAXPHYS, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
168 printf("%s: can't create map for drq %d\n",
169 sc->sc_wdcdev.sc_dev.dv_xname, sc->sc_drq);
170 sc->sc_ad.cap &= ~WDC_CAPABILITY_DMA;
171 }
172 }
173
174 static void
175 wdc_isa_dma_start(scv, buf, size, read)
176 void *scv, *buf;
177 size_t size;
178 int read;
179 {
180 struct wdc_isa_softc *sc = scv;
181
182 isa_dmastart(sc->sc_wdcdev.sc_dev.dv_parent, sc->sc_drq, buf,
183 size, NULL, read ? DMAMODE_READ : DMAMODE_WRITE,
184 BUS_DMA_NOWAIT);
185 }
186
187 static void
188 wdc_isa_dma_finish(scv)
189 void *scv;
190 {
191 struct wdc_isa_softc *sc = scv;
192
193 isa_dmadone(sc->sc_wdcdev.sc_dev.dv_parent, sc->sc_drq);
194 }
195