ata-dma.c revision 70186
190075Sobrien/*-
2117395Skan * Copyright (c) 1998,1999,2000 S�ren Schmidt
352284Sobrien * All rights reserved.
490075Sobrien *
552284Sobrien * Redistribution and use in source and binary forms, with or without
690075Sobrien * modification, are permitted provided that the following conditions
790075Sobrien * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
990075Sobrien *    notice, this list of conditions and the following disclaimer,
1052284Sobrien *    without modification, immediately at the beginning of the file.
1190075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1290075Sobrien *    notice, this list of conditions and the following disclaimer in the
1390075Sobrien *    documentation and/or other materials provided with the distribution.
1490075Sobrien * 3. The name of the author may not be used to endorse or promote products
1552284Sobrien *    derived from this software without specific prior written permission.
1652284Sobrien *
1790075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1890075Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1990075Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2052284Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2152284Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2290075Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2352284Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2452284Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2552284Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2652284Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2752284Sobrien *
2852284Sobrien * $FreeBSD: head/sys/dev/ata/ata-dma.c 70186 2000-12-19 10:37:03Z sos $
2952284Sobrien */
3052284Sobrien
3152284Sobrien#include "pci.h"
3252284Sobrien#include <sys/param.h>
3352284Sobrien#include <sys/systm.h>
3452284Sobrien#include <sys/bio.h>
3552284Sobrien#include <sys/malloc.h>
3652284Sobrien#include <sys/bus.h>
3752284Sobrien#include <sys/disk.h>
3852284Sobrien#include <sys/devicestat.h>
3952284Sobrien#include <vm/vm.h>
4052284Sobrien#include <vm/pmap.h>
4152284Sobrien#if NPCI > 0
4252284Sobrien#include <pci/pcivar.h>
4352284Sobrien#endif
4452284Sobrien#include <machine/bus.h>
4552284Sobrien#include <dev/ata/ata-all.h>
4652284Sobrien
4752284Sobrien#if NPCI > 0
4852284Sobrien
4952284Sobrien/* prototypes */
5052284Sobrienstatic void cyrix_timing(struct ata_softc *, int, int);
5152284Sobrienstatic void promise_timing(struct ata_softc *, int, int);
5252284Sobrienstatic void hpt_timing(struct ata_softc *, int, int);
5352284Sobrien
5452284Sobrien/* misc defines */
5552284Sobrien#ifdef __alpha__
5652284Sobrien#undef vtophys
5752284Sobrien#define vtophys(va)	alpha_XXX_dmamap((vm_offset_t)va)
5852284Sobrien#endif
5952284Sobrien
6052284Sobrienvoid *
6152284Sobrienata_dmaalloc(struct ata_softc *scp, int device)
62117395Skan{
6390075Sobrien    void *dmatab;
6452284Sobrien
6590075Sobrien    if ((dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) {
6690075Sobrien	if (((uintptr_t)dmatab >> PAGE_SHIFT) ^
6790075Sobrien	    (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
6852284Sobrien	    ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n");
6990075Sobrien	    free(dmatab, M_DEVBUF);
7090075Sobrien	    dmatab = NULL;
7190075Sobrien	}
7290075Sobrien    }
7390075Sobrien    return dmatab;
7490075Sobrien}
7590075Sobrien
7690075Sobrienvoid
7790075Sobrienata_dmainit(struct ata_softc *scp, int device,
7890075Sobrien	    int apiomode, int wdmamode, int udmamode)
7990075Sobrien{
8090075Sobrien    device_t parent = device_get_parent(scp->dev);
8190075Sobrien    int devno = (scp->channel << 1) + ATA_DEV(device);
8290075Sobrien    int error;
8352284Sobrien
8490075Sobrien    /* set our most pessimistic default mode */
8590075Sobrien    scp->mode[ATA_DEV(device)] = ATA_PIO;
8690075Sobrien
8790075Sobrien    if (!scp->bmaddr)
8890075Sobrien	return;
8990075Sobrien
9090075Sobrien    /* if simplex controller, only allow DMA on primary channel */
9190075Sobrien    if (scp->channel == 1) {
9290075Sobrien	outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) &
9390075Sobrien	     (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
9490075Sobrien	if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) {
9590075Sobrien	    ata_printf(scp, device, "simplex device, DMA on primary only\n");
9690075Sobrien	    return;
9790075Sobrien	}
9852284Sobrien    }
9990075Sobrien
10090075Sobrien    /* DMA engine address alignment is usually 1 word (2 bytes) */
10190075Sobrien    scp->alignment = 0x1;
10290075Sobrien
10390075Sobrien    if (udmamode > 2 && !ATA_PARAM(scp, device)->cblid) {
10490075Sobrien	ata_printf(scp, device,
10590075Sobrien		   "DMA limited to UDMA33, non-ATA66 compliant cable\n");
10652284Sobrien	udmamode = 2;
10790075Sobrien    }
10890075Sobrien
10952284Sobrien    switch (scp->chiptype) {
110117395Skan
11190075Sobrien    case 0x244b8086:	/* Intel ICH2 */
11290075Sobrien	if (udmamode >= 5) {
11390075Sobrien	    int32_t mask48, new48;
11452284Sobrien	    int16_t word54;
11590075Sobrien
11690075Sobrien	    word54 = pci_read_config(parent, 0x54, 2);
11790075Sobrien	    if (word54 & (0x10 << devno)) {
11890075Sobrien	        error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
11990075Sobrien				    ATA_UDMA5,  ATA_C_F_SETXFER,ATA_WAIT_READY);
12052284Sobrien	    	if (bootverbose)
12190075Sobrien		    ata_printf(scp, device,
12290075Sobrien			       "%s setting UDMA5 on ICH2 chip\n",
123117395Skan			       (error) ? "failed" : "success");
12452284Sobrien		if (!error) {
12590075Sobrien		    mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
12690075Sobrien		    new48 = (1 << devno) + (1 << (16 + (devno << 2)));
127117395Skan		    pci_write_config(parent, 0x48,
12890075Sobrien				     (pci_read_config(parent, 0x48, 4) &
129117395Skan				     ~mask48) | new48, 4);
130117395Skan	    	    pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2);
13190075Sobrien		    scp->mode[ATA_DEV(device)] = ATA_UDMA5;
13252284Sobrien		    return;
13390075Sobrien		}
13490075Sobrien	    }
13590075Sobrien	}
13652284Sobrien	/* make sure eventual ATA100 mode from the BIOS is disabled */
13790075Sobrien	pci_write_config(parent, 0x54,
13890075Sobrien			 pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2);
13990075Sobrien	/* FALLTHROUGH */
14090075Sobrien
14152284Sobrien    case 0x24118086:    /* Intel ICH */
14290075Sobrien	if (udmamode >= 4) {
14390075Sobrien	    int32_t mask48, new48;
14490075Sobrien	    int16_t word54;
14590075Sobrien
146117395Skan	    word54 = pci_read_config(parent, 0x54, 2);
14790075Sobrien	    if (word54 & (0x10 << devno)) {
14890075Sobrien	        error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
14990075Sobrien				    ATA_UDMA4,  ATA_C_F_SETXFER,ATA_WAIT_READY);
150117395Skan	    	if (bootverbose)
15190075Sobrien		    ata_printf(scp, device,
152117395Skan			       "%s setting UDMA4 on ICH%s chip\n",
15390075Sobrien			       (error) ? "failed" : "success",
15490075Sobrien			       (scp->chiptype == 0x244b8086) ? "2" : "");
15590075Sobrien		if (!error) {
156117395Skan		    mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
15790075Sobrien		    new48 = (1 << devno) + (2 << (16 + (devno << 2)));
15890075Sobrien		    pci_write_config(parent, 0x48,
15990075Sobrien				     (pci_read_config(parent, 0x48, 4) &
16090075Sobrien				     ~mask48) | new48, 4);
161117395Skan		    pci_write_config(parent, 0x54, word54 | (1 << devno), 2);
162117395Skan		    scp->mode[ATA_DEV(device)] = ATA_UDMA4;
16390075Sobrien		    return;
16490075Sobrien		}
165117395Skan	    }
166117395Skan	}
16790075Sobrien	/* make sure eventual ATA66 mode from the BIOS is disabled */
16890075Sobrien	pci_write_config(parent, 0x54,
16990075Sobrien			 pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2);
170117395Skan	/* FALLTHROUGH */
17190075Sobrien
17290075Sobrien    case 0x71118086:	/* Intel PIIX4 */
17390075Sobrien    case 0x71998086:	/* Intel PIIX4e */
17490075Sobrien    case 0x24218086:	/* Intel ICH0 */
17590075Sobrien	if (udmamode >= 2) {
17690075Sobrien	    int32_t mask48, new48;
177117395Skan
17890075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
17990075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
18090075Sobrien	    if (bootverbose)
18190075Sobrien		ata_printf(scp, device, "%s setting UDMA2 on %s chip\n",
18290075Sobrien			   (error) ? "failed" : "success",
18390075Sobrien			   (scp->chiptype == 0x244b8086) ? "ICH2" :
18452284Sobrien			    (scp->chiptype == 0x24118086) ? "ICH" :
18552284Sobrien			     (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
18690075Sobrien	    if (!error) {
18752284Sobrien		mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
18890075Sobrien		new48 = (1 << devno) + (2 << (16 + (devno << 2)));
18990075Sobrien		pci_write_config(parent, 0x48,
19090075Sobrien				 (pci_read_config(parent, 0x48, 4) &
19152284Sobrien				 ~mask48) | new48, 4);
19290075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
19352284Sobrien		return;
19490075Sobrien	    }
19590075Sobrien	}
19690075Sobrien	/* make sure eventual ATA33 mode from the BIOS is disabled */
19752284Sobrien	pci_write_config(parent, 0x48,
19890075Sobrien			 pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4);
19952284Sobrien	/* FALLTHROUGH */
20090075Sobrien
20190075Sobrien    case 0x70108086:	/* Intel PIIX3 */
20252284Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
20390075Sobrien	    int32_t mask40, new40, mask44, new44;
20490075Sobrien
20590075Sobrien	    /* if SITRE not set doit for both channels */
20690075Sobrien	    if (!((pci_read_config(parent,0x40,4)>>(scp->channel<<8))&0x4000)) {
20790075Sobrien		new40 = pci_read_config(parent, 0x40, 4);
20890075Sobrien		new44 = pci_read_config(parent, 0x44, 4);
20990075Sobrien		if (!(new40 & 0x00004000)) {
210117395Skan		    new44 &= ~0x0000000f;
211117395Skan		    new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8);
21290075Sobrien		}
21390075Sobrien		if (!(new40 & 0x40000000)) {
21490075Sobrien		    new44 &= ~0x000000f0;
21590075Sobrien		    new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20);
21690075Sobrien		}
21790075Sobrien		new40 |= 0x40004000;
21890075Sobrien		pci_write_config(parent, 0x40, new40, 4);
21990075Sobrien		pci_write_config(parent, 0x44, new44, 4);
22090075Sobrien	    }
22190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
22290075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
22352284Sobrien	    if (bootverbose)
22490075Sobrien		ata_printf(scp, device, "%s setting WDMA2 on %s chip\n",
22590075Sobrien			   (error) ? "failed" : "success",
22690075Sobrien			   (scp->chiptype == 0x244b8086) ? "ICH2" :
22752284Sobrien			    (scp->chiptype == 0x24118086) ? "ICH" :
22890075Sobrien			     (scp->chiptype == 0x24218086) ? "ICH0" :
22990075Sobrien			      (scp->chiptype == 0x70108086) ? "PIIX3":"PIIX4");
23052284Sobrien	    if (!error) {
23190075Sobrien		if (device == ATA_MASTER) {
23290075Sobrien		    mask40 = 0x0000330f;
23390075Sobrien		    new40 = 0x00002307;
23452284Sobrien		    mask44 = 0;
23590075Sobrien		    new44 = 0;
23690075Sobrien		}
23790075Sobrien		else {
23852284Sobrien		    mask40 = 0x000000f0;
23990075Sobrien		    new40 = 0x00000070;
24090075Sobrien		    mask44 = 0x0000000f;
24190075Sobrien		    new44 = 0x0000000b;
24290075Sobrien		}
24390075Sobrien		if (scp->channel) {
24490075Sobrien		    mask40 <<= 16;
24590075Sobrien		    new40 <<= 16;
24690075Sobrien		    mask44 <<= 4;
24790075Sobrien		    new44 <<= 4;
24890075Sobrien		}
24990075Sobrien		pci_write_config(parent, 0x40,
25090075Sobrien				 (pci_read_config(parent, 0x40, 4) & ~mask40)|
25190075Sobrien 				 new40, 4);
25290075Sobrien		pci_write_config(parent, 0x44,
25390075Sobrien				 (pci_read_config(parent, 0x44, 4) & ~mask44)|
25490075Sobrien 				 new44, 4);
25590075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
25690075Sobrien		return;
25752284Sobrien	    }
25890075Sobrien	}
25990075Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
26090075Sobrien	break;
26152284Sobrien
262117395Skan    case 0x12308086:	/* Intel PIIX */
26390075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
264117395Skan	    int32_t word40;
26590075Sobrien
26652284Sobrien	    word40 = pci_read_config(parent, 0x40, 4);
26790075Sobrien	    word40 >>= scp->channel * 16;
26852284Sobrien
26990075Sobrien	    /* Check for timing config usable for DMA on controller */
27090075Sobrien	    if (!((word40 & 0x3300) == 0x2300 &&
27190075Sobrien		  ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1))
27290075Sobrien		break;
27390075Sobrien
27452284Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
27590075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
27690075Sobrien	    if (bootverbose)
27790075Sobrien		ata_printf(scp, device,
27890075Sobrien			   "%s setting WDMA2 on PIIX chip\n",
27990075Sobrien			   (error) ? "failed" : "success");
28090075Sobrien	    if (!error) {
28190075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
28290075Sobrien		return;
28390075Sobrien	    }
28490075Sobrien	}
28590075Sobrien	break;
28690075Sobrien
28790075Sobrien    case 0x522910b9:	/* AcerLabs Aladdin IV/V */
28890075Sobrien	/* the Aladdin doesn't support ATAPI DMA on both master & slave */
28990075Sobrien	if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) {
29090075Sobrien	    ata_printf(scp, device,
29190075Sobrien		       "Aladdin: two atapi devices on this channel, no DMA\n");
29290075Sobrien	    break;
29390075Sobrien	}
29490075Sobrien	if (udmamode >= 2 && pci_get_revid(parent) > 0x20) {
29590075Sobrien	    int32_t word54 = pci_read_config(parent, 0x54, 4);
29690075Sobrien
29790075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
29890075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
29990075Sobrien	    if (bootverbose)
300117395Skan		ata_printf(scp, device,
30152284Sobrien			   "%s setting UDMA2 on Aladdin chip\n",
302117395Skan			   (error) ? "failed" : "success");
303117395Skan	    if (!error) {
30490075Sobrien		word54 &= ~(0x000f000f << (devno << 2));
30590075Sobrien		word54 |= (0x000a0005 << (devno << 2));
30690075Sobrien		pci_write_config(parent, 0x54, word54, 4);
30790075Sobrien		pci_write_config(parent, 0x53,
30890075Sobrien				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
30990075Sobrien		scp->flags |= ATA_ATAPI_DMA_RO;
31090075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
31152284Sobrien		return;
31290075Sobrien	    }
31390075Sobrien	}
31490075Sobrien
31590075Sobrien	/* make sure eventual UDMA mode from the BIOS is disabled */
316117395Skan	pci_write_config(parent, 0x54,
317117395Skan			 pci_read_config(parent, 0x54, 4) & ~0x88880000, 4);
31890075Sobrien
31990075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
320117395Skan	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
32152284Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
32290075Sobrien	    if (bootverbose)
323117395Skan		ata_printf(scp, device,
324117395Skan			   "%s setting WDMA2 on Aladdin chip\n",
325117395Skan			   (error) ? "failed" : "success");
32652284Sobrien	    if (!error) {
32790075Sobrien		pci_write_config(parent, 0x53,
328117395Skan				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
329117395Skan		scp->flags |= ATA_ATAPI_DMA_RO;
330117395Skan		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
331117395Skan		return;
332117395Skan	    }
33390075Sobrien	}
33490075Sobrien	pci_write_config(parent, 0x53,
33590075Sobrien			 (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1);
33690075Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
33790075Sobrien	break;
33890075Sobrien
33990075Sobrien    case 0x74091022:	/* AMD 756 */
34090075Sobrien	if (udmamode >= 4) {
34190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
34290075Sobrien				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
34390075Sobrien	    if (bootverbose)
34452284Sobrien		ata_printf(scp, device,
34590075Sobrien			   "%s setting UDMA4 on AMD chip\n",
34690075Sobrien			   (error) ? "failed" : "success");
34790075Sobrien	    if (!error) {
348117395Skan	        pci_write_config(parent, 0x53 - devno, 0xc3, 1);
34990075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
350117395Skan		return;
351117395Skan	    }
35290075Sobrien	}
35390075Sobrien	goto via_82c586;
35490075Sobrien
35590075Sobrien    case 0x05711106:	/* VIA 82C571, 82C586, 82C596, 82C686 */
35652284Sobrien	if (ata_find_dev(parent, 0x06861106, 0) ||		/* 82C686a */
35752284Sobrien	    ata_find_dev(parent, 0x05961106, 0x12)) {		/* 82C596b */
35890075Sobrien
35952284Sobrien	    if (udmamode >= 4) {
36090075Sobrien		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
36190075Sobrien				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
36290075Sobrien		if (bootverbose)
36390075Sobrien		    ata_printf(scp, device,
36490075Sobrien			       "%s setting UDMA4 on VIA chip\n",
36590075Sobrien			       (error) ? "failed" : "success");
36690075Sobrien		if (!error) {
367117395Skan		    pci_write_config(parent, 0x53 - devno, 0xe8, 1);
36852284Sobrien		    scp->mode[ATA_DEV(device)] = ATA_UDMA4;
369117395Skan		    return;
370117395Skan		}
37152284Sobrien	    }
37290075Sobrien	    if (udmamode >= 2) {
37390075Sobrien		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
37490075Sobrien				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
37590075Sobrien		if (bootverbose)
37690075Sobrien		    ata_printf(scp, device,
377117395Skan			       "%s setting UDMA2 on VIA chip\n",
37890075Sobrien			       (error) ? "failed" : "success");
37990075Sobrien		if (!error) {
38090075Sobrien		    pci_write_config(parent, 0x53 - devno, 0xea, 1);
38190075Sobrien		    scp->mode[ATA_DEV(device)] = ATA_UDMA2;
38290075Sobrien		    return;
38390075Sobrien		}
38490075Sobrien	    }
38590075Sobrien	}
38690075Sobrien	else if (ata_find_dev(parent, 0x05961106, 0) ||		/* 82C596a */
38790075Sobrien		 ata_find_dev(parent, 0x05861106, 0x02)) {	/* 82C586b */
38890075Sobrienvia_82c586:
38990075Sobrien	    if (udmamode >= 2) {
39052284Sobrien		error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
39152284Sobrien				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
39290075Sobrien		if (bootverbose)
39390075Sobrien		    ata_printf(scp, device, "%s setting UDMA2 on %s chip\n",
39490075Sobrien			       (error) ? "failed" : "success",
39590075Sobrien			       (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
39690075Sobrien		if (!error) {
39752284Sobrien	            pci_write_config(parent, 0x53 - devno, 0xc0, 1);
39890075Sobrien		    scp->mode[ATA_DEV(device)] = ATA_UDMA2;
39990075Sobrien		    return;
40090075Sobrien		}
40190075Sobrien	    }
40290075Sobrien	}
40352284Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
40490075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
40590075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
40652284Sobrien	    if (bootverbose)
40790075Sobrien		ata_printf(scp, device, "%s setting WDMA2 on %s chip\n",
40890075Sobrien			   (error) ? "failed" : "success",
40990075Sobrien			   (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
41090075Sobrien	    if (!error) {
41190075Sobrien	        pci_write_config(parent, 0x53 - devno, 0x82, 1);
41290075Sobrien	        pci_write_config(parent, 0x4b - devno, 0x31, 1);
413117395Skan		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
414117395Skan		return;
415117395Skan	    }
416117395Skan	}
41790075Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
41890075Sobrien	break;
41952284Sobrien
42090075Sobrien    case 0x55131039:	/* SiS 5591 */
421117395Skan	if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) {
422117395Skan	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
42390075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
42490075Sobrien	    if (bootverbose)
42552284Sobrien		ata_printf(scp, device,
42690075Sobrien			   "%s setting UDMA2 on SiS chip\n",
427117395Skan			   (error) ? "failed" : "success");
428117395Skan	    if (!error) {
42990075Sobrien		pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
43090075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
43190075Sobrien		return;
43290075Sobrien	    }
43352284Sobrien	}
434117395Skan	if (wdmamode >=2 && apiomode >= 4) {
435117395Skan	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
43690075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
43790075Sobrien	    if (bootverbose)
43852284Sobrien		ata_printf(scp, device,
43990075Sobrien			   "%s setting WDMA2 on SiS chip\n",
44090075Sobrien			   (error) ? "failed" : "success");
44190075Sobrien	    if (!error) {
44252284Sobrien		pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
44390075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
44490075Sobrien		return;
44590075Sobrien	    }
44690075Sobrien	}
44752284Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
44890075Sobrien	break;
44990075Sobrien
45090075Sobrien    case 0x06491095:	/* CMD 649 ATA100 controller */
45152284Sobrien	if (udmamode >= 5) {
45290075Sobrien	    u_int8_t umode;
45390075Sobrien
45490075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
455117395Skan				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
45690075Sobrien	    if (bootverbose)
45790075Sobrien		ata_printf(scp, device, "%s setting UDMA5 on CMD chip\n",
45890075Sobrien			   (error) ? "failed" : "success");
45990075Sobrien	    if (!error) {
46090075Sobrien		umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1);
461117395Skan		umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
46290075Sobrien		umode |= (device == ATA_MASTER ? 0x05 : 0x0a);
46352284Sobrien		pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1);
46490075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA5;
46552284Sobrien		return;
46690075Sobrien	    }
46752284Sobrien	}
46890075Sobrien	/* FALLTHROUGH */
469117395Skan
47090075Sobrien    case 0x06481095:	/* CMD 648 ATA66 controller */
47152284Sobrien	if (udmamode >= 4) {
47290075Sobrien	    u_int8_t umode;
47390075Sobrien
47452284Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
47590075Sobrien				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
47690075Sobrien	    if (bootverbose)
47790075Sobrien		ata_printf(scp, device, "%s setting UDMA4 on CMD chip\n",
47890075Sobrien			   (error) ? "failed" : "success");
47990075Sobrien	    if (!error) {
480117395Skan		umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1);
48190075Sobrien		umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
48290075Sobrien		umode |= (device == ATA_MASTER ? 0x15 : 0x4a);
48390075Sobrien		pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1);
48490075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
48590075Sobrien		return;
48690075Sobrien	    }
48790075Sobrien	}
48890075Sobrien	if (udmamode >= 2) {
48990075Sobrien	    u_int8_t umode;
49090075Sobrien
49190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
49290075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
49352284Sobrien	    if (bootverbose)
49490075Sobrien		ata_printf(scp, device, "%s setting UDMA2 on CMD chip\n",
495117395Skan			   (error) ? "failed" : "success");
49690075Sobrien	    if (!error) {
49752284Sobrien		umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1);
49890075Sobrien		umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
49990075Sobrien		umode |= (device == ATA_MASTER ? 0x11 : 0x42);
50090075Sobrien		pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1);
50190075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
50290075Sobrien		return;
50352284Sobrien	    }
50490075Sobrien	}
505117395Skan	/* make sure eventual UDMA mode from the BIOS is disabled */
50652284Sobrien	pci_write_config(parent, scp->channel ? 0x7b : 0x73,
50790075Sobrien			 pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1)&
50890075Sobrien			 ~(device == ATA_MASTER ? 0x35 : 0xca), 1);
509117395Skan	/* FALLTHROUGH */
51052284Sobrien
511117395Skan    case 0x06461095:	/* CMD 646 ATA controller */
512117395Skan	if (wdmamode >= 2 && apiomode >= 4) {
51390075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
51490075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
51590075Sobrien	    if (bootverbose)
51690075Sobrien		ata_printf(scp, device, "%s setting WDMA2 on CMD chip\n",
51790075Sobrien			   error ? "failed" : "success");
51890075Sobrien	    if (!error) {
51990075Sobrien		int32_t offset = (devno < 3) ? (devno << 1) : 7;
52090075Sobrien
52190075Sobrien		pci_write_config(parent, 0x54 + offset, 0x3f, 1);
52290075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
52390075Sobrien		return;
52490075Sobrien	    }
52590075Sobrien	}
52690075Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
52790075Sobrien	break;
528117395Skan
52990075Sobrien    case 0xc6931080:	/* Cypress 82c693 ATA controller */
53090075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
53190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
532117395Skan				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
53390075Sobrien	    if (bootverbose)
53490075Sobrien		ata_printf(scp, device,
53590075Sobrien			   "%s setting WDMA2 on Cypress chip\n",
53690075Sobrien			   error ? "failed" : "success");
537117395Skan	    if (!error) {
53890075Sobrien		pci_write_config(scp->dev, scp->channel ? 0x4e:0x4c, 0x2020, 2);
53990075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
540117395Skan		return;
54190075Sobrien	    }
54252284Sobrien	}
54390075Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
54490075Sobrien	break;
545117395Skan
546117395Skan    case 0x01021078:	/* Cyrix 5530 ATA33 controller */
54790075Sobrien	scp->alignment = 0xf;	/* DMA engine requires 16 byte alignment */
54890075Sobrien	if (udmamode >= 2) {
549117395Skan	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
55090075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
55190075Sobrien	    if (bootverbose)
55290075Sobrien		ata_printf(scp, device, "%s setting UDMA2 on Cyrix chip\n",
553117395Skan			   (error) ? "failed" : "success");
55490075Sobrien	    if (!error) {
55552284Sobrien		cyrix_timing(scp, devno, ATA_UDMA2);
55690075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
55790075Sobrien		return;
55890075Sobrien	    }
55990075Sobrien	}
56090075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
561117395Skan	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
56252284Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
56352284Sobrien	    if (bootverbose)
56452284Sobrien		ata_printf(scp, device, "%s setting WDMA2 on Cyrix chip\n",
56590075Sobrien			   (error) ? "failed" : "success");
56690075Sobrien	    if (!error) {
56790075Sobrien		cyrix_timing(scp, devno, ATA_WDMA2);
56852284Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
56952284Sobrien		return;
57090075Sobrien	    }
57152284Sobrien	}
57252284Sobrien	error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
57390075Sobrien			    ata_pio2mode(apiomode), ATA_C_F_SETXFER,
57490075Sobrien			    ATA_WAIT_READY);
57590075Sobrien	if (bootverbose)
57652284Sobrien	    ata_printf(scp, device, "%s setting %s on Cyrix chip\n",
57790075Sobrien		       (error) ? "failed" : "success",
57852284Sobrien		       ata_mode2str(ata_pio2mode(apiomode)));
57990075Sobrien	cyrix_timing(scp, devno, ata_pio2mode(apiomode));
58090075Sobrien	scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
58190075Sobrien	return;
58252284Sobrien
58390075Sobrien    case 0x02111166:	/* ServerWorks ROSB4 ATA33 controller */
58490075Sobrien	if (udmamode >= 2) {
58590075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
58652284Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
58752284Sobrien	    if (bootverbose)
58890075Sobrien		ata_printf(scp, device,
58952284Sobrien			   "%s setting UDMA2 on ServerWorks chip\n",
59090075Sobrien			   (error) ? "failed" : "success");
59190075Sobrien	    if (!error) {
59290075Sobrien		u_int16_t reg56;
59390075Sobrien
59490075Sobrien		pci_write_config(parent, 0x54,
59552284Sobrien				 pci_read_config(parent, 0x54, 1) |
59690075Sobrien				 (0x01 << devno), 1);
59790075Sobrien		reg56 = pci_read_config(parent, 0x56, 2);
59890075Sobrien		reg56 &= ~(0xf << (devno * 4));
59990075Sobrien		reg56 |= (0x2 << (devno * 4));
60090075Sobrien		pci_write_config(parent, 0x56, reg56, 2);
60190075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
60290075Sobrien		return;
60390075Sobrien	    }
60490075Sobrien	}
60590075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
60652284Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
60752284Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
60890075Sobrien	    if (bootverbose)
60990075Sobrien		ata_printf(scp, device,
61090075Sobrien			   "%s setting WDMA2 on ServerWorks chip\n",
61152284Sobrien			   (error) ? "failed" : "success");
61252284Sobrien	    if (!error) {
61390075Sobrien		int offset = (scp->channel * 2) + (device == ATA_MASTER);
61452284Sobrien		int word44 = pci_read_config(parent, 0x44, 4);
61590075Sobrien
61690075Sobrien		pci_write_config(parent, 0x54,
61752284Sobrien				 pci_read_config(parent, 0x54, 1) &
61852284Sobrien				 ~(0x01 << devno), 1);
61990075Sobrien		word44 &= ~(0xff << (offset << 8));
62090075Sobrien		word44 |= (0x20 << (offset << 8));
62190075Sobrien		pci_write_config(parent, 0x44, 0x20, 4);
62252284Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
623117395Skan		return;
62490075Sobrien	    }
625117395Skan	}
62652284Sobrien	/* we could set PIO mode timings, but we assume the BIOS did that */
62790075Sobrien	break;
62852284Sobrien
62990075Sobrien    case 0x4d33105a:	/* Promise Ultra/FastTrak 33 controllers */
63090075Sobrien    case 0x4d38105a:	/* Promise Ultra/FastTrak 66 controllers */
63190075Sobrien    case 0x4d30105a:	/* Promise Ultra/FastTrak 100 controllers */
63290075Sobrien    case 0x0d30105a:	/* Promise OEM ATA100 controllers */
63390075Sobrien	/* the Promise can only do DMA on ATA disks not on ATAPI devices */
63490075Sobrien	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
63590075Sobrien	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
63690075Sobrien	    break;
63790075Sobrien
63890075Sobrien	if (udmamode >= 5 &&
63990075Sobrien	    (scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
64090075Sobrien	    !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){
64190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
64290075Sobrien				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
64390075Sobrien	    if (bootverbose)
64490075Sobrien		ata_printf(scp, device,
64590075Sobrien			   "%s setting UDMA5 on Promise chip\n",
64690075Sobrien			   (error) ? "failed" : "success");
64790075Sobrien	    if (!error) {
64890075Sobrien		promise_timing(scp, devno, ATA_UDMA5);
64990075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA5;
65090075Sobrien		return;
65190075Sobrien	    }
652117395Skan	}
65352284Sobrien	if (udmamode >= 4 && (scp->chiptype == 0x4d38105a ||
654117395Skan	    scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) &&
655117395Skan	    !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){
65652284Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
65790075Sobrien				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
65890075Sobrien	    if (bootverbose)
65990075Sobrien		ata_printf(scp, device,
66090075Sobrien			   "%s setting UDMA4 on Promise chip\n",
66190075Sobrien			   (error) ? "failed" : "success");
662117395Skan	    if (!error) {
663117395Skan		promise_timing(scp, devno, ATA_UDMA4);
66490075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
66590075Sobrien		return;
666117395Skan	    }
667117395Skan	}
668117395Skan	if (udmamode >= 2) {
66990075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
67090075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
67190075Sobrien	    if (bootverbose)
672117395Skan		ata_printf(scp, device,
673117395Skan			   "%s setting UDMA2 on Promise chip\n",
674117395Skan			   (error) ? "failed" : "success");
675117395Skan	    if (!error) {
676117395Skan		promise_timing(scp, devno, ATA_UDMA2);
67790075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
67890075Sobrien		return;
67990075Sobrien	    }
68090075Sobrien	}
68190075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
68290075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
68390075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
68490075Sobrien	    if (bootverbose)
68590075Sobrien		ata_printf(scp, device,
68690075Sobrien			   "%s setting WDMA2 on Promise chip\n",
68790075Sobrien			   (error) ? "failed" : "success");
68890075Sobrien	    if (!error) {
689117395Skan		promise_timing(scp, devno, ATA_WDMA2);
69090075Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
691117395Skan		return;
692117395Skan	    }
69390075Sobrien	}
69490075Sobrien	error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
69590075Sobrien			    ata_pio2mode(apiomode),
69690075Sobrien			    ATA_C_F_SETXFER, ATA_WAIT_READY);
69752284Sobrien	if (bootverbose)
69852284Sobrien	    ata_printf(scp, device,
69990075Sobrien		       "%s setting PIO%d on Promise chip\n",
70052284Sobrien		       (error) ? "failed" : "success",
70152284Sobrien		       (apiomode >= 0) ? apiomode : 0);
70290075Sobrien	promise_timing(scp, devno, ata_pio2mode(apiomode));
70390075Sobrien	scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
70490075Sobrien	return;
70590075Sobrien
70652284Sobrien    case 0x00041103:	/* HighPoint HPT366/368/370 controllers */
70790075Sobrien	/* no ATAPI devices for now */
708117395Skan	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
70952284Sobrien	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
710117395Skan	    break;
711117395Skan
71290075Sobrien	if (udmamode >=5 && pci_get_revid(parent) >= 0x03 &&
71390075Sobrien	    !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) {
71490075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
71590075Sobrien				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
71690075Sobrien	    if (bootverbose)
717117395Skan		ata_printf(scp, device,
71890075Sobrien			   "%s setting UDMA5 on HighPoint chip\n",
71990075Sobrien			   (error) ? "failed" : "success");
72090075Sobrien	    if (!error) {
72152284Sobrien		hpt_timing(scp, devno, ATA_UDMA5);
72252284Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA5;
72390075Sobrien		return;
72490075Sobrien	    }
72590075Sobrien	}
72690075Sobrien	if (udmamode >=4 &&
72752284Sobrien	    !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) {
72890075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
72990075Sobrien				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
73090075Sobrien	    if (bootverbose)
73190075Sobrien		ata_printf(scp, device,
73252284Sobrien			   "%s setting UDMA4 on HighPoint chip\n",
73390075Sobrien			   (error) ? "failed" : "success");
73490075Sobrien	    if (!error) {
73590075Sobrien		hpt_timing(scp, devno, ATA_UDMA4);
73690075Sobrien		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
73790075Sobrien		return;
73890075Sobrien	    }
73952284Sobrien	}
74090075Sobrien	if (udmamode >= 2) {
74190075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
74290075Sobrien				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
74390075Sobrien	    if (bootverbose)
74490075Sobrien		ata_printf(scp, device,
74552284Sobrien			   "%s setting UDMA2 on HighPoint chip\n",
74690075Sobrien			   (error) ? "failed" : "success");
74790075Sobrien	    if (!error) {
74852284Sobrien		hpt_timing(scp, devno, ATA_UDMA2);
749117395Skan		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
750117395Skan		return;
751117395Skan	    }
752117395Skan	}
75390075Sobrien	if (wdmamode >= 2 && apiomode >= 4) {
75490075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
75590075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
756117395Skan	    if (bootverbose)
757117395Skan		ata_printf(scp, device,
75890075Sobrien			   "%s setting WDMA2 on HighPoint chip\n",
75990075Sobrien			   (error) ? "failed" : "success");
76090075Sobrien	    if (!error) {
76190075Sobrien		hpt_timing(scp, devno, ATA_WDMA2);
76252284Sobrien		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
76390075Sobrien		return;
76490075Sobrien	    }
76590075Sobrien	}
766117395Skan	error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
767117395Skan			    ata_pio2mode(apiomode),
768117395Skan			    ATA_C_F_SETXFER, ATA_WAIT_READY);
769117395Skan	if (bootverbose)
770117395Skan	    ata_printf(scp, device, "%s setting PIO%d on HighPoint chip\n",
771117395Skan		       (error) ? "failed" : "success",
77252284Sobrien		       (apiomode >= 0) ? apiomode : 0);
77390075Sobrien	hpt_timing(scp, devno, ata_pio2mode(apiomode));
77490075Sobrien	scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
77590075Sobrien	return;
77690075Sobrien
77790075Sobrien    default:		/* unknown controller chip */
778117395Skan	/* better not try generic DMA on ATAPI devices it almost never works */
779117395Skan	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
78090075Sobrien	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
78190075Sobrien	    break;
78290075Sobrien
78390075Sobrien	/* if controller says its setup for DMA take the easy way out */
78490075Sobrien	/* the downside is we dont know what DMA mode we are in */
78590075Sobrien	if ((udmamode >= 0 || wdmamode > 1) &&
78690075Sobrien	    (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
78790075Sobrien	     ((device==ATA_MASTER) ?
78890075Sobrien	      ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
78990075Sobrien	    scp->mode[ATA_DEV(device)] = ATA_DMA;
79090075Sobrien	    return;
79190075Sobrien	}
79290075Sobrien
79390075Sobrien	/* well, we have no support for this, but try anyways */
79490075Sobrien	if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
79590075Sobrien	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
79690075Sobrien				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
79790075Sobrien	    if (bootverbose)
79890075Sobrien		ata_printf(scp, device,
79990075Sobrien			   "%s setting WDMA2 on generic chip\n",
80090075Sobrien			   (error) ? "failed" : "success");
80190075Sobrien	    if (!error) {
802117395Skan		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
80390075Sobrien		return;
80490075Sobrien	    }
80590075Sobrien	}
80690075Sobrien    }
80790075Sobrien    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
80890075Sobrien			ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY);
809117395Skan    if (bootverbose)
81090075Sobrien	ata_printf(scp, device, "%s setting PIO%d on generic chip\n",
81190075Sobrien		   (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode);
81290075Sobrien    if (!error)
81390075Sobrien        scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
81490075Sobrien    else {
81590075Sobrien	if (bootverbose)
81690075Sobrien	    ata_printf(scp, device, "using PIO mode set by BIOS\n");
817117395Skan        scp->mode[ATA_DEV(device)] = ATA_PIO;
81890075Sobrien    }
81990075Sobrien}
82090075Sobrien
82190075Sobrienint
82290075Sobrienata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab,
82390075Sobrien	     caddr_t data, int32_t count)
82490075Sobrien{
82590075Sobrien    u_int32_t dma_count, dma_base;
82690075Sobrien    int i = 0;
82790075Sobrien
82890075Sobrien    if (((uintptr_t)data & scp->alignment) || (count & scp->alignment)) {
829117395Skan	ata_printf(scp, device, "non aligned DMA transfer attempted\n");
83090075Sobrien	return -1;
83190075Sobrien    }
83290075Sobrien
83352284Sobrien    if (!count) {
83452284Sobrien	ata_printf(scp, device, "zero length DMA transfer attempted\n");
83590075Sobrien	return -1;
83652284Sobrien    }
83790075Sobrien
83890075Sobrien    dma_base = vtophys(data);
83990075Sobrien    dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK)));
84090075Sobrien    data += dma_count;
84190075Sobrien    count -= dma_count;
84290075Sobrien
84390075Sobrien    while (count) {
84490075Sobrien	dmatab[i].base = dma_base;
84590075Sobrien	dmatab[i].count = (dma_count & 0xffff);
84690075Sobrien	i++;
84790075Sobrien	if (i >= ATA_DMA_ENTRIES) {
84890075Sobrien	    ata_printf(scp, device, "too many segments in DMA table\n");
84990075Sobrien	    return -1;
85090075Sobrien	}
85190075Sobrien	dma_base = vtophys(data);
85290075Sobrien	dma_count = min(count, PAGE_SIZE);
85390075Sobrien	data += min(count, PAGE_SIZE);
85490075Sobrien	count -= min(count, PAGE_SIZE);
85590075Sobrien    }
85690075Sobrien    dmatab[i].base = dma_base;
85790075Sobrien    dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT;
85890075Sobrien    return 0;
85990075Sobrien}
86090075Sobrien
86190075Sobrienvoid
86290075Sobrienata_dmastart(struct ata_softc *scp, int device,
86390075Sobrien	     struct ata_dmaentry *dmatab, int dir)
86490075Sobrien{
86590075Sobrien    scp->flags |= ATA_DMA_ACTIVE;
86690075Sobrien    outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
86790075Sobrien    outb(scp->bmaddr + ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
86890075Sobrien    outb(scp->bmaddr + ATA_BMSTAT_PORT,
86990075Sobrien         (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
87090075Sobrien	  (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
87190075Sobrien    outb(scp->bmaddr + ATA_BMCMD_PORT,
87290075Sobrien	 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
87390075Sobrien}
87490075Sobrien
87590075Sobrienint
87690075Sobrienata_dmadone(struct ata_softc *scp)
87790075Sobrien{
87890075Sobrien    outb(scp->bmaddr + ATA_BMCMD_PORT,
87990075Sobrien	 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
88090075Sobrien    scp->flags &= ~ATA_DMA_ACTIVE;
88190075Sobrien    return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
88290075Sobrien}
88390075Sobrien
88490075Sobrienint
88590075Sobrienata_dmastatus(struct ata_softc *scp)
88690075Sobrien{
88790075Sobrien    return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
88890075Sobrien}
88990075Sobrien
89090075Sobrienstatic void
89190075Sobriencyrix_timing(struct ata_softc *scp, int devno, int mode)
89290075Sobrien{
89390075Sobrien    u_int32_t reg20 = 0x0000e132;
89490075Sobrien    u_int32_t reg24 = 0x00017771;
89590075Sobrien
89690075Sobrien    switch (mode) {
89790075Sobrien    case ATA_PIO0:	reg20 = 0x0000e132; break;
89890075Sobrien    case ATA_PIO1:	reg20 = 0x00018121; break;
89990075Sobrien    case ATA_PIO2:	reg20 = 0x00024020; break;
90090075Sobrien    case ATA_PIO3:	reg20 = 0x00032010; break;
90190075Sobrien    case ATA_PIO4:	reg20 = 0x00040010; break;
90290075Sobrien    case ATA_WDMA2:	reg24 = 0x00002020; break;
90390075Sobrien    case ATA_UDMA2:	reg24 = 0x00911030; break;
90490075Sobrien    }
90590075Sobrien    outl(scp->bmaddr + (devno << 3) + 0x20, reg20);
90690075Sobrien    outl(scp->bmaddr + (devno << 3) + 0x24, reg24);
90790075Sobrien}
90890075Sobrien
90990075Sobrienstatic void
91090075Sobrienpromise_timing(struct ata_softc *scp, int devno, int mode)
91190075Sobrien{
91290075Sobrien    u_int32_t timing = 0;
91390075Sobrien    struct promise_timing {
91490075Sobrien	u_int8_t  pa:4;
91590075Sobrien	u_int8_t  prefetch:1;
91690075Sobrien	u_int8_t  iordy:1;
91790075Sobrien	u_int8_t  errdy:1;
91890075Sobrien	u_int8_t  syncin:1;
91990075Sobrien	u_int8_t  pb:5;
92052284Sobrien	u_int8_t  mb:3;
92190075Sobrien	u_int8_t  mc:4;
92290075Sobrien	u_int8_t  dmaw:1;
92390075Sobrien	u_int8_t  dmar:1;
92452284Sobrien	u_int8_t  iordyp:1;
92590075Sobrien	u_int8_t  dmarqp:1;
92652284Sobrien	u_int8_t  reserved:8;
92790075Sobrien    } *t = (struct promise_timing*)&timing;
92890075Sobrien
92990075Sobrien    t->iordy = 1; t->iordyp = 1;
93052284Sobrien    if (mode >= ATA_DMA) {
93190075Sobrien	t->prefetch = 1; t->errdy = 1; t->syncin = 1;
93290075Sobrien    }
933117395Skan
93490075Sobrien    switch (scp->chiptype) {
93552284Sobrien    case 0x4d33105a:  /* Promise Ultra/Fasttrak 33 */
93652284Sobrien	switch (mode) {
93752284Sobrien	default:
93890075Sobrien	case ATA_PIO0:  t->pa =  9; t->pb = 19; t->mb = 7; t->mc = 15; break;
93990075Sobrien	case ATA_PIO1:  t->pa =  5; t->pb = 12; t->mb = 7; t->mc = 15; break;
94090075Sobrien	case ATA_PIO2:  t->pa =  3; t->pb =  8; t->mb = 7; t->mc = 15; break;
94190075Sobrien	case ATA_PIO3:  t->pa =  2; t->pb =  6; t->mb = 7; t->mc = 15; break;
94290075Sobrien	case ATA_PIO4:  t->pa =  1; t->pb =  4; t->mb = 7; t->mc = 15; break;
94352284Sobrien	case ATA_WDMA2: t->pa =  3; t->pb =  7; t->mb = 3; t->mc =  3; break;
94452284Sobrien	case ATA_UDMA2: t->pa =  3; t->pb =  7; t->mb = 1; t->mc =  1; break;
94590075Sobrien	}
94690075Sobrien	break;
94790075Sobrien
94852284Sobrien    case 0x4d38105a:  /* Promise Ultra/Fasttrak 66 */
94990075Sobrien    case 0x4d30105a:  /* Promise Ultra/Fasttrak 100 */
95052284Sobrien    case 0x0d30105a:  /* Promise OEM ATA 100 */
95190075Sobrien	switch (mode) {
95290075Sobrien	default:
95390075Sobrien	case ATA_PIO0:  t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
95452284Sobrien	case ATA_PIO1:  t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break;
95590075Sobrien	case ATA_PIO2:  t->pa =  6; t->pb = 16; t->mb = 7; t->mc = 15; break;
95690075Sobrien	case ATA_PIO3:  t->pa =  4; t->pb = 12; t->mb = 7; t->mc = 15; break;
95752284Sobrien	case ATA_PIO4:  t->pa =  2; t->pb =  8; t->mb = 7; t->mc = 15; break;
95890075Sobrien	case ATA_WDMA2: t->pa =  6; t->pb = 14; t->mb = 6; t->mc =  6; break;
95990075Sobrien	case ATA_UDMA2: t->pa =  6; t->pb = 14; t->mb = 2; t->mc =  2; break;
96052284Sobrien	case ATA_UDMA4: t->pa =  3; t->pb =  7; t->mb = 1; t->mc =  1; break;
96190075Sobrien	case ATA_UDMA5: t->pa =  3; t->pb =  7; t->mb = 1; t->mc =  1; break;
96252284Sobrien	}
96390075Sobrien	break;
96490075Sobrien    }
96590075Sobrien    pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4);
96690075Sobrien}
96790075Sobrien
96890075Sobrienstatic void
96990075Sobrienhpt_timing(struct ata_softc *scp, int devno, int mode)
97090075Sobrien{
97190075Sobrien    device_t parent = device_get_parent(scp->dev);
97290075Sobrien    u_int32_t timing;
97390075Sobrien
97490075Sobrien    if (pci_get_revid(parent) >= 0x03) {	/* HPT370 */
97590075Sobrien	switch (mode) {
97690075Sobrien	case ATA_PIO0:	timing = 0x06914e57; break;
97790075Sobrien	case ATA_PIO1:	timing = 0x06914e43; break;
97890075Sobrien	case ATA_PIO2:	timing = 0x06514e33; break;
97990075Sobrien	case ATA_PIO3:	timing = 0x06514e22; break;
98052284Sobrien	case ATA_PIO4:	timing = 0x06514e21; break;
98152284Sobrien	case ATA_WDMA2:	timing = 0x26514e21; break;
98290075Sobrien	case ATA_UDMA2:	timing = 0x16494e31; break;
98390075Sobrien	case ATA_UDMA4:	timing = 0x16454e31; break;
98452284Sobrien	case ATA_UDMA5:	timing = 0x16454e31; break;
98552284Sobrien	default:	timing = 0x06514e57;
98690075Sobrien	}
98790075Sobrien	pci_write_config(parent, 0x40 + (devno << 2) , timing, 4);
98890075Sobrien	pci_write_config(parent, 0x5b, 0x22, 1);
98990075Sobrien    }
99052284Sobrien    else {					/* HPT36[68] */
99190075Sobrien	switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
99252284Sobrien	case 0x85:	/* 25Mhz */
99390075Sobrien	    switch (mode) {
99490075Sobrien	    case ATA_PIO0:	timing = 0xc0d08585; break;
99552284Sobrien	    case ATA_PIO1:	timing = 0xc0d08572; break;
99690075Sobrien	    case ATA_PIO2:	timing = 0xc0ca8542; break;
99790075Sobrien	    case ATA_PIO3:	timing = 0xc0ca8532; break;
99852284Sobrien	    case ATA_PIO4:	timing = 0xc0ca8521; break;
99990075Sobrien	    case ATA_WDMA2:	timing = 0xa0ca8521; break;
100090075Sobrien	    case ATA_UDMA2:	timing = 0x90cf8521; break;
100190075Sobrien	    case ATA_UDMA4:	timing = 0x90c98521; break;
100290075Sobrien	    default:		timing = 0x01208585;
100390075Sobrien	    }
100490075Sobrien	    break;
100590075Sobrien	default:
100690075Sobrien	case 0xa7:	/* 33MHz */
100790075Sobrien	    switch (mode) {
100890075Sobrien	    case ATA_PIO0:	timing = 0xc0d0a7aa; break;
100990075Sobrien	    case ATA_PIO1:	timing = 0xc0d0a7a3; break;
101090075Sobrien	    case ATA_PIO2:	timing = 0xc0d0a753; break;
101190075Sobrien	    case ATA_PIO3:	timing = 0xc0c8a742; break;
101290075Sobrien	    case ATA_PIO4:	timing = 0xc0c8a731; break;
101390075Sobrien	    case ATA_WDMA2:	timing = 0xa0c8a731; break;
1014117395Skan	    case ATA_UDMA2:	timing = 0x90caa731; break;
1015117395Skan	    case ATA_UDMA4:	timing = 0x90c9a731; break;
101690075Sobrien	    default:		timing = 0x0120a7a7;
101790075Sobrien	    }
101890075Sobrien	    break;
101990075Sobrien	case 0xd9:	/* 40Mhz */
1020117395Skan	    switch (mode) {
102190075Sobrien	    case ATA_PIO0:	timing = 0xc018d9d9; break;
102290075Sobrien	    case ATA_PIO1:	timing = 0xc010d9c7; break;
102390075Sobrien	    case ATA_PIO2:	timing = 0xc010d997; break;
102490075Sobrien	    case ATA_PIO3:	timing = 0xc010d974; break;
102590075Sobrien	    case ATA_PIO4:	timing = 0xc008d963; break;
102690075Sobrien	    case ATA_WDMA2:	timing = 0xa008d943; break;
1027117395Skan	    case ATA_UDMA2:	timing = 0x900bd943; break;
102890075Sobrien	    case ATA_UDMA4:	timing = 0x900fd943; break;
1029117395Skan	    default:		timing = 0x0120d9d9;
103090075Sobrien	    }
103190075Sobrien	}
103290075Sobrien	pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4);
103390075Sobrien    }
1034117395Skan}
1035117395Skan
1036117395Skan#else /* NPCI > 0 */
1037117395Skan
1038117395Skanvoid *
1039117395Skanata_dmaalloc(struct ata_softc *scp, int device)
1040117395Skan{
1041117395Skan    return 0;
104290075Sobrien}
1043117395Skan
1044117395Skanvoid
104590075Sobrienata_dmainit(struct ata_softc *scp, int device,
104690075Sobrien	    int piomode, int wdmamode, int udmamode)
104790075Sobrien{
104890075Sobrien}
104990075Sobrien
105090075Sobrienint
105190075Sobrienata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab,
105290075Sobrien	     caddr_t data, int32_t count)
105390075Sobrien{
1054117395Skan    return -1;
1055117395Skan}
1056117395Skan
1057117395Skanvoid
1058117395Skanata_dmastart(struct ata_softc *scp, int device,
1059117395Skan	     struct ata_dmaentry *dmatab, int dir)
1060117395Skan{
1061117395Skan}
1062117395Skan
1063117395Skanint
1064117395Skanata_dmadone(struct ata_softc *scp)
1065117395Skan{
1066117395Skan    return -1;
1067117395Skan}
1068117395Skan
1069117395Skanint
1070117395Skanata_dmastatus(struct ata_softc *scp)
1071117395Skan{
1072117395Skan    return -1;
1073117395Skan}
1074117395Skan
107590075Sobrien#endif /* NPCI > 0 */
107690075Sobrien