afsc.c revision 1.18
1/*	$NetBSD: afsc.c,v 1.18 1996/10/13 03:06:45 christos Exp $	*/
2
3/*
4 * Copyright (c) 1994 Michael L. Hitch
5 * Copyright (c) 1982, 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 *	@(#)dma.c
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/kernel.h>
42#include <sys/device.h>
43#include <scsi/scsi_all.h>
44#include <scsi/scsiconf.h>
45#include <machine/cpu.h>
46#include <amiga/amiga/custom.h>
47#include <amiga/amiga/cc.h>
48#include <amiga/amiga/device.h>
49#include <amiga/amiga/isr.h>
50#include <amiga/dev/siopreg.h>
51#include <amiga/dev/siopvar.h>
52#include <amiga/dev/zbusvar.h>
53
54void afscattach __P((struct device *, struct device *, void *));
55int afscmatch __P((struct device *, void *, void *));
56int afsc_dmaintr __P((void *));
57#ifdef DEBUG
58void afsc_dump __P((void));
59#endif
60
61struct scsi_adapter afsc_scsiswitch = {
62	siop_scsicmd,
63	siop_minphys,
64	0,			/* no lun support */
65	0,			/* no lun support */
66};
67
68struct scsi_device afsc_scsidev = {
69	NULL,		/* use default error handler */
70	NULL,		/* do not have a start functio */
71	NULL,		/* have no async handler */
72	NULL,		/* Use default done routine */
73};
74
75
76#ifdef DEBUG
77#endif
78
79struct cfattach afsc_ca = {
80	sizeof(struct siop_softc), afscmatch, afscattach
81};
82
83struct cfdriver afsc_cd = {
84	NULL, "afsc", DV_DULL, NULL, 0
85};
86
87struct cfattach aftsc_ca = {
88	sizeof(struct siop_softc), afscmatch, afscattach
89};
90
91struct cfdriver aftsc_cd = {
92	NULL, "aftsc", DV_DULL, NULL, 0
93};
94
95/*
96 * if we are a Commodore Amiga A4091 or possibly an A4000T
97 */
98int
99afscmatch(pdp, match, auxp)
100	struct device *pdp;
101	void *match, *auxp;
102{
103	struct zbus_args *zap;
104	siop_regmap_p rp;
105	u_long temp, scratch;
106
107	zap = auxp;
108	if (zap->manid == 514 && zap->prodid == 84)
109		return(1);		/* It's an A4091 SCSI card */
110	if (!is_a4000() || !matchname(auxp, "afsc"))
111		return(0);		/* Not on an A4000 or not A4000T SCSI */
112	rp = ztwomap(0xdd0040);
113	if (badaddr((caddr_t)&rp->siop_scratch) || badaddr((caddr_t)&rp->siop_temp)) {
114		return(0);
115	}
116	scratch = rp->siop_scratch;
117	temp = rp->siop_temp;
118	rp->siop_scratch = 0xdeadbeef;
119	rp->siop_temp = 0xaaaa5555;
120	if (rp->siop_scratch != 0xdeadbeef || rp->siop_temp != 0xaaaa5555)
121		return(0);
122	rp->siop_scratch = scratch;
123	rp->siop_temp = temp;
124	if (rp->siop_scratch != scratch || rp->siop_temp != temp)
125		return(0);
126	return(1);
127}
128
129void
130afscattach(pdp, dp, auxp)
131	struct device *pdp, *dp;
132	void *auxp;
133{
134	struct siop_softc *sc;
135	struct zbus_args *zap;
136	siop_regmap_p rp;
137
138	printf("\n");
139
140	zap = auxp;
141
142	sc = (struct siop_softc *)dp;
143	if (zap->manid == 514 && zap->prodid == 84)
144		sc->sc_siopp = rp = zap->va + 0x00800000;
145	else
146		sc->sc_siopp = rp = ztwomap(0xdd0040);
147
148	/*
149	 * CTEST7 = 80 [disable burst]
150	 */
151	sc->sc_clock_freq = 50;		/* Clock = 50Mhz */
152	sc->sc_ctest7 = SIOP_CTEST7_CDIS;
153	sc->sc_dcntl = SIOP_DCNTL_EA;
154
155	sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
156	sc->sc_link.adapter_softc = sc;
157	sc->sc_link.adapter_target = 7;
158	sc->sc_link.adapter = &afsc_scsiswitch;
159	sc->sc_link.device = &afsc_scsidev;
160	sc->sc_link.openings = 2;
161
162	siopinitialize(sc);
163
164	sc->sc_isr.isr_intr = afsc_dmaintr;
165	sc->sc_isr.isr_arg = sc;
166	sc->sc_isr.isr_ipl = 2;
167	add_isr (&sc->sc_isr);
168
169	/*
170	 * attach all scsi units on us
171	 */
172	config_found(dp, &sc->sc_link, scsiprint);
173}
174
175int
176afsc_dmaintr(arg)
177	void *arg;
178{
179	struct siop_softc *sc = arg;
180	siop_regmap_p rp;
181	u_char istat;
182
183	if (sc->sc_flags & SIOP_INTSOFF)
184		return (0);	/* interrupts are not active */
185	rp = sc->sc_siopp;
186	istat = rp->siop_istat;
187	if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0)
188		return(0);
189	/*
190	 * save interrupt status, DMA status, and SCSI status 0
191	 * (may need to deal with stacked interrupts?)
192	 */
193	sc->sc_sstat0 = rp->siop_sstat0;
194	sc->sc_istat = istat;
195	sc->sc_dstat = rp->siop_dstat;
196	siopintr(sc);
197	return(1);
198}
199
200#ifdef DEBUG
201void
202afsc_dump()
203{
204	int i;
205
206	for (i = 0; i < afsc_cd.cd_ndevs; ++i)
207		if (afsc_cd.cd_devs[i])
208			siop_dump(afsc_cd.cd_devs[i]);
209}
210#endif
211