xref: /freebsd/sys/powerpc/powermac/ata_kauai.c (revision 965205eb66cae3fd5de75a70a3aef2f014f98020)
160727d8bSWarner Losh /*-
2321fd460SPeter Grehan  * Copyright 2004 by Peter Grehan. All rights reserved.
3321fd460SPeter Grehan  *
4321fd460SPeter Grehan  * Redistribution and use in source and binary forms, with or without
5321fd460SPeter Grehan  * modification, are permitted provided that the following conditions
6321fd460SPeter Grehan  * are met:
7321fd460SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
8321fd460SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
9321fd460SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
10321fd460SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
11321fd460SPeter Grehan  *    documentation and/or other materials provided with the distribution.
12321fd460SPeter Grehan  * 3. The name of the author may not be used to endorse or promote products
13321fd460SPeter Grehan  *    derived from this software without specific prior written permission.
14321fd460SPeter Grehan  *
15321fd460SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16321fd460SPeter Grehan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17321fd460SPeter Grehan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18321fd460SPeter Grehan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19321fd460SPeter Grehan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20321fd460SPeter Grehan  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21321fd460SPeter Grehan  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22321fd460SPeter Grehan  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23321fd460SPeter Grehan  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24321fd460SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25321fd460SPeter Grehan  * SUCH DAMAGE.
26321fd460SPeter Grehan  *
27321fd460SPeter Grehan  */
28321fd460SPeter Grehan #include <sys/cdefs.h>
29321fd460SPeter Grehan __FBSDID("$FreeBSD$");
30321fd460SPeter Grehan 
31321fd460SPeter Grehan /*
32321fd460SPeter Grehan  * Mac 'Kauai' PCI ATA controller
33321fd460SPeter Grehan  */
34321fd460SPeter Grehan #include <sys/param.h>
35321fd460SPeter Grehan #include <sys/systm.h>
36321fd460SPeter Grehan #include <sys/kernel.h>
37321fd460SPeter Grehan #include <sys/module.h>
38321fd460SPeter Grehan #include <sys/bus.h>
39321fd460SPeter Grehan #include <sys/malloc.h>
40321fd460SPeter Grehan #include <sys/sema.h>
41321fd460SPeter Grehan #include <sys/taskqueue.h>
42321fd460SPeter Grehan #include <vm/uma.h>
43321fd460SPeter Grehan #include <machine/stdarg.h>
44321fd460SPeter Grehan #include <machine/resource.h>
45321fd460SPeter Grehan #include <machine/bus.h>
46321fd460SPeter Grehan #include <sys/rman.h>
47321fd460SPeter Grehan #include <sys/ata.h>
48321fd460SPeter Grehan #include <dev/ata/ata-all.h>
4998cbfce5SPeter Grehan #include <ata_if.h>
50321fd460SPeter Grehan 
51321fd460SPeter Grehan #include <dev/ofw/openfirm.h>
5251d163d3SNathan Whitehorn #include <dev/ofw/ofw_bus.h>
53b7382e09SNathan Whitehorn #include <machine/intr_machdep.h>
54321fd460SPeter Grehan 
55321fd460SPeter Grehan #include <dev/pci/pcivar.h>
56321fd460SPeter Grehan #include <dev/pci/pcireg.h>
57321fd460SPeter Grehan 
58b7382e09SNathan Whitehorn #include "ata_dbdma.h"
59b7382e09SNathan Whitehorn 
60321fd460SPeter Grehan #define  ATA_KAUAI_REGOFFSET	0x2000
61b7382e09SNathan Whitehorn #define  ATA_KAUAI_DBDMAOFFSET	0x1000
6280bd99beSPeter Grehan 
6380bd99beSPeter Grehan /*
6480bd99beSPeter Grehan  * Offset to alt-control register from base
6580bd99beSPeter Grehan  */
6680bd99beSPeter Grehan #define  ATA_KAUAI_ALTOFFSET    (ATA_KAUAI_REGOFFSET + 0x160)
6780bd99beSPeter Grehan 
6880bd99beSPeter Grehan /*
6980bd99beSPeter Grehan  * Define the gap between registers
7080bd99beSPeter Grehan  */
7180bd99beSPeter Grehan #define ATA_KAUAI_REGGAP        16
72321fd460SPeter Grehan 
73321fd460SPeter Grehan /*
74b7382e09SNathan Whitehorn  * PIO and DMA access registers
75b7382e09SNathan Whitehorn  */
76b7382e09SNathan Whitehorn #define PIO_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x200)
77b7382e09SNathan Whitehorn #define UDMA_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x210)
78b7382e09SNathan Whitehorn #define DMA_IRQ_REG	(ATA_KAUAI_REGOFFSET + 0x300)
79b7382e09SNathan Whitehorn 
80b7382e09SNathan Whitehorn #define USE_DBDMA_IRQ	0
81b7382e09SNathan Whitehorn 
82b7382e09SNathan Whitehorn /*
83321fd460SPeter Grehan  * Define the kauai pci bus attachment.
84321fd460SPeter Grehan  */
85321fd460SPeter Grehan static  int  ata_kauai_probe(device_t dev);
86b7382e09SNathan Whitehorn static  int  ata_kauai_attach(device_t dev);
87066f913aSAlexander Motin static  int  ata_kauai_setmode(device_t dev, int target, int mode);
88b7382e09SNathan Whitehorn static  int  ata_kauai_begin_transaction(struct ata_request *request);
89321fd460SPeter Grehan 
90321fd460SPeter Grehan static device_method_t ata_kauai_methods[] = {
91321fd460SPeter Grehan         /* Device interface */
92321fd460SPeter Grehan 	DEVMETHOD(device_probe,		ata_kauai_probe),
93b7382e09SNathan Whitehorn 	DEVMETHOD(device_attach,	ata_kauai_attach),
94321fd460SPeter Grehan 	DEVMETHOD(device_detach,	bus_generic_detach),
95321fd460SPeter Grehan 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
96321fd460SPeter Grehan 	DEVMETHOD(device_suspend,	bus_generic_suspend),
97321fd460SPeter Grehan 	DEVMETHOD(device_resume,	bus_generic_resume),
98321fd460SPeter Grehan 
9998cbfce5SPeter Grehan 	/* ATA interface */
10098cbfce5SPeter Grehan 	DEVMETHOD(ata_setmode,		ata_kauai_setmode),
101d2ce15bdSMarius Strobl 	DEVMETHOD_END
102321fd460SPeter Grehan };
103321fd460SPeter Grehan 
104b7382e09SNathan Whitehorn struct ata_kauai_softc {
105b7382e09SNathan Whitehorn 	struct ata_dbdma_channel sc_ch;
106b7382e09SNathan Whitehorn 
107b7382e09SNathan Whitehorn 	struct resource *sc_memr;
108b7382e09SNathan Whitehorn 
109b7382e09SNathan Whitehorn 	int shasta;
110b7382e09SNathan Whitehorn 
111b7382e09SNathan Whitehorn 	uint32_t udmaconf[2];
112b7382e09SNathan Whitehorn 	uint32_t wdmaconf[2];
113b7382e09SNathan Whitehorn 	uint32_t pioconf[2];
114b7382e09SNathan Whitehorn };
115b7382e09SNathan Whitehorn 
116321fd460SPeter Grehan static driver_t ata_kauai_driver = {
117321fd460SPeter Grehan 	"ata",
118321fd460SPeter Grehan 	ata_kauai_methods,
119b7382e09SNathan Whitehorn 	sizeof(struct ata_kauai_softc),
120321fd460SPeter Grehan };
121321fd460SPeter Grehan 
122d2ce15bdSMarius Strobl DRIVER_MODULE(ata, pci, ata_kauai_driver, ata_devclass, NULL, NULL);
12305a016a3SPeter Grehan MODULE_DEPEND(ata, ata, 1, 1, 1);
124321fd460SPeter Grehan 
125321fd460SPeter Grehan /*
126321fd460SPeter Grehan  * PCI ID search table
127321fd460SPeter Grehan  */
128d2ce15bdSMarius Strobl static const struct kauai_pci_dev {
129321fd460SPeter Grehan         u_int32_t	kpd_devid;
130d2ce15bdSMarius Strobl         const char	*kpd_desc;
131321fd460SPeter Grehan } kauai_pci_devlist[] = {
132321fd460SPeter Grehan         { 0x0033106b, "Uninorth2 Kauai ATA Controller" },
133321fd460SPeter Grehan         { 0x003b106b, "Intrepid Kauai ATA Controller" },
134321fd460SPeter Grehan         { 0x0043106b, "K2 Kauai ATA Controller" },
135b7382e09SNathan Whitehorn         { 0x0050106b, "Shasta Kauai ATA Controller" },
136a4fcb5ecSJulian Elischer         { 0x0069106b, "Intrepid-2 Kauai ATA Controller" },
137321fd460SPeter Grehan         { 0, NULL }
138321fd460SPeter Grehan };
139321fd460SPeter Grehan 
140b7382e09SNathan Whitehorn /*
141b7382e09SNathan Whitehorn  * IDE transfer timings
142b7382e09SNathan Whitehorn  */
143b7382e09SNathan Whitehorn #define KAUAI_PIO_MASK	0xff000fff
144b7382e09SNathan Whitehorn #define KAUAI_DMA_MASK	0x00fff000
145b7382e09SNathan Whitehorn #define KAUAI_UDMA_MASK	0x0000ffff
146b7382e09SNathan Whitehorn 
147b7382e09SNathan Whitehorn static const u_int pio_timing_kauai[] = {
148b7382e09SNathan Whitehorn 	0x08000a92,	/* PIO0 */
149b7382e09SNathan Whitehorn 	0x0800060f,	/* PIO1 */
150b7382e09SNathan Whitehorn 	0x0800038b,	/* PIO2 */
151b7382e09SNathan Whitehorn 	0x05000249,	/* PIO3 */
152b7382e09SNathan Whitehorn 	0x04000148	/* PIO4 */
153b7382e09SNathan Whitehorn };
154d2ce15bdSMarius Strobl 
155b7382e09SNathan Whitehorn static const u_int pio_timing_shasta[] = {
156b7382e09SNathan Whitehorn 	0x0a000c97,	/* PIO0 */
157b7382e09SNathan Whitehorn 	0x07000712,	/* PIO1 */
158b7382e09SNathan Whitehorn 	0x040003cd,	/* PIO2 */
159b7382e09SNathan Whitehorn 	0x0400028b,	/* PIO3 */
160b7382e09SNathan Whitehorn 	0x0400010a	/* PIO4 */
161b7382e09SNathan Whitehorn };
162b7382e09SNathan Whitehorn 
163b7382e09SNathan Whitehorn static const u_int dma_timing_kauai[] = {
164b7382e09SNathan Whitehorn         0x00618000,	/* WDMA0 */
165b7382e09SNathan Whitehorn         0x00209000,	/* WDMA1 */
166b7382e09SNathan Whitehorn         0x00148000	/* WDMA2 */
167b7382e09SNathan Whitehorn };
168d2ce15bdSMarius Strobl 
169b7382e09SNathan Whitehorn static const u_int dma_timing_shasta[] = {
170b7382e09SNathan Whitehorn         0x00820800,	/* WDMA0 */
171b7382e09SNathan Whitehorn         0x0028b000,	/* WDMA1 */
172b7382e09SNathan Whitehorn         0x001ca000	/* WDMA2 */
173b7382e09SNathan Whitehorn };
174b7382e09SNathan Whitehorn 
175b7382e09SNathan Whitehorn static const u_int udma_timing_kauai[] = {
176b7382e09SNathan Whitehorn         0x000070c1,	/* UDMA0 */
177b7382e09SNathan Whitehorn         0x00005d81,	/* UDMA1 */
178b7382e09SNathan Whitehorn         0x00004a61,	/* UDMA2 */
179b7382e09SNathan Whitehorn         0x00003a51,	/* UDMA3 */
180b7382e09SNathan Whitehorn         0x00002a31,	/* UDMA4 */
181b7382e09SNathan Whitehorn         0x00002921	/* UDMA5 */
182b7382e09SNathan Whitehorn };
183d2ce15bdSMarius Strobl 
184b7382e09SNathan Whitehorn static const u_int udma_timing_shasta[] = {
185b7382e09SNathan Whitehorn         0x00035901,	/* UDMA0 */
186b7382e09SNathan Whitehorn         0x000348b1,	/* UDMA1 */
187b7382e09SNathan Whitehorn         0x00033881,	/* UDMA2 */
188b7382e09SNathan Whitehorn         0x00033861,	/* UDMA3 */
189b7382e09SNathan Whitehorn         0x00033841,	/* UDMA4 */
190b7382e09SNathan Whitehorn         0x00033031,	/* UDMA5 */
191b7382e09SNathan Whitehorn         0x00033021	/* UDMA6 */
192b7382e09SNathan Whitehorn };
193b7382e09SNathan Whitehorn 
194321fd460SPeter Grehan static int
195321fd460SPeter Grehan ata_kauai_probe(device_t dev)
196321fd460SPeter Grehan {
197b7382e09SNathan Whitehorn 	struct ata_kauai_softc *sc;
198321fd460SPeter Grehan 	u_int32_t devid;
199b7382e09SNathan Whitehorn 	phandle_t node;
20051d163d3SNathan Whitehorn 	const char *compatstring = NULL;
201*965205ebSAndreas Tobler 	int i, found;
202321fd460SPeter Grehan 
203321fd460SPeter Grehan 	found = 0;
204321fd460SPeter Grehan 	devid = pci_get_devid(dev);
205321fd460SPeter Grehan         for (i = 0; kauai_pci_devlist[i].kpd_desc != NULL; i++) {
206321fd460SPeter Grehan                 if (devid == kauai_pci_devlist[i].kpd_devid) {
207321fd460SPeter Grehan 			found = 1;
208321fd460SPeter Grehan                         device_set_desc(dev, kauai_pci_devlist[i].kpd_desc);
209321fd460SPeter Grehan 		}
210321fd460SPeter Grehan 	}
211321fd460SPeter Grehan 
212321fd460SPeter Grehan 	if (!found)
213321fd460SPeter Grehan 		return (ENXIO);
214321fd460SPeter Grehan 
21551d163d3SNathan Whitehorn 	node = ofw_bus_get_node(dev);
216b7382e09SNathan Whitehorn 	sc = device_get_softc(dev);
217b7382e09SNathan Whitehorn 	bzero(sc, sizeof(struct ata_kauai_softc));
218b7382e09SNathan Whitehorn 
21951d163d3SNathan Whitehorn 	compatstring = ofw_bus_get_compat(dev);
220a0a3479cSNathan Whitehorn 	if (compatstring != NULL && strcmp(compatstring,"shasta-ata") == 0)
221b7382e09SNathan Whitehorn 		sc->shasta = 1;
222b7382e09SNathan Whitehorn 
22397af4af5SNathan Whitehorn 	/* Pre-K2 controllers apparently need this hack */
22497af4af5SNathan Whitehorn 	if (!sc->shasta &&
22597af4af5SNathan Whitehorn 	    (compatstring == NULL || strcmp(compatstring, "K2-UATA") != 0))
226b7382e09SNathan Whitehorn 		bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);
227321fd460SPeter Grehan 
228*965205ebSAndreas Tobler         return (ata_probe(dev));
229*965205ebSAndreas Tobler }
230*965205ebSAndreas Tobler 
231*965205ebSAndreas Tobler #if USE_DBDMA_IRQ
232*965205ebSAndreas Tobler static int
233*965205ebSAndreas Tobler ata_kauai_dma_interrupt(struct ata_kauai_softc *sc)
234*965205ebSAndreas Tobler {
235*965205ebSAndreas Tobler 	/* Clear the DMA interrupt bits */
236*965205ebSAndreas Tobler 
237*965205ebSAndreas Tobler 	bus_write_4(sc->sc_memr, DMA_IRQ_REG, 0x80000000);
238*965205ebSAndreas Tobler 
239*965205ebSAndreas Tobler 	return ata_interrupt(sc);
240*965205ebSAndreas Tobler }
241*965205ebSAndreas Tobler #endif
242*965205ebSAndreas Tobler 
243*965205ebSAndreas Tobler static int
244*965205ebSAndreas Tobler ata_kauai_attach(device_t dev)
245*965205ebSAndreas Tobler {
246*965205ebSAndreas Tobler 	struct ata_kauai_softc *sc = device_get_softc(dev);
247*965205ebSAndreas Tobler 	struct ata_channel *ch;
248*965205ebSAndreas Tobler 	int i, rid;
249*965205ebSAndreas Tobler #if USE_DBDMA_IRQ
250*965205ebSAndreas Tobler 	int dbdma_irq_rid = 1;
251*965205ebSAndreas Tobler 	struct resource *dbdma_irq;
252*965205ebSAndreas Tobler 	void *cookie;
253*965205ebSAndreas Tobler #endif
254*965205ebSAndreas Tobler 
255*965205ebSAndreas Tobler 	ch = &sc->sc_ch.sc_ch;
256*965205ebSAndreas Tobler 
25780bd99beSPeter Grehan         rid = PCIR_BARS;
258b7382e09SNathan Whitehorn 	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
259b7382e09SNathan Whitehorn 	    RF_ACTIVE);
260b7382e09SNathan Whitehorn         if (sc->sc_memr == NULL) {
261321fd460SPeter Grehan                 device_printf(dev, "could not allocate memory\n");
262321fd460SPeter Grehan                 return (ENXIO);
263321fd460SPeter Grehan         }
264321fd460SPeter Grehan 
265321fd460SPeter Grehan 	/*
266321fd460SPeter Grehan 	 * Set up the resource vectors
267321fd460SPeter Grehan 	 */
2685a276744SPeter Grehan         for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
269b7382e09SNathan Whitehorn                 ch->r_io[i].res = sc->sc_memr;
27080bd99beSPeter Grehan                 ch->r_io[i].offset = i*ATA_KAUAI_REGGAP + ATA_KAUAI_REGOFFSET;
271321fd460SPeter Grehan         }
272b7382e09SNathan Whitehorn         ch->r_io[ATA_CONTROL].res = sc->sc_memr;
273a378bbabSPeter Grehan         ch->r_io[ATA_CONTROL].offset = ATA_KAUAI_ALTOFFSET;
2746ac8f17eSPeter Grehan 	ata_default_registers(dev);
275321fd460SPeter Grehan 
276321fd460SPeter Grehan 	ch->unit = 0;
277edaccfc8SPeter Grehan 	ch->flags |= ATA_USE_16BIT;
278a0a3479cSNathan Whitehorn 
279a0a3479cSNathan Whitehorn 	/* XXX: ATAPI DMA is unreliable. We should find out why. */
280a0a3479cSNathan Whitehorn 	ch->flags |= ATA_NO_ATAPI_DMA;
2816ac8f17eSPeter Grehan 	ata_generic_hw(dev);
282321fd460SPeter Grehan 
283b7382e09SNathan Whitehorn 	pci_enable_busmaster(dev);
284b7382e09SNathan Whitehorn 
285b7382e09SNathan Whitehorn 	/* Init DMA engine */
286b7382e09SNathan Whitehorn 
287b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_rid = 1;
288b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_regs = sc->sc_memr;
289b7382e09SNathan Whitehorn 	sc->sc_ch.dbdma_offset = ATA_KAUAI_DBDMAOFFSET;
290b7382e09SNathan Whitehorn 
291b7382e09SNathan Whitehorn 	ata_dbdma_dmainit(dev);
292b7382e09SNathan Whitehorn 
293b7382e09SNathan Whitehorn #if USE_DBDMA_IRQ
294b7382e09SNathan Whitehorn 	/* Bind to DBDMA interrupt as well */
295b7382e09SNathan Whitehorn 	if ((dbdma_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
296b7382e09SNathan Whitehorn 	    &dbdma_irq_rid, RF_SHAREABLE | RF_ACTIVE)) != NULL) {
297b7382e09SNathan Whitehorn 		bus_setup_intr(dev, dbdma_irq, ATA_INTR_FLAGS, NULL,
298b7382e09SNathan Whitehorn 		    (driver_intr_t *)ata_kauai_dma_interrupt, sc,&cookie);
299b7382e09SNathan Whitehorn 	}
300b7382e09SNathan Whitehorn #endif
301b7382e09SNathan Whitehorn 
302b7382e09SNathan Whitehorn 	/* Set up initial mode */
303e8657200SNathan Whitehorn 	sc->pioconf[0] = sc->pioconf[1] =
304e8657200SNathan Whitehorn 	    bus_read_4(sc->sc_memr, PIO_CONFIG_REG) & 0x0f000fff;
305b7382e09SNathan Whitehorn 
306b7382e09SNathan Whitehorn 	sc->udmaconf[0] = sc->udmaconf[1] = 0;
307b7382e09SNathan Whitehorn 	sc->wdmaconf[0] = sc->wdmaconf[1] = 0;
308b7382e09SNathan Whitehorn 
309b7382e09SNathan Whitehorn 	/* Magic FCR value from Apple */
310b7382e09SNathan Whitehorn 	bus_write_4(sc->sc_memr, 0, 0x00000007);
311b7382e09SNathan Whitehorn 
312b7382e09SNathan Whitehorn 	/* Set begin_transaction */
313b7382e09SNathan Whitehorn 	sc->sc_ch.sc_ch.hw.begin_transaction = ata_kauai_begin_transaction;
314b7382e09SNathan Whitehorn 
315b7382e09SNathan Whitehorn 	return ata_attach(dev);
316b7382e09SNathan Whitehorn }
317b7382e09SNathan Whitehorn 
318066f913aSAlexander Motin static int
319066f913aSAlexander Motin ata_kauai_setmode(device_t dev, int target, int mode)
32098cbfce5SPeter Grehan {
321066f913aSAlexander Motin 	struct ata_kauai_softc *sc = device_get_softc(dev);
32298cbfce5SPeter Grehan 
323066f913aSAlexander Motin 	mode = min(mode,sc->shasta ? ATA_UDMA6 : ATA_UDMA5);
324b7382e09SNathan Whitehorn 
325b7382e09SNathan Whitehorn 	if (sc->shasta) {
326b7382e09SNathan Whitehorn 		switch (mode & ATA_DMA_MASK) {
327b7382e09SNathan Whitehorn 		    case ATA_UDMA0:
328066f913aSAlexander Motin 			sc->udmaconf[target]
329b7382e09SNathan Whitehorn 			    = udma_timing_shasta[mode & ATA_MODE_MASK];
330b7382e09SNathan Whitehorn 			break;
331b7382e09SNathan Whitehorn 		    case ATA_WDMA0:
332066f913aSAlexander Motin 			sc->udmaconf[target] = 0;
333066f913aSAlexander Motin 			sc->wdmaconf[target]
334b7382e09SNathan Whitehorn 			    = dma_timing_shasta[mode & ATA_MODE_MASK];
335b7382e09SNathan Whitehorn 			break;
336b7382e09SNathan Whitehorn 		    default:
337066f913aSAlexander Motin 			sc->pioconf[target]
338b7382e09SNathan Whitehorn 			    = pio_timing_shasta[(mode & ATA_MODE_MASK) -
339b7382e09SNathan Whitehorn 			    ATA_PIO0];
340b7382e09SNathan Whitehorn 			break;
34198cbfce5SPeter Grehan 		}
342b7382e09SNathan Whitehorn 	} else {
343b7382e09SNathan Whitehorn 		switch (mode & ATA_DMA_MASK) {
344b7382e09SNathan Whitehorn 		    case ATA_UDMA0:
345066f913aSAlexander Motin 			sc->udmaconf[target]
346b7382e09SNathan Whitehorn 			    = udma_timing_kauai[mode & ATA_MODE_MASK];
347b7382e09SNathan Whitehorn 			break;
348b7382e09SNathan Whitehorn 		    case ATA_WDMA0:
349066f913aSAlexander Motin 			sc->udmaconf[target] = 0;
350066f913aSAlexander Motin 			sc->wdmaconf[target]
351b7382e09SNathan Whitehorn 			    = dma_timing_kauai[mode & ATA_MODE_MASK];
352b7382e09SNathan Whitehorn 			break;
353b7382e09SNathan Whitehorn 		    default:
354066f913aSAlexander Motin 			sc->pioconf[target]
355b7382e09SNathan Whitehorn 			    = pio_timing_kauai[(mode & ATA_MODE_MASK)
356b7382e09SNathan Whitehorn 			    - ATA_PIO0];
357b7382e09SNathan Whitehorn 			break;
358b7382e09SNathan Whitehorn 		}
359b7382e09SNathan Whitehorn 	}
360066f913aSAlexander Motin 
361066f913aSAlexander Motin 	return (mode);
362b7382e09SNathan Whitehorn }
363b7382e09SNathan Whitehorn 
364b7382e09SNathan Whitehorn static int
365b7382e09SNathan Whitehorn ata_kauai_begin_transaction(struct ata_request *request)
366b7382e09SNathan Whitehorn {
367b7382e09SNathan Whitehorn 	struct ata_kauai_softc *sc = device_get_softc(request->parent);
368b7382e09SNathan Whitehorn 
369066f913aSAlexander Motin 	bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[request->unit]);
370b7382e09SNathan Whitehorn 	bus_write_4(sc->sc_memr, PIO_CONFIG_REG,
371066f913aSAlexander Motin 	    sc->wdmaconf[request->unit] | sc->pioconf[request->unit]);
372b7382e09SNathan Whitehorn 
373b7382e09SNathan Whitehorn 	return ata_begin_transaction(request);
374b7382e09SNathan Whitehorn }
375