예제 #1
0
static int
ata_highpoint_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    if (ctlr->chip->cfg2 == HPT_OLD) {
	/* disable interrupt prediction */
	pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
    }
    else {
	/* disable interrupt prediction */
	pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x03), 1);
	pci_write_config(dev, 0x55, (pci_read_config(dev, 0x55, 1) & ~0x03), 1);

	/* enable interrupts */
	pci_write_config(dev, 0x5a, (pci_read_config(dev, 0x5a, 1) & ~0x10), 1);

	/* set clocks etc */
	if (ctlr->chip->cfg1 < HPT_372)
	    pci_write_config(dev, 0x5b, 0x22, 1);
	else
	    pci_write_config(dev, 0x5b,
			     (pci_read_config(dev, 0x5b, 1) & 0x01) | 0x20, 1);
    }
    ctlr->ch_attach = ata_highpoint_ch_attach;
    ctlr->ch_detach = ata_pci_ch_detach;
    ctlr->setmode = ata_highpoint_setmode;
    return 0;
}
예제 #2
0
static int
ata_ati_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    /* IXP600 & IXP700 only have 1 PATA channel */
    if ((ctlr->chip->chipid == ATA_ATI_IXP600) ||
	(ctlr->chip->chipid == ATA_ATI_IXP700))
	ctlr->channels = 1;

    /* The SB600 needs special treatment. */
    if (ctlr->chip->cfg1 & ATI_AHCI) {
	/* Check if the chip is configured as an AHCI part. */
	if ((pci_get_subclass(dev) == PCIS_STORAGE_SATA) &&
	    (pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_STORAGE_SATA_AHCI_1_0)) {
	    ctlr->setmode = ata_sata_setmode;
	    if (ata_ahci_chipinit(dev) != ENXIO)
		return 0;
	}
    }

    ctlr->setmode = ata_ati_setmode;
    return 0;
}
예제 #3
0
static int
ata_acard_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
#ifndef ATA_CAM
    struct ata_serialize *serial;
#endif

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    ctlr->ch_attach = ata_acard_ch_attach;
    ctlr->ch_detach = ata_pci_ch_detach;
    if (ctlr->chip->cfg1 == ATP_OLD) {
	ctlr->setmode = ata_acard_850_setmode;
#ifndef ATA_CAM
	ctlr->locking = ata_serialize;
	serial = malloc(sizeof(struct ata_serialize),
			      M_ATAPCI, M_WAITOK | M_ZERO);
	ata_serialize_init(serial);
	ctlr->chipset_data = serial;
#else
	/* Work around the lack of channel serialization in ATA_CAM. */
	ctlr->channels = 1;
	device_printf(dev, "second channel ignored\n");
#endif
    }
    else
	ctlr->setmode = ata_acard_86X_setmode;
    return 0;
}
예제 #4
0
static int
ata_nvidia_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    if (ctlr->chip->cfg1 & NVAHCI) {
	ctlr->ch_attach = ata_nvidia_ch_attach_dumb;
	ctlr->setmode = ata_sata_setmode;
    } else if (ctlr->chip->max_dma >= ATA_SA150) {
	if (pci_read_config(dev, PCIR_BAR(5), 1) & 1)
	    ctlr->r_type2 = SYS_RES_IOPORT;
	else
	    ctlr->r_type2 = SYS_RES_MEMORY;
	ctlr->r_rid2 = PCIR_BAR(5);
	if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
						   &ctlr->r_rid2, RF_ACTIVE))) {
	    int offset = ctlr->chip->cfg1 & NV4 ? 0x0440 : 0x0010;

	    ctlr->ch_attach = ata_nvidia_ch_attach;
	    ctlr->ch_detach = ata_pci_ch_detach;
	    ctlr->reset = ata_nvidia_reset;

	    /* enable control access */
	    pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) | 0x04,1);
	    /* MCP55 seems to need some time to allow r_res2 read. */
	    DELAY(10);
	    if (ctlr->chip->cfg1 & NVQ) {
		/* clear interrupt status */
		ATA_OUTL(ctlr->r_res2, offset, 0x00ff00ff);

		/* enable device and PHY state change interrupts */
		ATA_OUTL(ctlr->r_res2, offset + 4, 0x000d000d);

		/* disable NCQ support */
		ATA_OUTL(ctlr->r_res2, 0x0400,
			 ATA_INL(ctlr->r_res2, 0x0400) & 0xfffffff9);
	    } 
	    else {
		/* clear interrupt status */
		ATA_OUTB(ctlr->r_res2, offset, 0xff);

		/* enable device and PHY state change interrupts */
		ATA_OUTB(ctlr->r_res2, offset + 1, 0xdd);
	    }
	}
	ctlr->setmode = ata_sata_setmode;
	ctlr->getrev = ata_sata_getrev;
    }
    else {
	/* disable prefetch, postwrite */
	pci_write_config(dev, 0x51, pci_read_config(dev, 0x51, 1) & 0x0f, 1);
	ctlr->setmode = ata_nvidia_setmode;
    }
    return 0;
}
예제 #5
0
파일: ata-pci.c 프로젝트: coyizumi/cs111
int
ata_generic_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;
    ctlr->setmode = ata_generic_setmode;
    return 0;
}
static int
ata_netcell_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
        return ENXIO;

    ctlr->ch_attach = ata_netcell_ch_attach;
    ctlr->ch_detach = ata_pci_ch_detach;
    ctlr->setmode = ata_netcell_setmode;
    return 0;
}
예제 #7
0
static int
ata_devel_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    /* setup interrupt delivery */
    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    /* perform any chipset specific setups here */

    /* setup function ptr's, in this case allocate and setmode */
    ctlr->allocate = ata_devel_allocate;
    ctlr->setmode = ata_devel_setmode;

    return 0;
}
예제 #8
0
static int
ata_amd_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    /* disable/set prefetch, postwrite */
    if (ctlr->chip->cfg1 & AMD_BUG)
	pci_write_config(dev, 0x41, pci_read_config(dev, 0x41, 1) & 0x0f, 1);
    else
	pci_write_config(dev, 0x41, pci_read_config(dev, 0x41, 1) | 0xf0, 1);

    ctlr->setmode = ata_amd_setmode;
    return 0;
}
예제 #9
0
파일: ata-fsl.c 프로젝트: Alkzndr/freebsd
static int
imx_ata_attach(device_t dev)
{
	struct ata_pci_controller *ctrl;
	device_t child;
	int unit;

	ctrl = device_get_softc(dev);
	/* do chipset specific setups only needed once */
	ctrl->legacy = ata_legacy(dev);
	ctrl->channels = 1;
	ctrl->ichannels = -1;
	ctrl->ch_attach = ata_pci_ch_attach;
	ctrl->ch_detach = ata_pci_ch_detach;
	ctrl->dev = dev;

	ctrl->r_type1 = SYS_RES_MEMORY;
	ctrl->r_rid1 = 0;
	ctrl->r_res1 = bus_alloc_resource_any(dev, ctrl->r_type1,
	    &ctrl->r_rid1, RF_ACTIVE);

	if (ata_setup_interrupt(dev, imx_ata_intr)) {
		device_printf(dev, "failed to setup interrupt\n");
    		return ENXIO;
	}

	ctrl->channels = 1;

	ctrl->ch_attach = imx_ata_ch_attach;
	ctrl->setmode = imx_ata_setmode;

	/* attach all channels on this controller */
	unit = 0;
	child = device_add_child(dev, "ata", ((unit == 0) && ctrl->legacy) ?
		    unit : devclass_find_free_unit(ata_devclass, 2));
	if (child == NULL)
		device_printf(dev, "failed to add ata child device\n");
	else
		device_set_ivars(child, (void *)(intptr_t)unit);

	bus_generic_attach(dev);
	return 0;
}
예제 #10
0
static int
ata_jmicron_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
    device_t child;

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    /* do we have multiple PCI functions ? */
    if (pci_read_config(dev, 0xdf, 1) & 0x40) {
	/* are we on the AHCI part ? */
	if (ata_ahci_chipinit(dev) != ENXIO)
	    return 0;

	/* otherwise we are on the PATA part */
	ctlr->ch_attach = ata_jmicron_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->reset = ata_generic_reset;
	ctlr->setmode = ata_jmicron_setmode;
	ctlr->channels = ctlr->chip->cfg2;
    }
    else {
	/* set controller configuration to a combined setup we support */
	pci_write_config(dev, 0x40, 0x80c0a131, 4);
	pci_write_config(dev, 0x80, 0x01200000, 4);
	/* Create AHCI subdevice if AHCI part present. */
	if (ctlr->chip->cfg1) {
	    	child = device_add_child(dev, NULL, -1);
		if (child != NULL) {
		    device_set_ivars(child, (void *)(intptr_t)-1);
		    bus_generic_attach(dev);
		}
	}
	ctlr->ch_attach = ata_jmicron_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->reset = ata_generic_reset;
	ctlr->setmode = ata_jmicron_setmode;
	ctlr->channels = ctlr->chip->cfg2;
    }
    return 0;
}
예제 #11
0
static int
ata_acard_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    ctlr->ch_attach = ata_acard_ch_attach;
    ctlr->ch_detach = ata_pci_ch_detach;
    if (ctlr->chip->cfg1 == ATP_OLD) {
	ctlr->setmode = ata_acard_850_setmode;
	/* Work around the lack of channel serialization in ATA_CAM. */
	ctlr->channels = 1;
	device_printf(dev, "second channel ignored\n");
    }
    else
	ctlr->setmode = ata_acard_86X_setmode;
    return 0;
}
예제 #12
0
static int
ata_sis_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
        return ENXIO;

    switch (ctlr->chip->cfg1) {
    case SIS_33:
        break;
    case SIS_66:
    case SIS_100OLD:
        pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 1) & ~0x04, 1);
        break;
    case SIS_100NEW:
    case SIS_133OLD:
        pci_write_config(dev, 0x49, pci_read_config(dev, 0x49, 1) & ~0x01, 1);
        break;
    case SIS_133NEW:
        pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 2) | 0x0008, 2);
        pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 2) | 0x0008, 2);
        break;
    case SIS_SATA:
        ctlr->r_type2 = SYS_RES_IOPORT;
        ctlr->r_rid2 = PCIR_BAR(5);
        if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
                            &ctlr->r_rid2, RF_ACTIVE))) {
            ctlr->ch_attach = ata_sis_ch_attach;
            ctlr->ch_detach = ata_pci_ch_detach;
            ctlr->reset = ata_sis_reset;
        }
        ctlr->setmode = ata_sata_setmode;
        ctlr->getrev = ata_sata_getrev;
        return 0;
    default:
        return ENXIO;
    }
    ctlr->setmode = ata_sis_setmode;
    return 0;
}
예제 #13
0
static int
ata_ali_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
    struct ali_sata_resources *res;
    int i, rid;

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    switch (ctlr->chip->cfg2) {
    case ALI_SATA:
	ctlr->channels = ctlr->chip->cfg1;
	ctlr->ch_attach = ata_ali_sata_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->setmode = ata_sata_setmode;
	ctlr->getrev = ata_sata_getrev;

	/* AHCI mode is correctly supported only on the ALi 5288. */
	if ((ctlr->chip->chipid == ATA_ALI_5288) &&
	    (ata_ahci_chipinit(dev) != ENXIO))
            return 0;

	/* Allocate resources for later use by channel attach routines. */
	res = malloc(sizeof(struct ali_sata_resources), M_ATAPCI, M_WAITOK);
	for (i = 0; i < 4; i++) {
		rid = PCIR_BAR(i);
		res->bars[i] = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
		    RF_ACTIVE);
		if (res->bars[i] == NULL) {
			device_printf(dev, "Failed to allocate BAR %d\n", i);
			for (i--; i >=0; i--)
				bus_release_resource(dev, SYS_RES_IOPORT,
				    PCIR_BAR(i), res->bars[i]);
			free(res, M_TEMP);
			return ENXIO;
		}
	}
	ctlr->chipset_data = res;
	break;

    case ALI_NEW:
	/* use device interrupt as byte count end */
	pci_write_config(dev, 0x4a, pci_read_config(dev, 0x4a, 1) | 0x20, 1);

	/* enable cable detection and UDMA support on revisions < 0xc7 */
	if (ctlr->chip->chiprev < 0xc7)
	    pci_write_config(dev, 0x4b, pci_read_config(dev, 0x4b, 1) |
		0x09, 1);

	/* enable ATAPI UDMA mode (even if we are going to do PIO) */
	pci_write_config(dev, 0x53, pci_read_config(dev, 0x53, 1) |
	    (ctlr->chip->chiprev >= 0xc7 ? 0x03 : 0x01), 1);

	/* only chips with revision > 0xc4 can do 48bit DMA */
	if (ctlr->chip->chiprev <= 0xc4)
	    device_printf(dev,
			  "using PIO transfers above 137GB as workaround for "
			  "48bit DMA access bug, expect reduced performance\n");
	ctlr->ch_attach = ata_ali_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->reset = ata_ali_reset;
	ctlr->setmode = ata_ali_setmode;
	break;

    case ALI_OLD:
	/* deactivate the ATAPI FIFO and enable ATAPI UDMA */
	pci_write_config(dev, 0x53, pci_read_config(dev, 0x53, 1) | 0x03, 1);
	ctlr->setmode = ata_ali_setmode;
	break;
    }
    return 0;
}
예제 #14
0
int
ata_sii_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    switch (ctlr->chip->cfg1) {
    case SII_MEMIO:
	ctlr->r_type2 = SYS_RES_MEMORY;
	ctlr->r_rid2 = PCIR_BAR(5);
	if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
						    &ctlr->r_rid2, RF_ACTIVE))){
	    if (ctlr->chip->chipid != ATA_SII0680 ||
			    (pci_read_config(dev, 0x8a, 1) & 1))
		return ENXIO;
	}

	if (ctlr->chip->cfg2 & SII_SETCLK) {
	    if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10)
		pci_write_config(dev, 0x8a,
				 (pci_read_config(dev, 0x8a, 1) & 0xcf)|0x10,1);
	    if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10)
		device_printf(dev, "%s could not set ATA133 clock\n",
			      ctlr->chip->text);
	}

	/* if we have 4 channels enable the second set */
	if (ctlr->chip->cfg2 & SII_4CH) {
	    ATA_OUTL(ctlr->r_res2, 0x0200, 0x00000002);
	    ctlr->channels = 4;
	}

	/* dont block interrupts from any channel */
	pci_write_config(dev, 0x48,
			 (pci_read_config(dev, 0x48, 4) & ~0x03c00000), 4);

	/* enable PCI interrupt as BIOS might not */
	pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1);

	if (ctlr->r_res2) {
	    ctlr->ch_attach = ata_sii_ch_attach;
	    ctlr->ch_detach = ata_sii_ch_detach;
	}

	if (ctlr->chip->max_dma >= ATA_SA150) {
	    ctlr->reset = ata_sii_reset;
	    ctlr->setmode = ata_sata_setmode;
	    ctlr->getrev = ata_sata_getrev;
	}
	else
	    ctlr->setmode = ata_sii_setmode;
	break;
    
    default:
	if ((pci_read_config(dev, 0x51, 1) & 0x08) != 0x08) {
	    device_printf(dev, "HW has secondary channel disabled\n");
	    ctlr->channels = 1;
	}    

	/* enable interrupt as BIOS might not */
	pci_write_config(dev, 0x71, 0x01, 1);

	ctlr->ch_attach = ata_cmd_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->setmode = ata_cmd_setmode;
	break;
    }
    return 0;
}
예제 #15
0
int
ata_sii_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    switch (ctlr->chip->cfg1) {
    case SII_PRBIO:
	ctlr->r_type1 = SYS_RES_MEMORY;
	ctlr->r_rid1 = PCIR_BAR(0);
	if (!(ctlr->r_res1 = bus_alloc_resource_any(dev, ctlr->r_type1,
						    &ctlr->r_rid1, RF_ACTIVE)))
	    return ENXIO;

	ctlr->r_rid2 = PCIR_BAR(2);
	ctlr->r_type2 = SYS_RES_MEMORY;
	if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
						    &ctlr->r_rid2, RF_ACTIVE))){
	    bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,ctlr->r_res1);
	    return ENXIO;
	}
#ifdef __sparc64__
	if (!bus_space_map(rman_get_bustag(ctlr->r_res2),
	    rman_get_bushandle(ctlr->r_res2), rman_get_size(ctlr->r_res2),
	    BUS_SPACE_MAP_LINEAR, NULL)) {
	    	bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1,
		    ctlr->r_res1);
		bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2,
		    ctlr->r_res2);
		return (ENXIO);
	}
#endif
	ctlr->ch_attach = ata_siiprb_ch_attach;
	ctlr->ch_detach = ata_siiprb_ch_detach;
	ctlr->reset = ata_siiprb_reset;
	ctlr->setmode = ata_sata_setmode;
	ctlr->getrev = ata_sata_getrev;
	ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2;

	/* reset controller */
	ATA_OUTL(ctlr->r_res1, 0x0040, 0x80000000);
	DELAY(10000);
	ATA_OUTL(ctlr->r_res1, 0x0040, 0x0000000f);
	break;

    case SII_MEMIO:
	ctlr->r_type2 = SYS_RES_MEMORY;
	ctlr->r_rid2 = PCIR_BAR(5);
	if (!(ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
						    &ctlr->r_rid2, RF_ACTIVE))){
	    if (ctlr->chip->chipid != ATA_SII0680 ||
			    (pci_read_config(dev, 0x8a, 1) & 1))
		return ENXIO;
	}

	if (ctlr->chip->cfg2 & SII_SETCLK) {
	    if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10)
		pci_write_config(dev, 0x8a,
				 (pci_read_config(dev, 0x8a, 1) & 0xcf)|0x10,1);
	    if ((pci_read_config(dev, 0x8a, 1) & 0x30) != 0x10)
		device_printf(dev, "%s could not set ATA133 clock\n",
			      ctlr->chip->text);
	}

	/* if we have 4 channels enable the second set */
	if (ctlr->chip->cfg2 & SII_4CH) {
	    ATA_OUTL(ctlr->r_res2, 0x0200, 0x00000002);
	    ctlr->channels = 4;
	}

	/* dont block interrupts from any channel */
	pci_write_config(dev, 0x48,
			 (pci_read_config(dev, 0x48, 4) & ~0x03c00000), 4);

	/* enable PCI interrupt as BIOS might not */
	pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1);

	if (ctlr->r_res2) {
	    ctlr->ch_attach = ata_sii_ch_attach;
	    ctlr->ch_detach = ata_sii_ch_detach;
	}

	if (ctlr->chip->max_dma >= ATA_SA150) {
	    ctlr->reset = ata_sii_reset;
	    ctlr->setmode = ata_sata_setmode;
	    ctlr->getrev = ata_sata_getrev;
	}
	else
	    ctlr->setmode = ata_sii_setmode;
	break;
    
    default:
	if ((pci_read_config(dev, 0x51, 1) & 0x08) != 0x08) {
	    device_printf(dev, "HW has secondary channel disabled\n");
	    ctlr->channels = 1;
	}    

	/* enable interrupt as BIOS might not */
	pci_write_config(dev, 0x71, 0x01, 1);

	ctlr->ch_attach = ata_cmd_ch_attach;
	ctlr->ch_detach = ata_pci_ch_detach;
	ctlr->setmode = ata_cmd_setmode;
	break;
    }
    return 0;
}
예제 #16
0
static int
ata_via_chipinit(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);

    if (ata_setup_interrupt(dev, ata_generic_intr))
	return ENXIO;

    /* AHCI SATA */
    if (ctlr->chip->cfg2 & VIAAHCI) {
	if (ata_ahci_chipinit(dev) != ENXIO)
	    return (0);
    }
    /* 2 SATA with "SATA registers" at PCI config space + PATA on secondary */
    if (ctlr->chip->cfg2 & VIASATA) {
	ctlr->ch_attach = ata_via_sata_ch_attach;
	ctlr->setmode = ata_via_sata_setmode;
	ctlr->getrev = ata_via_sata_getrev;
	ctlr->reset = ata_via_sata_reset;
	return 0;
    }
    /* Legacy SATA/SATA+PATA with SATA registers in BAR(5). */
    if (ctlr->chip->max_dma >= ATA_SA150) {
	ctlr->r_type2 = SYS_RES_IOPORT;
	ctlr->r_rid2 = PCIR_BAR(5);
	if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
						   &ctlr->r_rid2, RF_ACTIVE))) {
	    ctlr->ch_attach = ata_via_ch_attach;
	    ctlr->ch_detach = ata_via_ch_detach;
	    ctlr->reset = ata_via_reset;
	}
	if (ctlr->chip->cfg2 & VIABAR) {
	    ctlr->channels = 3;
	    ctlr->setmode = ata_via_new_setmode;
	} else
	    ctlr->setmode = ata_sata_setmode;
	ctlr->getrev = ata_sata_getrev;
	return 0;
    }

    /* prepare for ATA-66 on the 82C686a and 82C596b */
    if (ctlr->chip->cfg2 & VIACLK)
	pci_write_config(dev, 0x50, 0x030b030b, 4);       

    /* the southbridge might need the data corruption fix */
    if (ctlr->chip->cfg2 & VIABUG)
	ata_via_southbridge_fixup(dev);

    /* set fifo configuration half'n'half */
    pci_write_config(dev, 0x43, 
		     (pci_read_config(dev, 0x43, 1) & 0x90) | 0x2a, 1);

    /* set status register read retry */
    pci_write_config(dev, 0x44, pci_read_config(dev, 0x44, 1) | 0x08, 1);

    /* set DMA read & end-of-sector fifo flush */
    pci_write_config(dev, 0x46, 
		     (pci_read_config(dev, 0x46, 1) & 0x0c) | 0xf0, 1);

    /* set sector size */
    pci_write_config(dev, 0x60, DEV_BSIZE, 2);
    pci_write_config(dev, 0x68, DEV_BSIZE, 2);

    ctlr->setmode = ata_via_old_setmode;
    return 0;
}