1 /* $NetBSD: osiop_pcctwo.c,v 1.13 2008/04/28 20:23:54 martin Exp $ */
4 * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Steve C. Woodford.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Front-end attachment code for the ncr53c710 SCSI controller
34 * on mvme68k/mvme88k boards.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: osiop_pcctwo.c,v 1.13 2008/04/28 20:23:54 martin Exp $");
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
45 #include <dev/scsipi/scsi_all.h>
46 #include <dev/scsipi/scsipi_all.h>
47 #include <dev/scsipi/scsiconf.h>
51 #include <machine/autoconf.h>
53 #include <dev/ic/osiopreg.h>
54 #include <dev/ic/osiopvar.h>
56 #include <dev/mvme/pcctworeg.h>
57 #include <dev/mvme/pcctwovar.h>
61 int osiop_pcctwo_match(device_t
, cfdata_t
, void *);
62 void osiop_pcctwo_attach(device_t
, device_t
, void *);
64 struct osiop_pcctwo_softc
{
65 struct osiop_softc sc_osiop
;
66 struct evcnt sc_evcnt
;
69 CFATTACH_DECL_NEW(osiop_pcctwo
, sizeof(struct osiop_pcctwo_softc
),
70 osiop_pcctwo_match
, osiop_pcctwo_attach
, NULL
, NULL
);
72 static int osiop_pcctwo_intr(void *);
76 osiop_pcctwo_match(device_t parent
, cfdata_t cf
, void *args
)
78 struct pcctwo_attach_args
*pa
;
79 bus_space_handle_t bsh
;
84 if (strcmp(pa
->pa_name
, osiop_cd
.cd_name
))
88 * See if the SCSI controller is responding.
90 if (bus_space_map(pa
->pa_bust
, pa
->pa_offset
, OSIOP_NREGS
, 0, &bsh
))
92 rv
= bus_space_peek_1(pa
->pa_bust
, bsh
, OSIOP_CTEST8
, NULL
);
93 bus_space_unmap(pa
->pa_bust
, bsh
, OSIOP_NREGS
);
97 pa
->pa_ipl
= cf
->pcctwocf_ipl
;
104 osiop_pcctwo_attach(device_t parent
, device_t self
, void *aux
)
106 struct pcctwo_attach_args
*pa
;
107 struct osiop_pcctwo_softc
*sc
;
110 sc
= device_private(self
);
114 * On the '17x the siop's clock is the same as the CPU clock.
115 * On the other boards, the siop runs at twice the CPU clock.
116 * Also, the 17x cannot do proper bus-snooping (the 68060 is
117 * lame in this repspect) so don't enable it on that board.
120 if (machineid
== MVME_172
|| machineid
== MVME_177
) {
125 ctest7
= OSIOP_CTEST7_SC0
;
128 #error Set up siop clock speed for mvme187
131 sc
->sc_osiop
.sc_dev
= self
;
132 sc
->sc_osiop
.sc_bst
= pa
->pa_bust
;
133 sc
->sc_osiop
.sc_dmat
= pa
->pa_dmat
;
134 (void) bus_space_map(sc
->sc_osiop
.sc_bst
, pa
->pa_offset
, OSIOP_NREGS
,
135 0, &sc
->sc_osiop
.sc_reg
);
137 sc
->sc_osiop
.sc_clock_freq
= clk
;
138 sc
->sc_osiop
.sc_ctest7
= ctest7
| OSIOP_CTEST7_TT1
;
139 sc
->sc_osiop
.sc_dcntl
= OSIOP_DCNTL_EA
;
140 sc
->sc_osiop
.sc_id
= 7; /* XXX: Could use NVRAM setting */
142 /* Attach main MI driver */
143 osiop_attach(&sc
->sc_osiop
);
145 /* Register the event counter */
146 evcnt_attach_dynamic(&sc
->sc_evcnt
, EVCNT_TYPE_INTR
,
147 pcctwointr_evcnt(pa
->pa_ipl
), "disk",
148 device_xname(sc
->sc_osiop
.sc_dev
));
150 /* Hook the chip's interrupt */
151 pcctwointr_establish(PCCTWOV_SCSI
, osiop_pcctwo_intr
, pa
->pa_ipl
, sc
,
156 osiop_pcctwo_intr(void *arg
)
158 struct osiop_pcctwo_softc
*sc
= arg
;
162 * Catch any errors which can happen when the SIOP is
163 * local bus master...
165 istat
= pcc2_reg_read(sys_pcctwo
, PCC2REG_SCSI_ERR_STATUS
);
166 if ((istat
& PCCTWO_ERR_SR_MASK
) != 0) {
167 printf("%s: Local bus error: 0x%02x\n",
168 device_xname(sc
->sc_osiop
.sc_dev
), istat
);
169 istat
|= PCCTWO_ERR_SR_SCLR
;
170 pcc2_reg_write(sys_pcctwo
, PCC2REG_SCSI_ERR_STATUS
, istat
);
173 /* This is potentially nasty, since the IRQ is level triggered... */
174 if (sc
->sc_osiop
.sc_flags
& OSIOP_INTSOFF
)
177 istat
= osiop_read_1(&sc
->sc_osiop
, OSIOP_ISTAT
);
179 if ((istat
& (OSIOP_ISTAT_SIP
| OSIOP_ISTAT_DIP
)) == 0)
182 /* Save interrupt details for the back-end interrupt handler */
183 sc
->sc_osiop
.sc_sstat0
= osiop_read_1(&sc
->sc_osiop
, OSIOP_SSTAT0
);
184 sc
->sc_osiop
.sc_istat
= istat
;
185 sc
->sc_osiop
.sc_dstat
= osiop_read_1(&sc
->sc_osiop
, OSIOP_DSTAT
);
187 /* Deal with the interrupt */
188 osiop_intr(&sc
->sc_osiop
);