From a059eb3a326c7a5efb9863919466e59f8f13ecfc Mon Sep 17 00:00:00 2001 From: grehan Date: Thu, 12 Feb 2004 09:17:16 +0000 Subject: Work-in-progress for the 'Kauai' ATA device in Mac notebooks. The device seems to be the macio ATA cell with a PCI front-end, and has no relation to PIIX-style ATA/PCI devices. --- sys/powerpc/powermac/ata_kauai.c | 190 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 sys/powerpc/powermac/ata_kauai.c (limited to 'sys/powerpc') diff --git a/sys/powerpc/powermac/ata_kauai.c b/sys/powerpc/powermac/ata_kauai.c new file mode 100644 index 0000000..3a6dfe4 --- /dev/null +++ b/sys/powerpc/powermac/ata_kauai.c @@ -0,0 +1,190 @@ +/* + * Copyright 2004 by Peter Grehan. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include +__FBSDID("$FreeBSD$"); + +/* + * Mac 'Kauai' PCI ATA controller + */ +#include "opt_ata.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define ATA_KAUAI_REGOFFSET 0x2000 +#define ATA_KAUAI_ALTOFFSET (ATA_KAUAI_REGOFFSET + 0x16) + +/* + * Define the kauai pci bus attachment. + */ +static int ata_kauai_probe(device_t dev); + +static device_method_t ata_kauai_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ata_kauai_probe), + DEVMETHOD(device_attach, ata_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + { 0, 0 } +}; + +static driver_t ata_kauai_driver = { + "ata", + ata_kauai_methods, + sizeof(struct ata_channel), +}; + +DRIVER_MODULE(ata, pci, ata_kauai_driver, ata_devclass, 0, 0); + +static void +ata_kauai_locknoop(struct ata_channel *ch, int type) +{ + /* XXX SMP ? */ +} + +static void +ata_kauai_setmode(struct ata_device *atadev, int mode) +{ + atadev->mode = ATA_PIO; +} + + +/* + * PCI ID search table + */ +static struct kauai_pci_dev { + u_int32_t kpd_devid; + char *kpd_desc; +} kauai_pci_devlist[] = { + { 0x0033106b, "Uninorth2 Kauai ATA Controller" }, + { 0x003b106b, "Intrepid Kauai ATA Controller" }, + { 0x0043106b, "K2 Kauai ATA Controller" }, + { 0, NULL } +}; + +static int +ata_kauai_probe(device_t dev) +{ + struct ata_channel *ch; + struct resource *mem; + u_long startp, countp; + u_int32_t devid; + int i, found, rid, status; + + 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); + + /* + * This device seems to ignore writes to the interrupt + * config register, resulting in interrupt resources + * not being attached. If this is the case, use + * OpenFirmware to determine the irq, and then attach + * the resource. This allows the ATA common code to + * allocate the irq. + */ + status = bus_get_resource(dev, SYS_RES_IRQ, 0, &startp, &countp); + if (status == ENOENT) { + int irq; + + /* + * Aargh, hideous hack until ofw pci intr routine is + * exported + */ + irq = 39; /* XXX */ + bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); + + /* + * Sanity check... + */ + status = bus_get_resource(dev, SYS_RES_IRQ, 0, &startp, + &countp); + if (status == ENOENT || + startp != 39) { + printf("kauai irq not set!\n"); + return (ENXIO); + } + } + + ch = device_get_softc(dev); + + rid = 0; + mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~1, 1, + RF_ACTIVE); + if (mem == NULL) { + device_printf(dev, "could not allocate memory\n"); + return (ENXIO); + } + + /* + * Set up the resource vectors + */ + for (i = ATA_DATA; i <= ATA_STATUS; i++) { + ch->r_io[i].res = mem; + ch->r_io[i].offset = i + ATA_KAUAI_REGOFFSET; + } + ch->r_io[ATA_ALTSTAT].res = mem; + ch->r_io[ATA_ALTSTAT].offset = ATA_KAUAI_ALTOFFSET; + + ch->unit = 0; + ch->flags |= ATA_USE_16BIT|ATA_NO_SLAVE; + ch->locking = ata_kauai_locknoop; + ch->device[MASTER].setmode = ata_kauai_setmode; + ch->device[SLAVE].setmode = ata_kauai_setmode; + + return (ata_probe(dev)); +} + -- cgit v1.1