xref: /freebsd/sys/powerpc/powermac/ata_kauai.c (revision d5a7306c75d2f9bddf7e264cbd61c83eee67f071)
160727d8bSWarner Losh /*-
271e3c308SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
371e3c308SPedro F. Giffuni  *
4321fd460SPeter Grehan  * Copyright 2004 by Peter Grehan. All rights reserved.
5321fd460SPeter Grehan  *
6321fd460SPeter Grehan  * Redistribution and use in source and binary forms, with or without
7321fd460SPeter Grehan  * modification, are permitted provided that the following conditions
8321fd460SPeter Grehan  * are met:
9321fd460SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
10321fd460SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
11321fd460SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
12321fd460SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
13321fd460SPeter Grehan  *    documentation and/or other materials provided with the distribution.
14321fd460SPeter Grehan  * 3. The name of the author may not be used to endorse or promote products
15321fd460SPeter Grehan  *    derived from this software without specific prior written permission.
16321fd460SPeter Grehan  *
17321fd460SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18321fd460SPeter Grehan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19321fd460SPeter Grehan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20321fd460SPeter Grehan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21321fd460SPeter Grehan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22321fd460SPeter Grehan  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23321fd460SPeter Grehan  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24321fd460SPeter Grehan  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25321fd460SPeter Grehan  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26321fd460SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27321fd460SPeter Grehan  * SUCH DAMAGE.
28321fd460SPeter Grehan  *
29321fd460SPeter Grehan  */
30321fd460SPeter Grehan #include <sys/cdefs.h>
31321fd460SPeter Grehan __FBSDID("$FreeBSD$");
32321fd460SPeter Grehan 
33321fd460SPeter Grehan /*
34321fd460SPeter Grehan  * Mac 'Kauai' PCI ATA controller
35321fd460SPeter Grehan  */
36321fd460SPeter Grehan #include <sys/param.h>
37321fd460SPeter Grehan #include <sys/systm.h>
38321fd460SPeter Grehan #include <sys/kernel.h>
39321fd460SPeter Grehan #include <sys/module.h>
40321fd460SPeter Grehan #include <sys/bus.h>
41321fd460SPeter Grehan #include <sys/malloc.h>
42321fd460SPeter Grehan #include <sys/sema.h>
43321fd460SPeter Grehan #include <sys/taskqueue.h>
44321fd460SPeter Grehan #include <vm/uma.h>
45321fd460SPeter Grehan #include <machine/stdarg.h>
46321fd460SPeter Grehan #include <machine/resource.h>
47321fd460SPeter Grehan #include <machine/bus.h>
48321fd460SPeter Grehan #include <sys/rman.h>
49321fd460SPeter Grehan #include <sys/ata.h>
50321fd460SPeter Grehan #include <dev/ata/ata-all.h>
5198cbfce5SPeter Grehan #include <ata_if.h>
52321fd460SPeter Grehan 
53321fd460SPeter Grehan #include <dev/ofw/openfirm.h>
5451d163d3SNathan Whitehorn #include <dev/ofw/ofw_bus.h>
55b7382e09SNathan Whitehorn #include <machine/intr_machdep.h>
56321fd460SPeter Grehan 
57321fd460SPeter Grehan #include <dev/pci/pcivar.h>
58321fd460SPeter Grehan #include <dev/pci/pcireg.h>
59321fd460SPeter Grehan 
60b7382e09SNathan Whitehorn #include "ata_dbdma.h"
61b7382e09SNathan Whitehorn 
62321fd460SPeter Grehan #define  ATA_KAUAI_REGOFFSET	0x2000
63b7382e09SNathan Whitehorn #define  ATA_KAUAI_DBDMAOFFSET	0x1000
6480bd99beSPeter Grehan 
6580bd99beSPeter Grehan /*
6680bd99beSPeter Grehan  * Offset to alt-control register from base
6780bd99beSPeter Grehan  */
6880bd99beSPeter Grehan #define  ATA_KAUAI_ALTOFFSET    (ATA_KAUAI_REGOFFSET + 0x160)
6980bd99beSPeter Grehan 
7080bd99beSPeter Grehan /*
7180bd99beSPeter Grehan  * Define the gap between registers
7280bd99beSPeter Grehan  */
7380bd99beSPeter Grehan #define ATA_KAUAI_REGGAP        16
74321fd460SPeter Grehan 
75321fd460SPeter Grehan /*
76b7382e09SNathan Whitehorn  * PIO and DMA access registers
77b7382e09SNathan Whitehorn  */
78b7382e09SNathan Whitehorn #define PIO_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x200)
79b7382e09SNathan Whitehorn #define UDMA_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x210)
80b7382e09SNathan Whitehorn #define DMA_IRQ_REG	(ATA_KAUAI_REGOFFSET + 0x300)
81b7382e09SNathan Whitehorn 
82b7382e09SNathan Whitehorn #define USE_DBDMA_IRQ	0
83b7382e09SNathan Whitehorn 
84b7382e09SNathan Whitehorn /*
85321fd460SPeter Grehan  * Define the kauai pci bus attachment.
86321fd460SPeter Grehan  */
87321fd460SPeter Grehan static  int  ata_kauai_probe(device_t dev);
88b7382e09SNathan Whitehorn static  int  ata_kauai_attach(device_t dev);
89066f913aSAlexander Motin static  int  ata_kauai_setmode(device_t dev, int target, int mode);
90b7382e09SNathan Whitehorn static  int  ata_kauai_begin_transaction(struct ata_request *request);
91321fd460SPeter Grehan 
92321fd460SPeter Grehan static device_method_t ata_kauai_methods[] = {
93321fd460SPeter Grehan         /* Device interface */
94321fd460SPeter Grehan 	DEVMETHOD(device_probe,		ata_kauai_probe),
95b7382e09SNathan Whitehorn 	DEVMETHOD(device_attach,	ata_kauai_attach),
96321fd460SPeter Grehan 	DEVMETHOD(device_detach,	bus_generic_detach),
97321fd460SPeter Grehan 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
98321fd460SPeter Grehan 	DEVMETHOD(device_suspend,	bus_generic_suspend),
99321fd460SPeter Grehan 	DEVMETHOD(device_resume,	bus_generic_resume),
100321fd460SPeter Grehan 
10198cbfce5SPeter Grehan 	/* ATA interface */
10298cbfce5SPeter Grehan 	DEVMETHOD(ata_setmode,		ata_kauai_setmode),
103d2ce15bdSMarius Strobl 	DEVMETHOD_END
104321fd460SPeter Grehan };
105321fd460SPeter Grehan 
106b7382e09SNathan Whitehorn struct ata_kauai_softc {
107b7382e09SNathan Whitehorn 	struct ata_dbdma_channel sc_ch;
108b7382e09SNathan Whitehorn 
109b7382e09SNathan Whitehorn 	struct resource *sc_memr;
110b7382e09SNathan Whitehorn 
111b7382e09SNathan Whitehorn 	int shasta;
112b7382e09SNathan Whitehorn 
113b7382e09SNathan Whitehorn 	uint32_t udmaconf[2];
114b7382e09SNathan Whitehorn 	uint32_t wdmaconf[2];
115b7382e09SNathan Whitehorn 	uint32_t pioconf[2];
116b7382e09SNathan Whitehorn };
117b7382e09SNathan Whitehorn 
118321fd460SPeter Grehan static driver_t ata_kauai_driver = {
119321fd460SPeter Grehan 	"ata",
120321fd460SPeter Grehan 	ata_kauai_methods,
121b7382e09SNathan Whitehorn 	sizeof(struct ata_kauai_softc),
122321fd460SPeter Grehan };
123321fd460SPeter Grehan 
124*d5a7306cSJohn Baldwin DRIVER_MODULE(ata, pci, ata_kauai_driver, NULL, NULL);
12505a016a3SPeter Grehan MODULE_DEPEND(ata, ata, 1, 1, 1);
126321fd460SPeter Grehan 
127321fd460SPeter Grehan /*
128321fd460SPeter Grehan  * PCI ID search table
129321fd460SPeter Grehan  */
130d2ce15bdSMarius Strobl static const struct kauai_pci_dev {
131321fd460SPeter Grehan         u_int32_t	kpd_devid;
132d2ce15bdSMarius Strobl         const char	*kpd_desc;
133321fd460SPeter Grehan } kauai_pci_devlist[] = {
134321fd460SPeter Grehan         { 0x0033106b, "Uninorth2 Kauai ATA Controller" },
135321fd460SPeter Grehan         { 0x003b106b, "Intrepid Kauai ATA Controller" },
136321fd460SPeter Grehan         { 0x0043106b, "K2 Kauai ATA Controller" },
137b7382e09SNathan Whitehorn         { 0x0050106b, "Shasta Kauai ATA Controller" },
138a4fcb5ecSJulian Elischer         { 0x0069106b, "Intrepid-2 Kauai ATA Controller" },
139321fd460SPeter Grehan         { 0, NULL }
140321fd460SPeter Grehan };
141321fd460SPeter Grehan 
142b7382e09SNathan Whitehorn /*
143b7382e09SNathan Whitehorn  * IDE transfer timings
144b7382e09SNathan Whitehorn  */
145b7382e09SNathan Whitehorn #define KAUAI_PIO_MASK	0xff000fff
146b7382e09SNathan Whitehorn #define KAUAI_DMA_MASK	0x00fff000
147b7382e09SNathan Whitehorn #define KAUAI_UDMA_MASK	0x0000ffff
148b7382e09SNathan Whitehorn 
149b7382e09SNathan Whitehorn static const u_int pio_timing_kauai[] = {
150b7382e09SNathan Whitehorn 	0x08000a92,	/* PIO0 */
151b7382e09SNathan Whitehorn 	0x0800060f,	/* PIO1 */
152b7382e09SNathan Whitehorn 	0x0800038b,	/* PIO2 */
153b7382e09SNathan Whitehorn 	0x05000249,	/* PIO3 */
154b7382e09SNathan Whitehorn 	0x04000148	/* PIO4 */
155b7382e09SNathan Whitehorn };
156d2ce15bdSMarius Strobl 
157b7382e09SNathan Whitehorn static const u_int pio_timing_shasta[] = {
158b7382e09SNathan Whitehorn 	0x0a000c97,	/* PIO0 */
159b7382e09SNathan Whitehorn 	0x07000712,	/* PIO1 */
160b7382e09SNathan Whitehorn 	0x040003cd,	/* PIO2 */
161b7382e09SNathan Whitehorn 	0x0400028b,	/* PIO3 */
162b7382e09SNathan Whitehorn 	0x0400010a	/* PIO4 */
163b7382e09SNathan Whitehorn };
164b7382e09SNathan Whitehorn 
165b7382e09SNathan Whitehorn static const u_int dma_timing_kauai[] = {
166b7382e09SNathan Whitehorn         0x00618000,	/* WDMA0 */
167b7382e09SNathan Whitehorn         0x00209000,	/* WDMA1 */
168b7382e09SNathan Whitehorn         0x00148000	/* WDMA2 */
169b7382e09SNathan Whitehorn };
170d2ce15bdSMarius Strobl 
171b7382e09SNathan Whitehorn static const u_int dma_timing_shasta[] = {
172b7382e09SNathan Whitehorn         0x00820800,	/* WDMA0 */
173b7382e09SNathan Whitehorn         0x0028b000,	/* WDMA1 */
174b7382e09SNathan Whitehorn         0x001ca000	/* WDMA2 */
175b7382e09SNathan Whitehorn };
176b7382e09SNathan Whitehorn 
177b7382e09SNathan Whitehorn static const u_int udma_timing_kauai[] = {
178b7382e09SNathan Whitehorn         0x000070c1,	/* UDMA0 */
179b7382e09SNathan Whitehorn         0x00005d81,	/* UDMA1 */
180b7382e09SNathan Whitehorn         0x00004a61,	/* UDMA2 */
181b7382e09SNathan Whitehorn         0x00003a51,	/* UDMA3 */
182b7382e09SNathan Whitehorn         0x00002a31,	/* UDMA4 */
183b7382e09SNathan Whitehorn         0x00002921	/* UDMA5 */
184b7382e09SNathan Whitehorn };
185d2ce15bdSMarius Strobl 
186b7382e09SNathan Whitehorn static const u_int udma_timing_shasta[] = {
187b7382e09SNathan Whitehorn         0x00035901,	/* UDMA0 */
188b7382e09SNathan Whitehorn         0x000348b1,	/* UDMA1 */
189b7382e09SNathan Whitehorn         0x00033881,	/* UDMA2 */
190b7382e09SNathan Whitehorn         0x00033861,	/* UDMA3 */
191b7382e09SNathan Whitehorn         0x00033841,	/* UDMA4 */
192b7382e09SNathan Whitehorn         0x00033031,	/* UDMA5 */
193b7382e09SNathan Whitehorn         0x00033021	/* UDMA6 */
194b7382e09SNathan Whitehorn };
195b7382e09SNathan Whitehorn 
196321fd460SPeter Grehan static int
197321fd460SPeter Grehan ata_kauai_probe(device_t dev)
198321fd460SPeter Grehan {
199321fd460SPeter Grehan 	u_int32_t devid;
200965205ebSAndreas Tobler 	int i, found;
201321fd460SPeter Grehan 
202321fd460SPeter Grehan 	found = 0;
203321fd460SPeter Grehan 	devid = pci_get_devid(dev);
204321fd460SPeter Grehan         for (i = 0; kauai_pci_devlist[i].kpd_desc != NULL; i++) {
205321fd460SPeter Grehan                 if (devid == kauai_pci_devlist[i].kpd_devid) {
206321fd460SPeter Grehan 			found = 1;
207321fd460SPeter Grehan                         device_set_desc(dev, kauai_pci_devlist[i].kpd_desc);
208321fd460SPeter Grehan 		}
209321fd460SPeter Grehan 	}
210321fd460SPeter Grehan 
211321fd460SPeter Grehan 	if (!found)
212321fd460SPeter Grehan 		return (ENXIO);
213321fd460SPeter Grehan 
214965205ebSAndreas Tobler         return (ata_probe(dev));
215965205ebSAndreas Tobler }
216965205ebSAndreas Tobler 
217965205ebSAndreas Tobler #if USE_DBDMA_IRQ
218965205ebSAndreas Tobler static int
219965205ebSAndreas Tobler ata_kauai_dma_interrupt(struct ata_kauai_softc *sc)
220965205ebSAndreas Tobler {
221965205ebSAndreas Tobler 	/* Clear the DMA interrupt bits */
222965205ebSAndreas Tobler 
223965205ebSAndreas Tobler 	bus_write_4(sc->sc_memr, DMA_IRQ_REG, 0x80000000);
224965205ebSAndreas Tobler 
225965205ebSAndreas Tobler 	return ata_interrupt(sc);
226965205ebSAndreas Tobler }
227965205ebSAndreas Tobler #endif
228965205ebSAndreas Tobler 
229965205ebSAndreas Tobler static int
230965205ebSAndreas Tobler ata_kauai_attach(device_t dev)
231965205ebSAndreas Tobler {
232965205ebSAndreas Tobler 	struct ata_kauai_softc *sc = device_get_softc(dev);
233965205ebSAndreas Tobler 	struct ata_channel *ch;
234d5472cd4SJohn Baldwin 	const char *compatstring;
235965205ebSAndreas Tobler 	int i, rid;
236965205ebSAndreas Tobler #if USE_DBDMA_IRQ
237965205ebSAndreas Tobler 	int dbdma_irq_rid = 1;
238965205ebSAndreas Tobler 	struct resource *dbdma_irq;
239965205ebSAndreas Tobler 	void *cookie;
240965205ebSAndreas Tobler #endif
241965205ebSAndreas Tobler 
242d5472cd4SJohn Baldwin 	compatstring = ofw_bus_get_compat(dev);
243d5472cd4SJohn Baldwin 	if (compatstring != NULL && strcmp(compatstring,"shasta-ata") == 0)
244d5472cd4SJohn Baldwin 		sc->shasta = 1;
245d5472cd4SJohn Baldwin 
246d5472cd4SJohn Baldwin 	/* Pre-K2 controllers apparently need this hack */
247d5472cd4SJohn Baldwin 	if (!sc->shasta &&
248d5472cd4SJohn Baldwin 	    (compatstring == NULL || strcmp(compatstring, "K2-UATA") != 0))
249d5472cd4SJohn Baldwin 		bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);
250d5472cd4SJohn Baldwin 
251965205ebSAndreas Tobler 	ch = &sc->sc_ch.sc_ch;
252965205ebSAndreas Tobler 
25380bd99beSPeter Grehan         rid = PCIR_BARS;
254b7382e09SNathan Whitehorn 	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
255b7382e09SNathan Whitehorn 	    RF_ACTIVE);
256b7382e09SNathan Whitehorn         if (sc->sc_memr == NULL) {
257321fd460SPeter Grehan                 device_printf(dev, "could not allocate memory\n");
258321fd460SPeter Grehan                 return (ENXIO);
259321fd460SPeter Grehan         }
260321fd460SPeter Grehan 
261321fd460SPeter Grehan 	/*
262321fd460SPeter Grehan 	 * Set up the resource vectors
263321fd460SPeter Grehan 	 */
2645a276744SPeter Grehan         for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
265b7382e09SNathan Whitehorn                 ch->r_io[i].res = sc->sc_memr;
26680bd99beSPeter Grehan                 ch->r_io[i].offset = i*ATA_KAUAI_REGGAP + ATA_KAUAI_REGOFFSET;
267321fd460SPeter Grehan         }
268b7382e09SNathan Whitehorn         ch->r_io[ATA_CONTROL].res = sc->sc_memr;
269a378bbabSPeter Grehan         ch->r_io[ATA_CONTROL].offset = ATA_KAUAI_ALTOFFSET;
2706ac8f17eSPeter Grehan 	ata_default_registers(dev);
271321fd460SPeter Grehan 
272321fd460SPeter Grehan 	ch->unit = 0;
273edaccfc8SPeter Grehan 	ch->flags |= ATA_USE_16BIT;
274a0a3479cSNathan Whitehorn 
275a0a3479cSNathan Whitehorn 	/* XXX: ATAPI DMA is unreliable. We should find out why. */
276a0a3479cSNathan Whitehorn 	ch->flags |= ATA_NO_ATAPI_DMA;
2776ac8f17eSPeter Grehan 	ata_generic_hw(dev);
278321fd460SPeter Grehan 
279b7382e09SNathan Whitehorn 	pci_enable_busmaster(dev);
280b7382e09SNathan Whitehorn 
281b7382e09SNathan Whitehorn 	/* Init DMA engine */
282b7382e09SNathan Whitehorn 
283b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_rid = 1;
284b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_regs = sc->sc_memr;
285b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_offset = ATA_KAUAI_DBDMAOFFSET;
286b7382e09SNathan Whitehorn 
287b7382e09SNathan Whitehorn 	ata_dbdma_dmainit(dev);
288b7382e09SNathan Whitehorn 
289b7382e09SNathan Whitehorn #if USE_DBDMA_IRQ
290b7382e09SNathan Whitehorn 	/* Bind to DBDMA interrupt as well */
291b7382e09SNathan Whitehorn 	if ((dbdma_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
292b7382e09SNathan Whitehorn 	    &dbdma_irq_rid, RF_SHAREABLE | RF_ACTIVE)) != NULL) {
293b7382e09SNathan Whitehorn 		bus_setup_intr(dev, dbdma_irq, ATA_INTR_FLAGS, NULL,
294b7382e09SNathan Whitehorn 		    (driver_intr_t *)ata_kauai_dma_interrupt, sc,&cookie);
295b7382e09SNathan Whitehorn 	}
296b7382e09SNathan Whitehorn #endif
297b7382e09SNathan Whitehorn 
298b7382e09SNathan Whitehorn 	/* Set up initial mode */
299e8657200SNathan Whitehorn 	sc->pioconf[0] = sc->pioconf[1] =
300e8657200SNathan Whitehorn 	    bus_read_4(sc->sc_memr, PIO_CONFIG_REG) & 0x0f000fff;
301b7382e09SNathan Whitehorn 
302b7382e09SNathan Whitehorn 	sc->udmaconf[0] = sc->udmaconf[1] = 0;
303b7382e09SNathan Whitehorn 	sc->wdmaconf[0] = sc->wdmaconf[1] = 0;
304b7382e09SNathan Whitehorn 
305b7382e09SNathan Whitehorn 	/* Magic FCR value from Apple */
306b7382e09SNathan Whitehorn 	bus_write_4(sc->sc_memr, 0, 0x00000007);
307b7382e09SNathan Whitehorn 
308b7382e09SNathan Whitehorn 	/* Set begin_transaction */
309b7382e09SNathan Whitehorn 	sc->sc_ch.sc_ch.hw.begin_transaction = ata_kauai_begin_transaction;
310b7382e09SNathan Whitehorn 
311b7382e09SNathan Whitehorn 	return ata_attach(dev);
312b7382e09SNathan Whitehorn }
313b7382e09SNathan Whitehorn 
314066f913aSAlexander Motin static int
315066f913aSAlexander Motin ata_kauai_setmode(device_t dev, int target, int mode)
31698cbfce5SPeter Grehan {
317066f913aSAlexander Motin 	struct ata_kauai_softc *sc = device_get_softc(dev);
31898cbfce5SPeter Grehan 
319066f913aSAlexander Motin 	mode = min(mode,sc->shasta ? ATA_UDMA6 : ATA_UDMA5);
320b7382e09SNathan Whitehorn 
321b7382e09SNathan Whitehorn 	if (sc->shasta) {
322b7382e09SNathan Whitehorn 		switch (mode & ATA_DMA_MASK) {
323b7382e09SNathan Whitehorn 		    case ATA_UDMA0:
324066f913aSAlexander Motin 			sc->udmaconf[target]
325b7382e09SNathan Whitehorn 			    = udma_timing_shasta[mode & ATA_MODE_MASK];
326b7382e09SNathan Whitehorn 			break;
327b7382e09SNathan Whitehorn 		    case ATA_WDMA0:
328066f913aSAlexander Motin 			sc->udmaconf[target] = 0;
329066f913aSAlexander Motin 			sc->wdmaconf[target]
330b7382e09SNathan Whitehorn 			    = dma_timing_shasta[mode & ATA_MODE_MASK];
331b7382e09SNathan Whitehorn 			break;
332b7382e09SNathan Whitehorn 		    default:
333066f913aSAlexander Motin 			sc->pioconf[target]
334b7382e09SNathan Whitehorn 			    = pio_timing_shasta[(mode & ATA_MODE_MASK) -
335b7382e09SNathan Whitehorn 			    ATA_PIO0];
336b7382e09SNathan Whitehorn 			break;
33798cbfce5SPeter Grehan 		}
338b7382e09SNathan Whitehorn 	} else {
339b7382e09SNathan Whitehorn 		switch (mode & ATA_DMA_MASK) {
340b7382e09SNathan Whitehorn 		    case ATA_UDMA0:
341066f913aSAlexander Motin 			sc->udmaconf[target]
342b7382e09SNathan Whitehorn 			    = udma_timing_kauai[mode & ATA_MODE_MASK];
343b7382e09SNathan Whitehorn 			break;
344b7382e09SNathan Whitehorn 		    case ATA_WDMA0:
345066f913aSAlexander Motin 			sc->udmaconf[target] = 0;
346066f913aSAlexander Motin 			sc->wdmaconf[target]
347b7382e09SNathan Whitehorn 			    = dma_timing_kauai[mode & ATA_MODE_MASK];
348b7382e09SNathan Whitehorn 			break;
349b7382e09SNathan Whitehorn 		    default:
350066f913aSAlexander Motin 			sc->pioconf[target]
351b7382e09SNathan Whitehorn 			    = pio_timing_kauai[(mode & ATA_MODE_MASK)
352b7382e09SNathan Whitehorn 			    - ATA_PIO0];
353b7382e09SNathan Whitehorn 			break;
354b7382e09SNathan Whitehorn 		}
355b7382e09SNathan Whitehorn 	}
356066f913aSAlexander Motin 
357066f913aSAlexander Motin 	return (mode);
358b7382e09SNathan Whitehorn }
359b7382e09SNathan Whitehorn 
360b7382e09SNathan Whitehorn static int
361b7382e09SNathan Whitehorn ata_kauai_begin_transaction(struct ata_request *request)
362b7382e09SNathan Whitehorn {
363b7382e09SNathan Whitehorn 	struct ata_kauai_softc *sc = device_get_softc(request->parent);
364b7382e09SNathan Whitehorn 
365066f913aSAlexander Motin 	bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[request->unit]);
366b7382e09SNathan Whitehorn 	bus_write_4(sc->sc_memr, PIO_CONFIG_REG,
367066f913aSAlexander Motin 	    sc->wdmaconf[request->unit] | sc->pioconf[request->unit]);
368b7382e09SNathan Whitehorn 
369b7382e09SNathan Whitehorn 	return ata_begin_transaction(request);
370b7382e09SNathan Whitehorn }
371