ata_kauai.c revision 183409
1139825Simp/*-
2125735Sgrehan * Copyright 2004 by Peter Grehan. All rights reserved.
3125735Sgrehan *
4125735Sgrehan * Redistribution and use in source and binary forms, with or without
5125735Sgrehan * modification, are permitted provided that the following conditions
6125735Sgrehan * are met:
7125735Sgrehan * 1. Redistributions of source code must retain the above copyright
8125735Sgrehan *    notice, this list of conditions and the following disclaimer.
9125735Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
10125735Sgrehan *    notice, this list of conditions and the following disclaimer in the
11125735Sgrehan *    documentation and/or other materials provided with the distribution.
12125735Sgrehan * 3. The name of the author may not be used to endorse or promote products
13125735Sgrehan *    derived from this software without specific prior written permission.
14125735Sgrehan *
15125735Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16125735Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17125735Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18125735Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19125735Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20125735Sgrehan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21125735Sgrehan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22125735Sgrehan * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23125735Sgrehan * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24125735Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25125735Sgrehan * SUCH DAMAGE.
26125735Sgrehan *
27125735Sgrehan */
28125735Sgrehan#include <sys/cdefs.h>
29125735Sgrehan__FBSDID("$FreeBSD: head/sys/powerpc/powermac/ata_kauai.c 183409 2008-09-27 15:13:44Z nwhitehorn $");
30125735Sgrehan
31125735Sgrehan/*
32125735Sgrehan * Mac 'Kauai' PCI ATA controller
33125735Sgrehan */
34125735Sgrehan#include "opt_ata.h"
35125735Sgrehan#include <sys/param.h>
36125735Sgrehan#include <sys/systm.h>
37125735Sgrehan#include <sys/kernel.h>
38125735Sgrehan#include <sys/module.h>
39125735Sgrehan#include <sys/bus.h>
40125735Sgrehan#include <sys/malloc.h>
41125735Sgrehan#include <sys/sema.h>
42125735Sgrehan#include <sys/taskqueue.h>
43125735Sgrehan#include <vm/uma.h>
44125735Sgrehan#include <machine/stdarg.h>
45125735Sgrehan#include <machine/resource.h>
46125735Sgrehan#include <machine/bus.h>
47125735Sgrehan#include <sys/rman.h>
48125735Sgrehan#include <sys/ata.h>
49125735Sgrehan#include <dev/ata/ata-all.h>
50144457Sgrehan#include <ata_if.h>
51125735Sgrehan
52125735Sgrehan#include <dev/ofw/openfirm.h>
53183409Snwhitehorn#include <powerpc/ofw/ofw_pci.h>
54183409Snwhitehorn#include <machine/intr_machdep.h>
55125735Sgrehan
56125735Sgrehan#include <dev/pci/pcivar.h>
57125735Sgrehan#include <dev/pci/pcireg.h>
58125735Sgrehan
59183409Snwhitehorn#include "ata_dbdma.h"
60183409Snwhitehorn
61125735Sgrehan#define  ATA_KAUAI_REGOFFSET	0x2000
62183409Snwhitehorn#define  ATA_KAUAI_DBDMAOFFSET	0x1000
63125735Sgrehan
64125735Sgrehan/*
65126394Sgrehan * Offset to alt-control register from base
66126394Sgrehan */
67126394Sgrehan#define  ATA_KAUAI_ALTOFFSET    (ATA_KAUAI_REGOFFSET + 0x160)
68126394Sgrehan
69126394Sgrehan/*
70126394Sgrehan * Define the gap between registers
71126394Sgrehan */
72126394Sgrehan#define ATA_KAUAI_REGGAP        16
73126394Sgrehan
74126394Sgrehan/*
75183409Snwhitehorn * PIO and DMA access registers
76183409Snwhitehorn */
77183409Snwhitehorn#define PIO_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x200)
78183409Snwhitehorn#define UDMA_CONFIG_REG	(ATA_KAUAI_REGOFFSET + 0x210)
79183409Snwhitehorn#define DMA_IRQ_REG	(ATA_KAUAI_REGOFFSET + 0x300)
80183409Snwhitehorn
81183409Snwhitehorn#define USE_DBDMA_IRQ	0
82183409Snwhitehorn
83183409Snwhitehorn/*
84125735Sgrehan * Define the kauai pci bus attachment.
85125735Sgrehan */
86125735Sgrehanstatic  int  ata_kauai_probe(device_t dev);
87183409Snwhitehornstatic  int  ata_kauai_attach(device_t dev);
88144457Sgrehanstatic  void ata_kauai_setmode(device_t parent, device_t dev);
89183409Snwhitehornstatic  int  ata_kauai_begin_transaction(struct ata_request *request);
90125735Sgrehan
91125735Sgrehanstatic device_method_t ata_kauai_methods[] = {
92125735Sgrehan        /* Device interface */
93125735Sgrehan	DEVMETHOD(device_probe,		ata_kauai_probe),
94183409Snwhitehorn	DEVMETHOD(device_attach,	ata_kauai_attach),
95125735Sgrehan	DEVMETHOD(device_detach,	bus_generic_detach),
96125735Sgrehan	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
97125735Sgrehan	DEVMETHOD(device_suspend,	bus_generic_suspend),
98125735Sgrehan	DEVMETHOD(device_resume,	bus_generic_resume),
99125735Sgrehan
100144457Sgrehan	/* ATA interface */
101144457Sgrehan	DEVMETHOD(ata_setmode,		ata_kauai_setmode),
102125735Sgrehan	{ 0, 0 }
103125735Sgrehan};
104125735Sgrehan
105183409Snwhitehornstruct ata_kauai_softc {
106183409Snwhitehorn	struct ata_dbdma_channel sc_ch;
107183409Snwhitehorn
108183409Snwhitehorn	struct resource *sc_memr;
109183409Snwhitehorn
110183409Snwhitehorn	int shasta;
111183409Snwhitehorn
112183409Snwhitehorn	uint32_t udmaconf[2];
113183409Snwhitehorn	uint32_t wdmaconf[2];
114183409Snwhitehorn	uint32_t pioconf[2];
115183409Snwhitehorn};
116183409Snwhitehorn
117125735Sgrehanstatic driver_t ata_kauai_driver = {
118125735Sgrehan	"ata",
119125735Sgrehan	ata_kauai_methods,
120183409Snwhitehorn	sizeof(struct ata_kauai_softc),
121125735Sgrehan};
122125735Sgrehan
123125735SgrehanDRIVER_MODULE(ata, pci, ata_kauai_driver, ata_devclass, 0, 0);
124144359SgrehanMODULE_DEPEND(ata, ata, 1, 1, 1);
125125735Sgrehan
126125735Sgrehan/*
127125735Sgrehan * PCI ID search table
128125735Sgrehan */
129125735Sgrehanstatic struct kauai_pci_dev {
130125735Sgrehan        u_int32_t  kpd_devid;
131125735Sgrehan        char    *kpd_desc;
132125735Sgrehan} kauai_pci_devlist[] = {
133125735Sgrehan        { 0x0033106b, "Uninorth2 Kauai ATA Controller" },
134125735Sgrehan        { 0x003b106b, "Intrepid Kauai ATA Controller" },
135125735Sgrehan        { 0x0043106b, "K2 Kauai ATA Controller" },
136183409Snwhitehorn        { 0x0050106b, "Shasta Kauai ATA Controller" },
137175668Sjulian        { 0x0069106b, "Intrepid-2 Kauai ATA Controller" },
138125735Sgrehan        { 0, NULL }
139125735Sgrehan};
140125735Sgrehan
141183409Snwhitehorn/*
142183409Snwhitehorn * IDE transfer timings
143183409Snwhitehorn */
144183409Snwhitehorn#define KAUAI_PIO_MASK	0xff000fff
145183409Snwhitehorn#define KAUAI_DMA_MASK	0x00fff000
146183409Snwhitehorn#define KAUAI_UDMA_MASK	0x0000ffff
147183409Snwhitehorn
148183409Snwhitehornstatic const u_int pio_timing_kauai[] = {
149183409Snwhitehorn	0x08000a92,	/* PIO0 */
150183409Snwhitehorn	0x0800060f,	/* PIO1 */
151183409Snwhitehorn	0x0800038b,	/* PIO2 */
152183409Snwhitehorn	0x05000249,	/* PIO3 */
153183409Snwhitehorn	0x04000148	/* PIO4 */
154183409Snwhitehorn};
155183409Snwhitehornstatic const u_int pio_timing_shasta[] = {
156183409Snwhitehorn	0x0a000c97,	/* PIO0 */
157183409Snwhitehorn	0x07000712,	/* PIO1 */
158183409Snwhitehorn	0x040003cd,	/* PIO2 */
159183409Snwhitehorn	0x0400028b,	/* PIO3 */
160183409Snwhitehorn	0x0400010a	/* PIO4 */
161183409Snwhitehorn};
162183409Snwhitehorn
163183409Snwhitehornstatic const u_int dma_timing_kauai[] = {
164183409Snwhitehorn        0x00618000,	/* WDMA0 */
165183409Snwhitehorn        0x00209000,	/* WDMA1 */
166183409Snwhitehorn        0x00148000	/* WDMA2 */
167183409Snwhitehorn};
168183409Snwhitehornstatic const u_int dma_timing_shasta[] = {
169183409Snwhitehorn        0x00820800,	/* WDMA0 */
170183409Snwhitehorn        0x0028b000,	/* WDMA1 */
171183409Snwhitehorn        0x001ca000	/* WDMA2 */
172183409Snwhitehorn};
173183409Snwhitehorn
174183409Snwhitehornstatic const u_int udma_timing_kauai[] = {
175183409Snwhitehorn        0x000070c1,	/* UDMA0 */
176183409Snwhitehorn        0x00005d81,	/* UDMA1 */
177183409Snwhitehorn        0x00004a61,	/* UDMA2 */
178183409Snwhitehorn        0x00003a51,	/* UDMA3 */
179183409Snwhitehorn        0x00002a31,	/* UDMA4 */
180183409Snwhitehorn        0x00002921	/* UDMA5 */
181183409Snwhitehorn};
182183409Snwhitehornstatic const u_int udma_timing_shasta[] = {
183183409Snwhitehorn        0x00035901,	/* UDMA0 */
184183409Snwhitehorn        0x000348b1,	/* UDMA1 */
185183409Snwhitehorn        0x00033881,	/* UDMA2 */
186183409Snwhitehorn        0x00033861,	/* UDMA3 */
187183409Snwhitehorn        0x00033841,	/* UDMA4 */
188183409Snwhitehorn        0x00033031,	/* UDMA5 */
189183409Snwhitehorn        0x00033021	/* UDMA6 */
190183409Snwhitehorn};
191183409Snwhitehorn
192125735Sgrehanstatic int
193125735Sgrehanata_kauai_probe(device_t dev)
194125735Sgrehan{
195125735Sgrehan	struct ata_channel *ch;
196183409Snwhitehorn	struct ata_kauai_softc *sc;
197125735Sgrehan	u_long startp, countp;
198125735Sgrehan	u_int32_t devid;
199183409Snwhitehorn	phandle_t node;
200183409Snwhitehorn	char *compatstring = NULL;
201125735Sgrehan	int i, found, rid, status;
202125735Sgrehan
203125735Sgrehan	found = 0;
204125735Sgrehan	devid = pci_get_devid(dev);
205125735Sgrehan        for (i = 0; kauai_pci_devlist[i].kpd_desc != NULL; i++) {
206125735Sgrehan                if (devid == kauai_pci_devlist[i].kpd_devid) {
207125735Sgrehan			found = 1;
208125735Sgrehan                        device_set_desc(dev, kauai_pci_devlist[i].kpd_desc);
209125735Sgrehan		}
210125735Sgrehan	}
211125735Sgrehan
212125735Sgrehan	if (!found)
213125735Sgrehan		return (ENXIO);
214125735Sgrehan
215183409Snwhitehorn	node = ofw_pci_find_node(dev);
216183409Snwhitehorn	sc = device_get_softc(dev);
217183409Snwhitehorn	bzero(sc, sizeof(struct ata_kauai_softc));
218183409Snwhitehorn	ch = &sc->sc_ch.sc_ch;
219183409Snwhitehorn
220183409Snwhitehorn	OF_getprop_alloc(node, "compatible", 1, (void **)&compatstring);
221183409Snwhitehorn	if (strcmp(compatstring,"shasta-ata") == 0)
222183409Snwhitehorn		sc->shasta = 1;
223183409Snwhitehorn
224183409Snwhitehorn	free(compatstring, M_OFWPROP);
225183409Snwhitehorn
226183409Snwhitehorn
227125735Sgrehan	/*
228125735Sgrehan	 * This device seems to ignore writes to the interrupt
229125735Sgrehan	 * config register, resulting in interrupt resources
230125735Sgrehan	 * not being attached. If this is the case, use
231133862Smarius	 * Open Firmware to determine the irq, and then attach
232125735Sgrehan	 * the resource. This allows the ATA common code to
233125735Sgrehan	 * allocate the irq.
234125735Sgrehan	 */
235125735Sgrehan	status = bus_get_resource(dev, SYS_RES_IRQ, 0, &startp, &countp);
236125735Sgrehan	if (status == ENOENT) {
237183409Snwhitehorn		int *irq;
238183409Snwhitehorn		phandle_t iparent;
239183409Snwhitehorn		int icells, nintr, i;
240125735Sgrehan
241125735Sgrehan		/*
242183409Snwhitehorn		 * Horrible hack to handle Kauai devices that have their IRQs
243183409Snwhitehorn		 * set up in an utterly wrong way
244125735Sgrehan		 */
245183409Snwhitehorn		if (!sc->shasta)
246183409Snwhitehorn			bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);
247125735Sgrehan
248125735Sgrehan		/*
249183409Snwhitehorn		 * For the rest of the interrupts, and the main Shasta
250183409Snwhitehorn		 * interrupt, get the IRQs from firmware.
251125735Sgrehan		 */
252183409Snwhitehorn		if (OF_getprop(node, "interrupt-parent", &iparent,
253183409Snwhitehorn		    sizeof(iparent)) == sizeof(iparent)) {
254183409Snwhitehorn			OF_getprop(iparent, "#interrupt-cells", &icells,
255183409Snwhitehorn			    sizeof(icells)) ;
256125735Sgrehan		}
257183409Snwhitehorn
258183409Snwhitehorn		nintr = OF_getprop_alloc(node, "interrupts", sizeof(*irq),
259183409Snwhitehorn		    (void **)&irq);
260183409Snwhitehorn
261183409Snwhitehorn		for (i = 0; i < nintr; i += icells)
262183409Snwhitehorn			bus_set_resource(dev, SYS_RES_IRQ,
263183409Snwhitehorn			    i/icells + !sc->shasta, irq[i], 1);
264183409Snwhitehorn
265183409Snwhitehorn		free(irq, M_OFWPROP);
266125735Sgrehan	}
267125735Sgrehan
268125735Sgrehan
269126394Sgrehan        rid = PCIR_BARS;
270183409Snwhitehorn	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
271183409Snwhitehorn	    RF_ACTIVE);
272183409Snwhitehorn        if (sc->sc_memr == NULL) {
273125735Sgrehan                device_printf(dev, "could not allocate memory\n");
274125735Sgrehan                return (ENXIO);
275125735Sgrehan        }
276125735Sgrehan
277125735Sgrehan	/*
278125735Sgrehan	 * Set up the resource vectors
279125735Sgrehan	 */
280145221Sgrehan        for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
281183409Snwhitehorn                ch->r_io[i].res = sc->sc_memr;
282126394Sgrehan                ch->r_io[i].offset = i*ATA_KAUAI_REGGAP + ATA_KAUAI_REGOFFSET;
283125735Sgrehan        }
284183409Snwhitehorn        ch->r_io[ATA_CONTROL].res = sc->sc_memr;
285145311Sgrehan        ch->r_io[ATA_CONTROL].offset = ATA_KAUAI_ALTOFFSET;
286145772Sgrehan	ata_default_registers(dev);
287125735Sgrehan
288125735Sgrehan        ch->unit = 0;
289146198Sgrehan        ch->flags |= ATA_USE_16BIT;
290145772Sgrehan	ata_generic_hw(dev);
291125735Sgrehan
292125735Sgrehan        return (ata_probe(dev));
293125735Sgrehan}
294125735Sgrehan
295183409Snwhitehorn#if USE_DBDMA_IRQ
296183409Snwhitehornstatic int
297183409Snwhitehornata_kauai_dma_interrupt(struct ata_kauai_softc *sc)
298183409Snwhitehorn{
299183409Snwhitehorn	/* Clear the DMA interrupt bits */
300183409Snwhitehorn
301183409Snwhitehorn	bus_write_4(sc->sc_memr, DMA_IRQ_REG, 0x80000000);
302183409Snwhitehorn
303183409Snwhitehorn	return ata_interrupt(sc);
304183409Snwhitehorn}
305183409Snwhitehorn#endif
306183409Snwhitehorn
307183409Snwhitehornstatic int
308183409Snwhitehornata_kauai_attach(device_t dev)
309183409Snwhitehorn{
310183409Snwhitehorn	struct ata_kauai_softc *sc = device_get_softc(dev);
311183409Snwhitehorn#if USE_DBDMA_IRQ
312183409Snwhitehorn	int dbdma_irq_rid = 1;
313183409Snwhitehorn	struct resource *dbdma_irq;
314183409Snwhitehorn	void *cookie;
315183409Snwhitehorn#endif
316183409Snwhitehorn
317183409Snwhitehorn	pci_enable_busmaster(dev);
318183409Snwhitehorn
319183409Snwhitehorn	/* Init DMA engine */
320183409Snwhitehorn
321183409Snwhitehorn	sc->sc_ch.dbdma_rid = 1;
322183409Snwhitehorn	sc->sc_ch.dbdma_regs = sc->sc_memr;
323183409Snwhitehorn	sc->sc_ch.dbdma_offset = ATA_KAUAI_DBDMAOFFSET;
324183409Snwhitehorn
325183409Snwhitehorn	ata_dbdma_dmainit(dev);
326183409Snwhitehorn
327183409Snwhitehorn#if USE_DBDMA_IRQ
328183409Snwhitehorn	/* Bind to DBDMA interrupt as well */
329183409Snwhitehorn	if ((dbdma_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
330183409Snwhitehorn	    &dbdma_irq_rid, RF_SHAREABLE | RF_ACTIVE)) != NULL) {
331183409Snwhitehorn		bus_setup_intr(dev, dbdma_irq, ATA_INTR_FLAGS, NULL,
332183409Snwhitehorn		    (driver_intr_t *)ata_kauai_dma_interrupt, sc,&cookie);
333183409Snwhitehorn	}
334183409Snwhitehorn#endif
335183409Snwhitehorn
336183409Snwhitehorn	/* Set up initial mode */
337183409Snwhitehorn	if (sc->shasta)
338183409Snwhitehorn		sc->pioconf[0] = sc->pioconf[1] = pio_timing_shasta[4];
339183409Snwhitehorn	else
340183409Snwhitehorn		sc->pioconf[0] = sc->pioconf[1] = pio_timing_kauai[4];
341183409Snwhitehorn
342183409Snwhitehorn	sc->udmaconf[0] = sc->udmaconf[1] = 0;
343183409Snwhitehorn	sc->wdmaconf[0] = sc->wdmaconf[1] = 0;
344183409Snwhitehorn
345183409Snwhitehorn	bus_write_4(sc->sc_memr, PIO_CONFIG_REG, sc->pioconf[0]);
346183409Snwhitehorn
347183409Snwhitehorn	/* Magic FCR value from Apple */
348183409Snwhitehorn	bus_write_4(sc->sc_memr, 0, 0x00000007);
349183409Snwhitehorn
350183409Snwhitehorn	/* Set begin_transaction */
351183409Snwhitehorn	sc->sc_ch.sc_ch.hw.begin_transaction = ata_kauai_begin_transaction;
352183409Snwhitehorn
353183409Snwhitehorn	return ata_attach(dev);
354183409Snwhitehorn}
355183409Snwhitehorn
356144457Sgrehanstatic void
357144457Sgrehanata_kauai_setmode(device_t parent, device_t dev)
358144457Sgrehan{
359144457Sgrehan	struct ata_device *atadev = device_get_softc(dev);
360183409Snwhitehorn	struct ata_kauai_softc *sc = device_get_softc(parent);
361183409Snwhitehorn	uint32_t mode;
362144457Sgrehan
363183409Snwhitehorn	mode = ata_limit_mode(dev,atadev->mode,
364183409Snwhitehorn	    (sc->shasta) ? ATA_UDMA6 : ATA_UDMA5);
365183409Snwhitehorn
366183409Snwhitehorn	if (ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
367183409Snwhitehorn		return;
368183409Snwhitehorn
369183409Snwhitehorn	atadev->mode = mode;
370183409Snwhitehorn
371183409Snwhitehorn	if (sc->shasta) {
372183409Snwhitehorn		switch (mode & ATA_DMA_MASK) {
373183409Snwhitehorn		    case ATA_UDMA0:
374183409Snwhitehorn			sc->udmaconf[atadev->unit]
375183409Snwhitehorn			    = udma_timing_shasta[mode & ATA_MODE_MASK];
376183409Snwhitehorn			break;
377183409Snwhitehorn		    case ATA_WDMA0:
378183409Snwhitehorn			sc->udmaconf[atadev->unit] = 0;
379183409Snwhitehorn			sc->wdmaconf[atadev->unit]
380183409Snwhitehorn			    = dma_timing_shasta[mode & ATA_MODE_MASK];
381183409Snwhitehorn			break;
382183409Snwhitehorn		    default:
383183409Snwhitehorn			sc->pioconf[atadev->unit]
384183409Snwhitehorn			    = pio_timing_shasta[(mode & ATA_MODE_MASK) -
385183409Snwhitehorn			    ATA_PIO0];
386183409Snwhitehorn			break;
387183409Snwhitehorn		}
388183409Snwhitehorn	} else {
389183409Snwhitehorn		switch (mode & ATA_DMA_MASK) {
390183409Snwhitehorn		    case ATA_UDMA0:
391183409Snwhitehorn			sc->udmaconf[atadev->unit]
392183409Snwhitehorn			    = udma_timing_kauai[mode & ATA_MODE_MASK];
393183409Snwhitehorn			break;
394183409Snwhitehorn		    case ATA_WDMA0:
395183409Snwhitehorn			sc->udmaconf[atadev->unit] = 0;
396183409Snwhitehorn			sc->wdmaconf[atadev->unit]
397183409Snwhitehorn			    = dma_timing_kauai[mode & ATA_MODE_MASK];
398183409Snwhitehorn			break;
399183409Snwhitehorn		    default:
400183409Snwhitehorn			sc->pioconf[atadev->unit]
401183409Snwhitehorn			    = pio_timing_kauai[(mode & ATA_MODE_MASK)
402183409Snwhitehorn			    - ATA_PIO0];
403183409Snwhitehorn			break;
404183409Snwhitehorn		}
405183409Snwhitehorn	}
406144457Sgrehan}
407183409Snwhitehorn
408183409Snwhitehornstatic int
409183409Snwhitehornata_kauai_begin_transaction(struct ata_request *request)
410183409Snwhitehorn{
411183409Snwhitehorn	struct ata_device *atadev = device_get_softc(request->dev);
412183409Snwhitehorn	struct ata_kauai_softc *sc = device_get_softc(request->parent);
413183409Snwhitehorn
414183409Snwhitehorn	bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[atadev->unit]);
415183409Snwhitehorn	bus_write_4(sc->sc_memr, PIO_CONFIG_REG,
416183409Snwhitehorn	    sc->wdmaconf[atadev->unit] | sc->pioconf[atadev->unit]);
417183409Snwhitehorn
418183409Snwhitehorn	return ata_begin_transaction(request);
419183409Snwhitehorn}
420183409Snwhitehorn
421