1 /* $NetBSD: rapide.c,v 1.25 2006/10/09 21:12:44 bjh21 Exp $ */
4 * Copyright (c) 1997-1998 Mark Brinicombe
5 * Copyright (c) 1997-1998 Causality Limited
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Mark Brinicombe
18 * for the NetBSD Project.
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.
33 * Card driver and probe and attach functions to use generic IDE driver
34 * for the RapIDE podule
38 * Thanks to Chris Honey at Raymond Datalink for providing information on
39 * addressing the RapIDE podule.
40 * RapIDE32 is Copyright (C) 1995,1996 Raymond Datalink. RapIDE32 is
41 * manufactured under license by Yellowstone Educational Solutions.
45 * At present this driver only supports the Issue 2 RapIDE podule.
49 * A small amount of work is required for Issue 1 podule support.
50 * The primary differences are the register addresses.
51 * Things are eased by the fact that we can identify the card by register
52 * the same register on both issues of the podule.
53 * Once we kmnow the issue we must change all our addresses accordingly.
54 * All the control registers are mapped the same between cards.
55 * The interrupt handler needs to take note that the issue 1 card needs
56 * the interrupt to be cleared via the interrupt clear register.
57 * This means we share addresses for the mapping of the control block and
58 * thus the card driver does not need to know about the differences.
59 * The differences show up a the controller level.
60 * A structure is used to hold the information about the addressing etc.
61 * An array of these structures holds the information for the primary and
62 * secondary connectors. This needs to be extended to hold this information
63 * for both issues. Then the indexing of these structures will use the
64 * card version number.
66 * Opps just noticed a mistake. The interrupt request register is different
67 * between cards so the card level attach routine will need to consider this.
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: rapide.c,v 1.25 2006/10/09 21:12:44 bjh21 Exp $");
73 #include <sys/param.h>
74 #include <sys/systm.h>
76 #include <sys/device.h>
77 #include <sys/malloc.h>
79 #include <machine/intr.h>
80 #include <machine/io.h>
81 #include <machine/bus.h>
82 #include <machine/bootconfig.h>
83 #include <arm/iomd/iomdreg.h>
84 #include <arm/iomd/iomdvar.h>
85 #include <acorn32/podulebus/podulebus.h>
86 #include <acorn32/podulebus/rapidereg.h>
88 #include <dev/ata/atavar.h>
89 #include <dev/ic/wdcreg.h>
90 #include <dev/ic/wdcvar.h>
91 #include <dev/podulebus/podules.h>
95 * RapIDE podule device.
97 * This probes and attaches the top level RapIDE device to the podulebus.
98 * It then configures any children of the RapIDE device.
99 * The attach args specify whether it is configuring the primary or
101 * The children are expected to be wdc devices using rapide attachments.
105 * RapIDE card softc structure.
107 * Contains the device node, podule information and global information
108 * required by the driver such as the card version and the interrupt mask.
111 struct rapide_softc
{
112 struct wdc_softc sc_wdcdev
; /* common wdc definitions */
113 struct ata_channel
*sc_chanarray
[2]; /* channels definition */
114 podule_t
*sc_podule
; /* Our podule info */
115 int sc_podule_number
; /* Our podule number */
116 int sc_intr_enable_mask
; /* Global intr mask */
117 int sc_version
; /* Card version */
118 bus_space_tag_t sc_ctliot
; /* Bus tag */
119 bus_space_handle_t sc_ctlioh
; /* control handler */
120 struct rapide_channel
{
121 struct ata_channel rc_channel
; /* generic part */
122 struct ata_queue rc_chqueue
; /* channel queue */
123 irqhandler_t rc_ih
; /* interrupt handler */
124 int rc_irqmask
; /* IRQ mask for this channel */
125 } rapide_channels
[2];
126 struct wdc_regs sc_wdc_regs
[2];
129 int rapide_probe (device_t
, struct cfdata
*, void *);
130 void rapide_attach (device_t
, device_t
, void *);
131 void rapide_shutdown (void *arg
);
132 int rapide_intr (void *);
134 CFATTACH_DECL_NEW(rapide
, sizeof(struct rapide_softc
),
135 rapide_probe
, rapide_attach
, NULL
, NULL
);
138 * We have a private bus space tag.
139 * This is created by copying the podulebus tag and then replacing
140 * a couple of the transfer functions.
143 static struct bus_space rapide_bs_tag
;
145 bs_rm_4_proto(rapide
);
146 bs_wm_4_proto(rapide
);
149 * Create an array of address structures. These define the addresses and
150 * masks needed for the different channels for the card.
152 * XXX - Needs some work for issue 1 cards.
161 { PRIMARY_DRIVE_REGISTERS_OFFSET
, PRIMARY_AUX_REGISTER_OFFSET
,
162 PRIMARY_DATA_REGISTER_OFFSET
, PRIMARY_IRQ_MASK
},
163 { SECONDARY_DRIVE_REGISTERS_OFFSET
, SECONDARY_AUX_REGISTER_OFFSET
,
164 SECONDARY_DATA_REGISTER_OFFSET
, SECONDARY_IRQ_MASK
}
169 * Card probe function
171 * Just match the manufacturer and podule ID's
175 rapide_probe(device_t parent
, cfdata_t cf
, void *aux
)
177 struct podule_attach_args
*pa
= (void *)aux
;
179 return (pa
->pa_product
== PODULE_RAPIDE
);
183 * Card attach function
185 * Identify the card version and configure any children.
186 * Install a shutdown handler to kill interrupts on shutdown
190 rapide_attach(device_t parent
, device_t self
, void *aux
)
192 struct rapide_softc
*sc
= device_private(self
);
193 struct podule_attach_args
*pa
= (void *)aux
;
195 bus_space_handle_t ctlioh
;
198 struct rapide_channel
*rcp
;
199 struct ata_channel
*cp
;
200 struct wdc_regs
*wdr
;
203 /* Note the podule number and validate */
204 if (pa
->pa_podule_number
== -1)
205 panic("Podule has disappeared !");
207 sc
->sc_wdcdev
.sc_atac
.atac_dev
= self
;
208 sc
->sc_podule_number
= pa
->pa_podule_number
;
209 sc
->sc_podule
= pa
->pa_podule
;
210 podules
[sc
->sc_podule_number
].attached
= 1;
212 sc
->sc_wdcdev
.regs
= sc
->sc_wdc_regs
;
214 set_easi_cycle_type(sc
->sc_podule_number
, EASI_CYCLE_TYPE_C
);
217 * Duplicate the podule bus space tag and provide alternative
218 * bus_space_read_multi_4() and bus_space_write_multi_4()
221 rapide_bs_tag
= *pa
->pa_iot
;
222 rapide_bs_tag
.bs_rm_4
= rapide_bs_rm_4
;
223 rapide_bs_tag
.bs_wm_4
= rapide_bs_wm_4
;
224 sc
->sc_ctliot
= iot
= &rapide_bs_tag
;
226 if (bus_space_map(iot
, pa
->pa_podule
->easi_base
+
227 CONTROL_REGISTERS_OFFSET
, CONTROL_REGISTER_SPACE
, 0, &ctlioh
))
228 panic("%s: Cannot map control registers", device_xname(self
));
230 sc
->sc_ctlioh
= ctlioh
;
231 sc
->sc_version
= bus_space_read_1(iot
, ctlioh
, VERSION_REGISTER_OFFSET
) & VERSION_REGISTER_MASK
;
232 /* bus_space_unmap(iot, ctl_ioh, CONTROL_REGISTER_SPACE);*/
234 aprint_normal(": Issue %d\n", sc
->sc_version
+ 1);
235 if (sc
->sc_version
!= VERSION_2_ID
)
238 if (shutdownhook_establish(rapide_shutdown
, (void *)sc
) == NULL
)
239 panic("%s: Cannot install shutdown handler", device_xname(self
));
241 /* Set the interrupt info for this podule */
242 sc
->sc_podule
->irq_addr
= pa
->pa_podule
->easi_base
243 + CONTROL_REGISTERS_OFFSET
+ IRQ_REQUEST_REGISTER_BYTE_OFFSET
;
244 sc
->sc_podule
->irq_mask
= IRQ_MASK
;
246 iobase
= pa
->pa_podule
->easi_base
;
248 /* Fill in wdc and channel infos */
249 sc
->sc_wdcdev
.sc_atac
.atac_cap
|= ATAC_CAP_DATA32
;
250 sc
->sc_wdcdev
.sc_atac
.atac_pio_cap
= 0;
251 sc
->sc_wdcdev
.sc_atac
.atac_channels
= sc
->sc_chanarray
;
252 sc
->sc_wdcdev
.sc_atac
.atac_nchannels
= 2;
253 for (channel
= 0 ; channel
< 2; channel
++) {
254 rcp
= &sc
->rapide_channels
[channel
];
255 sc
->sc_chanarray
[channel
] = &rcp
->rc_channel
;
256 cp
= &rcp
->rc_channel
;
257 wdr
= &sc
->sc_wdc_regs
[channel
];
259 cp
->ch_channel
= channel
;
260 cp
->ch_atac
= &sc
->sc_wdcdev
.sc_atac
;
261 cp
->ch_queue
= &rcp
->rc_chqueue
;
265 wdr
->data32iot
= iot
;
267 if (bus_space_map(iot
, iobase
+ rapide_info
[channel
].registers
,
268 DRIVE_REGISTERS_SPACE
, 0, &wdr
->cmd_baseioh
))
270 for (i
= 0; i
< WDC_NREG
; i
++) {
271 if (bus_space_subregion(wdr
->cmd_iot
, wdr
->cmd_baseioh
,
272 i
, i
== 0 ? 4 : 1, &wdr
->cmd_iohs
[i
]) != 0) {
273 bus_space_unmap(iot
, wdr
->cmd_baseioh
,
274 DRIVE_REGISTERS_SPACE
);
278 wdc_init_shadow_regs(cp
);
279 if (bus_space_map(iot
, iobase
+
280 rapide_info
[channel
].aux_register
, 4, 0, &wdr
->ctl_ioh
)) {
281 bus_space_unmap(iot
, wdr
->cmd_baseioh
,
282 DRIVE_REGISTERS_SPACE
);
285 if (bus_space_map(iot
, iobase
+
286 rapide_info
[channel
].data_register
, 4, 0, &wdr
->data32ioh
)) {
287 bus_space_unmap(iot
, wdr
->cmd_baseioh
,
288 DRIVE_REGISTERS_SPACE
);
289 bus_space_unmap(iot
, wdr
->ctl_ioh
, 4);
292 /* Disable interrupts and clear any pending interrupts */
293 rcp
->rc_irqmask
= rapide_info
[channel
].irq_mask
;
294 sc
->sc_intr_enable_mask
&= ~rcp
->rc_irqmask
;
295 bus_space_write_1(iot
, sc
->sc_ctlioh
, IRQ_MASK_REGISTER_OFFSET
,
296 sc
->sc_intr_enable_mask
);
297 /* XXX - Issue 1 cards will need to clear any pending interrupts */
299 ihp
->ih_func
= rapide_intr
;
301 ihp
->ih_level
= IPL_BIO
;
302 ihp
->ih_name
= "rapide";
303 ihp
->ih_maskaddr
= pa
->pa_podule
->irq_addr
;
304 ihp
->ih_maskbits
= rcp
->rc_irqmask
;
305 if (irq_claim(sc
->sc_podule
->interrupt
, ihp
))
306 panic("%s: Cannot claim interrupt %d",
307 device_xname(self
), sc
->sc_podule
->interrupt
);
308 /* clear any pending interrupts and enable interrupts */
309 sc
->sc_intr_enable_mask
|= rcp
->rc_irqmask
;
310 bus_space_write_1(iot
, sc
->sc_ctlioh
,
311 IRQ_MASK_REGISTER_OFFSET
, sc
->sc_intr_enable_mask
);
312 /* XXX - Issue 1 cards will need to clear any pending interrupts */
318 * Card shutdown function
320 * Called via do_shutdown_hooks() during kernel shutdown.
321 * Clear the cards's interrupt mask to stop any podule interrupts.
325 rapide_shutdown(void *arg
)
327 struct rapide_softc
*sc
= arg
;
329 /* Disable card interrupts */
330 bus_space_write_1(sc
->sc_ctliot
, sc
->sc_ctlioh
,
331 IRQ_MASK_REGISTER_OFFSET
, 0);
335 * Podule interrupt handler
337 * If the interrupt was from our card pass it on to the wdc interrupt handler
341 rapide_intr(void *arg
)
343 struct rapide_channel
*rcp
= arg
;
344 irqhandler_t
*ihp
= &rcp
->rc_ih
;
345 volatile u_char
*intraddr
= (volatile u_char
*)ihp
->ih_maskaddr
;
347 /* XXX - Issue 1 cards will need to clear the interrupt */
349 /* XXX - not bus space yet - should really be handled by podulebus */
350 if ((*intraddr
) & ihp
->ih_maskbits
)
351 wdcintr(&rcp
->rc_channel
);