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