ata-dma.c revision 57771
145095Ssos/*-
255333Ssos * Copyright (c) 1998,1999,2000 S�ren Schmidt
345095Ssos * All rights reserved.
445095Ssos *
545095Ssos * Redistribution and use in source and binary forms, with or without
645095Ssos * modification, are permitted provided that the following conditions
745095Ssos * are met:
845095Ssos * 1. Redistributions of source code must retain the above copyright
945095Ssos *    notice, this list of conditions and the following disclaimer,
1045095Ssos *    without modification, immediately at the beginning of the file.
1145095Ssos * 2. Redistributions in binary form must reproduce the above copyright
1245095Ssos *    notice, this list of conditions and the following disclaimer in the
1345095Ssos *    documentation and/or other materials provided with the distribution.
1445095Ssos * 3. The name of the author may not be used to endorse or promote products
1545095Ssos *    derived from this software without specific prior written permission.
1645095Ssos *
1745095Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1845095Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1945095Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2045095Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2145095Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2245095Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2345095Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2445095Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2545095Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2645095Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2745095Ssos *
2850477Speter * $FreeBSD: head/sys/dev/ata/ata-dma.c 57771 2000-03-05 16:52:26Z sos $
2945095Ssos */
3045095Ssos
3145150Ssos#include "pci.h"
3245095Ssos#include <sys/param.h>
3345095Ssos#include <sys/systm.h>
3445095Ssos#include <sys/buf.h>
3545095Ssos#include <sys/malloc.h>
3645798Ssos#include <sys/bus.h>
3754270Ssos#include <sys/disk.h>
3854270Ssos#include <sys/devicestat.h>
3951520Ssos#include <vm/vm.h>
4045095Ssos#include <vm/pmap.h>
4147272Ssos#if NPCI > 0
4245095Ssos#include <pci/pcivar.h>
4347272Ssos#endif
4445095Ssos#include <dev/ata/ata-all.h>
4554270Ssos#include <dev/ata/ata-disk.h>
4645095Ssos
4756754Ssos#if NPCI > 0
4856754Ssos
4952067Ssos/* prototypes */
5055333Ssosstatic void promise_timing(struct ata_softc *, int32_t, int32_t);
5152067Ssosstatic void hpt366_timing(struct ata_softc *, int32_t, int32_t);
5252067Ssos
5352067Ssos/* misc defines */
5445720Speter#ifdef __alpha__
5545720Speter#undef vtophys
5651520Ssos#define vtophys(va)	alpha_XXX_dmamap((vm_offset_t)va)
5745720Speter#endif
5845720Speter
5956744Ssosvoid
6045095Ssosata_dmainit(struct ata_softc *scp, int32_t device,
6145095Ssos	    int32_t apiomode, int32_t wdmamode, int32_t udmamode)
6245095Ssos{
6357325Ssos    device_t parent = device_get_parent(scp->dev);
6456558Ssos    int32_t devno = (scp->unit << 1) + ATA_DEV(device);
6555333Ssos    int32_t error;
6645095Ssos
6756744Ssos    /* set our most pessimistic default mode */
6856744Ssos    scp->mode[ATA_DEV(device)] = ATA_PIO;
6956744Ssos
7045095Ssos    if (!scp->bmaddr)
7156744Ssos	return;
7245095Ssos
7352067Ssos    /* if simplex controller, only allow DMA on primary channel */
7452067Ssos    if (scp->unit == 1) {
7552067Ssos	outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) &
7652067Ssos	     (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
7752067Ssos	if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) {
7856558Ssos	    ata_printf(scp, device, "simplex device, DMA on primary only\n");
7956744Ssos	    return;
8052067Ssos	}
8152067Ssos    }
8252067Ssos
8356558Ssos    if (!scp->dmatab[ATA_DEV(device)]) {
8456558Ssos	void *dmatab;
8545095Ssos
8656558Ssos	if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT)))
8756744Ssos	    return;
8856558Ssos	if (((uintptr_t)dmatab >> PAGE_SHIFT) ^
8956558Ssos	    (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
9056558Ssos	    ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n");
9156558Ssos	    free(dmatab, M_DEVBUF);
9256744Ssos	    return;
9356558Ssos	}
9456558Ssos	scp->dmatab[ATA_DEV(device)] = dmatab;
9545095Ssos    }
9645095Ssos
9755333Ssos    switch (scp->chiptype) {
9845095Ssos
9957391Ssos    case 0x24118086:    /* Intel ICH */
10057391Ssos	if (udmamode >= 4) {
10157391Ssos	    int32_t mask48, new48;
10257391Ssos	    int16_t word54;
10357391Ssos
10457391Ssos	    word54 = pci_read_config(parent, 0x54, 2);
10557391Ssos	    if (word54 & (0x10 << devno)) {
10657391Ssos	        error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
10757391Ssos				    ATA_UDMA4,  ATA_C_F_SETXFER,ATA_WAIT_READY);
10857391Ssos	    	if (bootverbose)
10957391Ssos		    ata_printf(scp, device,
11057391Ssos			       "%s setting up UDMA4 mode on ICH chip\n",
11157391Ssos			       (error) ? "failed" : "success");
11257391Ssos		if (!error) {
11357391Ssos		    mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
11457391Ssos		    new48 = (1 << devno) + (2 << (16 + (devno << 2)));
11557391Ssos		    pci_write_config(parent, 0x48,
11657391Ssos				     (pci_read_config(parent, 0x48, 4) &
11757391Ssos				     ~mask48) | new48, 4);
11857391Ssos		    pci_write_config(parent, 0x54, word54 | (1 << devno), 2);
11957391Ssos		    scp->mode[ATA_DEV(device)] = ATA_UDMA4;
12057391Ssos		    return;
12157391Ssos		}
12257391Ssos	    }
12357391Ssos	}
12457391Ssos	/* FALLTHROUGH */
12557391Ssos
12645095Ssos    case 0x71118086:	/* Intel PIIX4 */
12756138Ssos    case 0x71998086:	/* Intel PIIX4e */
12856138Ssos    case 0x24218086:	/* Intel ICH0 */
12945095Ssos	if (udmamode >= 2) {
13051520Ssos	    int32_t mask48, new48;
13145095Ssos
13245095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
13353029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
13451520Ssos	    if (bootverbose)
13556558Ssos		ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n",
13656558Ssos			   (error) ? "failed" : "success",
13756558Ssos			   (scp->chiptype == 0x24118086) ? "ICH" :
13856558Ssos			    (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
13953681Ssos	    if (!error) {
14053681Ssos		mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
14153681Ssos		new48 = (1 << devno) + (2 << (16 + (devno << 2)));
14257325Ssos		pci_write_config(parent, 0x48,
14357325Ssos				 (pci_read_config(parent, 0x48, 4) &
14453681Ssos				 ~mask48) | new48, 4);
14556558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
14656744Ssos		return;
14753681Ssos	    }
14845095Ssos	}
14945095Ssos	/* FALLTHROUGH */
15045095Ssos
15145095Ssos    case 0x70108086:	/* Intel PIIX3 */
15245095Ssos	if (wdmamode >= 2 && apiomode >= 4) {
15345095Ssos	    int32_t mask40, new40, mask44, new44;
15445095Ssos
15545095Ssos	    /* if SITRE not set doit for both channels */
15657325Ssos	    if (!((pci_read_config(parent, 0x40, 4)>>(scp->unit<<8))&0x4000)){
15757325Ssos		new40 = pci_read_config(parent, 0x40, 4);
15857325Ssos		new44 = pci_read_config(parent, 0x44, 4);
15951520Ssos		if (!(new40 & 0x00004000)) {
16051520Ssos		    new44 &= ~0x0000000f;
16151520Ssos		    new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8);
16251520Ssos		}
16351520Ssos		if (!(new40 & 0x40000000)) {
16451520Ssos		    new44 &= ~0x000000f0;
16551520Ssos		    new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20);
16651520Ssos		}
16751520Ssos		new40 |= 0x40004000;
16857325Ssos		pci_write_config(parent, 0x40, new40, 4);
16957325Ssos		pci_write_config(parent, 0x44, new44, 4);
17045095Ssos	    }
17145095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
17253029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
17351520Ssos	    if (bootverbose)
17456558Ssos		ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n",
17556558Ssos			   (error) ? "failed" : "success",
17656558Ssos			   (scp->chiptype == 0x70108086) ? "PIIX3" :
17756558Ssos			    (scp->chiptype == 0x24118086) ? "ICH" :
17856558Ssos			     (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4");
17953681Ssos	    if (!error) {
18053681Ssos		if (device == ATA_MASTER) {
18153681Ssos		    mask40 = 0x0000330f;
18253681Ssos		    new40 = 0x00002307;
18353681Ssos		    mask44 = 0;
18453681Ssos		    new44 = 0;
18553681Ssos		}
18653681Ssos		else {
18753681Ssos		    mask40 = 0x000000f0;
18853681Ssos		    new40 = 0x00000070;
18953681Ssos		    mask44 = 0x0000000f;
19053681Ssos		    new44 = 0x0000000b;
19153681Ssos		}
19253681Ssos		if (scp->unit) {
19353681Ssos		    mask40 <<= 16;
19453681Ssos		    new40 <<= 16;
19553681Ssos		    mask44 <<= 4;
19653681Ssos		    new44 <<= 4;
19753681Ssos		}
19857325Ssos		pci_write_config(parent, 0x40,
19957325Ssos				 (pci_read_config(parent, 0x40, 4) & ~mask40)|
20053681Ssos 				 new40, 4);
20157325Ssos		pci_write_config(parent, 0x44,
20257325Ssos				 (pci_read_config(parent, 0x44, 4) & ~mask44)|
20353681Ssos 				 new44, 4);
20456558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
20556744Ssos		return;
20645095Ssos	    }
20751520Ssos	}
20853681Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
20945095Ssos	break;
21045095Ssos
21145095Ssos    case 0x12308086:	/* Intel PIIX */
21254544Ssos	if (wdmamode >= 2 && apiomode >= 4) {
21354544Ssos	    int32_t word40;
21454544Ssos
21557325Ssos	    word40 = pci_read_config(parent, 0x40, 4);
21654544Ssos	    word40 >>= scp->unit * 16;
21754544Ssos
21854544Ssos	    /* Check for timing config usable for DMA on controller */
21954544Ssos	    if (!((word40 & 0x3300) == 0x2300 &&
22054544Ssos		  ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1))
22154544Ssos		break;
22254544Ssos
22354544Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
22454544Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
22554544Ssos	    if (bootverbose)
22656558Ssos		ata_printf(scp, device,
22756558Ssos			   "%s setting up WDMA2 mode on PIIX chip\n",
22856558Ssos			   (error) ? "failed" : "success");
22954544Ssos	    if (!error) {
23056558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
23156744Ssos		return;
23254544Ssos	    }
23354544Ssos	}
23445095Ssos	break;
23545095Ssos
23652067Ssos    case 0x522910b9:	/* AcerLabs Aladdin IV/V */
23753029Ssos	/* the Aladdin doesn't support ATAPI DMA on both master & slave */
23853029Ssos	if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) {
23956558Ssos	    ata_printf(scp, device,
24056558Ssos		       "Aladdin: two atapi devices on this channel, no DMA\n");
24153029Ssos	    break;
24252067Ssos	}
24353681Ssos	if (udmamode >= 2) {
24457325Ssos	    int32_t word54 = pci_read_config(parent, 0x54, 4);
24552067Ssos
24651520Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
24753029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
24851520Ssos	    if (bootverbose)
24956558Ssos		ata_printf(scp, device,
25056558Ssos			   "%s setting up UDMA2 mode on Aladdin chip\n",
25156558Ssos			   (error) ? "failed" : "success");
25253681Ssos	    if (!error) {
25353681Ssos		word54 |= 0x5555;
25453681Ssos		word54 |= (0x0a << (16 + (scp->unit << 3) + (device << 2)));
25557325Ssos		pci_write_config(parent, 0x54, word54, 4);
25657325Ssos		pci_write_config(parent, 0x53,
25757325Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
25853681Ssos		scp->flags |= ATA_ATAPI_DMA_RO;
25956558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
26056744Ssos		return;
26153681Ssos	    }
26251520Ssos	}
26353681Ssos	if (wdmamode >= 2 && apiomode >= 4) {
26452067Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
26553029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
26652067Ssos	    if (bootverbose)
26756558Ssos		ata_printf(scp, device,
26856558Ssos			   "%s setting up WDMA2 mode on Aladdin chip\n",
26956558Ssos			   (error) ? "failed" : "success");
27053681Ssos	    if (!error) {
27157325Ssos		pci_write_config(parent, 0x53,
27257325Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
27353681Ssos		scp->flags |= ATA_ATAPI_DMA_RO;
27456558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
27556744Ssos		return;
27653681Ssos	    }
27752067Ssos	}
27857771Ssos	pci_write_config(parent, 0x53,
27957771Ssos			 (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1);
28053681Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
28152067Ssos	break;
28252067Ssos
28356988Ssos    case 0x06861106:	/* VIA 82C686 */
28456988Ssos	if (udmamode >= 4) {
28556988Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
28656988Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
28756988Ssos	    if (bootverbose)
28856988Ssos		ata_printf(scp, device,
28956988Ssos			   "%s setting up UDMA4 mode on VIA chip\n",
29056988Ssos			   (error) ? "failed" : "success");
29156988Ssos	    if (!error) {
29257325Ssos		pci_write_config(parent, 0x53 - devno, 0xe8, 1);
29356988Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
29456988Ssos		return;
29556138Ssos	    }
29656988Ssos	}
29756988Ssos	if (udmamode >= 2) {
29856988Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
29956988Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
30056988Ssos	    if (bootverbose)
30156988Ssos		ata_printf(scp, device,
30256988Ssos			   "%s setting up UDMA2 mode on VIA chip\n",
30356988Ssos			   (error) ? "failed" : "success");
30456988Ssos	    if (!error) {
30557325Ssos		pci_write_config(parent, 0x53 - devno, 0xea, 1);
30656988Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
30756988Ssos		return;
30856138Ssos	    }
30956138Ssos	}
31056988Ssos	goto via_generic;
31156138Ssos
31256988Ssos    case 0x74091022:	/* AMD 756 */
31356988Ssos	if (udmamode >= 4) {
31454270Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
31556138Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
31654270Ssos	    if (bootverbose)
31756558Ssos		ata_printf(scp, device,
31856558Ssos			   "%s setting up UDMA4 mode on AMD chip\n",
31956558Ssos			   (error) ? "failed" : "success");
32054270Ssos	    if (!error) {
32157325Ssos	        pci_write_config(parent, 0x53 - devno, 0xc3, 1);
32256558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
32356744Ssos		return;
32453681Ssos	    }
32554270Ssos	}
32656988Ssos	/* FALLTHROUGH */
32754270Ssos
32856988Ssos    case 0x05961106:	/* VIA 82C596 */
32956988Ssos    case 0x05861106:	/* VIA 82C586 */
33056988Ssos
33156138Ssos	/* UDMA2 mode only on 82C586 > rev1, 82C596, AMD 756 */
33256988Ssos	if ((udmamode >= 2 && scp->chiptype == 0x05861106 &&
33355333Ssos	     pci_read_config(scp->dev, 0x08, 1) >= 0x01) ||
33456988Ssos	    (udmamode >= 2 && scp->chiptype == 0x05961106) ||
33555333Ssos	    (udmamode >= 2 && scp->chiptype == 0x74091022)) {
33653681Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
33753681Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
33853681Ssos	    if (bootverbose)
33956558Ssos		ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n",
34056558Ssos			   (error) ? "failed" : "success",
34156558Ssos			   (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
34253681Ssos	    if (!error) {
34357325Ssos	        pci_write_config(parent, 0x53 - devno, 0xc0, 1);
34456558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
34556744Ssos		return;
34653681Ssos	    }
34753681Ssos	}
34856988Ssos	/* FALLTHROUGH */
34956988Ssos
35056988Ssos    case 0x05711106:	/* VIA 82C571 */
35156988Ssosvia_generic:
35253681Ssos	if (wdmamode >= 2 && apiomode >= 4) {
35353681Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
35453681Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
35553681Ssos	    if (bootverbose)
35656558Ssos		ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n",
35756558Ssos			   (error) ? "failed" : "success",
35856558Ssos			   (scp->chiptype == 0x74091022) ? "AMD" : "VIA");
35953681Ssos	    if (!error) {
36057325Ssos	        pci_write_config(parent, 0x53 - devno, 0x82, 1);
36157325Ssos	        pci_write_config(parent, 0x4b - devno, 0x31, 1);
36256558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
36356744Ssos		return;
36453681Ssos	    }
36553681Ssos	}
36653681Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
36753681Ssos	break;
36853681Ssos
36954544Ssos    case 0x55131039:	/* SiS 5591 */
37054544Ssos	if (udmamode >= 2) {
37154544Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
37254544Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
37354544Ssos	    if (bootverbose)
37456558Ssos		ata_printf(scp, device,
37556558Ssos			   "%s setting up UDMA2 mode on SiS chip\n",
37656558Ssos			   (error) ? "failed" : "success");
37754544Ssos	    if (!error) {
37857325Ssos		pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
37956558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
38056744Ssos		return;
38154544Ssos	    }
38254544Ssos	}
38354544Ssos	if (wdmamode >=2 && apiomode >= 4) {
38454544Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
38554544Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
38654544Ssos	    if (bootverbose)
38756558Ssos		ata_printf(scp, device,
38856558Ssos			   "%s setting up WDMA2 mode on SiS chip\n",
38956558Ssos			   (error) ? "failed" : "success");
39054544Ssos	    if (!error) {
39157325Ssos		pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
39256558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
39356744Ssos		return;
39454544Ssos	    }
39554544Ssos	}
39654544Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
39754544Ssos	break;
39854544Ssos
39957325Ssos    case 0x06461095:	/* CMD 646 ATA controller */
40057325Ssos	if (wdmamode >= 2 && apiomode >= 4) {
40157325Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
40257325Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
40357325Ssos	    if (bootverbose)
40457325Ssos		ata_printf(scp, device,
40557325Ssos			   "%s setting up WDMA2 mode on CMD646 chip\n",
40657325Ssos			   error ? "failed" : "success");
40757325Ssos	    if (!error) {
40857325Ssos		int32_t offset = (devno < 3) ? (devno << 1) : 7;
40957325Ssos
41057325Ssos		pci_write_config(parent, 0x54 + offset, 0x3f, 1);
41157325Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
41257325Ssos		return;
41357325Ssos	    }
41457325Ssos	}
41557325Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
41657325Ssos	break;
41757325Ssos
41857477Ssos    case 0xc6931080:	/* Cypress 82c693 ATA controller */
41957477Ssos	if (wdmamode >= 2 && apiomode >= 4) {
42057477Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
42157477Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
42257477Ssos	    if (bootverbose)
42357477Ssos		ata_printf(scp, device,
42457477Ssos			   "%s setting up WDMA2 mode on Cypress chip\n",
42557477Ssos			   error ? "failed" : "success");
42657477Ssos	    if (!error) {
42757477Ssos		pci_write_config(scp->dev, scp->unit ? 0x4e : 0x4c, 0x2020, 2);
42857477Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
42957477Ssos		return;
43057477Ssos	    }
43157477Ssos	}
43257477Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
43357477Ssos	break;
43457477Ssos
43552067Ssos    case 0x4d33105a:	/* Promise Ultra33 / FastTrak33 controllers */
43652067Ssos    case 0x4d38105a:	/* Promise Ultra66 / FastTrak66 controllers */
43752067Ssos	/* the Promise can only do DMA on ATA disks not on ATAPI devices */
43852067Ssos	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
43952067Ssos	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
44052067Ssos	    break;
44152067Ssos
44255333Ssos	if (udmamode >=4 && scp->chiptype == 0x4d38105a &&
44357325Ssos	    !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
44452918Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
44553029Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
44652918Ssos	    if (bootverbose)
44756558Ssos		ata_printf(scp, device,
44856558Ssos			   "%s setting up UDMA4 mode on Promise chip\n",
44956558Ssos			   (error) ? "failed" : "success");
45053681Ssos	    if (!error) {
45155333Ssos		promise_timing(scp, devno, ATA_UDMA4);
45256558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
45356744Ssos		return;
45453681Ssos	    }
45552918Ssos	}
45653681Ssos	if (udmamode >= 2) {
45745095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
45853029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
45951520Ssos	    if (bootverbose)
46056558Ssos		ata_printf(scp, device,
46156558Ssos			   "%s setting up UDMA2 mode on Promise chip\n",
46256558Ssos			   (error) ? "failed" : "success");
46353681Ssos	    if (!error) {
46455333Ssos		promise_timing(scp, devno, ATA_UDMA2);
46556558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
46656744Ssos		return;
46753681Ssos	    }
46845095Ssos	}
46953681Ssos	if (wdmamode >= 2 && apiomode >= 4) {
47045095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
47153029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
47251520Ssos	    if (bootverbose)
47356558Ssos		ata_printf(scp, device,
47456558Ssos			   "%s setting up WDMA2 mode on Promise chip\n",
47556558Ssos			   (error) ? "failed" : "success");
47653681Ssos	    if (!error) {
47755333Ssos		promise_timing(scp, devno, ATA_WDMA2);
47856558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
47956744Ssos		return;
48053681Ssos	    }
48151520Ssos	}
48255333Ssos	error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
48355333Ssos			    ata_pio2mode(apiomode),
48455333Ssos			    ATA_C_F_SETXFER, ATA_WAIT_READY);
48553681Ssos	if (bootverbose)
48656558Ssos	    ata_printf(scp, device,
48756558Ssos		       "%s setting up PIO%d mode on Promise chip\n",
48856558Ssos		       (error) ? "failed" : "success",
48956558Ssos		       (apiomode >= 0) ? apiomode : 0);
49056686Ssos	promise_timing(scp, devno, ata_pio2mode(apiomode));
49156686Ssos	scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
49256744Ssos	return;
49345095Ssos
49454270Ssos    case 0x00041103:	/* HighPoint HPT366 controller */
49553681Ssos	/* no ATAPI devices for now */
49651520Ssos	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
49752067Ssos	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
49852067Ssos	    break;
49951520Ssos
50057325Ssos	if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) {
50152067Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
50253029Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
50352067Ssos	    if (bootverbose)
50456558Ssos		ata_printf(scp, device,
50556558Ssos			   "%s setting up UDMA4 mode on HPT366 chip\n",
50656558Ssos			   (error) ? "failed" : "success");
50753681Ssos	    if (!error) {
50855333Ssos		hpt366_timing(scp, devno, ATA_UDMA4);
50956558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA4;
51056744Ssos		return;
51153681Ssos	    }
51251520Ssos	}
51353681Ssos	if (udmamode >= 2) {
51452067Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
51553029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
51651520Ssos	    if (bootverbose)
51756558Ssos		ata_printf(scp, device,
51856558Ssos			   "%s setting up UDMA2 mode on HPT366 chip\n",
51956558Ssos			   (error) ? "failed" : "success");
52053681Ssos	    if (!error) {
52155333Ssos		hpt366_timing(scp, devno, ATA_UDMA2);
52256558Ssos		scp->mode[ATA_DEV(device)] = ATA_UDMA2;
52356744Ssos		return;
52453681Ssos	    }
52545095Ssos	}
52653681Ssos	if (wdmamode >= 2 && apiomode >= 4) {
52745095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
52853029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
52951520Ssos	    if (bootverbose)
53056558Ssos		ata_printf(scp, device,
53156558Ssos			   "%s setting up WDMA2 mode on HPT366 chip\n",
53256558Ssos			   (error) ? "failed" : "success");
53353681Ssos	    if (!error) {
53455333Ssos		hpt366_timing(scp, devno, ATA_WDMA2);
53556558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
53656744Ssos		return;
53753681Ssos	    }
53845095Ssos	}
53955333Ssos	error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
54055333Ssos			    ata_pio2mode(apiomode),
54155333Ssos			    ATA_C_F_SETXFER, ATA_WAIT_READY);
54253681Ssos	if (bootverbose)
54356558Ssos	    ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n",
54456558Ssos		       (error) ? "failed" : "success",
54556558Ssos		       (apiomode >= 0) ? apiomode : 0);
54656686Ssos	hpt366_timing(scp, devno, ata_pio2mode(apiomode));
54756686Ssos	scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
54856744Ssos	return;
54945095Ssos
55051548Ssos    default:		/* unknown controller chip */
55151548Ssos	/* better not try generic DMA on ATAPI devices it almost never works */
55251548Ssos	if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
55351548Ssos	    (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
55451548Ssos	    break;
55551548Ssos
55656744Ssos	/* if controller says its setup for DMA take the easy way out */
55756744Ssos	/* the downside is we dont know what DMA mode we are in */
55856744Ssos	if ((udmamode >= 0 || wdmamode > 1) &&
55956744Ssos	    (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
56056744Ssos	     ((device==ATA_MASTER) ?
56156744Ssos	      ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
56256744Ssos	    scp->mode[ATA_DEV(device)] = ATA_DMA;
56356744Ssos	    return;
56456744Ssos	}
56556744Ssos
56651548Ssos	/* well, we have no support for this, but try anyways */
56754594Ssos	if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
56845095Ssos	    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
56953029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
57051520Ssos	    if (bootverbose)
57156558Ssos		ata_printf(scp, device,
57256558Ssos			   "%s setting up WDMA2 mode on generic chip\n",
57356558Ssos			   (error) ? "failed" : "success");
57453681Ssos	    if (!error) {
57556558Ssos		scp->mode[ATA_DEV(device)] = ATA_WDMA2;
57656744Ssos		return;
57753681Ssos	    }
57845095Ssos	}
57945095Ssos    }
58056988Ssos    error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
58156988Ssos			ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY);
58255333Ssos    if (bootverbose)
58356988Ssos	ata_printf(scp, device, "%s setting up PIO%d mode on generic chip\n",
58456988Ssos		   (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode);
58556988Ssos    if (!error)
58656988Ssos        scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
58757771Ssos    else {
58856988Ssos	if (bootverbose)
58956988Ssos	    ata_printf(scp, device, "using PIO mode set by BIOS\n");
59057771Ssos        scp->mode[ATA_DEV(device)] = ATA_PIO;
59157771Ssos    }
59245095Ssos}
59345095Ssos
59445095Ssosint32_t
59545095Ssosata_dmasetup(struct ata_softc *scp, int32_t device,
59645095Ssos	     int8_t *data, int32_t count, int32_t flags)
59745095Ssos{
59845095Ssos    struct ata_dmaentry *dmatab;
59945095Ssos    u_int32_t dma_count, dma_base;
60045095Ssos    int32_t i = 0;
60145095Ssos
60245720Speter    if (((uintptr_t)data & 1) || (count & 1))
60345095Ssos	return -1;
60445095Ssos
60545095Ssos    if (!count) {
60656558Ssos	ata_printf(scp, device, "zero length DMA transfer attempted\n");
60745095Ssos	return -1;
60845095Ssos    }
60945095Ssos
61056558Ssos    dmatab = scp->dmatab[ATA_DEV(device)];
61145095Ssos    dma_base = vtophys(data);
61256558Ssos    dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK)));
61345095Ssos    data += dma_count;
61445095Ssos    count -= dma_count;
61545095Ssos
61645095Ssos    while (count) {
61745095Ssos	dmatab[i].base = dma_base;
61845095Ssos	dmatab[i].count = (dma_count & 0xffff);
61945095Ssos	i++;
62045095Ssos	if (i >= ATA_DMA_ENTRIES) {
62156558Ssos	    ata_printf(scp, device, "too many segments in DMA table\n");
62245095Ssos	    return -1;
62345095Ssos	}
62445095Ssos	dma_base = vtophys(data);
62556558Ssos	dma_count = min(count, PAGE_SIZE);
62656558Ssos	data += min(count, PAGE_SIZE);
62756558Ssos	count -= min(count, PAGE_SIZE);
62845095Ssos    }
62945095Ssos    dmatab[i].base = dma_base;
63045095Ssos    dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT;
63145095Ssos    outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
63245095Ssos    outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0);
63345095Ssos    outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
63445095Ssos				   (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
63545095Ssos    return 0;
63645095Ssos}
63745095Ssos
63845095Ssosvoid
63952067Ssosata_dmastart(struct ata_softc *scp)
64045095Ssos{
64152067Ssos    scp->flags |= ATA_DMA_ACTIVE;
64245095Ssos    outb(scp->bmaddr + ATA_BMCMD_PORT,
64345095Ssos	 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
64445095Ssos}
64545095Ssos
64645095Ssosint32_t
64752067Ssosata_dmadone(struct ata_softc *scp)
64845095Ssos{
64945095Ssos    outb(scp->bmaddr + ATA_BMCMD_PORT,
65045095Ssos	 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
65152067Ssos    scp->flags &= ~ATA_DMA_ACTIVE;
65245095Ssos    return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
65345095Ssos}
65445095Ssos
65545095Ssosint32_t
65652067Ssosata_dmastatus(struct ata_softc *scp)
65745095Ssos{
65845095Ssos    return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
65945095Ssos}
66045095Ssos
66152067Ssosstatic void
66255333Ssospromise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
66352067Ssos{
66456988Ssos    u_int32_t timing = 0;
66556988Ssos    struct promise_timing {
66656988Ssos	u_int8_t  pa:4;
66756988Ssos	u_int8_t  prefetch:1;
66856988Ssos	u_int8_t  iordy:1;
66956988Ssos	u_int8_t  errdy:1;
67056988Ssos	u_int8_t  syncin:1;
67156988Ssos	u_int8_t  pb:5;
67256988Ssos	u_int8_t  mb:3;
67356988Ssos	u_int8_t  mc:4;
67456988Ssos	u_int8_t  dmaw:1;
67556988Ssos	u_int8_t  dmar:1;
67656988Ssos	u_int8_t  iordyp:1;
67756988Ssos	u_int8_t  dmarqp:1;
67856988Ssos	u_int8_t  reserved:8;
67956988Ssos    } *t = (struct promise_timing*)&timing;
68056988Ssos
68156988Ssos    t->iordy = 1; t->iordyp = 1;
68256988Ssos    if (mode >= ATA_DMA) {
68356988Ssos	t->prefetch = 1; t->errdy = 1; t->syncin = 1;
68455333Ssos    }
68556988Ssos
68656988Ssos    switch (scp->chiptype) {
68756988Ssos    case 0x4d33105a:  /* Promise 33's */
68856988Ssos	switch (mode) {
68956988Ssos	default:
69056988Ssos	case ATA_PIO0:  t->pa =  9; t->pb = 19; t->mb = 7; t->mc = 15; break;
69156988Ssos	case ATA_PIO1:  t->pa =  5; t->pb = 12; t->mb = 7; t->mc = 15; break;
69256988Ssos	case ATA_PIO2:  t->pa =  3; t->pb =  8; t->mb = 7; t->mc = 15; break;
69356988Ssos	case ATA_PIO3:  t->pa =  2; t->pb =  6; t->mb = 7; t->mc = 15; break;
69456988Ssos	case ATA_PIO4:  t->pa =  1; t->pb =  4; t->mb = 7; t->mc = 15; break;
69556988Ssos	case ATA_WDMA2: t->pa =  3; t->pb =  7; t->mb = 3; t->mc =  3; break;
69656988Ssos	case ATA_UDMA2: t->pa =  3; t->pb =  7; t->mb = 1; t->mc =  1; break;
69756988Ssos	}
69856988Ssos	break;
69956988Ssos
70056988Ssos    case 0x4d38105a:  /* Promise 66's */
70156988Ssos	switch (mode) {
70256988Ssos	default:
70356988Ssos	case ATA_PIO0:  t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
70456988Ssos	case ATA_PIO1:  t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break;
70556988Ssos	case ATA_PIO2:  t->pa =  6; t->pb = 16; t->mb = 7; t->mc = 15; break;
70656988Ssos	case ATA_PIO3:  t->pa =  4; t->pb = 12; t->mb = 7; t->mc = 15; break;
70756988Ssos	case ATA_PIO4:  t->pa =  2; t->pb =  8; t->mb = 7; t->mc = 15; break;
70856988Ssos	case ATA_WDMA2: t->pa =  6; t->pb = 14; t->mb = 6; t->mc =  6; break;
70956988Ssos	case ATA_UDMA2: t->pa =  6; t->pb = 14; t->mb = 2; t->mc =  2; break;
71056988Ssos	case ATA_UDMA4: t->pa =  3; t->pb =  7; t->mb = 1; t->mc =  1; break;
71156988Ssos	}
71256988Ssos	break;
71356988Ssos    }
71457325Ssos    pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4);
71555333Ssos}
71652067Ssos
71755333Ssosstatic void
71855333Ssoshpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
71955333Ssos{
72057325Ssos    device_t parent = device_get_parent(scp->dev);
72155333Ssos    u_int32_t timing;
72255333Ssos
72357325Ssos    switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
72452067Ssos    case 0x85:	/* 25Mhz */
72552067Ssos	switch (mode) {
72655333Ssos	case ATA_PIO0:	timing = 0xc0d08585; break;
72755333Ssos	case ATA_PIO1:	timing = 0xc0d08572; break;
72855333Ssos	case ATA_PIO2:	timing = 0xc0ca8542; break;
72955333Ssos	case ATA_PIO3:	timing = 0xc0ca8532; break;
73055333Ssos	case ATA_PIO4:	timing = 0xc0ca8521; break;
73155333Ssos	case ATA_WDMA2:	timing = 0xa0ca8521; break;
73255333Ssos	case ATA_UDMA2:	timing = 0x90cf8521; break;
73355333Ssos	case ATA_UDMA4:	timing = 0x90c98521; break;
73455333Ssos	default:	timing = 0x01208585;
73552067Ssos	}
73652067Ssos	break;
73752067Ssos    default:
73852067Ssos    case 0xa7:	/* 33MHz */
73952067Ssos	switch (mode) {
74055333Ssos	case ATA_PIO0:	timing = 0xc0d0a7aa; break;
74155333Ssos	case ATA_PIO1:	timing = 0xc0d0a7a3; break;
74255333Ssos	case ATA_PIO2:	timing = 0xc0d0a753; break;
74355333Ssos	case ATA_PIO3:	timing = 0xc0c8a742; break;
74455333Ssos	case ATA_PIO4:	timing = 0xc0c8a731; break;
74555333Ssos	case ATA_WDMA2:	timing = 0xa0c8a731; break;
74655333Ssos	case ATA_UDMA2:	timing = 0x90caa731; break;
74755333Ssos	case ATA_UDMA4:	timing = 0x90c9a731; break;
74855333Ssos	default:	timing = 0x0120a7a7;
74952067Ssos	}
75052067Ssos	break;
75152067Ssos    case 0xd9:	/* 40Mhz */
75252067Ssos	switch (mode) {
75355333Ssos	case ATA_PIO0:	timing = 0xc018d9d9; break;
75455333Ssos	case ATA_PIO1:	timing = 0xc010d9c7; break;
75555333Ssos	case ATA_PIO2:	timing = 0xc010d997; break;
75655333Ssos	case ATA_PIO3:	timing = 0xc010d974; break;
75755333Ssos	case ATA_PIO4:	timing = 0xc008d963; break;
75855333Ssos	case ATA_WDMA2:	timing = 0xa008d943; break;
75955333Ssos	case ATA_UDMA2:	timing = 0x900bd943; break;
76055333Ssos	case ATA_UDMA4:	timing = 0x900fd943; break;
76155333Ssos	default:	timing = 0x0120d9d9;
76252067Ssos	}
76352067Ssos    }
76457325Ssos    pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
76552067Ssos}
76652067Ssos
76745095Ssos#else /* NPCI > 0 */
76845095Ssos
76956754Ssosvoid
77045095Ssosata_dmainit(struct ata_softc *scp, int32_t device,
77151520Ssos	    int32_t piomode, int32_t wdmamode, int32_t udmamode)
77245095Ssos{
77345095Ssos}
77445095Ssos
77545095Ssosint32_t
77645095Ssosata_dmasetup(struct ata_softc *scp, int32_t device,
77751520Ssos	     int8_t *data, int32_t count, int32_t flags)
77845095Ssos{
77945095Ssos    return -1;
78045095Ssos}
78145095Ssos
78245095Ssosvoid
78352067Ssosata_dmastart(struct ata_softc *scp)
78445095Ssos{
78545095Ssos}
78645095Ssos
78745095Ssosint32_t
78852067Ssosata_dmadone(struct ata_softc *scp)
78945095Ssos{
79045095Ssos    return -1;
79145095Ssos}
79245095Ssos
79345095Ssosint32_t
79452067Ssosata_dmastatus(struct ata_softc *scp)
79545095Ssos{
79645095Ssos    return -1;
79745095Ssos}
79845095Ssos
79945095Ssos#endif /* NPCI > 0 */
800