ata-dma.c revision 98428
145095Ssos/*-
289917Ssos * Copyright (c) 1998,1999,2000,2001,2002 S�ren Schmidt <sos@FreeBSD.org>
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 98428 2002-06-19 12:26:20Z sos $
2945095Ssos */
3045095Ssos
3145095Ssos#include <sys/param.h>
3245095Ssos#include <sys/systm.h>
3374302Ssos#include <sys/ata.h>
3460041Sphk#include <sys/bio.h>
3595533Smike#include <sys/endian.h>
3645095Ssos#include <sys/malloc.h>
3745798Ssos#include <sys/bus.h>
3854270Ssos#include <sys/disk.h>
3954270Ssos#include <sys/devicestat.h>
4045095Ssos#include <pci/pcivar.h>
4166106Ssos#include <machine/bus.h>
4272106Ssos#include <sys/rman.h>
4345095Ssos#include <dev/ata/ata-all.h>
4445095Ssos
4552067Ssos/* prototypes */
4693882Ssosstatic void ata_dmacreate(struct ata_device *, int, int);
4793882Ssosstatic void ata_dmasetupd_cb(void *, bus_dma_segment_t *, int, int);
4893882Ssosstatic void ata_dmasetupc_cb(void *, bus_dma_segment_t *, int, int);
4993882Ssosstatic void cyrix_timing(struct ata_device *, int, int);
5093882Ssosstatic void promise_timing(struct ata_device *, int, int);
5193882Ssosstatic void hpt_timing(struct ata_device *, int, int);
5293882Ssosstatic int hpt_cable80(struct ata_device *);
5352067Ssos
5452067Ssos/* misc defines */
5593882Ssos#define ATAPI_DEVICE(atadev) \
5693882Ssos	((atadev->unit == ATA_MASTER && \
5793882Ssos	  atadev->channel->devices & ATA_ATAPI_MASTER) || \
5893882Ssos	 (atadev->unit == ATA_SLAVE && \
5993882Ssos	  atadev->channel->devices & ATA_ATAPI_SLAVE))
6045720Speter
6193882Ssos#define	MAXSEGSZ	PAGE_SIZE
6293882Ssos#define	MAXTABSZ	PAGE_SIZE
6393882Ssos#define	MAXCTLDMASZ	(2 * (MAXTABSZ + MAXPHYS))
6493882Ssos
6593882Ssosstruct ata_dc_cb_args {
6693882Ssos    bus_addr_t maddr;
6793882Ssos    int error;
6893882Ssos};
6993882Ssos
7093882Ssosstatic void
7193882Ssosata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
7266070Ssos{
7393882Ssos    struct ata_dc_cb_args *cba = (struct ata_dc_cb_args *)xsc;
7466070Ssos
7593882Ssos    if (!(cba->error = error))
7693882Ssos	cba->maddr = segs[0].ds_addr;
7793882Ssos}
7893882Ssos
7993882Ssosint
8093882Ssosata_dmaalloc(struct ata_device *atadev)
8193882Ssos{
8293882Ssos    struct ata_channel *ch;
8393882Ssos    struct ata_dc_cb_args ccba;
8493882Ssos    struct ata_dmastate *ds;
8593882Ssos    int error;
8693882Ssos
8793882Ssos    ch = atadev->channel;
8893882Ssos    ds = &atadev->dmastate;
8993882Ssos    if (!ds->cdmatag) {
9093882Ssos	if ((error = bus_dma_tag_create(ch->dmatag, 1, PAGE_SIZE,
9193882Ssos					BUS_SPACE_MAXADDR_32BIT,
9293882Ssos					BUS_SPACE_MAXADDR, NULL, NULL,
9393882Ssos					MAXTABSZ, 1, MAXTABSZ,
9493882Ssos					BUS_DMA_ALLOCNOW, &ds->cdmatag)))
9593882Ssos	    return error;
9693882Ssos    }
9793882Ssos    if (!ds->ddmatag) {
9893882Ssos	if ((error = bus_dma_tag_create(ch->dmatag, ch->alignment + 1, 0,
9993882Ssos					BUS_SPACE_MAXADDR_32BIT,
10093882Ssos					BUS_SPACE_MAXADDR, NULL, NULL,
10193882Ssos					MAXPHYS, ATA_DMA_ENTRIES, MAXSEGSZ,
10293882Ssos					BUS_DMA_ALLOCNOW, &ds->ddmatag)))
10393882Ssos	    return error;
10493882Ssos    }
10593882Ssos    if (!ds->mdmatab) {
10693882Ssos	if ((error = bus_dmamem_alloc(ds->cdmatag, (void **)&ds->dmatab, 0,
10793882Ssos				      &ds->cdmamap)))
10893882Ssos	    return error;
10993882Ssos
11093882Ssos	if ((error = bus_dmamap_load(ds->cdmatag, ds->cdmamap, ds->dmatab,
11193882Ssos				     MAXTABSZ, ata_dmasetupc_cb, &ccba,
11293882Ssos				     0)) != 0 || ccba.error != 0) {
11393882Ssos	    bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap);
11493882Ssos	    return error;
11566070Ssos	}
11693882Ssos	ds->mdmatab = ccba.maddr;
11766070Ssos    }
11893882Ssos    if (!ds->ddmamap) {
11993882Ssos	if ((error = bus_dmamap_create(ds->ddmatag, 0, &ds->ddmamap)) != 0)
12093882Ssos	    return error;
12193882Ssos    }
12293882Ssos    return 0;
12366070Ssos}
12466070Ssos
12556744Ssosvoid
12693882Ssosata_dmafree(struct ata_device *atadev)
12745095Ssos{
12893882Ssos    struct ata_dmastate *ds;
12993882Ssos
13093882Ssos    ds = &atadev->dmastate;
13193882Ssos    if (ds->mdmatab) {
13293882Ssos	bus_dmamap_unload(ds->cdmatag, ds->cdmamap);
13393882Ssos	bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap);
13493882Ssos	ds->mdmatab = 0;
13593882Ssos	ds->cdmamap = NULL;
13693882Ssos	ds->dmatab = NULL;
13793882Ssos    }
13893882Ssos    if (ds->ddmamap) {
13993882Ssos	bus_dmamap_destroy(ds->ddmatag, ds->ddmamap);
14093882Ssos	ds->ddmamap = NULL;
14193882Ssos    }
14293882Ssos    if (ds->cdmatag) {
14393882Ssos	bus_dma_tag_destroy(ds->cdmatag);
14493882Ssos	ds->cdmatag = NULL;
14593882Ssos    }
14693882Ssos    if (ds->ddmatag) {
14793882Ssos	bus_dma_tag_destroy(ds->ddmatag);
14893882Ssos	ds->ddmatag = NULL;
14993882Ssos    }
15093882Ssos}
15193882Ssos
15293882Ssosvoid
15393882Ssosata_dmafreetags(struct ata_channel *ch)
15493882Ssos{
15593882Ssos
15693882Ssos    if (ch->dmatag) {
15793882Ssos	bus_dma_tag_destroy(ch->dmatag);
15893882Ssos	ch->dmatag = NULL;
15993882Ssos    }
16093882Ssos}
16193882Ssos
16293882Ssosstatic void
16393882Ssosata_dmacreate(struct ata_device *atadev, int apiomode, int mode)
16493882Ssos{
16593882Ssos
16693882Ssos    atadev->mode = mode;
16793882Ssos    if (!atadev->channel->dmatag) {
16893882Ssos	if (bus_dma_tag_create(NULL, 1, 0,
16993882Ssos			       BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
17093882Ssos			       NULL, NULL, MAXCTLDMASZ, ATA_DMA_ENTRIES,
17193882Ssos			       BUS_SPACE_MAXSIZE_32BIT, 0,
17293882Ssos			       &atadev->channel->dmatag)) {
17393882Ssos	    ata_prtdev(atadev, "DMA tag allocation failed, disabling DMA\n");
17493882Ssos	    ata_dmainit(atadev, apiomode, -1, -1);
17593882Ssos	}
17693882Ssos    }
17793882Ssos}
17893882Ssos
17993882Ssosvoid
18093882Ssosata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode)
18193882Ssos{
18293882Ssos    device_t parent = device_get_parent(atadev->channel->dev);
18393882Ssos    int chiptype = atadev->channel->chiptype;
18493882Ssos    int chiprev = pci_get_revid(parent);
18593882Ssos    int channel = atadev->channel->unit;
18693882Ssos    int device = ATA_DEV(atadev->unit);
18793882Ssos    int devno = (channel << 1) + device;
18864307Ssos    int error;
18945095Ssos
19056744Ssos    /* set our most pessimistic default mode */
19190215Ssos    atadev->mode = ATA_PIO;
19256744Ssos
19393882Ssos    if (!atadev->channel->r_bmio)
19456744Ssos	return;
19545095Ssos
19652067Ssos    /* if simplex controller, only allow DMA on primary channel */
19793882Ssos    if (channel == 1) {
19893882Ssos	ATA_OUTB(atadev->channel->r_bmio, ATA_BMSTAT_PORT,
19993882Ssos		 ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) &
20072106Ssos		 (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
20193882Ssos	if (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) &
20293882Ssos	    ATA_BMSTAT_DMA_SIMPLEX) {
20390215Ssos	    ata_prtdev(atadev, "simplex device, DMA on primary only\n");
20456744Ssos	    return;
20552067Ssos	}
20652067Ssos    }
20752067Ssos
20866070Ssos    /* DMA engine address alignment is usually 1 word (2 bytes) */
20993882Ssos    atadev->channel->alignment = 0x1;
21045095Ssos
21185345Ssos#if 1
21293882Ssos    if (udmamode > 2 && !atadev->param->hwres_cblid) {
21390215Ssos	ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n");
21460829Ssos	udmamode = 2;
21560829Ssos    }
21685345Ssos#endif
21793882Ssos    switch (chiptype) {
21845095Ssos
21985352Ssos    case 0x248a8086:	/* Intel ICH3 mobile */
22085352Ssos    case 0x248b8086:	/* Intel ICH3 */
22175553Ssos    case 0x244a8086:	/* Intel ICH2 mobile */
22264307Ssos    case 0x244b8086:	/* Intel ICH2 */
22364307Ssos	if (udmamode >= 5) {
22464307Ssos	    int32_t mask48, new48;
22564307Ssos	    int16_t word54;
22664307Ssos
22764307Ssos	    word54 = pci_read_config(parent, 0x54, 2);
22864307Ssos	    if (word54 & (0x10 << devno)) {
22990215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
23090215Ssos				    ATA_UDMA5,	ATA_C_F_SETXFER,ATA_WAIT_READY);
23190215Ssos		if (bootverbose)
23290215Ssos		    ata_prtdev(atadev, "%s setting UDMA5 on Intel chip\n",
23364307Ssos			       (error) ? "failed" : "success");
23464307Ssos		if (!error) {
23564307Ssos		    mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
23664307Ssos		    new48 = (1 << devno) + (1 << (16 + (devno << 2)));
23764307Ssos		    pci_write_config(parent, 0x48,
23864307Ssos				     (pci_read_config(parent, 0x48, 4) &
23964307Ssos				     ~mask48) | new48, 4);
24090215Ssos		    pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2);
24193882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA5);
24264307Ssos		    return;
24364307Ssos		}
24464307Ssos	    }
24564307Ssos	}
24664479Ssos	/* make sure eventual ATA100 mode from the BIOS is disabled */
24764479Ssos	pci_write_config(parent, 0x54,
24864479Ssos			 pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2);
24964307Ssos	/* FALLTHROUGH */
25064307Ssos
25190215Ssos    case 0x24118086:	/* Intel ICH */
25290215Ssos    case 0x76018086:	/* Intel ICH */
25357391Ssos	if (udmamode >= 4) {
25457391Ssos	    int32_t mask48, new48;
25557391Ssos	    int16_t word54;
25657391Ssos
25757391Ssos	    word54 = pci_read_config(parent, 0x54, 2);
25857391Ssos	    if (word54 & (0x10 << devno)) {
25990215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
26090215Ssos				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
26190215Ssos		if (bootverbose)
26290215Ssos		    ata_prtdev(atadev, "%s setting UDMA4 on Intel chip\n",
26375553Ssos			       (error) ? "failed" : "success");
26457391Ssos		if (!error) {
26557391Ssos		    mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
26657391Ssos		    new48 = (1 << devno) + (2 << (16 + (devno << 2)));
26757391Ssos		    pci_write_config(parent, 0x48,
26857391Ssos				     (pci_read_config(parent, 0x48, 4) &
26957391Ssos				     ~mask48) | new48, 4);
27057391Ssos		    pci_write_config(parent, 0x54, word54 | (1 << devno), 2);
27193882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA4);
27257391Ssos		    return;
27357391Ssos		}
27457391Ssos	    }
27590215Ssos	}
27664479Ssos	/* make sure eventual ATA66 mode from the BIOS is disabled */
27764479Ssos	pci_write_config(parent, 0x54,
27864479Ssos			 pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2);
27957391Ssos	/* FALLTHROUGH */
28057391Ssos
28145095Ssos    case 0x71118086:	/* Intel PIIX4 */
28285352Ssos    case 0x84CA8086:	/* Intel PIIX4 */
28356138Ssos    case 0x71998086:	/* Intel PIIX4e */
28456138Ssos    case 0x24218086:	/* Intel ICH0 */
28545095Ssos	if (udmamode >= 2) {
28651520Ssos	    int32_t mask48, new48;
28745095Ssos
28890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
28953029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
29051520Ssos	    if (bootverbose)
29190215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n",
29275553Ssos			   (error) ? "failed" : "success");
29353681Ssos	    if (!error) {
29453681Ssos		mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
29553681Ssos		new48 = (1 << devno) + (2 << (16 + (devno << 2)));
29657325Ssos		pci_write_config(parent, 0x48,
29757325Ssos				 (pci_read_config(parent, 0x48, 4) &
29853681Ssos				 ~mask48) | new48, 4);
29993882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
30056744Ssos		return;
30153681Ssos	    }
30245095Ssos	}
30364479Ssos	/* make sure eventual ATA33 mode from the BIOS is disabled */
30464479Ssos	pci_write_config(parent, 0x48,
30564479Ssos			 pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4);
30645095Ssos	/* FALLTHROUGH */
30745095Ssos
30845095Ssos    case 0x70108086:	/* Intel PIIX3 */
30945095Ssos	if (wdmamode >= 2 && apiomode >= 4) {
31045095Ssos	    int32_t mask40, new40, mask44, new44;
31145095Ssos
31245095Ssos	    /* if SITRE not set doit for both channels */
31393882Ssos	    if (!((pci_read_config(parent, 0x40, 4) >> (channel<<8)) & 0x4000)){
31457325Ssos		new40 = pci_read_config(parent, 0x40, 4);
31557325Ssos		new44 = pci_read_config(parent, 0x44, 4);
31651520Ssos		if (!(new40 & 0x00004000)) {
31751520Ssos		    new44 &= ~0x0000000f;
31851520Ssos		    new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8);
31951520Ssos		}
32051520Ssos		if (!(new40 & 0x40000000)) {
32151520Ssos		    new44 &= ~0x000000f0;
32251520Ssos		    new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20);
32351520Ssos		}
32451520Ssos		new40 |= 0x40004000;
32557325Ssos		pci_write_config(parent, 0x40, new40, 4);
32657325Ssos		pci_write_config(parent, 0x44, new44, 4);
32745095Ssos	    }
32890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
32953029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
33051520Ssos	    if (bootverbose)
33190215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n",
33275553Ssos			   (error) ? "failed" : "success");
33353681Ssos	    if (!error) {
33453681Ssos		if (device == ATA_MASTER) {
33553681Ssos		    mask40 = 0x0000330f;
33653681Ssos		    new40 = 0x00002307;
33753681Ssos		    mask44 = 0;
33853681Ssos		    new44 = 0;
33953681Ssos		}
34053681Ssos		else {
34153681Ssos		    mask40 = 0x000000f0;
34253681Ssos		    new40 = 0x00000070;
34353681Ssos		    mask44 = 0x0000000f;
34453681Ssos		    new44 = 0x0000000b;
34553681Ssos		}
34693882Ssos		if (channel) {
34753681Ssos		    mask40 <<= 16;
34853681Ssos		    new40 <<= 16;
34953681Ssos		    mask44 <<= 4;
35053681Ssos		    new44 <<= 4;
35153681Ssos		}
35257325Ssos		pci_write_config(parent, 0x40,
35357325Ssos				 (pci_read_config(parent, 0x40, 4) & ~mask40)|
35490215Ssos				 new40, 4);
35557325Ssos		pci_write_config(parent, 0x44,
35657325Ssos				 (pci_read_config(parent, 0x44, 4) & ~mask44)|
35790215Ssos				 new44, 4);
35893882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
35956744Ssos		return;
36045095Ssos	    }
36151520Ssos	}
36253681Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
36345095Ssos	break;
36445095Ssos
36545095Ssos    case 0x12308086:	/* Intel PIIX */
36654544Ssos	if (wdmamode >= 2 && apiomode >= 4) {
36754544Ssos	    int32_t word40;
36854544Ssos
36957325Ssos	    word40 = pci_read_config(parent, 0x40, 4);
37093882Ssos	    word40 >>= channel * 16;
37154544Ssos
37254544Ssos	    /* Check for timing config usable for DMA on controller */
37354544Ssos	    if (!((word40 & 0x3300) == 0x2300 &&
37493882Ssos		  ((word40 >> (device ? 4 : 0)) & 1) == 1))
37554544Ssos		break;
37654544Ssos
37790215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
37854544Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
37954544Ssos	    if (bootverbose)
38090215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n",
38156558Ssos			   (error) ? "failed" : "success");
38254544Ssos	    if (!error) {
38393882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
38456744Ssos		return;
38554544Ssos	    }
38654544Ssos	}
38745095Ssos	break;
38845095Ssos
38952067Ssos    case 0x522910b9:	/* AcerLabs Aladdin IV/V */
39075271Ssos	/* the older Aladdin doesn't support ATAPI DMA on both master & slave */
39193882Ssos	if (chiprev < 0xc2 &&
39293882Ssos	    atadev->channel->devices & ATA_ATAPI_MASTER &&
39393882Ssos	    atadev->channel->devices & ATA_ATAPI_SLAVE) {
39490215Ssos	    ata_prtdev(atadev, "two atapi devices on this channel, no DMA\n");
39553029Ssos	    break;
39652067Ssos	}
39793882Ssos	pci_write_config(parent, 0x58 + (channel << 2), 0x00310001, 4);
39893882Ssos	if (udmamode >= 5 && chiprev >= 0xc4) {
39990215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
40075271Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
40175271Ssos	    if (bootverbose)
40290215Ssos		ata_prtdev(atadev, "%s setting UDMA5 on Acer chip\n",
40375271Ssos			   (error) ? "failed" : "success");
40475271Ssos	    if (!error) {
40575271Ssos		int32_t word54 = pci_read_config(parent, 0x54, 4);
40652067Ssos
40775271Ssos		pci_write_config(parent, 0x4b,
40875271Ssos				 pci_read_config(parent, 0x4b, 1) | 0x01, 1);
40975271Ssos		word54 &= ~(0x000f000f << (devno << 2));
41075271Ssos		word54 |= (0x000f0005 << (devno << 2));
41175271Ssos		pci_write_config(parent, 0x54, word54, 4);
41275271Ssos		pci_write_config(parent, 0x53,
41375271Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
41493882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
41575271Ssos		return;
41675271Ssos	    }
41775271Ssos	}
41893882Ssos	if (udmamode >= 4 && chiprev >= 0xc2) {
41990215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
42075271Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
42175271Ssos	    if (bootverbose)
42290215Ssos		ata_prtdev(atadev, "%s setting UDMA4 on Acer chip\n",
42375271Ssos			   (error) ? "failed" : "success");
42475271Ssos	    if (!error) {
42575271Ssos		int32_t word54 = pci_read_config(parent, 0x54, 4);
42675271Ssos
42775271Ssos		pci_write_config(parent, 0x4b,
42875271Ssos				 pci_read_config(parent, 0x4b, 1) | 0x01, 1);
42975271Ssos		word54 &= ~(0x000f000f << (devno << 2));
43075271Ssos		word54 |= (0x00080005 << (devno << 2));
43175271Ssos		pci_write_config(parent, 0x54, word54, 4);
43275271Ssos		pci_write_config(parent, 0x53,
43375271Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
43493882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
43575271Ssos		return;
43675271Ssos	    }
43775271Ssos	}
43893882Ssos	if (udmamode >= 2 && chiprev >= 0x20) {
43990215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
44053029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
44151520Ssos	    if (bootverbose)
44290215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on Acer chip\n",
44356558Ssos			   (error) ? "failed" : "success");
44453681Ssos	    if (!error) {
44575271Ssos		int32_t word54 = pci_read_config(parent, 0x54, 4);
44675271Ssos
44760829Ssos		word54 &= ~(0x000f000f << (devno << 2));
44860829Ssos		word54 |= (0x000a0005 << (devno << 2));
44957325Ssos		pci_write_config(parent, 0x54, word54, 4);
45057325Ssos		pci_write_config(parent, 0x53,
45157325Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
45293882Ssos		atadev->channel->flags |= ATA_ATAPI_DMA_RO;
45393882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
45456744Ssos		return;
45553681Ssos	    }
45651520Ssos	}
45770186Ssos
45870186Ssos	/* make sure eventual UDMA mode from the BIOS is disabled */
45970752Ssos	pci_write_config(parent, 0x56, pci_read_config(parent, 0x56, 2) &
46070752Ssos				       ~(0x0008 << (devno << 2)), 2);
46170186Ssos
46253681Ssos	if (wdmamode >= 2 && apiomode >= 4) {
46390215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
46453029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
46552067Ssos	    if (bootverbose)
46690215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Acer chip\n",
46756558Ssos			   (error) ? "failed" : "success");
46853681Ssos	    if (!error) {
46957325Ssos		pci_write_config(parent, 0x53,
47057325Ssos				 pci_read_config(parent, 0x53, 1) | 0x03, 1);
47193882Ssos		atadev->channel->flags |= ATA_ATAPI_DMA_RO;
47293882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
47356744Ssos		return;
47453681Ssos	    }
47552067Ssos	}
47657771Ssos	pci_write_config(parent, 0x53,
47757771Ssos			 (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1);
47893882Ssos	error = ata_command(atadev, ATA_C_SETFEATURES, 0,
47993882Ssos			    ATA_PIO0 + apiomode,
48093882Ssos			    ATA_C_F_SETXFER, ATA_WAIT_READY);
48193882Ssos	if (bootverbose)
48293882Ssos	    ata_prtdev(atadev, "%s setting PIO%d on Acer chip\n",
48393882Ssos		       (error) ? "failed" : "success",
48493882Ssos		       (apiomode >= 0) ? apiomode : 0);
48593882Ssos	if (!error) {
48693882Ssos	    int32_t word54 = pci_read_config(parent, 0x54, 4);
48793882Ssos	    int32_t timing;
48893882Ssos
48993882Ssos	    switch(ATA_PIO0 + apiomode) {
49093882Ssos	    case ATA_PIO0: timing = 0x006d0003;
49193882Ssos	    case ATA_PIO1: timing = 0x00580002;
49293882Ssos	    case ATA_PIO2: timing = 0x00440001;
49393882Ssos	    case ATA_PIO3: timing = 0x00330001;
49493882Ssos	    case ATA_PIO4: timing = 0x00310001;
49593882Ssos	    default:	   timing = 0x006d0003;
49693882Ssos	    }
49793882Ssos	    pci_write_config(parent, 0x58 + (channel << 2), timing, 4);
49893882Ssos	    word54 &= ~(0x000f000f << (devno << 2));
49993882Ssos	    word54 |= (0x00000004 << (devno << 2));
50093882Ssos	    pci_write_config(parent, 0x54, word54, 4);
50193882Ssos	    atadev->mode = ATA_PIO0 + apiomode;
50293882Ssos	    return;
50393882Ssos	}
50452067Ssos	break;
50552067Ssos
50694826Ssos    case 0x01bc10de:	/* nVIDIA nForce */
50793094Ssos    case 0x74411022:	/* AMD 768 */
50876584Ssos    case 0x74111022:	/* AMD 766 */
50959103Ssos    case 0x74091022:	/* AMD 756 */
51089917Ssos    case 0x05711106:	/* VIA 82C571, 82C586, 82C596, 82C686 , 8231, 8233 */
51189917Ssos	{
51294826Ssos	    int via_modes[5][7] = {
51394826Ssos		{ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 },	/* VIA ATA33 */
51494826Ssos		{ 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 },	/* VIA ATA66 */
51594826Ssos		{ 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 },	/* VIA ATA100 */
51694826Ssos		{ 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 },	/* VIA ATA133 */
51794826Ssos		{ 0x00, 0x00, 0xc0, 0x00, 0xc5, 0xc6, 0x00 }};	/* AMD/nVIDIA */
51889917Ssos	    int *reg_val = NULL;
51994826Ssos	    char *chip = "VIA";
52089917Ssos
52193674Ssos	    if (ata_find_dev(parent, 0x31471106, 0)) {		/* 8233a */
52289917Ssos		udmamode = imin(udmamode, 6);
52389917Ssos		reg_val = via_modes[3];
52471156Ssos	    }
52589917Ssos	    else if (ata_find_dev(parent, 0x06861106, 0x40) ||	/* 82C686b */
52689917Ssos		ata_find_dev(parent, 0x82311106, 0) ||		/* 8231 */
52789917Ssos		ata_find_dev(parent, 0x30741106, 0) ||		/* 8233 */
52889917Ssos		ata_find_dev(parent, 0x31091106, 0)) {		/* 8233c */
52989917Ssos		udmamode = imin(udmamode, 5);
53089917Ssos		reg_val = via_modes[2];
53189917Ssos	    }
53289917Ssos	    else if (ata_find_dev(parent, 0x06861106, 0x10) ||	/* 82C686a */
53389917Ssos		     ata_find_dev(parent, 0x05961106, 0x12)) {	/* 82C596b */
53489917Ssos		udmamode = imin(udmamode, 4);
53589917Ssos		reg_val = via_modes[1];
53689917Ssos	    }
53793674Ssos	    else if (ata_find_dev(parent, 0x06861106, 0)) {	/* 82C686 */
53889917Ssos		udmamode = imin(udmamode, 2);
53989917Ssos		reg_val = via_modes[1];
54089917Ssos	    }
54189917Ssos	    else if (ata_find_dev(parent, 0x05961106, 0) ||	/* 82C596a */
54289917Ssos		     ata_find_dev(parent, 0x05861106, 0x03)) {	/* 82C586b */
54389917Ssos		udmamode = imin(udmamode, 2);
54489917Ssos		reg_val = via_modes[0];
54589917Ssos	    }
54694826Ssos	    else if (chiptype == 0x74411022 ||			/* AMD 768 */
54794826Ssos		     chiptype == 0x74111022) {			/* AMD 766 */
54894826Ssos		udmamode = imin(udmamode, 5);
54994826Ssos		reg_val = via_modes[4];
55094826Ssos		chip = "AMD";
55194826Ssos	    }
55294826Ssos	    else if (chiptype == 0x74091022) {			/* AMD 756 */
55394826Ssos		udmamode = imin(udmamode, 4);
55494826Ssos		reg_val = via_modes[4];
55594826Ssos		chip = "AMD";
55694826Ssos	    }
55794826Ssos	    else if (chiptype == 0x01bc10de) {			/* nVIDIA */
55894826Ssos		udmamode = imin(udmamode, 5);
55994826Ssos		reg_val = via_modes[4];
56094826Ssos		chip = "nVIDIA";
56194826Ssos	    }
56294826Ssos	    else
56389917Ssos		udmamode = 0;
56494826Ssos
56589917Ssos	    if (udmamode >= 6) {
56690215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
56789917Ssos				    ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY);
56864695Ssos		if (bootverbose)
56994826Ssos		    ata_prtdev(atadev, "%s setting UDMA6 on %s chip\n",
57094826Ssos			       (error) ? "failed" : "success", chip);
57164695Ssos		if (!error) {
57289917Ssos		    pci_write_config(parent, 0x53 - devno, reg_val[6], 1);
57393882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA6);
57471156Ssos		    return;
57571156Ssos		}
57671156Ssos	    }
57789917Ssos	    if (udmamode >= 5) {
57890215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
57989917Ssos				    ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
58071156Ssos		if (bootverbose)
58194826Ssos		    ata_prtdev(atadev, "%s setting UDMA5 on %s chip\n",
58294826Ssos			       (error) ? "failed" : "success", chip);
58371156Ssos		if (!error) {
58489917Ssos		    pci_write_config(parent, 0x53 - devno, reg_val[5], 1);
58593882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA5);
58671156Ssos		    return;
58771156Ssos		}
58871156Ssos	    }
58971156Ssos	    if (udmamode >= 4) {
59090215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
59171156Ssos				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
59271156Ssos		if (bootverbose)
59394826Ssos		    ata_prtdev(atadev, "%s setting UDMA4 on %s chip\n",
59494826Ssos			       (error) ? "failed" : "success", chip);
59571156Ssos		if (!error) {
59689917Ssos		    pci_write_config(parent, 0x53 - devno, reg_val[4], 1);
59793882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA4);
59864695Ssos		    return;
59964695Ssos		}
60056138Ssos	    }
60164695Ssos	    if (udmamode >= 2) {
60290215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
60364695Ssos				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
60464695Ssos		if (bootverbose)
60594826Ssos		    ata_prtdev(atadev, "%s setting UDMA2 on %s chip\n",
60694826Ssos			       (error) ? "failed" : "success", chip);
60764695Ssos		if (!error) {
60889917Ssos		    pci_write_config(parent, 0x53 - devno, reg_val[2], 1);
60993882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA2);
61064695Ssos		    return;
61164695Ssos		}
61256138Ssos	    }
61394826Ssos	    if (wdmamode >= 2 && apiomode >= 4) {
61494826Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
61594826Ssos				    ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
61694826Ssos		if (bootverbose)
61794826Ssos		    ata_prtdev(atadev, "%s setting WDMA2 on %s chip\n",
61894826Ssos			       (error) ? "failed" : "success", chip);
61994826Ssos		if (!error) {
62094826Ssos		    pci_write_config(parent, 0x53 - devno, 0x0b, 1);
62194826Ssos		    pci_write_config(parent, 0x4b - devno, 0x31, 1);
62294826Ssos		    ata_dmacreate(atadev, apiomode, ATA_WDMA2);
62394826Ssos		    return;
62494826Ssos		}
62553681Ssos	    }
62653681Ssos	}
62753681Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
62853681Ssos	break;
62953681Ssos
63054544Ssos    case 0x55131039:	/* SiS 5591 */
63190215Ssos	if (ata_find_dev(parent, 0x06301039, 0x30) ||	/* SiS 630 */
63293674Ssos	    ata_find_dev(parent, 0x06331039, 0) ||	/* SiS 633 */
63393674Ssos	    ata_find_dev(parent, 0x06351039, 0) ||	/* SiS 635 */
63493674Ssos	    ata_find_dev(parent, 0x06401039, 0) ||	/* SiS 640 */
63593674Ssos	    ata_find_dev(parent, 0x06451039, 0) ||	/* SiS 645 */
63693674Ssos	    ata_find_dev(parent, 0x06501039, 0) ||	/* SiS 650 */
63793674Ssos	    ata_find_dev(parent, 0x07301039, 0) ||	/* SiS 730 */
63893674Ssos	    ata_find_dev(parent, 0x07331039, 0) ||	/* SiS 733 */
63993674Ssos	    ata_find_dev(parent, 0x07351039, 0) ||	/* SiS 735 */
64093674Ssos	    ata_find_dev(parent, 0x07401039, 0) ||	/* SiS 740 */
64193674Ssos	    ata_find_dev(parent, 0x07451039, 0) ||	/* SiS 745 */
64293674Ssos	    ata_find_dev(parent, 0x07501039, 0)) {	/* SiS 750 */
64387198Ssos	    int8_t reg = 0x40 + (devno << 1);
64487951Ssos	    int16_t val = pci_read_config(parent, reg, 2) & 0x0fff;
64587198Ssos
64687198Ssos	    if (udmamode >= 5) {
64790215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
64887198Ssos				    ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
64987198Ssos		if (bootverbose)
65090215Ssos		    ata_prtdev(atadev, "%s setting UDMA5 on SiS chip\n",
65187198Ssos			       (error) ? "failed" : "success");
65287198Ssos		if (!error) {
65387951Ssos		    pci_write_config(parent, reg, val | 0x8000, 2);
65493882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA5);
65587198Ssos		    return;
65687198Ssos		}
65754544Ssos	    }
65887198Ssos	    if (udmamode >= 4) {
65990215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
66087198Ssos				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
66187198Ssos		if (bootverbose)
66290215Ssos		    ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n",
66387198Ssos			       (error) ? "failed" : "success");
66487198Ssos		if (!error) {
66587951Ssos		    pci_write_config(parent, reg, val | 0x9000, 2);
66693882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA4);
66787198Ssos		    return;
66887198Ssos		}
66987198Ssos	    }
67087198Ssos	    if (udmamode >= 2) {
67190215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
67287198Ssos				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
67387198Ssos		if (bootverbose)
67490215Ssos		    ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n",
67587198Ssos			       (error) ? "failed" : "success");
67687198Ssos		if (!error) {
67787951Ssos		    pci_write_config(parent, reg, val | 0xb000, 2);
67893882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA2);
67987198Ssos		    return;
68087198Ssos		}
68187198Ssos	    }
68287198Ssos	} else if (ata_find_dev(parent, 0x05301039, 0) || /* SiS 530 */
68387198Ssos		   ata_find_dev(parent, 0x05401039, 0) || /* SiS 540 */
68487198Ssos		   ata_find_dev(parent, 0x06201039, 0) || /* SiS 620 */
68587198Ssos		   ata_find_dev(parent, 0x06301039, 0)) { /* SiS 630 */
68687198Ssos	    int8_t reg = 0x40 + (devno << 1);
68787198Ssos	    int16_t val = pci_read_config(parent, reg, 2) & 0x0fff;
68887198Ssos
68987198Ssos	    if (udmamode >= 4) {
69090215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
69187198Ssos				    ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
69287198Ssos		if (bootverbose)
69390215Ssos		    ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n",
69487198Ssos			       (error) ? "failed" : "success");
69587198Ssos		if (!error) {
69687198Ssos		    pci_write_config(parent, reg, val | 0x9000, 2);
69793882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA4);
69887198Ssos		    return;
69987198Ssos		}
70087198Ssos	    }
70187198Ssos	    if (udmamode >= 2) {
70290215Ssos		error = ata_command(atadev, ATA_C_SETFEATURES, 0,
70387198Ssos				    ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
70487198Ssos		if (bootverbose)
70590215Ssos		    ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n",
70687198Ssos			       (error) ? "failed" : "success");
70787198Ssos		if (!error) {
70887951Ssos		    pci_write_config(parent, reg, val | 0xa000, 2);
70993882Ssos		    ata_dmacreate(atadev, apiomode, ATA_UDMA2);
71087198Ssos		    return;
71187198Ssos		}
71287198Ssos	    }
71393882Ssos	} else if (udmamode >= 2 && chiprev > 0xc1) {
71490215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
71588478Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
71688478Ssos	    if (bootverbose)
71790215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n",
71888478Ssos			   (error) ? "failed" : "success");
71988478Ssos	    if (!error) {
72088478Ssos		pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
72193882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
72288478Ssos		return;
72387198Ssos	    }
72454544Ssos	}
72554544Ssos	if (wdmamode >=2 && apiomode >= 4) {
72690215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
72754544Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
72854544Ssos	    if (bootverbose)
72990215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on SiS chip\n",
73056558Ssos			   (error) ? "failed" : "success");
73154544Ssos	    if (!error) {
73257325Ssos		pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
73393882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
73456744Ssos		return;
73554544Ssos	    }
73654544Ssos	}
73754544Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
73854544Ssos	break;
73954544Ssos
74066583Ssos    case 0x06491095:	/* CMD 649 ATA100 controller */
74166583Ssos	if (udmamode >= 5) {
74266583Ssos	    u_int8_t umode;
74366583Ssos
74490215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
74566583Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
74666583Ssos	    if (bootverbose)
74790215Ssos		ata_prtdev(atadev, "%s setting UDMA5 on CMD chip\n",
74866583Ssos			   (error) ? "failed" : "success");
74966583Ssos	    if (!error) {
75093882Ssos		umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1);
75193882Ssos		umode &= ~(device ? 0xca : 0x35);
75293882Ssos		umode |= (device ? 0x0a : 0x05);
75393882Ssos		pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1);
75493882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
75566583Ssos		return;
75666583Ssos	    }
75766583Ssos	}
75866583Ssos	/* FALLTHROUGH */
75966583Ssos
76066583Ssos    case 0x06481095:	/* CMD 648 ATA66 controller */
76166583Ssos	if (udmamode >= 4) {
76266583Ssos	    u_int8_t umode;
76366583Ssos
76490215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
76566583Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
76666583Ssos	    if (bootverbose)
76790215Ssos		ata_prtdev(atadev, "%s setting UDMA4 on CMD chip\n",
76866583Ssos			   (error) ? "failed" : "success");
76966583Ssos	    if (!error) {
77093882Ssos		umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1);
77193882Ssos		umode &= ~(device ? 0xca : 0x35);
77293882Ssos		umode |= (device ? 0x4a : 0x15);
77393882Ssos		pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1);
77493882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
77566583Ssos		return;
77666583Ssos	    }
77766583Ssos	}
77866583Ssos	if (udmamode >= 2) {
77966583Ssos	    u_int8_t umode;
78066583Ssos
78190215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
78266583Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
78366583Ssos	    if (bootverbose)
78490215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on CMD chip\n",
78566583Ssos			   (error) ? "failed" : "success");
78666583Ssos	    if (!error) {
78793882Ssos		umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1);
78893882Ssos		umode &= ~(device ? 0xca : 0x35);
78993882Ssos		umode |= (device ? 0x42 : 0x11);
79093882Ssos		pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1);
79193882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
79266583Ssos		return;
79366583Ssos	    }
79466583Ssos	}
79566583Ssos	/* make sure eventual UDMA mode from the BIOS is disabled */
79693882Ssos	pci_write_config(parent, channel ? 0x7b : 0x73,
79793882Ssos			 pci_read_config(parent, channel ? 0x7b : 0x73, 1) &
79895010Ssos					 ~(device ? 0xca : 0x53), 1);
79966583Ssos	/* FALLTHROUGH */
80066583Ssos
80157325Ssos    case 0x06461095:	/* CMD 646 ATA controller */
80257325Ssos	if (wdmamode >= 2 && apiomode >= 4) {
80390215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
80457325Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
80557325Ssos	    if (bootverbose)
80690215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on CMD chip\n",
80757325Ssos			   error ? "failed" : "success");
80857325Ssos	    if (!error) {
80957325Ssos		int32_t offset = (devno < 3) ? (devno << 1) : 7;
81057325Ssos
81157325Ssos		pci_write_config(parent, 0x54 + offset, 0x3f, 1);
81293882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
81357325Ssos		return;
81457325Ssos	    }
81557325Ssos	}
81657325Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
81757325Ssos	break;
81857325Ssos
81957477Ssos    case 0xc6931080:	/* Cypress 82c693 ATA controller */
82057477Ssos	if (wdmamode >= 2 && apiomode >= 4) {
82190215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
82257477Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
82357477Ssos	    if (bootverbose)
82490215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Cypress chip\n",
82557477Ssos			   error ? "failed" : "success");
82657477Ssos	    if (!error) {
82793882Ssos		pci_write_config(atadev->channel->dev,
82893882Ssos				 channel ? 0x4e:0x4c, 0x2020, 2);
82993882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
83057477Ssos		return;
83157477Ssos	    }
83257477Ssos	}
83357477Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
83457477Ssos	break;
83557477Ssos
83666583Ssos    case 0x01021078:	/* Cyrix 5530 ATA33 controller */
83793882Ssos	atadev->channel->alignment = 0xf;
83866070Ssos	if (udmamode >= 2) {
83990215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
84066070Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
84166070Ssos	    if (bootverbose)
84290215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on Cyrix chip\n",
84366070Ssos			   (error) ? "failed" : "success");
84466070Ssos	    if (!error) {
84593882Ssos		cyrix_timing(atadev, devno, ATA_UDMA2);
84693882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
84766070Ssos		return;
84866070Ssos	    }
84966070Ssos	}
85066070Ssos	if (wdmamode >= 2 && apiomode >= 4) {
85190215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
85266070Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
85366070Ssos	    if (bootverbose)
85490215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Cyrix chip\n",
85566070Ssos			   (error) ? "failed" : "success");
85666070Ssos	    if (!error) {
85793882Ssos		cyrix_timing(atadev, devno, ATA_WDMA2);
85893882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
85966070Ssos		return;
86066070Ssos	    }
86166070Ssos	}
86290215Ssos	error = ata_command(atadev, ATA_C_SETFEATURES, 0,
86384584Ssos			    ATA_PIO0 + apiomode, ATA_C_F_SETXFER,
86466070Ssos			    ATA_WAIT_READY);
86566070Ssos	if (bootverbose)
86690215Ssos	    ata_prtdev(atadev, "%s setting %s on Cyrix chip\n",
86766070Ssos		       (error) ? "failed" : "success",
86884584Ssos		       ata_mode2str(ATA_PIO0 + apiomode));
86993882Ssos	cyrix_timing(atadev, devno, ATA_PIO0 + apiomode);
87090215Ssos	atadev->mode = ATA_PIO0 + apiomode;
87166070Ssos	return;
87266070Ssos
87392573Ssos    case 0x02121166:	/* ServerWorks CSB5 ATA66/100 controller */
87493882Ssos	if (udmamode >= 5 && chiprev >= 0x92) {
87592573Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
87692573Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
87792573Ssos	    if (bootverbose)
87892573Ssos		ata_prtdev(atadev, "%s setting UDMA5 on ServerWorks chip\n",
87992573Ssos			   (error) ? "failed" : "success");
88092573Ssos	    if (!error) {
88192573Ssos		u_int16_t reg56;
88292573Ssos
88392573Ssos		pci_write_config(parent, 0x54,
88492573Ssos				 pci_read_config(parent, 0x54, 1) |
88592573Ssos				 (0x01 << devno), 1);
88692573Ssos		reg56 = pci_read_config(parent, 0x56, 2);
88792573Ssos		reg56 &= ~(0xf << (devno * 4));
88892573Ssos		reg56 |= (0x5 << (devno * 4));
88992573Ssos		pci_write_config(parent, 0x56, reg56, 2);
89093882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
89192573Ssos		return;
89292573Ssos	    }
89392573Ssos	}
89492573Ssos	if (udmamode >= 4) {
89592573Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
89692573Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
89792573Ssos	    if (bootverbose)
89892573Ssos		ata_prtdev(atadev, "%s setting UDMA4 on ServerWorks chip\n",
89992573Ssos			   (error) ? "failed" : "success");
90092573Ssos	    if (!error) {
90192573Ssos		u_int16_t reg56;
90292573Ssos
90392573Ssos		pci_write_config(parent, 0x54,
90492573Ssos				 pci_read_config(parent, 0x54, 1) |
90592573Ssos				 (0x01 << devno), 1);
90692573Ssos		reg56 = pci_read_config(parent, 0x56, 2);
90792573Ssos		reg56 &= ~(0xf << (devno * 4));
90892573Ssos		reg56 |= (0x4 << (devno * 4));
90992573Ssos		pci_write_config(parent, 0x56, reg56, 2);
91093882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
91192573Ssos		return;
91292573Ssos	    }
91392573Ssos	}
91492573Ssos	/* FALLTHROUGH */
91592573Ssos
91666583Ssos    case 0x02111166:	/* ServerWorks ROSB4 ATA33 controller */
91766583Ssos	if (udmamode >= 2) {
91890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
91966583Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
92066583Ssos	    if (bootverbose)
92190215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on ServerWorks chip\n",
92266583Ssos			   (error) ? "failed" : "success");
92366583Ssos	    if (!error) {
92470186Ssos		u_int16_t reg56;
92570186Ssos
92666583Ssos		pci_write_config(parent, 0x54,
92766583Ssos				 pci_read_config(parent, 0x54, 1) |
92866583Ssos				 (0x01 << devno), 1);
92966583Ssos		reg56 = pci_read_config(parent, 0x56, 2);
93066583Ssos		reg56 &= ~(0xf << (devno * 4));
93166583Ssos		reg56 |= (0x2 << (devno * 4));
93266583Ssos		pci_write_config(parent, 0x56, reg56, 2);
93393882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
93466583Ssos		return;
93566583Ssos	    }
93666583Ssos	}
93766583Ssos	if (wdmamode >= 2 && apiomode >= 4) {
93890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
93966583Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
94066583Ssos	    if (bootverbose)
94190215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on ServerWorks chip\n",
94266583Ssos			   (error) ? "failed" : "success");
94366583Ssos	    if (!error) {
94493882Ssos		int offset = devno ^ 0x01;
94566583Ssos		int word44 = pci_read_config(parent, 0x44, 4);
94666583Ssos
94766583Ssos		pci_write_config(parent, 0x54,
94866583Ssos				 pci_read_config(parent, 0x54, 1) &
94966583Ssos				 ~(0x01 << devno), 1);
95066583Ssos		word44 &= ~(0xff << (offset << 8));
95166583Ssos		word44 |= (0x20 << (offset << 8));
95266583Ssos		pci_write_config(parent, 0x44, 0x20, 4);
95393882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
95466583Ssos		return;
95566583Ssos	    }
95666583Ssos	}
95766583Ssos	/* we could set PIO mode timings, but we assume the BIOS did that */
95866583Ssos	break;
95966583Ssos
96089917Ssos    case 0x4d69105a:	/* Promise TX2 ATA133 controllers */
96194037Ssos    case 0x5275105a:	/* Promise TX2 ATA133 controllers */
96294426Ssos    case 0x6269105a:	/* Promise TX2 ATA133 controllers */
96393882Ssos	ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b);
96493882Ssos	if (udmamode >= 6 &&
96593882Ssos	    !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) {
96690215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
96789917Ssos				ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY);
96889917Ssos	    if (bootverbose)
96990215Ssos		ata_prtdev(atadev, "%s setting UDMA6 on Promise chip\n",
97089917Ssos			   (error) ? "failed" : "success");
97189917Ssos	    if (!error) {
97293882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA6);
97389917Ssos		return;
97489917Ssos	    }
97589917Ssos	}
97689917Ssos	/* FALLTHROUGH */
97789917Ssos
97884413Ssos    case 0x4d68105a:	/* Promise TX2 ATA100 controllers */
97988478Ssos    case 0x6268105a:	/* Promise TX2 ATA100 controllers */
98093882Ssos	ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b);
98193882Ssos	if (udmamode >= 5 &&
98293882Ssos	    !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) {
98390215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
98489917Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
98589917Ssos	    if (bootverbose)
98690215Ssos		ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n",
98789917Ssos			   (error) ? "failed" : "success");
98889917Ssos	    if (!error) {
98993882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
99089917Ssos		return;
99189917Ssos	    }
99289917Ssos	}
99393882Ssos	ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b);
99493882Ssos	if (udmamode >= 4 &&
99593882Ssos	    !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) {
99690215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
99789917Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
99884413Ssos	    if (bootverbose)
99990215Ssos		ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n",
100089917Ssos			   (error) ? "failed" : "success");
100184413Ssos	    if (!error) {
100293882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
100384413Ssos		return;
100484413Ssos	    }
100584413Ssos	}
100684413Ssos	if (udmamode >= 2) {
100790215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
100884413Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
100984413Ssos	    if (bootverbose)
101090215Ssos		ata_prtdev(atadev, "%s setting UDMA on Promise chip\n",
101190215Ssos			   (error) ? "failed" : "success");
101284413Ssos	    if (!error) {
101393882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
101484413Ssos		return;
101584413Ssos	    }
101684413Ssos	}
101784413Ssos	if (wdmamode >= 2 && apiomode >= 4) {
101890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
101984413Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
102084413Ssos	    if (bootverbose)
102190215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n",
102290215Ssos			   (error) ? "failed" : "success");
102384413Ssos	    if (!error) {
102493882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
102584413Ssos		return;
102684413Ssos	    }
102784413Ssos	}
102884413Ssos	break;
102984413Ssos
103098428Ssos    case 0x0d30105a:	/* Promise OEM ATA100 controllers */
103166070Ssos    case 0x4d30105a:	/* Promise Ultra/FastTrak 100 controllers */
103293882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 5 &&
103393882Ssos	    !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) {
103490215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
103564307Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
103664307Ssos	    if (bootverbose)
103790215Ssos		ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n",
103864307Ssos			   (error) ? "failed" : "success");
103964307Ssos	    if (!error) {
104093882Ssos		promise_timing(atadev, devno, ATA_UDMA5);
104193882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
104264307Ssos		return;
104364307Ssos	    }
104464307Ssos	}
104582053Ssos	/* FALLTHROUGH */
104682053Ssos
104798428Ssos    case 0x0d38105a:	/* Promise FastTrak 66 controllers */
104882053Ssos    case 0x4d38105a:	/* Promise Ultra/FastTrak 66 controllers */
104993882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 4 &&
105093882Ssos	    !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) {
105190215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
105253029Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
105352918Ssos	    if (bootverbose)
105490215Ssos		ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n",
105556558Ssos			   (error) ? "failed" : "success");
105653681Ssos	    if (!error) {
105793882Ssos		promise_timing(atadev, devno, ATA_UDMA4);
105893882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
105956744Ssos		return;
106053681Ssos	    }
106152918Ssos	}
106282053Ssos	/* FALLTHROUGH */
106382053Ssos
106482053Ssos    case 0x4d33105a:	/* Promise Ultra/FastTrak 33 controllers */
106593882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 2) {
106690215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
106753029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
106851520Ssos	    if (bootverbose)
106990215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on Promise chip\n",
107056558Ssos			   (error) ? "failed" : "success");
107153681Ssos	    if (!error) {
107293882Ssos		promise_timing(atadev, devno, ATA_UDMA2);
107393882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
107456744Ssos		return;
107553681Ssos	    }
107645095Ssos	}
107793882Ssos	if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) {
107890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
107953029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
108051520Ssos	    if (bootverbose)
108190215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n",
108256558Ssos			   (error) ? "failed" : "success");
108353681Ssos	    if (!error) {
108493882Ssos		promise_timing(atadev, devno, ATA_WDMA2);
108593882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
108656744Ssos		return;
108753681Ssos	    }
108851520Ssos	}
108990215Ssos	error = ata_command(atadev, ATA_C_SETFEATURES, 0,
109084584Ssos			    ATA_PIO0 + apiomode,
109155333Ssos			    ATA_C_F_SETXFER, ATA_WAIT_READY);
109253681Ssos	if (bootverbose)
109390215Ssos	    ata_prtdev(atadev, "%s setting PIO%d on Promise chip\n",
109456558Ssos		       (error) ? "failed" : "success",
109556558Ssos		       (apiomode >= 0) ? apiomode : 0);
109693882Ssos	promise_timing(atadev, devno, ATA_PIO0 + apiomode);
109790215Ssos	atadev->mode = ATA_PIO0 + apiomode;
109856744Ssos	return;
109945095Ssos
110085350Ssos    case 0x00041103:	/* HighPoint HPT366/368/370/372 controllers */
110190844Ssos    case 0x00051103:	/* HighPoint HPT372 controllers */
110290533Ssos    case 0x00081103:	/* HighPoint HPT374 controllers */
110393882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 6 && hpt_cable80(atadev) &&
110493882Ssos	    ((chiptype == 0x00041103 && chiprev >= 0x05) ||
110593882Ssos	     (chiptype == 0x00051103 && chiprev >= 0x01) ||
110693882Ssos	     (chiptype == 0x00081103 && chiprev >= 0x07))) {
110790215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
110885350Ssos				ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY);
110985350Ssos	    if (bootverbose)
111090215Ssos		ata_prtdev(atadev, "%s setting UDMA6 on HighPoint chip\n",
111185350Ssos			   (error) ? "failed" : "success");
111285350Ssos	    if (!error) {
111393882Ssos		hpt_timing(atadev, devno, ATA_UDMA6);
111493882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA6);
111585350Ssos		return;
111685350Ssos	    }
111785350Ssos	}
111893882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && hpt_cable80(atadev) &&
111993882Ssos	    ((chiptype == 0x00041103 && chiprev >= 0x03) ||
112093882Ssos	     (chiptype == 0x00051103 && chiprev >= 0x01) ||
112193882Ssos	     (chiptype == 0x00081103 && chiprev >= 0x07))) {
112290215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
112364307Ssos				ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
112464307Ssos	    if (bootverbose)
112590215Ssos		ata_prtdev(atadev, "%s setting UDMA5 on HighPoint chip\n",
112664307Ssos			   (error) ? "failed" : "success");
112764307Ssos	    if (!error) {
112893882Ssos		hpt_timing(atadev, devno, ATA_UDMA5);
112993882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA5);
113064307Ssos		return;
113164307Ssos	    }
113264307Ssos	}
113393882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && hpt_cable80(atadev)) {
113490215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
113553029Ssos				ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
113652067Ssos	    if (bootverbose)
113790215Ssos		ata_prtdev(atadev, "%s setting UDMA4 on HighPoint chip\n",
113856558Ssos			   (error) ? "failed" : "success");
113953681Ssos	    if (!error) {
114093882Ssos		hpt_timing(atadev, devno, ATA_UDMA4);
114193882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA4);
114256744Ssos		return;
114353681Ssos	    }
114451520Ssos	}
114593882Ssos	if (!ATAPI_DEVICE(atadev) && udmamode >= 2) {
114690215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
114753029Ssos				ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
114851520Ssos	    if (bootverbose)
114990215Ssos		ata_prtdev(atadev, "%s setting UDMA2 on HighPoint chip\n",
115056558Ssos			   (error) ? "failed" : "success");
115153681Ssos	    if (!error) {
115293882Ssos		hpt_timing(atadev, devno, ATA_UDMA2);
115393882Ssos		ata_dmacreate(atadev, apiomode, ATA_UDMA2);
115456744Ssos		return;
115553681Ssos	    }
115645095Ssos	}
115793882Ssos	if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) {
115890215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
115953029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
116051520Ssos	    if (bootverbose)
116190215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on HighPoint chip\n",
116256558Ssos			   (error) ? "failed" : "success");
116353681Ssos	    if (!error) {
116493882Ssos		hpt_timing(atadev, devno, ATA_WDMA2);
116593882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
116656744Ssos		return;
116753681Ssos	    }
116845095Ssos	}
116990215Ssos	error = ata_command(atadev, ATA_C_SETFEATURES, 0,
117084584Ssos			    ATA_PIO0 + apiomode,
117155333Ssos			    ATA_C_F_SETXFER, ATA_WAIT_READY);
117253681Ssos	if (bootverbose)
117390215Ssos	    ata_prtdev(atadev, "%s setting PIO%d on HighPoint chip\n",
117456558Ssos		       (error) ? "failed" : "success",
117556558Ssos		       (apiomode >= 0) ? apiomode : 0);
117693882Ssos	hpt_timing(atadev, devno, ATA_PIO0 + apiomode);
117790215Ssos	atadev->mode = ATA_PIO0 + apiomode;
117856744Ssos	return;
117945095Ssos
118090572Ssos    case 0x000116ca:	/* Cenatek Rocket Drive controller */
118190572Ssos	if (wdmamode >= 0 &&
118293882Ssos	    (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) &
118393882Ssos	     (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER)))
118493882Ssos	    ata_dmacreate(atadev, apiomode, ATA_DMA);
118590572Ssos	else
118690572Ssos	    atadev->mode = ATA_PIO;
118790572Ssos	return;
118890572Ssos
118951548Ssos    default:		/* unknown controller chip */
119051548Ssos	/* better not try generic DMA on ATAPI devices it almost never works */
119193882Ssos	if (ATAPI_DEVICE(atadev))
119251548Ssos	    break;
119351548Ssos
119456744Ssos	/* if controller says its setup for DMA take the easy way out */
119556744Ssos	/* the downside is we dont know what DMA mode we are in */
119690572Ssos	if ((udmamode >= 0 || wdmamode >= 2) &&
119793882Ssos	    (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) &
119893882Ssos	     (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) {
119993882Ssos	    ata_dmacreate(atadev, apiomode, ATA_DMA);
120056744Ssos	    return;
120156744Ssos	}
120256744Ssos
120351548Ssos	/* well, we have no support for this, but try anyways */
120493882Ssos	if ((wdmamode >= 2 && apiomode >= 4) && atadev->channel->r_bmio) {
120590215Ssos	    error = ata_command(atadev, ATA_C_SETFEATURES, 0,
120653029Ssos				ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
120751520Ssos	    if (bootverbose)
120890215Ssos		ata_prtdev(atadev, "%s setting WDMA2 on generic chip\n",
120956558Ssos			   (error) ? "failed" : "success");
121053681Ssos	    if (!error) {
121193882Ssos		ata_dmacreate(atadev, apiomode, ATA_WDMA2);
121256744Ssos		return;
121353681Ssos	    }
121445095Ssos	}
121545095Ssos    }
121690215Ssos    error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode,
121790572Ssos			ATA_C_F_SETXFER, ATA_WAIT_READY);
121855333Ssos    if (bootverbose)
121990215Ssos	ata_prtdev(atadev, "%s setting PIO%d on generic chip\n",
122056988Ssos		   (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode);
122156988Ssos    if (!error)
122290215Ssos	atadev->mode = ATA_PIO0 + apiomode;
122357771Ssos    else {
122456988Ssos	if (bootverbose)
122590215Ssos	    ata_prtdev(atadev, "using PIO mode set by BIOS\n");
122690215Ssos	atadev->mode = ATA_PIO;
122757771Ssos    }
122845095Ssos}
122945095Ssos
123093882Ssosstruct ata_dmasetup_data_cb_args {
123193882Ssos    struct ata_dmaentry *dmatab;
123293882Ssos    int error;
123393882Ssos};
123493882Ssos
123593882Ssosstatic void
123693882Ssosata_dmasetupd_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
123793882Ssos{
123893882Ssos    struct ata_dmasetup_data_cb_args *cba =
123993882Ssos	(struct ata_dmasetup_data_cb_args *)xsc;
124093882Ssos    bus_size_t cnt;
124193882Ssos    u_int32_t lastcount;
124293882Ssos    int i, j;
124393882Ssos
124493882Ssos    cba->error = error;
124593882Ssos    if (error != 0)
124693882Ssos	return;
124793882Ssos    lastcount = j = 0;
124893882Ssos    for (i = 0; i < nsegs; i++) {
124993882Ssos	/*
125093882Ssos	 * A maximum segment size was specified for bus_dma_tag_create, but
125193882Ssos	 * some busdma code does not seem to honor this, so fix up if needed.
125293882Ssos	 */
125393882Ssos	for (cnt = 0; cnt < segs[i].ds_len; cnt += MAXSEGSZ, j++) {
125493882Ssos	    cba->dmatab[j].base = htole32(segs[i].ds_addr + cnt);
125593882Ssos	    lastcount = ulmin(segs[i].ds_len - cnt, MAXSEGSZ) & 0xffff;
125693882Ssos	    cba->dmatab[j].count = htole32(lastcount);
125793882Ssos	}
125893882Ssos    }
125993882Ssos    cba->dmatab[j - 1].count = htole32(lastcount | ATA_DMA_EOT);
126093882Ssos}
126193882Ssos
126266070Ssosint
126393882Ssosata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count)
126445095Ssos{
126593882Ssos    struct ata_channel *ch = atadev->channel;
126645095Ssos
126790215Ssos    if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) {
126893882Ssos	ata_prtdev(atadev, "non aligned DMA transfer attempted\n");
126945095Ssos	return -1;
127066070Ssos    }
127145095Ssos
127245095Ssos    if (!count) {
127393882Ssos	ata_prtdev(atadev, "zero length DMA transfer attempted\n");
127445095Ssos	return -1;
127545095Ssos    }
127695010Ssos    return 0;
127795010Ssos}
127845095Ssos
127995010Ssosint
128095010Ssosata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir)
128195010Ssos{
128295010Ssos    struct ata_channel *ch = atadev->channel;
128395010Ssos    struct ata_dmastate *ds = &atadev->dmastate;
128495010Ssos    struct ata_dmasetup_data_cb_args cba;
128595010Ssos
128695010Ssos    if (ds->flags & ATA_DS_ACTIVE)
128795010Ssos	    panic("ata_dmasetup: transfer active on this device!");
128895010Ssos
128993882Ssos    cba.dmatab = ds->dmatab;
129095010Ssos    bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE);
129193882Ssos    if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count,
129293882Ssos			ata_dmasetupd_cb, &cba, 0) || cba.error)
129395010Ssos	return -1;
129493882Ssos
129595010Ssos    bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_POSTWRITE);
129693882Ssos    bus_dmamap_sync(ds->ddmatag, ds->ddmamap, dir ? BUS_DMASYNC_PREREAD :
129793882Ssos		    BUS_DMASYNC_PREWRITE);
129895010Ssos
129995010Ssos    ch->flags |= ATA_DMA_ACTIVE;
130095010Ssos    ds->flags = ATA_DS_ACTIVE;
130193882Ssos    if (dir)
130293882Ssos	    ds->flags |= ATA_DS_READ;
130395010Ssos
130493882Ssos    ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab);
130590215Ssos    ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
130690215Ssos    ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,
130790215Ssos	 (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) |
130866070Ssos	  (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
130990215Ssos    ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
131090215Ssos	 ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
131195010Ssos    return 0;
131245095Ssos}
131345095Ssos
131466070Ssosint
131593882Ssosata_dmadone(struct ata_device *atadev)
131645095Ssos{
131793882Ssos    struct ata_channel *ch;
131893882Ssos    struct ata_dmastate *ds;
131972106Ssos    int error;
132072106Ssos
132193882Ssos    ch = atadev->channel;
132293882Ssos    ds = &atadev->dmastate;
132393882Ssos    bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ?
132493882Ssos		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
132593882Ssos    bus_dmamap_unload(ds->ddmatag, ds->ddmamap);
132695010Ssos
132790215Ssos    ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT,
132890215Ssos		ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
132990215Ssos    error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT);
133090215Ssos    ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,
133172106Ssos	     error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR);
133295010Ssos    ch->flags &= ~ATA_DMA_ACTIVE;
133393882Ssos    ds->flags = 0;
133495010Ssos    return (error & ATA_BMSTAT_MASK);
133545095Ssos}
133645095Ssos
133766070Ssosint
133890215Ssosata_dmastatus(struct ata_channel *ch)
133945095Ssos{
134090215Ssos    return ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
134145095Ssos}
134245095Ssos
134352067Ssosstatic void
134493882Ssoscyrix_timing(struct ata_device *atadev, int devno, int mode)
134552067Ssos{
134666070Ssos    u_int32_t reg20 = 0x0000e132;
134766070Ssos    u_int32_t reg24 = 0x00017771;
134866070Ssos
134966070Ssos    switch (mode) {
135066070Ssos    case ATA_PIO0:	reg20 = 0x0000e132; break;
135166070Ssos    case ATA_PIO1:	reg20 = 0x00018121; break;
135266070Ssos    case ATA_PIO2:	reg20 = 0x00024020; break;
135366070Ssos    case ATA_PIO3:	reg20 = 0x00032010; break;
135466070Ssos    case ATA_PIO4:	reg20 = 0x00040010; break;
135566070Ssos    case ATA_WDMA2:	reg24 = 0x00002020; break;
135666070Ssos    case ATA_UDMA2:	reg24 = 0x00911030; break;
135766070Ssos    }
135893882Ssos    ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x20, reg20);
135993882Ssos    ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x24, reg24);
136066070Ssos}
136189917Ssos
136266070Ssosstatic void
136393882Ssospromise_timing(struct ata_device *atadev, int devno, int mode)
136466070Ssos{
136556988Ssos    u_int32_t timing = 0;
136693882Ssos    /* XXX: Endianess */
136756988Ssos    struct promise_timing {
136856988Ssos	u_int8_t  pa:4;
136956988Ssos	u_int8_t  prefetch:1;
137056988Ssos	u_int8_t  iordy:1;
137156988Ssos	u_int8_t  errdy:1;
137256988Ssos	u_int8_t  syncin:1;
137356988Ssos	u_int8_t  pb:5;
137456988Ssos	u_int8_t  mb:3;
137556988Ssos	u_int8_t  mc:4;
137656988Ssos	u_int8_t  dmaw:1;
137756988Ssos	u_int8_t  dmar:1;
137856988Ssos	u_int8_t  iordyp:1;
137956988Ssos	u_int8_t  dmarqp:1;
138056988Ssos	u_int8_t  reserved:8;
138156988Ssos    } *t = (struct promise_timing*)&timing;
138256988Ssos
138356988Ssos    t->iordy = 1; t->iordyp = 1;
138456988Ssos    if (mode >= ATA_DMA) {
138556988Ssos	t->prefetch = 1; t->errdy = 1; t->syncin = 1;
138655333Ssos    }
138756988Ssos
138893882Ssos    switch (atadev->channel->chiptype) {
138966070Ssos    case 0x4d33105a:  /* Promise Ultra/Fasttrak 33 */
139056988Ssos	switch (mode) {
139156988Ssos	default:
139290215Ssos	case ATA_PIO0:	t->pa =	 9; t->pb = 19; t->mb = 7; t->mc = 15; break;
139390215Ssos	case ATA_PIO1:	t->pa =	 5; t->pb = 12; t->mb = 7; t->mc = 15; break;
139490215Ssos	case ATA_PIO2:	t->pa =	 3; t->pb =  8; t->mb = 7; t->mc = 15; break;
139590215Ssos	case ATA_PIO3:	t->pa =	 2; t->pb =  6; t->mb = 7; t->mc = 15; break;
139690215Ssos	case ATA_PIO4:	t->pa =	 1; t->pb =  4; t->mb = 7; t->mc = 15; break;
139790215Ssos	case ATA_WDMA2: t->pa =	 3; t->pb =  7; t->mb = 3; t->mc =  3; break;
139890215Ssos	case ATA_UDMA2: t->pa =	 3; t->pb =  7; t->mb = 1; t->mc =  1; break;
139956988Ssos	}
140056988Ssos	break;
140156988Ssos
140298428Ssos    case 0x0d38105a:  /* Promise Fasttrak 66 */
140366070Ssos    case 0x4d38105a:  /* Promise Ultra/Fasttrak 66 */
140498428Ssos    case 0x0d30105a:  /* Promise OEM ATA 100 */
140566070Ssos    case 0x4d30105a:  /* Promise Ultra/Fasttrak 100 */
140656988Ssos	switch (mode) {
140756988Ssos	default:
140890215Ssos	case ATA_PIO0:	t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
140990215Ssos	case ATA_PIO1:	t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break;
141090215Ssos	case ATA_PIO2:	t->pa =	 6; t->pb = 16; t->mb = 7; t->mc = 15; break;
141190215Ssos	case ATA_PIO3:	t->pa =	 4; t->pb = 12; t->mb = 7; t->mc = 15; break;
141290215Ssos	case ATA_PIO4:	t->pa =	 2; t->pb =  8; t->mb = 7; t->mc = 15; break;
141390215Ssos	case ATA_WDMA2: t->pa =	 6; t->pb = 14; t->mb = 6; t->mc =  6; break;
141490215Ssos	case ATA_UDMA2: t->pa =	 6; t->pb = 14; t->mb = 2; t->mc =  2; break;
141590215Ssos	case ATA_UDMA4: t->pa =	 3; t->pb =  7; t->mb = 1; t->mc =  1; break;
141690215Ssos	case ATA_UDMA5: t->pa =	 3; t->pb =  7; t->mb = 1; t->mc =  1; break;
141756988Ssos	}
141856988Ssos	break;
141956988Ssos    }
142093882Ssos    pci_write_config(device_get_parent(atadev->channel->dev),
142193882Ssos		     0x60 + (devno << 2), timing, 4);
142255333Ssos}
142352067Ssos
142455333Ssosstatic void
142593882Ssoshpt_timing(struct ata_device *atadev, int devno, int mode)
142655333Ssos{
142793882Ssos    device_t parent = device_get_parent(atadev->channel->dev);
142893882Ssos    u_int32_t chiptype = atadev->channel->chiptype;
142993882Ssos    int chiprev = pci_get_revid(parent);
143055333Ssos    u_int32_t timing;
143191914Ssos
143293882Ssos    if (chiptype == 0x00081103 && chiprev >= 0x07) {
143390844Ssos	switch (mode) {						/* HPT374 */
143490533Ssos	case ATA_PIO0:	timing = 0x0ac1f48a; break;
143590533Ssos	case ATA_PIO1:	timing = 0x0ac1f465; break;
143690533Ssos	case ATA_PIO2:	timing = 0x0a81f454; break;
143790533Ssos	case ATA_PIO3:	timing = 0x0a81f443; break;
143890533Ssos	case ATA_PIO4:	timing = 0x0a81f442; break;
143991593Ssos	case ATA_WDMA2: timing = 0x22808242; break;
144091593Ssos	case ATA_UDMA2: timing = 0x120c8242; break;
144191593Ssos	case ATA_UDMA4: timing = 0x12ac8242; break;
144291593Ssos	case ATA_UDMA5: timing = 0x12848242; break;
144391593Ssos	case ATA_UDMA6: timing = 0x12808242; break;
144490533Ssos	default:	timing = 0x0d029d5e;
144590533Ssos	}
144690533Ssos    }
144793882Ssos    else if ((chiptype == 0x00041103 && chiprev >= 0x05) ||
144893882Ssos	     (chiptype == 0x00051103 && chiprev >= 0x01)) {
144990844Ssos	switch (mode) {						/* HPT372 */
145090215Ssos	case ATA_PIO0:	timing = 0x0d029d5e; break;
145190215Ssos	case ATA_PIO1:	timing = 0x0d029d26; break;
145290215Ssos	case ATA_PIO2:	timing = 0x0c829ca6; break;
145390215Ssos	case ATA_PIO3:	timing = 0x0c829c84; break;
145490215Ssos	case ATA_PIO4:	timing = 0x0c829c62; break;
145585350Ssos	case ATA_WDMA2: timing = 0x2c829262; break;
145690215Ssos	case ATA_UDMA2: timing = 0x1c91dc62; break;
145790215Ssos	case ATA_UDMA4: timing = 0x1c8ddc62; break;
145890215Ssos	case ATA_UDMA5: timing = 0x1c6ddc62; break;
145990215Ssos	case ATA_UDMA6: timing = 0x1c81dc62; break;
146085350Ssos	default:	timing = 0x0d029d5e;
146185350Ssos	}
146285350Ssos    }
146393882Ssos    else if (chiptype == 0x00041103 && chiprev >= 0x03) {
146490844Ssos	switch (mode) {						/* HPT370 */
146564307Ssos	case ATA_PIO0:	timing = 0x06914e57; break;
146664307Ssos	case ATA_PIO1:	timing = 0x06914e43; break;
146764307Ssos	case ATA_PIO2:	timing = 0x06514e33; break;
146864307Ssos	case ATA_PIO3:	timing = 0x06514e22; break;
146964307Ssos	case ATA_PIO4:	timing = 0x06514e21; break;
147090215Ssos	case ATA_WDMA2: timing = 0x26514e21; break;
147190215Ssos	case ATA_UDMA2: timing = 0x16494e31; break;
147290215Ssos	case ATA_UDMA4: timing = 0x16454e31; break;
147390215Ssos	case ATA_UDMA5: timing = 0x16454e31; break;
147464307Ssos	default:	timing = 0x06514e57;
147552067Ssos	}
147664307Ssos	pci_write_config(parent, 0x40 + (devno << 2) , timing, 4);
147764307Ssos    }
147890844Ssos    else {							/* HPT36[68] */
147964307Ssos	switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
148064307Ssos	case 0x85:	/* 25Mhz */
148164307Ssos	    switch (mode) {
148291914Ssos	    case ATA_PIO0:	timing = 0x40d08585; break;
148391914Ssos	    case ATA_PIO1:	timing = 0x40d08572; break;
148491914Ssos	    case ATA_PIO2:	timing = 0x40ca8542; break;
148591914Ssos	    case ATA_PIO3:	timing = 0x40ca8532; break;
148691914Ssos	    case ATA_PIO4:	timing = 0x40ca8521; break;
148791914Ssos	    case ATA_WDMA2:	timing = 0x20ca8521; break;
148891914Ssos	    case ATA_UDMA2:	timing = 0x10cf8521; break;
148991914Ssos	    case ATA_UDMA4:	timing = 0x10c98521; break;
149064307Ssos	    default:		timing = 0x01208585;
149164307Ssos	    }
149264307Ssos	    break;
149364307Ssos	default:
149464307Ssos	case 0xa7:	/* 33MHz */
149564307Ssos	    switch (mode) {
149691914Ssos	    case ATA_PIO0:	timing = 0x40d0a7aa; break;
149791914Ssos	    case ATA_PIO1:	timing = 0x40d0a7a3; break;
149891914Ssos	    case ATA_PIO2:	timing = 0x40d0a753; break;
149991914Ssos	    case ATA_PIO3:	timing = 0x40c8a742; break;
150091914Ssos	    case ATA_PIO4:	timing = 0x40c8a731; break;
150191914Ssos	    case ATA_WDMA2:	timing = 0x20c8a731; break;
150291914Ssos	    case ATA_UDMA2:	timing = 0x10caa731; break;
150391914Ssos	    case ATA_UDMA4:	timing = 0x10c9a731; break;
150464307Ssos	    default:		timing = 0x0120a7a7;
150564307Ssos	    }
150664307Ssos	    break;
150764307Ssos	case 0xd9:	/* 40Mhz */
150864307Ssos	    switch (mode) {
150991914Ssos	    case ATA_PIO0:	timing = 0x4018d9d9; break;
151091914Ssos	    case ATA_PIO1:	timing = 0x4010d9c7; break;
151191914Ssos	    case ATA_PIO2:	timing = 0x4010d997; break;
151291914Ssos	    case ATA_PIO3:	timing = 0x4010d974; break;
151391914Ssos	    case ATA_PIO4:	timing = 0x4008d963; break;
151491914Ssos	    case ATA_WDMA2:	timing = 0x2008d943; break;
151591914Ssos	    case ATA_UDMA2:	timing = 0x100bd943; break;
151691914Ssos	    case ATA_UDMA4:	timing = 0x100fd943; break;
151764307Ssos	    default:		timing = 0x0120d9d9;
151864307Ssos	    }
151952067Ssos	}
152052067Ssos    }
152191914Ssos    pci_write_config(parent, 0x40 + (devno << 2) , timing, 4);
152252067Ssos}
152391914Ssos
152491914Ssosstatic int
152593882Ssoshpt_cable80(struct ata_device *atadev)
152691914Ssos{
152793882Ssos    device_t parent = device_get_parent(atadev->channel->dev);
152891914Ssos    u_int8_t reg, val, res;
152991914Ssos
153093882Ssos    if (atadev->channel->chiptype==0x00081103 && pci_get_function(parent)==1) {
153193882Ssos	reg = atadev->channel->unit ? 0x57 : 0x53;
153291914Ssos	val = pci_read_config(parent, reg, 1);
153391914Ssos	pci_write_config(parent, reg, val | 0x80, 1);
153491914Ssos    }
153591914Ssos    else {
153691914Ssos	reg = 0x5b;
153791914Ssos	val = pci_read_config(parent, reg, 1);
153891914Ssos	pci_write_config(parent, reg, val & 0xfe, 1);
153991914Ssos    }
154093882Ssos    res = pci_read_config(parent, 0x5a, 1) & (atadev->channel->unit ? 0x1:0x2);
154191914Ssos    pci_write_config(parent, reg, val, 1);
154291914Ssos    return !res;
154391914Ssos}
1544