1 /* $NetBSD: wdc_obio.c,v 1.22 2006/10/05 09:34:52 tsutsui Exp $ */
4 * Copyright (c) 2002 Takeshi Shibagaki All rights reserved.
6 * mac68k OBIO-IDE attachment created by Takeshi Shibagaki
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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 Charles M. Hannum.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: wdc_obio.c,v 1.22 2006/10/05 09:34:52 tsutsui Exp $");
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/callout.h>
45 #include <machine/bus.h>
46 #include <machine/intr.h>
47 #include <machine/cpu.h>
48 #include <machine/viareg.h>
50 #include <mac68k/obio/obiovar.h>
52 #include <dev/ata/atavar.h>
53 #include <dev/ic/wdcvar.h>
55 #define WDC_OBIO_REG_NPORTS 0x40
56 #define WDC_OBIO_AUXREG_OFFSET 0x38
57 #define WDC_OBIO_AUXREG_NPORTS 1
58 #define WDC_OBIO_ISR_OFFSET 0x101
59 #define WDC_OBIO_ISR_NPORTS 1
61 static u_long IDEBase
= 0x50f1a000;
64 * XXX This code currently doesn't even try to allow 32-bit data port use.
67 struct wdc_obio_softc
{
68 struct wdc_softc sc_wdcdev
;
69 struct ata_channel
*sc_chanlist
[1];
70 struct ata_channel sc_channel
;
71 struct ata_queue sc_chqueue
;
72 struct wdc_regs sc_wdc_regs
;
76 int wdc_obio_match(device_t
, cfdata_t
, void *);
77 void wdc_obio_attach(device_t
, device_t
, void *);
78 void wdc_obio_intr(void *);
80 CFATTACH_DECL_NEW(wdc_obio
, sizeof(struct wdc_obio_softc
),
81 wdc_obio_match
, wdc_obio_attach
, NULL
, NULL
);
83 static bus_space_tag_t wdc_obio_isr_tag
;
84 static bus_space_handle_t wdc_obio_isr_hdl
;
85 static struct ata_channel
*ch_sc
;
88 wdc_obio_match(device_t parent
, cfdata_t match
, void *aux
)
90 struct obio_attach_args
*oa
= (struct obio_attach_args
*) aux
;
91 struct ata_channel ch
;
94 static int wdc_matched
= 0;
97 memset(&wdc
, 0, sizeof(wdc
));
98 memset(&ch
, 0, sizeof(ch
));
99 ch
.ch_atac
= &wdc
.sc_atac
;
102 switch (current_mac_model
->machineid
) {
105 case MACH_MACPB190CS
:
108 wdr
.cmd_iot
= wdr
.ctl_iot
= oa
->oa_tag
;
110 if (bus_space_map(wdr
.cmd_iot
, IDEBase
, WDC_OBIO_REG_NPORTS
,
111 0, &wdr
.cmd_baseioh
))
114 mac68k_bus_space_handle_swapped(wdr
.cmd_iot
, &wdr
.cmd_baseioh
);
116 for (i
= 0; i
< WDC_NREG
; i
++) {
117 if (bus_space_subregion(wdr
.cmd_iot
, wdr
.cmd_baseioh
,
118 4 * i
, 4, &wdr
.cmd_iohs
[i
]) != 0) {
122 wdc_init_shadow_regs(&ch
);
125 if (bus_space_subregion(wdr
.cmd_iot
, wdr
.cmd_baseioh
,
126 WDC_OBIO_AUXREG_OFFSET
,
127 WDC_OBIO_AUXREG_NPORTS
,
131 result
= wdcprobe(&ch
);
133 bus_space_unmap(wdr
.cmd_iot
, wdr
.cmd_baseioh
, WDC_OBIO_REG_NPORTS
);
143 wdc_obio_attach(device_t parent
, device_t self
, void *aux
)
145 struct wdc_obio_softc
*sc
= device_private(self
);
146 struct wdc_regs
*wdr
;
147 struct obio_attach_args
*oa
= aux
;
148 struct ata_channel
*chp
= &sc
->sc_channel
;
151 sc
->sc_wdcdev
.sc_atac
.atac_dev
= self
;
152 sc
->sc_wdcdev
.regs
= wdr
= &sc
->sc_wdc_regs
;
154 oa
->oa_addr
= IDEBase
;
155 wdr
->cmd_iot
= wdr
->ctl_iot
= oa
->oa_tag
;
157 if (bus_space_map(wdr
->cmd_iot
, oa
->oa_addr
,
158 WDC_OBIO_REG_NPORTS
, 0, &wdr
->cmd_baseioh
)) {
159 aprint_error_dev(self
, "couldn't map registers\n");
163 mac68k_bus_space_handle_swapped(wdr
->cmd_iot
,
166 for (i
= 0; i
< WDC_NREG
; i
++) {
167 if (bus_space_subregion(wdr
->cmd_iot
,
168 wdr
->cmd_baseioh
, 4 * i
, 4,
169 &wdr
->cmd_iohs
[i
]) != 0) {
170 aprint_error_dev(self
,
171 "unable to subregion control register\n");
176 if (bus_space_subregion(wdr
->cmd_iot
,
178 WDC_OBIO_AUXREG_OFFSET
, WDC_OBIO_AUXREG_NPORTS
,
180 aprint_error_dev(self
, "unable to subregion aux register\n");
184 wdc_obio_isr_tag
= oa
->oa_tag
;
186 if (bus_space_map(wdc_obio_isr_tag
,
187 oa
->oa_addr
+WDC_OBIO_ISR_OFFSET
,
188 WDC_OBIO_ISR_NPORTS
, 0, &wdc_obio_isr_hdl
)) {
189 aprint_error_dev(self
, " couldn't map intr status register\n");
193 switch (current_mac_model
->machineid
) {
197 * Quadra/Performa IDE generates pseudo Nubus intr at slot F
199 aprint_normal(" (Quadra/Performa series IDE interface)");
201 add_nubus_intr(0xf, (void (*)(void*))wdc_obio_intr
, (void *)sc
);
206 case MACH_MACPB190CS
:
208 * PowerBook IDE generates pseudo NuBus intr at slot C
210 aprint_normal(" (PowerBook series IDE interface)");
212 add_nubus_intr(0xc, (void (*)(void*))wdc_obio_intr
, (void *)sc
);
218 if (device_cfdata(sc
->sc_wdcdev
.sc_atac
.atac_dev
)->cf_flags
&
220 sc
->sc_wdcdev
.sc_atac
.atac_cap
|= ATAC_CAP_NOIRQ
;
221 sc
->sc_wdcdev
.sc_atac
.atac_cap
|= ATAC_CAP_DATA16
;
222 sc
->sc_wdcdev
.sc_atac
.atac_pio_cap
= 0;
223 sc
->sc_chanlist
[0] = chp
;
224 sc
->sc_wdcdev
.sc_atac
.atac_channels
= sc
->sc_chanlist
;
225 sc
->sc_wdcdev
.sc_atac
.atac_nchannels
= 1;
227 chp
->ch_atac
= &sc
->sc_wdcdev
.sc_atac
;
228 chp
->ch_queue
= &sc
->sc_chqueue
;
230 wdc_init_shadow_regs(chp
);
238 wdc_obio_intr(void *arg
)
240 unsigned char status
;
242 status
= bus_space_read_1(wdc_obio_isr_tag
,
243 wdc_obio_isr_hdl
, 0);
246 bus_space_write_1(wdc_obio_isr_tag
,
247 wdc_obio_isr_hdl
, 0, status
&~0x20);