1 /* $NetBSD: siop_gsc.c,v 1.10 2009/05/15 17:55:44 tsutsui Exp $ */
3 /* $OpenBSD: siop_gsc.c,v 1.4 2007/08/23 21:01:22 kettenis Exp $ */
6 * Copyright (c) 2007 Mark Kettenis
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: siop_gsc.c,v 1.10 2009/05/15 17:55:44 tsutsui Exp $");
24 #include <sys/param.h>
25 #include <sys/device.h>
26 #include <sys/systm.h>
28 #include <uvm/uvm_extern.h>
30 #include <machine/autoconf.h>
31 #include <machine/bus.h>
32 #include <machine/iomod.h>
34 #include <dev/scsipi/scsi_all.h>
35 #include <dev/scsipi/scsipi_all.h>
36 #include <dev/scsipi/scsiconf.h>
38 #include <dev/ic/siopreg.h>
39 #include <dev/ic/siopvar_common.h>
40 #include <dev/ic/siopvar.h>
42 #include <hp700/dev/cpudevs.h>
43 #include <hp700/gsc/gscbusvar.h>
45 #define SIOP_GSC_RESET 0x0000
46 #define SIOP_GSC_OFFSET 0x0100
48 int siop_gsc_match(device_t
, cfdata_t
, void *);
49 void siop_gsc_attach(device_t
, device_t
, void *);
50 int siop_gsc_intr(void *);
51 void siop_gsc_reset(struct siop_common_softc
*);
53 uint8_t siop_gsc_r1(void *, bus_space_handle_t
, bus_size_t
);
54 uint16_t siop_gsc_r2(void *, bus_space_handle_t
, bus_size_t
);
55 void siop_gsc_w1(void *, bus_space_handle_t
, bus_size_t
, uint8_t);
56 void siop_gsc_w2(void *, bus_space_handle_t
, bus_size_t
, uint16_t);
58 struct siop_gsc_softc
{
59 struct siop_softc sc_siop
;
60 bus_space_tag_t sc_iot
;
61 bus_space_handle_t sc_ioh
;
62 struct hppa_bus_space_tag sc_bustag
;
65 CFATTACH_DECL_NEW(siop_gsc
, sizeof(struct siop_gsc_softc
),
66 siop_gsc_match
, siop_gsc_attach
, NULL
, NULL
);
69 siop_gsc_match(device_t parent
, cfdata_t match
, void *aux
)
71 struct gsc_attach_args
*ga
= aux
;
73 if (ga
->ga_type
.iodc_type
!= HPPA_TYPE_FIO
||
74 ga
->ga_type
.iodc_sv_model
!= HPPA_FIO_FWSCSI
)
81 siop_gsc_attach(device_t parent
, device_t self
, void *aux
)
83 struct siop_gsc_softc
*gsc
= device_private(self
);
84 struct siop_softc
*sc
= &gsc
->sc_siop
;
85 struct gsc_attach_args
*ga
= aux
;
87 sc
->sc_c
.sc_dev
= self
;
88 gsc
->sc_iot
= ga
->ga_iot
;
89 if (bus_space_map(gsc
->sc_iot
, ga
->ga_hpa
,
90 IOMOD_HPASIZE
, 0, &gsc
->sc_ioh
)) {
91 aprint_error(": can't map io space\n");
95 gsc
->sc_bustag
= *gsc
->sc_iot
;
96 gsc
->sc_bustag
.hbt_r1
= siop_gsc_r1
;
97 gsc
->sc_bustag
.hbt_r2
= siop_gsc_r2
;
98 gsc
->sc_bustag
.hbt_w1
= siop_gsc_w1
;
99 gsc
->sc_bustag
.hbt_w2
= siop_gsc_w2
;
101 sc
->sc_c
.features
= SF_CHIP_PF
| SF_CHIP_BE
| SF_BUS_WIDE
;
102 sc
->sc_c
.maxburst
= 4;
104 sc
->sc_c
.clock_div
= 3;
105 sc
->sc_c
.clock_period
= 250;
106 sc
->sc_c
.ram_size
= 0;
108 sc
->sc_c
.sc_reset
= siop_gsc_reset
;
109 sc
->sc_c
.sc_dmat
= ga
->ga_dmatag
;
111 sc
->sc_c
.sc_rt
= &gsc
->sc_bustag
;
112 bus_space_subregion(gsc
->sc_iot
, gsc
->sc_ioh
, SIOP_GSC_OFFSET
,
113 IOMOD_HPASIZE
- SIOP_GSC_OFFSET
, &sc
->sc_c
.sc_rh
);
116 * Reset the SCSI subsystem.
118 bus_space_write_1(gsc
->sc_iot
, gsc
->sc_ioh
, SIOP_GSC_RESET
, 0);
120 siop_gsc_reset(&sc
->sc_c
);
122 aprint_normal(": NCR53C720 rev %d\n", bus_space_read_1(sc
->sc_c
.sc_rt
,
123 sc
->sc_c
.sc_rh
, SIOP_CTEST3
) >> 4);
127 (void)hp700_intr_establish(self
, IPL_BIO
,
128 siop_intr
, sc
, ga
->ga_int_reg
, ga
->ga_irq
);
133 siop_gsc_reset(struct siop_common_softc
*sc
)
135 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_DCNTL
, DCNTL_EA
);
136 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_CTEST0
, CTEST0_EHP
);
137 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_CTEST4
, CTEST4_MUX
);
139 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_STIME0
,
140 (0xc << STIME0_SEL_SHIFT
));
144 siop_gsc_r1(void *v
, bus_space_handle_t h
, bus_size_t o
)
146 return *(volatile uint8_t *)(h
+ (o
^ 3));
150 siop_gsc_r2(void *v
, bus_space_handle_t h
, bus_size_t o
)
152 if (o
== SIOP_SIST0
) {
155 reg
= siop_gsc_r1(v
, h
, SIOP_SIST0
);
156 reg
|= siop_gsc_r1(v
, h
, SIOP_SIST1
) << 8;
159 return *(volatile uint16_t *)(h
+ (o
^ 2));
163 siop_gsc_w1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t vv
)
165 *(volatile uint8_t *)(h
+ (o
^ 3)) = vv
;
169 siop_gsc_w2(void *v
, bus_space_handle_t h
, bus_size_t o
, uint16_t vv
)
171 *(volatile uint16_t *)(h
+ (o
^ 2)) = vv
;