1 /* $OpenBSD: kauaiata.c,v 1.10 2008/04/25 14:51:35 jmc Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Dale Rahn 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 /* 30 * Glue to to attach kauai ata to the macobio_wdc 31 * which it heavily resembles. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/device.h> 37 38 #include <machine/bus.h> 39 40 #include <dev/pci/pcivar.h> 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcidevs.h> 43 44 #include <dev/ofw/openfirm.h> 45 46 #include <machine/autoconf.h> 47 48 49 struct kauaiata_softc { 50 struct device sc_dev; 51 struct ppc_bus_space sc_membus_space; 52 /* XXX */ 53 }; 54 55 int kauaiatamatch(struct device *parent, void *match, void *aux); 56 void kauaiataattach(struct device *parent, struct device *self, void *aux); 57 int kauaiata_print(void *aux, const char *dev); 58 59 60 struct cfattach kauaiata_ca = { 61 sizeof(struct kauaiata_softc), kauaiatamatch, kauaiataattach, 62 }; 63 64 struct cfdriver kauaiata_cd = { 65 NULL, "kauaiata", DV_DULL, 66 }; 67 68 int 69 kauaiatamatch(struct device *parent, void *match, void *aux) 70 { 71 struct pci_attach_args *pa = aux; 72 73 /* 74 * Match the adapter 75 * XXX match routine?? 76 */ 77 switch(PCI_VENDOR(pa->pa_id)) { 78 case PCI_VENDOR_APPLE: 79 switch (PCI_PRODUCT(pa->pa_id)) { 80 case PCI_PRODUCT_APPLE_UNINORTH_ATA: 81 case PCI_PRODUCT_APPLE_INTREPID_ATA: 82 case PCI_PRODUCT_APPLE_INTREPID2_ATA: 83 case PCI_PRODUCT_APPLE_K2_ATA: 84 case PCI_PRODUCT_APPLE_SHASTA_ATA: 85 return (1); 86 } 87 break; 88 } 89 return 0; 90 } 91 92 void 93 kauaiataattach(struct device *parent, struct device *self, void *aux) 94 { 95 int node; 96 struct confargs ca; 97 int namelen; 98 u_int32_t reg[20]; 99 char name[32]; 100 int32_t intr[8]; 101 102 struct kauaiata_softc *sc = (struct kauaiata_softc *)self; 103 struct pci_attach_args *pa = aux; 104 pci_chipset_tag_t pc = pa->pa_pc; 105 106 /* XXX not necessarily the right device */ 107 node = OF_finddevice("uata"); 108 if (node == -1) 109 node = OF_finddevice("/pci@f4000000/ata-6"); 110 111 if (node == -1) { 112 printf("\n"); 113 return; 114 } 115 116 /* 117 * XXX - need to compare node and PCI id to verify this is the 118 * correct device. 119 */ 120 121 ca.ca_nreg = OF_getprop(node, "reg", reg, sizeof(reg)); 122 123 /* 124 * The PCI Interrupt Configuration Registers seems to be 125 * hardwired to 0. Get the interrupt line from OpenFirmware. 126 */ 127 /* XXX */ 128 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE && 129 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_SHASTA_ATA) { 130 ca.ca_nintr = OF_getprop(node, "interrupts", 131 intr, sizeof intr); 132 } else { 133 ca.ca_nintr = 4; 134 intr[0] = 0x27; 135 } 136 137 namelen = OF_getprop(node, "name", name, sizeof(name)); 138 if ((namelen < 0) || (namelen >= sizeof(name))) { 139 printf(" bad name prop len %x\n", namelen); 140 return; 141 } 142 143 name[namelen] = 0; /* name property may not be null terminated */ 144 145 /* config read */ 146 sc->sc_membus_space.bus_base = 147 pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START); 148 149 /* make sure device memory access is enabled */ 150 { 151 bus_space_tag_t iot; 152 bus_space_handle_t ioh; 153 bus_size_t size; 154 155 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0, 156 &iot, &ioh, NULL, &size, 0)) { 157 printf(": mapping memory failed\n"); 158 return; 159 } 160 161 bus_space_unmap(iot, ioh, size); 162 } 163 #if 0 164 pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, 0xffffffff); 165 size = ~(pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START)); 166 pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, 167 sc->sc_membus_space.bus_base); 168 #endif 169 170 ca.ca_baseaddr = sc->sc_membus_space.bus_base; 171 172 ca.ca_name = name; 173 ca.ca_iot = &sc->sc_membus_space; 174 ca.ca_dmat = pa->pa_dmat; 175 176 ca.ca_reg = reg; 177 reg[0] = 0x2000; /* offset to wdc registers */ 178 reg[1] = reg[9] - 0x2000; /* map size of wdc registers */ 179 reg[2] = 0x1000; /* offset to dbdma registers */ 180 reg[3] = 0x1000; /* map size of dbdma registers */ 181 ca.ca_intr = intr; 182 183 printf("\n"); 184 185 config_found(self, &ca, kauaiata_print); 186 } 187 188 int 189 kauaiata_print(void *aux, const char *dev) 190 { 191 return QUIET; 192 } 193