Beispiel #1
0
static int
ata_cbuschannel_attach(device_t dev)
{
    struct ata_cbus_controller *ctlr = device_get_softc(device_get_parent(dev));
    struct ata_channel *ch = device_get_softc(dev);
    int i;

    if (ch->attached)
	return (0);
    ch->attached = 1;

    ch->unit = (intptr_t)device_get_ivars(dev);
    /* setup the resource vectors */
    for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
	ch->r_io[i].res = ctlr->io;
	ch->r_io[i].offset = i << 1;
    }
    ch->r_io[ATA_CONTROL].res = ctlr->ctlio;
    ch->r_io[ATA_CONTROL].offset = 0;
    ch->r_io[ATA_IDX_ADDR].res = ctlr->io;
    ata_default_registers(dev);

    /* initialize softc for this channel */
    ch->flags |= ATA_USE_16BIT;
    ata_generic_hw(dev);

    return ata_attach(dev);
}
Beispiel #2
0
static int
ata_pccard_attach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);
    struct resource *io, *ctlio;
    int i, rid, err;
    uint16_t funce;

    if (ch->attached)
        return (0);
    ch->attached = 1;

    /* allocate the io range to get start and length */
    rid = ATA_IOADDR_RID;
    if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
                                  ATA_IOSIZE, RF_ACTIVE)))
        return (ENXIO);

    /* setup the resource vectors */
    for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
        ch->r_io[i].res = io;
        ch->r_io[i].offset = i;
    }
    ch->r_io[ATA_IDX_ADDR].res = io;

    /*
     * if we got more than the default ATA_IOSIZE ports, this is a device
     * where ctlio is located at offset 14 into "normal" io space.
     */
    if (rman_get_size(io) > ATA_IOSIZE) {
        ch->r_io[ATA_CONTROL].res = io;
        ch->r_io[ATA_CONTROL].offset = 14;
    }
    else {
        rid = ATA_CTLADDR_RID;
        if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
                                         ATA_CTLIOSIZE, RF_ACTIVE))) {
            bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
            for (i = ATA_DATA; i < ATA_MAX_RES; i++)
                ch->r_io[i].res = NULL;
            return (ENXIO);
        }
        ch->r_io[ATA_CONTROL].res = ctlio;
        ch->r_io[ATA_CONTROL].offset = 0;
    }
    ata_default_registers(dev);

    /* initialize softc for this channel */
    ch->unit = 0;
    ch->flags |= ATA_USE_16BIT;
    funce = 0;		/* Default to sane setting of FUNCE */
    pccard_get_funce_disk(dev, &funce);
    if (!(funce & PFD_I_D))
        ch-> flags |= ATA_NO_SLAVE;
    ata_generic_hw(dev);
    err = ata_probe(dev);
    if (err)
        return (err);
    return (ata_attach(dev));
}
Beispiel #3
0
static int
at91_channel_attach(device_t dev)
{
	struct at91_cfata_softc *sc = device_get_softc(device_get_parent(dev));
	struct ata_channel *ch = device_get_softc(dev);
	int i;

	for (i = 0; i < ATA_MAX_RES; i++)
		ch->r_io[i].res = sc->mem_res;

	/*
	 * CF+ Specification.
	 * 6.1.3 Memory Mapped Addressing.
	 */
	ch->r_io[ATA_DATA].offset = 0x00;
	ch->r_io[ATA_FEATURE].offset = 0x01;
	ch->r_io[ATA_COUNT].offset = 0x02;
	ch->r_io[ATA_SECTOR].offset = 0x03;
	ch->r_io[ATA_CYL_LSB].offset = 0x04;
	ch->r_io[ATA_CYL_MSB].offset = 0x05;
	ch->r_io[ATA_DRIVE].offset = 0x06;
	ch->r_io[ATA_COMMAND].offset = 0x07;
	ch->r_io[ATA_ERROR].offset = 0x01;
	ch->r_io[ATA_IREASON].offset = 0x02;
	ch->r_io[ATA_STATUS].offset = 0x07;
	ch->r_io[ATA_ALTSTAT].offset = 0x0e;
	ch->r_io[ATA_CONTROL].offset = 0x0e;

	/* Should point at the base of registers. */
	ch->r_io[ATA_IDX_ADDR].offset = 0x0;

	ata_generic_hw(dev);
	return (ata_attach(dev));
}
Beispiel #4
0
static int
avila_channel_attach(device_t dev)
{
	struct ata_avila_softc *sc = device_get_softc(device_get_parent(dev));
	struct ata_channel *ch = device_get_softc(dev);
	int i;

	for (i = 0; i < ATA_MAX_RES; i++)
		ch->r_io[i].res = &sc->sc_ata;

	ch->r_io[ATA_DATA].offset = ATA_DATA;
	ch->r_io[ATA_FEATURE].offset = ATA_FEATURE;
	ch->r_io[ATA_COUNT].offset = ATA_COUNT;
	ch->r_io[ATA_SECTOR].offset = ATA_SECTOR;
	ch->r_io[ATA_CYL_LSB].offset = ATA_CYL_LSB;
	ch->r_io[ATA_CYL_MSB].offset = ATA_CYL_MSB;
	ch->r_io[ATA_DRIVE].offset = ATA_DRIVE;
	ch->r_io[ATA_COMMAND].offset = ATA_COMMAND;
	ch->r_io[ATA_ERROR].offset = ATA_FEATURE;
	/* NB: should be used only for ATAPI devices */
	ch->r_io[ATA_IREASON].offset = ATA_COUNT;
	ch->r_io[ATA_STATUS].offset = ATA_COMMAND;

	/* NB: the control and alt status registers are special */
	ch->r_io[ATA_ALTSTAT].res = &sc->sc_alt_ata;
	ch->r_io[ATA_ALTSTAT].offset = AVILA_IDE_CTRL;
	ch->r_io[ATA_CONTROL].res = &sc->sc_alt_ata;
	ch->r_io[ATA_CONTROL].offset = AVILA_IDE_CTRL;

	/* NB: by convention this points at the base of registers */
	ch->r_io[ATA_IDX_ADDR].offset = 0;

	ata_generic_hw(dev);
	return ata_attach(dev);
}
static int
ata_cbuschannel_probe(device_t dev)
{
    struct ata_cbus_controller *ctlr = device_get_softc(device_get_parent(dev));
    struct ata_channel *ch = device_get_softc(dev);
    device_t *children;
    int count, i;

    /* find channel number on this controller */
    device_get_children(device_get_parent(dev), &children, &count);
    for (i = 0; i < count; i++) {
	if (children[i] == dev) 
	    ch->unit = i;
    }
    free(children, M_TEMP);

    /* setup the resource vectors */
    for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
	ch->r_io[i].res = ctlr->io;
	ch->r_io[i].offset = i << 1;
    }
    ch->r_io[ATA_CONTROL].res = ctlr->ctlio;
    ch->r_io[ATA_CONTROL].offset = 0;
    ch->r_io[ATA_IDX_ADDR].res = ctlr->io;
    ata_default_registers(dev);

    /* initialize softc for this channel */
    ch->flags |= ATA_USE_16BIT;
    ata_generic_hw(dev);
    return ata_probe(dev);
}
Beispiel #6
0
void
ata_pci_hw(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);

    ata_generic_hw(dev);
    ch->hw.status = ata_pci_status;
}
Beispiel #7
0
static int
ata_zbbus_attach(device_t dev)
{
	int i, rid, regshift, regoffset;
	struct ata_channel *ch;
	struct resource *io;
	
	ch = device_get_softc(dev);

	if (ch->attached)
		return (0);
	ch->attached = 1;

	rid = 0;
	io = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE);
	if (io == NULL)
		return (ENXIO);

	/*
	 * SWARM needs an address shift of 5 when accessing ATA registers.
	 *
	 * For e.g. an access to register 4 actually needs an address
	 * of (4 << 5) to be output on the generic bus.
	 */
	regshift = 5;
	resource_int_value(device_get_name(dev), device_get_unit(dev),
			   "regshift", &regshift);
	if (regshift && bootverbose)
		device_printf(dev, "using a register shift of %d\n", regshift);

	regoffset = 0x1F0;
	resource_int_value(device_get_name(dev), device_get_unit(dev),
			   "regoffset", &regoffset);
	if (regoffset && bootverbose) {
		device_printf(dev, "using a register offset of 0x%0x\n",
			      regoffset);
	}

	/* setup the ata register addresses */
	for (i = ATA_DATA; i <= ATA_COMMAND; ++i) {
		ch->r_io[i].res = io;
		ch->r_io[i].offset = (regoffset + i) << regshift;
	}

	ch->r_io[ATA_CONTROL].res = io;
	ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift;
	ch->r_io[ATA_IDX_ADDR].res = io;	/* XXX what is this used for */
	ata_default_registers(dev);

	/* initialize softc for this channel */
	ch->unit = 0;
	ch->flags |= ATA_USE_16BIT;
	ata_generic_hw(dev);

	return (ata_attach(dev));
}
Beispiel #8
0
static int
ata_iobus_sub_probe(device_t dev)
{
	struct ata_channel *ch = device_get_softc(dev);

	/* Only a single unit per controller thus far */
	ch->unit = 0;
	ch->flags = (ATA_USE_16BIT|ATA_NO_SLAVE);
	ata_generic_hw(dev);

	return ata_probe(dev);
}
Beispiel #9
0
static int
ata_macio_probe(device_t dev)
{
	const char *type = ofw_bus_get_type(dev);
	const char *name = ofw_bus_get_name(dev);
	struct ata_macio_softc *sc;
	struct ata_channel *ch;
	int rid, i;

	if (strcmp(type, "ata") != 0 &&
	    strcmp(type, "ide") != 0)
		return (ENXIO);

	sc = device_get_softc(dev);
	bzero(sc, sizeof(struct ata_macio_softc));
	ch = &sc->sc_ch.sc_ch;

	if (strcmp(name,"ata-4") == 0) {
		device_set_desc(dev,"Apple MacIO Ultra ATA Controller");
		sc->rev = 4;
		sc->max_mode = ATA_UDMA4;
	} else {
		device_set_desc(dev,"Apple MacIO ATA Controller");
		sc->rev = 3;
		sc->max_mode = ATA_WDMA2;
	}

	rid = 0;
	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
	    RF_ACTIVE);
	if (sc->sc_mem == NULL) {
		device_printf(dev, "could not allocate memory\n");
		return (ENXIO);
	}

	/*
	 * Set up the resource vectors
	 */
	for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
		ch->r_io[i].res = sc->sc_mem;
		ch->r_io[i].offset = i * ATA_MACIO_REGGAP;
	}
	ch->r_io[ATA_CONTROL].res = sc->sc_mem;
	ch->r_io[ATA_CONTROL].offset = ATA_MACIO_ALTOFFSET;
	ata_default_registers(dev);

	ch->unit = 0;
	ch->flags |= ATA_USE_16BIT | ATA_NO_ATAPI_DMA;
	ata_generic_hw(dev);

	return (ata_probe(dev));
}
Beispiel #10
0
static int
ata_isa_attach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);
    struct resource *io = NULL, *ctlio = NULL;
    u_long tmp;
    int i, rid;

    if (ch->attached)
	return (0);
    ch->attached = 1;

    /* allocate the io port range */
    rid = ATA_IOADDR_RID;
    if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
				  ATA_IOSIZE, RF_ACTIVE)))
	return ENXIO;

    /* set the altport range */
    if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, &tmp, &tmp)) {
	bus_set_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
			 rman_get_start(io) + ATA_CTLOFFSET, ATA_CTLIOSIZE);
    }

    /* allocate the altport range */
    rid = ATA_CTLADDR_RID; 
    if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
				     ATA_CTLIOSIZE, RF_ACTIVE))) {
	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
	return ENXIO;
    }

    /* setup the resource vectors */
    for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
	ch->r_io[i].res = io;
	ch->r_io[i].offset = i;
    }
    ch->r_io[ATA_CONTROL].res = ctlio;
    ch->r_io[ATA_CONTROL].offset = 0;
    ch->r_io[ATA_IDX_ADDR].res = io;
    ata_default_registers(dev);
 
    /* initialize softc for this channel */
    ch->unit = 0;
    ch->flags |= ATA_USE_16BIT;
    ata_generic_hw(dev);
    return ata_attach(dev);
}
Beispiel #11
0
/*
 * We add all the devices which we know about.
 * The generic attach routine will attach them if they are alive.
 */
static int
xlr_pcmcia_attach(device_t dev)
{
	struct ata_channel *ch = device_get_softc(dev);
	int i;
	int rid =0;
	struct resource *mem_res;


	mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,  RF_ACTIVE);
	for (i = 0; i < ATA_MAX_RES; i++)
		ch->r_io[i].res = mem_res;

	/*
	 * CF+ Specification.
	 */
	ch->r_io[ATA_DATA].offset 	= XLR_PCMCIA_DATA_REG;
	ch->r_io[ATA_FEATURE].offset 	= XLR_PCMCIA_ERROR_REG;
	ch->r_io[ATA_COUNT].offset 	= XLR_PCMCIA_SECT_CNT_REG;
	ch->r_io[ATA_SECTOR].offset 	= XLR_PCMCIA_SECT_NUM_REG;
	ch->r_io[ATA_CYL_LSB].offset 	= XLR_PCMCIA_CYLINDER_LOW_REG;
	ch->r_io[ATA_CYL_MSB].offset 	= XLR_PCMCIA_CYLINDER_HIGH_REG;
	ch->r_io[ATA_DRIVE].offset 	= XLR_PCMCIA_SECT_DRIVE_HEAD_REG;
	ch->r_io[ATA_COMMAND].offset 	= XLR_PCMCIA_CMD_STATUS_REG;
	ch->r_io[ATA_ERROR].offset 	= XLR_PCMCIA_ERROR_REG;
	ch->r_io[ATA_IREASON].offset 	= XLR_PCMCIA_SECT_CNT_REG;
	ch->r_io[ATA_STATUS].offset 	= XLR_PCMCIA_CMD_STATUS_REG;
	ch->r_io[ATA_ALTSTAT].offset 	= XLR_PCMCIA_ALT_STATUS_REG;
	ch->r_io[ATA_CONTROL].offset 	= XLR_PCMCIA_CONTROL_REG;

	/* Should point at the base of registers. */
	ch->r_io[ATA_IDX_ADDR].offset = XLR_PCMCIA_DATA_REG;

	ata_generic_hw(dev);

	return (ata_attach(dev)); 
}
Beispiel #12
0
static int
sata_channel_attach(device_t dev)
{
	struct sata_softc *sc;
	struct ata_channel *ch;
	uint64_t work;
	int error, i;

	sc = device_get_softc(device_get_parent(dev));
	ch = device_get_softc(dev);

	if (ch->attached)
		return (0);

	ch->dev = dev;
	ch->unit = device_get_unit(dev);
	ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA;

	/* Set legacy ATA resources. */
	for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
		ch->r_io[i].res = sc->sc_mem_res;
		ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2);
	}

	ch->r_io[ATA_CONTROL].res = sc->sc_mem_res;
	ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit);

	ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res;
	ata_default_registers(dev);

	/* Set SATA resources. */
	ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res;
	ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit);
	ch->r_io[ATA_SERROR].res = sc->sc_mem_res;
	ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit);
	ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res;
	ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit);
	ata_generic_hw(dev);

	ch->hw.begin_transaction = sata_channel_begin_transaction;
	ch->hw.end_transaction = sata_channel_end_transaction;
	ch->hw.status = sata_channel_status;

	/* Set DMA resources */
	ata_dmainit(dev);
	ch->dma.setprd = sata_channel_dmasetprd;

	/* Clear work area */
	KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
	    sizeof(struct sata_crpb)) <= ch->dma.max_iosize,
	    ("insufficient DMA memory for request/response queues.\n"));
	bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
	    sizeof(struct sata_crpb)));
	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);

	/* Turn off EDMA engine */
	error = sata_edma_ctrl(dev, 0);
	if (error) {
		ata_dmafini(dev);
		return (error);
	}

	/*
	 * Initialize EDMA engine:
	 *	- Native Command Queuing off,
	 *	- Non-Queued operation,
	 *	- Host Queue Cache enabled.
	 */
	SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE |
	    (sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0);

	/* Set request queue pointers */
	work = ch->dma.work_bus;
	SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32);
	SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF);
	SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF);

	/* Set response queue pointers */
	work += sc->sc_edma_qlen * sizeof(struct sata_crqb);
	SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32);
	SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF);
	SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF);

	/* Clear any outstanding interrupts */
	ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
	SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
	SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
	SATA_OUTL(sc, SATA_ICR,
	    ~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit)));

	/* Umask channel interrupts */
	SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
	SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) |
	    SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
	    SATA_MICR_ERR(ch->unit));

	ch->attached = 1;

	return (ata_attach(dev));
}
Beispiel #13
0
static int
ata_macio_attach(device_t dev)
{
    struct ata_macio_softc *sc = device_get_softc(dev);
    uint32_t timingreg;
    struct ata_channel *ch;
    int rid, i;

    /*
     * Allocate resources
     */

    rid = 0;
    ch = &sc->sc_ch.sc_ch;
    sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
                                        RF_ACTIVE);
    if (sc->sc_mem == NULL) {
        device_printf(dev, "could not allocate memory\n");
        return (ENXIO);
    }

    /*
     * Set up the resource vectors
     */
    for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
        ch->r_io[i].res = sc->sc_mem;
        ch->r_io[i].offset = i * ATA_MACIO_REGGAP;
    }
    ch->r_io[ATA_CONTROL].res = sc->sc_mem;
    ch->r_io[ATA_CONTROL].offset = ATA_MACIO_ALTOFFSET;
    ata_default_registers(dev);

    ch->unit = 0;
    ch->flags |= ATA_USE_16BIT | ATA_NO_ATAPI_DMA;
    ata_generic_hw(dev);

#if USE_DBDMA_IRQ
    int dbdma_irq_rid = 1;
    struct resource *dbdma_irq;
    void *cookie;
#endif

    /* Init DMA engine */

    sc->sc_ch.dbdma_rid = 1;
    sc->sc_ch.dbdma_regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
                           &sc->sc_ch.dbdma_rid, RF_ACTIVE);

    ata_dbdma_dmainit(dev);

    /* Configure initial timings */
    timingreg = bus_read_4(sc->sc_mem, ATA_MACIO_TIMINGREG);
    if (sc->rev == 4) {
        sc->udmaconf[0] = sc->udmaconf[1] = timingreg & 0x1ff00000;
        sc->wdmaconf[0] = sc->wdmaconf[1] = timingreg & 0x001ffc00;
        sc->pioconf[0]  = sc->pioconf[1]  = timingreg & 0x000003ff;
    } else {
        sc->udmaconf[0] = sc->udmaconf[1] = 0;
        sc->wdmaconf[0] = sc->wdmaconf[1] = timingreg & 0xfffff800;
        sc->pioconf[0]  = sc->pioconf[1]  = timingreg & 0x000007ff;
    }

#if USE_DBDMA_IRQ
    /* Bind to DBDMA interrupt as well */

    if ((dbdma_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
                                            &dbdma_irq_rid, RF_SHAREABLE | RF_ACTIVE)) != NULL) {
        bus_setup_intr(dev, dbdma_irq, ATA_INTR_FLAGS, NULL,
                       (driver_intr_t *)ata_interrupt, sc,&cookie);
    }
#endif

    /* Set begin_transaction */
    sc->sc_ch.sc_ch.hw.begin_transaction = ata_macio_begin_transaction;

    return ata_attach(dev);
}
Beispiel #14
0
static int
ata_kauai_probe(device_t dev)
{
	struct ata_channel *ch;
	struct ata_kauai_softc *sc;
	u_int32_t devid;
	phandle_t node;
	const char *compatstring = NULL;
	int i, found, rid;

	found = 0;
	devid = pci_get_devid(dev);
        for (i = 0; kauai_pci_devlist[i].kpd_desc != NULL; i++) {
                if (devid == kauai_pci_devlist[i].kpd_devid) {
			found = 1;
                        device_set_desc(dev, kauai_pci_devlist[i].kpd_desc);
		}
	}

	if (!found)
		return (ENXIO);

	node = ofw_bus_get_node(dev);
	sc = device_get_softc(dev);
	bzero(sc, sizeof(struct ata_kauai_softc));
	ch = &sc->sc_ch.sc_ch;

	compatstring = ofw_bus_get_compat(dev);
	if (compatstring != NULL && strcmp(compatstring,"shasta-ata") == 0)
		sc->shasta = 1;

	/* Pre-K2 controllers apparently need this hack */
	if (!sc->shasta &&
	    (compatstring == NULL || strcmp(compatstring, "K2-UATA") != 0))
		bus_set_resource(dev, SYS_RES_IRQ, 0, 39, 1);

        rid = PCIR_BARS;
	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
	    RF_ACTIVE);
        if (sc->sc_memr == NULL) {
                device_printf(dev, "could not allocate memory\n");
                return (ENXIO);
        }

	/*
	 * Set up the resource vectors
	 */
        for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
                ch->r_io[i].res = sc->sc_memr;
                ch->r_io[i].offset = i*ATA_KAUAI_REGGAP + ATA_KAUAI_REGOFFSET;
        }
        ch->r_io[ATA_CONTROL].res = sc->sc_memr;
        ch->r_io[ATA_CONTROL].offset = ATA_KAUAI_ALTOFFSET;
	ata_default_registers(dev);

	ch->unit = 0;
	ch->flags |= ATA_USE_16BIT;
	
	/* XXX: ATAPI DMA is unreliable. We should find out why. */
	ch->flags |= ATA_NO_ATAPI_DMA;
	ata_generic_hw(dev);

        return (ata_probe(dev));
}