wdc_mb.c revision 1.1 1 /* $NetBSD: wdc_mb.c,v 1.1 1998/04/10 10:37:12 leo 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/cpu.h>
43 #include <machine/bus.h>
44 #include <machine/iomap.h>
45 #include <machine/mfp.h>
46 #include <machine/dma.h>
47
48 #include <dev/ic/wdcvar.h>
49
50 #include <m68k/asm_single.h>
51
52 #include <atari/dev/ym2149reg.h>
53 #include <atari/atari/device.h>
54
55 /*
56 * XXX This code currently doesn't even try to allow 32-bit data port use.
57 */
58 static int claim_hw __P((void *, int));
59 static void free_hw __P((void *));
60
61 struct wdc_mb_softc {
62 struct wdc_softc sc_wdcdev;
63 struct wdc_attachment_data sc_ad;
64 void *sc_ih;
65 };
66
67 int wdc_mb_probe __P((struct device *, struct cfdata *, void *));
68 void wdc_mb_attach __P((struct device *, struct device *, void *));
69
70 struct cfattach wdc_mb_ca = {
71 sizeof(struct wdc_mb_softc), wdc_mb_probe, wdc_mb_attach
72 };
73
74 int
75 wdc_mb_probe(parent, cfp, aux)
76 struct device *parent;
77 struct cfdata *cfp;
78 void *aux;
79 {
80 #if 0 /* XXX memset */
81 struct wdc_attachment_data ad = { 0 };
82 #else /* XXX memset */
83 struct wdc_attachment_data ad;
84 #endif /* XXX memset */
85 int result = 0;
86 u_char sv_ierb;
87
88 #if 0 /* XXX memset */
89 #else /* XXX memset */
90 bzero(&ad, sizeof ad);
91 #endif /* XXX memset */
92
93 if ((machineid & ATARI_TT) || strcmp("wdc", aux) || cfp->cf_unit != 0)
94 return 0;
95 if (!atari_realconfig)
96 return 0;
97
98 ad.iot = ad.auxiot = mb_alloc_bus_space_tag();
99 if (ad.iot == NULL)
100 return 0;
101 ad.iot->stride = 2;
102 ad.iot->wo_1 = 1;
103
104 if (bus_space_map(ad.iot, 0xfff00000, 0x40, 0, &ad.ioh))
105 return 0;
106 if (bus_space_subregion(ad.iot, ad.ioh, 0x38, 1, &ad.auxioh))
107 return 0;
108
109 /*
110 * Make sure IDE interrupts are disabled during probing.
111 */
112 sv_ierb = MFP->mf_ierb;
113 MFP->mf_ierb &= ~IB_DINT;
114
115 /*
116 * Make sure that IDE is turned on on the Falcon.
117 */
118 if (machineid & ATARI_FALCON)
119 ym2149_ser2(0);
120
121 result = wdcprobe(&ad);
122
123 MFP->mf_ierb = sv_ierb;
124
125 bus_space_unmap(ad.iot, ad.ioh, 0x40);
126 mb_free_bus_space_tag(ad.iot);
127
128 return (result);
129 }
130
131 void
132 wdc_mb_attach(parent, self, aux)
133 struct device *parent, *self;
134 void *aux;
135 {
136 struct wdc_mb_softc *sc = (void *)self;
137
138 printf("\n");
139
140 sc->sc_ad.iot = sc->sc_ad.auxiot = mb_alloc_bus_space_tag();
141 sc->sc_ad.iot->stride = 2;
142 sc->sc_ad.iot->wo_1 = 1;
143 if (bus_space_map(sc->sc_ad.iot, 0xfff00000, 0x40, 0,
144 &sc->sc_ad.ioh)) {
145 printf("%s: couldn't map registers\n",
146 sc->sc_wdcdev.sc_dev.dv_xname);
147 return;
148 }
149 if (bus_space_subregion(sc->sc_ad.iot, sc->sc_ad.ioh, 0x38, 1,
150 &sc->sc_ad.auxioh))
151 return;
152
153 /*
154 * Play a nasty trick here. Normally we only manipulate the
155 * interrupt *mask*. However to defeat wd_get_parms(), we
156 * disable the interrupts here using the *enable* register.
157 */
158 MFP->mf_ierb &= ~IB_DINT;
159
160 /*
161 * XXX: Is this true on all atari's??
162 */
163 sc->sc_wdcdev.sc_flags |= WDCF_SINGLE;
164
165 sc->sc_ad.cap |= WDC_CAPABILITY_HWLOCK;
166 sc->sc_ad.claim_hw = &claim_hw;
167 sc->sc_ad.free_hw = &free_hw;
168
169 wdcattach(&sc->sc_wdcdev, &sc->sc_ad);
170
171 /*
172 * Setup & enable disk related interrupts.
173 */
174 MFP->mf_ierb |= IB_DINT;
175 MFP->mf_iprb &= ~IB_DINT;
176 MFP->mf_imrb |= IB_DINT;
177 }
178
179 /*
180 * Hardware locking
181 */
182 static int wd_lock;
183
184 static int
185 claim_hw(softc, maysleep)
186 void *softc;
187 int maysleep;
188 {
189 void wdcrestart __P((void *));
190
191 if (wd_lock != DMA_LOCK_GRANT) {
192 if (wd_lock == DMA_LOCK_REQ) {
193 /*
194 * ST_DMA access is being claimed.
195 */
196 return 0;
197 }
198 if (!st_dmagrab((dma_farg)wdcintr,
199 (dma_farg)(maysleep ? NULL : wdcrestart), softc,
200 &wd_lock, 1))
201 return 0;
202 }
203 return 1;
204 }
205
206 static void
207 free_hw(softc)
208 void *softc;
209 {
210 /*
211 * Flush pending interrupts before giving-up lock
212 */
213 single_inst_bclr_b(MFP->mf_iprb, IB_DINT);
214
215 /*
216 * Only free the lock on a Falcon. On the Hades, keep it.
217 */
218 /* if (machineid & ATARI_FALCON) */
219 st_dmafree(softc, &wd_lock);
220 }
221