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 */
58static int	claim_hw __P((void *, int));
59static void	free_hw __P((void *));
60
61struct wdc_mb_softc {
62	struct wdc_softc sc_wdcdev;
63	struct wdc_attachment_data sc_ad;
64	void	*sc_ih;
65};
66
67int	wdc_mb_probe	__P((struct device *, struct cfdata *, void *));
68void	wdc_mb_attach	__P((struct device *, struct device *, void *));
69
70struct cfattach wdc_mb_ca = {
71	sizeof(struct wdc_mb_softc), wdc_mb_probe, wdc_mb_attach
72};
73
74int
75wdc_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
131void
132wdc_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 */
182static int	wd_lock;
183
184static int
185claim_hw(softc, maysleep)
186void *softc;
187int  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
206static void
207free_hw(softc)
208void *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