1 /* $NetBSD: asc.c,v 1.15 2008/06/12 23:22:36 cegger Exp $ */
4 * Copyright (c) 2001 Richard Earnshaw
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the company nor the name of the author may be used to
13 * endorse or promote products derived from this software without specific
14 * prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * POSSIBILITY OF SUCH DAMAGE.
28 * Copyright (c) 1982, 1990 The Regents of the University of California.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * Copyright (c) 1996 Mark Brinicombe
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89 * Driver for the Acorn SCSI card using the SBIC (WD33C93A) generic driver
91 * Thanks to Acorn for supplying programming information on this card.
94 /* #define ASC_DMAMAP_DEBUG */
99 #include <sys/param.h>
101 __KERNEL_RCSID(0, "$NetBSD: asc.c,v 1.15 2008/06/12 23:22:36 cegger Exp $");
103 #include <sys/systm.h>
104 #include <sys/kernel.h>
105 #include <sys/device.h>
108 #include <uvm/uvm_extern.h>
110 #include <machine/bus.h>
111 #include <machine/intr.h>
112 #include <machine/bootconfig.h> /* asc_poll */
114 #include <dev/scsipi/scsi_all.h>
115 #include <dev/scsipi/scsipi_all.h>
116 #include <dev/scsipi/scsiconf.h>
118 #include <arm/arm32/katelib.h>
120 #include <dev/podulebus/podules.h>
121 #include <dev/podulebus/powerromreg.h>
123 #include <acorn32/podulebus/podulebus.h>
124 #include <acorn32/podulebus/sbicreg.h>
125 #include <acorn32/podulebus/sbicvar.h>
126 #include <acorn32/podulebus/ascreg.h>
127 #include <acorn32/podulebus/ascvar.h>
129 void ascattach (struct device
*, struct device
*, void *);
130 int ascmatch (struct device
*, struct cfdata
*, void *);
132 void asc_enintr (struct sbic_softc
*);
134 int asc_dmaok (void *, bus_dma_tag_t
, struct sbic_acb
*);
135 int asc_dmasetup (void *, bus_dma_tag_t
, struct sbic_acb
*, int);
136 int asc_dmanext (void *, bus_dma_tag_t
, struct sbic_acb
*, int);
137 void asc_dmastop (void *, bus_dma_tag_t
, struct sbic_acb
*);
138 void asc_dmafinish (void *, bus_dma_tag_t
, struct sbic_acb
*);
140 int asc_intr (void *);
141 void asc_minphys (struct buf
*);
143 void asc_dump (void);
146 int asc_dmadebug
= 0;
149 CFATTACH_DECL(asc
, sizeof(struct asc_softc
),
150 ascmatch
, ascattach
, NULL
, NULL
);
152 extern struct cfdriver asc_cd
;
163 ascmatch(struct device
*pdp
, struct cfdata
*cf
, void *auxp
)
165 struct podule_attach_args
*pa
= (struct podule_attach_args
*)auxp
;
167 /* Look for the card */
169 /* Standard ROM, skipping the MCS card that used the same ID. */
170 if (pa
->pa_product
== PODULE_ACORN_SCSI
&&
171 strncmp(pa
->pa_podule
->description
, "MCS", 3) != 0)
175 if (pa
->pa_product
== PODULE_ALSYSTEMS_SCSI
&&
176 podulebus_initloader(pa
) == 0 &&
177 podloader_callloader(pa
, 0, 0) == PRID_ACORN_SCSI1
)
184 ascattach(struct device
*pdp
, struct device
*dp
, void *auxp
)
186 /* volatile struct sdmac *rp;*/
187 struct asc_softc
*sc
;
188 struct sbic_softc
*sbic
;
189 struct podule_attach_args
*pa
;
191 sc
= (struct asc_softc
*)dp
;
192 pa
= (struct podule_attach_args
*)auxp
;
194 if (pa
->pa_podule_number
== -1)
195 panic("Podule has disappeared !");
197 sc
->sc_podule_number
= pa
->pa_podule_number
;
198 sc
->sc_podule
= pa
->pa_podule
;
199 podules
[sc
->sc_podule_number
].attached
= 1;
201 sbic
= &sc
->sc_softc
;
203 sbic
->sc_enintr
= asc_enintr
;
204 sbic
->sc_dmaok
= asc_dmaok
;
205 sbic
->sc_dmasetup
= asc_dmasetup
;
206 sbic
->sc_dmanext
= asc_dmanext
;
207 sbic
->sc_dmastop
= asc_dmastop
;
208 sbic
->sc_dmafinish
= asc_dmafinish
;
211 sbic
->sc_sbicp
.sc_sbiciot
= pa
->pa_iot
;
212 if (bus_space_map (sbic
->sc_sbicp
.sc_sbiciot
,
213 sc
->sc_podule
->mod_base
+ ASC_SBIC
, ASC_SBIC_SPACE
, 0,
214 &sbic
->sc_sbicp
.sc_sbicioh
))
215 panic("%s: Cannot map SBIC", dp
->dv_xname
);
217 sbic
->sc_clkfreq
= sbic_clock_override
? sbic_clock_override
: 143;
219 sbic
->sc_adapter
.adapt_dev
= &sbic
->sc_dev
;
220 sbic
->sc_adapter
.adapt_nchannels
= 1;
221 sbic
->sc_adapter
.adapt_openings
= 7;
222 sbic
->sc_adapter
.adapt_max_periph
= 1;
223 sbic
->sc_adapter
.adapt_ioctl
= NULL
;
224 sbic
->sc_adapter
.adapt_minphys
= asc_minphys
;
225 sbic
->sc_adapter
.adapt_request
= sbic_scsi_request
;
227 sbic
->sc_channel
.chan_adapter
= &sbic
->sc_adapter
;
228 sbic
->sc_channel
.chan_bustype
= &scsi_bustype
;
229 sbic
->sc_channel
.chan_channel
= 0;
230 sbic
->sc_channel
.chan_ntargets
= 8;
231 sbic
->sc_channel
.chan_nluns
= 8;
232 sbic
->sc_channel
.chan_id
= 7;
234 /* Provide an override for the host id */
235 (void)get_bootconf_option(boot_args
, "asc.hostid",
236 BOOTOPT_TYPE_INT
, &sbic
->sc_channel
.chan_id
);
238 printf(": hostid=%d", sbic
->sc_channel
.chan_id
);
242 get_bootconf_option(boot_args
, "ascpoll", BOOTOPT_TYPE_BOOLEAN
,
246 sbic
->sc_adapter
.adapt_flags
|= SCSIPI_ADAPT_POLL_ONLY
;
252 sc
->sc_pagereg
= sc
->sc_podule
->fast_base
+ ASC_PAGEREG
;
253 sc
->sc_intstat
= sc
->sc_podule
->fast_base
+ ASC_INTSTATUS
;
257 WriteByte(sc
->sc_pagereg
, 0x80);
259 WriteByte(sc
->sc_pagereg
, 0x00);
264 /* If we are polling only, we don't need a interrupt handler. */
270 evcnt_attach_dynamic(&sc
->sc_intrcnt
, EVCNT_TYPE_INTR
, NULL
,
271 device_xname(dp
), "intr");
272 sc
->sc_ih
= podulebus_irq_establish(pa
->pa_ih
, IPL_BIO
,
273 asc_intr
, sc
, &sc
->sc_intrcnt
);
274 if (sc
->sc_ih
== NULL
)
275 panic("%s: Cannot claim podule IRQ", dp
->dv_xname
);
279 * attach all scsi units on us
281 config_found(dp
, &sbic
->sc_channel
, scsiprint
);
286 asc_enintr(struct sbic_softc
*sbicsc
)
288 struct asc_softc
*sc
= (struct asc_softc
*)sbicsc
;
290 sbicsc
->sc_flags
|= SBICF_INTR
;
291 WriteByte(sc
->sc_pagereg
, 0x40);
295 asc_dmaok (void *dma_h
, bus_dma_tag_t dma_t
, struct sbic_acb
*acb
)
301 asc_dmasetup (void *dma_h
, bus_dma_tag_t dma_t
, struct sbic_acb
*acb
, int dir
)
303 printf("asc_dmasetup()");
307 panic("Hit a brick wall");
313 asc_dmanext (void *dma_h
, bus_dma_tag_t dma_t
, struct sbic_acb
*acb
, int dir
)
315 printf("asc_dmanext()");
319 panic("Hit a brick wall");
325 asc_dmastop (void *dma_h
, bus_dma_tag_t dma_t
, struct sbic_acb
*acb
)
327 printf("asc_dmastop\n");
331 asc_dmafinish (void *dma_h
, bus_dma_tag_t dma_t
, struct sbic_acb
*acb
)
333 printf("asc_dmafinish\n");
340 struct sbi_softc
*sc
;
342 for (i
= 0; i
< asc_cd
.cd_ndevs
; ++i
) {
343 sc
= device_lookup_private(&asc_cd
, i
);
352 struct asc_softc
*sc
= arg
;
355 /* printf("ascintr:");*/
356 intr
= ReadByte(sc
->sc_intstat
);
357 /* printf("%02x\n", intr);*/
359 if (intr
& IS_SBIC_IRQ
)
360 sbicintr((struct sbic_softc
*)sc
);
362 return 0; /* Pass interrupt on down the chain */
366 * limit the transfer as required.
369 asc_minphys(struct buf
*bp
)
373 * We must limit the DMA xfer size
375 if (bp
->b_bcount
> MAX_DMA_LEN
) {
376 printf("asc: Reducing DMA length\n");
377 bp
->b_bcount
= MAX_DMA_LEN
;