1 /* $OpenBSD: kauaiata.c,v 1.12 2023/04/11 00:45:07 jsg 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 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 const 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
kauaiatamatch(struct device * parent,void * match,void * aux)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
kauaiataattach(struct device * parent,struct device * self,void * aux)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
kauaiata_print(void * aux,const char * dev)189 kauaiata_print(void *aux, const char *dev)
190 {
191 return QUIET;
192 }
193