| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: pci_addr_fixup.c,v 1.6 2011/07/01 18:22:08 dyoung Exp $ */ | | 1 | /* $NetBSD: pci_addr_fixup.c,v 1.7 2011/08/28 05:32:41 dyoung Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved. | | 4 | * Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. The name of the author may not be used to endorse or promote products | | 14 | * 3. The name of the author may not be used to endorse or promote products |
| @@ -17,56 +17,52 @@ | | | @@ -17,56 +17,52 @@ |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: pci_addr_fixup.c,v 1.6 2011/07/01 18:22:08 dyoung Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: pci_addr_fixup.c,v 1.7 2011/08/28 05:32:41 dyoung Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/systm.h> | | 33 | #include <sys/systm.h> |
34 | #include <sys/malloc.h> | | 34 | #include <sys/malloc.h> |
35 | #include <sys/kernel.h> | | 35 | #include <sys/kernel.h> |
36 | #include <sys/device.h> | | 36 | #include <sys/device.h> |
37 | #include <sys/extent.h> | | 37 | #include <sys/extent.h> |
38 | | | 38 | |
39 | #include <sys/bus.h> | | 39 | #include <sys/bus.h> |
40 | | | 40 | |
41 | #include <dev/pci/pcireg.h> | | 41 | #include <dev/pci/pcireg.h> |
42 | #include <dev/pci/pcivar.h> | | 42 | #include <dev/pci/pcivar.h> |
43 | #include <dev/pci/pcidevs.h> | | 43 | #include <dev/pci/pcidevs.h> |
44 | | | 44 | |
45 | #include <x86/pci/pci_addr_fixup.h> | | 45 | #include <x86/pci/pci_addr_fixup.h> |
46 | | | 46 | |
47 | struct pciaddr pciaddr; | | 47 | struct pciaddr pciaddr; |
48 | | | 48 | |
49 | static int pciaddrverbose = 0; | | 49 | static void pciaddr_resource_reserve(pci_chipset_tag_t, pcitag_t, void *); |
50 | | | 50 | static int pciaddr_do_resource_reserve(pci_chipset_tag_t, pcitag_t, int, |
51 | void pciaddr_resource_reserve(pci_chipset_tag_t, pcitag_t, void *context); | | | |
52 | int pciaddr_do_resource_reserve(pci_chipset_tag_t, pcitag_t, int, | | | |
53 | void *, int, bus_addr_t *, bus_size_t); | | 51 | void *, int, bus_addr_t *, bus_size_t); |
54 | void pciaddr_resource_allocate(pci_chipset_tag_t, pcitag_t, void *context); | | 52 | static void pciaddr_resource_allocate(pci_chipset_tag_t, pcitag_t, void *); |
55 | int pciaddr_do_resource_allocate(pci_chipset_tag_t, pcitag_t, int, | | 53 | static int pciaddr_do_resource_allocate(pci_chipset_tag_t, pcitag_t, int, |
56 | void *, int, bus_addr_t *, bus_size_t); | | 54 | void *, int, bus_addr_t *, bus_size_t); |
57 | int device_is_agp(pci_chipset_tag_t, pcitag_t); | | 55 | static int device_is_agp(pci_chipset_tag_t, pcitag_t); |
58 | | | | |
59 | int device_is_agp(pci_chipset_tag_t, pcitag_t); | | | |
60 | | | 56 | |
61 | #define PCIADDR_MEM_START 0x0 | | 57 | #define PCIADDR_MEM_START 0x0 |
62 | #define PCIADDR_MEM_END 0xffffffff | | 58 | #define PCIADDR_MEM_END 0xffffffff |
63 | #define PCIADDR_PORT_START 0x0 | | 59 | #define PCIADDR_PORT_START 0x0 |
64 | #define PCIADDR_PORT_END 0xffff | | 60 | #define PCIADDR_PORT_END 0xffff |
65 | | | 61 | |
66 | /* for ISA devices */ | | 62 | /* for ISA devices */ |
67 | #define PCIADDR_ISAPORT_RESERVE 0x5800 /* empirical value */ | | 63 | #define PCIADDR_ISAPORT_RESERVE 0x5800 /* empirical value */ |
68 | #define PCIADDR_ISAMEM_RESERVE (16 * 1024 * 1024) | | 64 | #define PCIADDR_ISAMEM_RESERVE (16 * 1024 * 1024) |
69 | | | 65 | |
70 | void | | 66 | void |
71 | pci_addr_fixup(pci_chipset_tag_t pc, int maxbus) | | 67 | pci_addr_fixup(pci_chipset_tag_t pc, int maxbus) |
72 | { | | 68 | { |
| @@ -137,72 +133,70 @@ pci_addr_fixup(pci_chipset_tag_t pc, int | | | @@ -137,72 +133,70 @@ pci_addr_fixup(pci_chipset_tag_t pc, int |
137 | if (pciaddr.nbogus == 0) | | 133 | if (pciaddr.nbogus == 0) |
138 | return; /* no need to fixup */ | | 134 | return; /* no need to fixup */ |
139 | | | 135 | |
140 | /* | | 136 | /* |
141 | * 4. do fixup | | 137 | * 4. do fixup |
142 | */ | | 138 | */ |
143 | aprint_debug(verbose_header, "PCIBIOS fixup stage"); | | 139 | aprint_debug(verbose_header, "PCIBIOS fixup stage"); |
144 | pciaddr.nbogus = 0; | | 140 | pciaddr.nbogus = 0; |
145 | pci_device_foreach_min(pc, 0, maxbus, pciaddr_resource_allocate, NULL); | | 141 | pci_device_foreach_min(pc, 0, maxbus, pciaddr_resource_allocate, NULL); |
146 | aprint_debug(verbose_footer, pciaddr.nbogus); | | 142 | aprint_debug(verbose_footer, pciaddr.nbogus); |
147 | | | 143 | |
148 | } | | 144 | } |
149 | | | 145 | |
150 | void | | 146 | static void |
151 | pciaddr_resource_reserve(pci_chipset_tag_t pc, pcitag_t tag, | | 147 | pciaddr_resource_reserve(pci_chipset_tag_t pc, pcitag_t tag, |
152 | void *context) | | 148 | void *context) |
153 | { | | 149 | { |
154 | if (pciaddrverbose) | | | |
155 | pciaddr_print_devid(pc, tag); | | 150 | pciaddr_print_devid(pc, tag); |
156 | pciaddr_resource_manage(pc, tag, | | 151 | pciaddr_resource_manage(pc, tag, |
157 | pciaddr_do_resource_reserve, | | 152 | pciaddr_do_resource_reserve, |
158 | &pciaddr); | | 153 | &pciaddr); |
159 | } | | 154 | } |
160 | | | 155 | |
161 | void | | 156 | static void |
162 | pciaddr_resource_allocate(pci_chipset_tag_t pc, pcitag_t tag, | | 157 | pciaddr_resource_allocate(pci_chipset_tag_t pc, pcitag_t tag, |
163 | void *context) | | 158 | void *context) |
164 | { | | 159 | { |
165 | if (pciaddrverbose) | | | |
166 | pciaddr_print_devid(pc, tag); | | 160 | pciaddr_print_devid(pc, tag); |
167 | pciaddr_resource_manage(pc, tag, | | 161 | pciaddr_resource_manage(pc, tag, |
168 | pciaddr_do_resource_allocate, | | 162 | pciaddr_do_resource_allocate, |
169 | &pciaddr); | | 163 | &pciaddr); |
170 | } | | 164 | } |
171 | | | 165 | |
172 | void | | 166 | void |
173 | pciaddr_resource_manage(pci_chipset_tag_t pc, pcitag_t tag, | | 167 | pciaddr_resource_manage(pci_chipset_tag_t pc, pcitag_t tag, |
174 | pciaddr_resource_manage_func_t func, void *ctx) | | 168 | pciaddr_resource_manage_func_t func, void *ctx) |
175 | { | | 169 | { |
176 | pcireg_t val, mask; | | 170 | pcireg_t val, mask; |
177 | bus_addr_t addr; | | 171 | bus_addr_t addr; |
178 | bus_size_t size; | | 172 | bus_size_t size; |
179 | int error, useport, usemem, mapreg, type, reg_start, reg_end, width; | | 173 | int error, useport, usemem, mapreg, type, reg_start, reg_end, width; |
180 | | | 174 | |
181 | val = pci_conf_read(pc, tag, PCI_BHLC_REG); | | 175 | val = pci_conf_read(pc, tag, PCI_BHLC_REG); |
182 | switch (PCI_HDRTYPE_TYPE(val)) { | | 176 | switch (PCI_HDRTYPE_TYPE(val)) { |
183 | default: | | 177 | default: |
184 | aprint_error("WARNING: unknown PCI device header."); | | 178 | aprint_error("WARNING: unknown PCI device header."); |
185 | pciaddr.nbogus++; | | 179 | pciaddr.nbogus++; |
186 | return; | | 180 | return; |
187 | case 0: | | 181 | case PCI_HDRTYPE_DEVICE: |
188 | reg_start = PCI_MAPREG_START; | | 182 | reg_start = PCI_MAPREG_START; |
189 | reg_end = PCI_MAPREG_END; | | 183 | reg_end = PCI_MAPREG_END; |
190 | break; | | 184 | break; |
191 | case 1: /* PCI-PCI bridge */ | | 185 | case PCI_HDRTYPE_PPB: /* PCI-PCI bridge */ |
192 | reg_start = PCI_MAPREG_START; | | 186 | reg_start = PCI_MAPREG_START; |
193 | reg_end = PCI_MAPREG_PPB_END; | | 187 | reg_end = PCI_MAPREG_PPB_END; |
194 | break; | | 188 | break; |
195 | case 2: /* PCI-CardBus bridge */ | | 189 | case PCI_HDRTYPE_PCB: /* PCI-CardBus bridge */ |
196 | reg_start = PCI_MAPREG_START; | | 190 | reg_start = PCI_MAPREG_START; |
197 | reg_end = PCI_MAPREG_PCB_END; | | 191 | reg_end = PCI_MAPREG_PCB_END; |
198 | break; | | 192 | break; |
199 | } | | 193 | } |
200 | error = useport = usemem = 0; | | 194 | error = useport = usemem = 0; |
201 | | | 195 | |
202 | for (mapreg = reg_start; mapreg < reg_end; mapreg += width) { | | 196 | for (mapreg = reg_start; mapreg < reg_end; mapreg += width) { |
203 | /* inquire PCI device bus space requirement */ | | 197 | /* inquire PCI device bus space requirement */ |
204 | val = pci_conf_read(pc, tag, mapreg); | | 198 | val = pci_conf_read(pc, tag, mapreg); |
205 | pci_conf_write(pc, tag, mapreg, ~0); | | 199 | pci_conf_write(pc, tag, mapreg, ~0); |
206 | | | 200 | |
207 | mask = pci_conf_read(pc, tag, mapreg); | | 201 | mask = pci_conf_read(pc, tag, mapreg); |
208 | pci_conf_write(pc, tag, mapreg, val); | | 202 | pci_conf_write(pc, tag, mapreg, val); |
| @@ -219,166 +213,162 @@ pciaddr_resource_manage(pci_chipset_tag_ | | | @@ -219,166 +213,162 @@ pciaddr_resource_manage(pci_chipset_tag_ |
219 | * XXX i386-land. | | 213 | * XXX i386-land. |
220 | * XXX So just arrange to not look at the | | 214 | * XXX So just arrange to not look at the |
221 | * XXX upper 32 bits, lest we misinterpret | | 215 | * XXX upper 32 bits, lest we misinterpret |
222 | * XXX it as a 32-bit BAR set to zero. | | 216 | * XXX it as a 32-bit BAR set to zero. |
223 | */ | | 217 | */ |
224 | width = 8; | | 218 | width = 8; |
225 | } | | 219 | } |
226 | size = PCI_MAPREG_MEM_SIZE(mask); | | 220 | size = PCI_MAPREG_MEM_SIZE(mask); |
227 | } else { | | 221 | } else { |
228 | size = PCI_MAPREG_IO_SIZE(mask); | | 222 | size = PCI_MAPREG_IO_SIZE(mask); |
229 | } | | 223 | } |
230 | addr = pciaddr_ioaddr(val); | | 224 | addr = pciaddr_ioaddr(val); |
231 | | | 225 | |
232 | if (!size) /* unused register */ | | 226 | if (size == 0) /* unused register */ |
233 | continue; | | 227 | continue; |
234 | | | 228 | |
235 | if (type == PCI_MAPREG_TYPE_MEM) | | 229 | if (type == PCI_MAPREG_TYPE_MEM) |
236 | ++usemem; | | 230 | ++usemem; |
237 | else | | 231 | else |
238 | ++useport; | | 232 | ++useport; |
239 | | | 233 | |
240 | /* reservation/allocation phase */ | | 234 | /* reservation/allocation phase */ |
241 | error += (*func) (pc, tag, mapreg, ctx, type, &addr, size); | | 235 | error += (*func) (pc, tag, mapreg, ctx, type, &addr, size); |
242 | | | 236 | |
243 | aprint_debug("\n\t%02xh %s 0x%08x 0x%08x", | | 237 | aprint_debug("\n\t%02xh %s 0x%08x 0x%08x", |
244 | mapreg, type ? "port" : "mem ", | | 238 | mapreg, type ? "port" : "mem ", |
245 | (unsigned int)addr, (unsigned int)size); | | 239 | (unsigned int)addr, (unsigned int)size); |
246 | } | | 240 | } |
247 | | | 241 | |
248 | /* enable/disable PCI device */ | | 242 | /* enable/disable PCI device */ |
249 | val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); | | 243 | val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); |
250 | if (error == 0) | | 244 | if (error == 0) |
251 | val |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | | | 245 | val |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | |
252 | PCI_COMMAND_MASTER_ENABLE); | | 246 | PCI_COMMAND_MASTER_ENABLE); |
253 | else | | 247 | else |
254 | val &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | | | 248 | val &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | |
255 | PCI_COMMAND_MASTER_ENABLE); | | 249 | PCI_COMMAND_MASTER_ENABLE); |
256 | pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, val); | | 250 | pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, val); |
257 | | | 251 | |
258 | if (error) | | 252 | if (error != 0) |
259 | pciaddr.nbogus++; | | 253 | pciaddr.nbogus++; |
260 | | | 254 | |
261 | aprint_debug("\n\t\t[%s]\n", error ? "NG" : "OK"); | | 255 | aprint_debug("\n\t\t[%s]\n", error ? "NG" : "OK"); |
262 | } | | 256 | } |
263 | | | 257 | |
264 | int | | 258 | static int |
265 | pciaddr_do_resource_allocate(pci_chipset_tag_t pc, pcitag_t tag, | | 259 | pciaddr_do_resource_allocate(pci_chipset_tag_t pc, pcitag_t tag, |
266 | int mapreg, void *ctx, int type, bus_addr_t *addr, bus_size_t size) | | 260 | int mapreg, void *ctx, int type, bus_addr_t *addr, bus_size_t size) |
267 | { | | 261 | { |
268 | struct pciaddr *pciaddrmap = (struct pciaddr *)ctx; | | 262 | struct pciaddr *pciaddrmap = (struct pciaddr *)ctx; |
269 | bus_addr_t start; | | 263 | bus_addr_t start; |
270 | int error; | | 264 | int error; |
271 | struct extent *ex; | | 265 | struct extent *ex; |
272 | | | 266 | |
273 | if (*addr) /* no need to allocate */ | | 267 | if (*addr != 0) /* no need to allocate */ |
274 | return (0); | | 268 | return 0; |
275 | | | 269 | |
276 | ex = (type == PCI_MAPREG_TYPE_MEM ? | | 270 | ex = (type == PCI_MAPREG_TYPE_MEM ? |
277 | pciaddrmap->extent_mem : pciaddrmap->extent_port); | | 271 | pciaddrmap->extent_mem : pciaddrmap->extent_port); |
278 | | | 272 | |
279 | /* XXX Don't allocate if device is AGP device to avoid conflict. */ | | 273 | /* XXX Don't allocate if device is AGP device to avoid conflict. */ |
280 | if (device_is_agp(pc, tag)) | | 274 | if (device_is_agp(pc, tag)) |
281 | return (0); | | 275 | return 0; |
282 | | | 276 | |
283 | start = (type == PCI_MAPREG_TYPE_MEM ? | | 277 | start = (type == PCI_MAPREG_TYPE_MEM ? |
284 | pciaddrmap->mem_alloc_start : pciaddrmap->port_alloc_start); | | 278 | pciaddrmap->mem_alloc_start : pciaddrmap->port_alloc_start); |
285 | | | 279 | |
286 | if (start < ex->ex_start || start + size - 1 >= ex->ex_end) { | | 280 | if (start < ex->ex_start || start + size - 1 >= ex->ex_end) { |
287 | aprint_debug("No available resources. fixup failed\n"); | | 281 | aprint_debug("No available resources. fixup failed\n"); |
288 | return (1); | | 282 | return 1; |
289 | } | | 283 | } |
290 | error = extent_alloc_subregion(ex, start, ex->ex_end, size, | | 284 | error = extent_alloc_subregion(ex, start, ex->ex_end, size, |
291 | size, 0, | | 285 | size, 0, |
292 | EX_FAST|EX_NOWAIT|EX_MALLOCOK, | | 286 | EX_FAST|EX_NOWAIT|EX_MALLOCOK, |
293 | (u_long *)addr); | | 287 | (u_long *)addr); |
294 | if (error) { | | 288 | if (error) { |
295 | aprint_debug("No available resources. fixup failed\n"); | | 289 | aprint_debug("No available resources. fixup failed\n"); |
296 | return (1); | | 290 | return 1; |
297 | } | | 291 | } |
298 | | | 292 | |
299 | /* write new address to PCI device configuration header */ | | 293 | /* write new address to PCI device configuration header */ |
300 | pci_conf_write(pc, tag, mapreg, *addr); | | 294 | pci_conf_write(pc, tag, mapreg, *addr); |
301 | /* check */ | | 295 | /* check */ |
302 | if (!pciaddrverbose) | | 296 | aprint_debug("pci_addr_fixup: "); |
303 | { | | | |
304 | aprint_verbose("pci_addr_fixup: "); | | | |
305 | pciaddr_print_devid(pc, tag); | | 297 | pciaddr_print_devid(pc, tag); |
306 | } | | | |
307 | if (pciaddr_ioaddr(pci_conf_read(pc, tag, mapreg)) != *addr) { | | 298 | if (pciaddr_ioaddr(pci_conf_read(pc, tag, mapreg)) != *addr) { |
308 | pci_conf_write(pc, tag, mapreg, 0); /* clear */ | | 299 | pci_conf_write(pc, tag, mapreg, 0); /* clear */ |
309 | aprint_error("fixup failed. (new address=%#x)\n", (unsigned)*addr); | | 300 | aprint_error("fixup failed. (new address=%#x)\n", (unsigned)*addr); |
310 | return (1); | | 301 | return 1; |
311 | } | | 302 | } |
312 | if (!pciaddrverbose) | | 303 | aprint_debug("new address 0x%08x\n", (unsigned)*addr); |
313 | aprint_verbose("new address 0x%08x\n", (unsigned)*addr); | | | |
314 | | | 304 | |
315 | return (0); | | 305 | return 0; |
316 | } | | 306 | } |
317 | | | 307 | |
318 | int | | 308 | int |
319 | pciaddr_do_resource_reserve(pci_chipset_tag_t pc, pcitag_t tag, | | 309 | pciaddr_do_resource_reserve(pci_chipset_tag_t pc, pcitag_t tag, |
320 | int mapreg, void *ctx, int type, bus_addr_t *addr, bus_size_t size) | | 310 | int mapreg, void *ctx, int type, bus_addr_t *addr, bus_size_t size) |
321 | { | | 311 | { |
322 | struct extent *ex; | | 312 | struct extent *ex; |
323 | struct pciaddr *pciaddrmap = (struct pciaddr *)ctx; | | 313 | struct pciaddr *pciaddrmap = (struct pciaddr *)ctx; |
324 | int error; | | 314 | int error; |
325 | | | 315 | |
326 | if (*addr == 0) | | 316 | if (*addr == 0) |
327 | return (1); | | 317 | return 1; |
328 | | | 318 | |
329 | ex = (type == PCI_MAPREG_TYPE_MEM ? | | 319 | ex = (type == PCI_MAPREG_TYPE_MEM ? |
330 | pciaddrmap->extent_mem : pciaddrmap->extent_port); | | 320 | pciaddrmap->extent_mem : pciaddrmap->extent_port); |
331 | | | 321 | |
332 | error = extent_alloc_region(ex, *addr, size, EX_NOWAIT| EX_MALLOCOK); | | 322 | error = extent_alloc_region(ex, *addr, size, EX_NOWAIT| EX_MALLOCOK); |
333 | if (error) { | | 323 | if (error) { |
334 | aprint_debug("Resource conflict.\n"); | | 324 | aprint_debug("Resource conflict.\n"); |
335 | pci_conf_write(pc, tag, mapreg, 0); /* clear */ | | 325 | pci_conf_write(pc, tag, mapreg, 0); /* clear */ |
336 | return (1); | | 326 | return 1; |
337 | } | | 327 | } |
338 | | | 328 | |
339 | return (0); | | 329 | return 0; |
340 | } | | 330 | } |
341 | | | 331 | |
342 | bus_addr_t | | 332 | bus_addr_t |
343 | pciaddr_ioaddr(uint32_t val) | | 333 | pciaddr_ioaddr(uint32_t val) |
344 | { | | 334 | { |
345 | return ((PCI_MAPREG_TYPE(val) == PCI_MAPREG_TYPE_MEM) | | 335 | return (PCI_MAPREG_TYPE(val) == PCI_MAPREG_TYPE_MEM) |
346 | ? PCI_MAPREG_MEM_ADDR(val) | | 336 | ? PCI_MAPREG_MEM_ADDR(val) |
347 | : PCI_MAPREG_IO_ADDR(val)); | | 337 | : PCI_MAPREG_IO_ADDR(val); |
348 | } | | 338 | } |
349 | | | 339 | |
350 | void | | 340 | void |
351 | pciaddr_print_devid(pci_chipset_tag_t pc, pcitag_t tag) | | 341 | pciaddr_print_devid(pci_chipset_tag_t pc, pcitag_t tag) |
352 | { | | 342 | { |
353 | int bus, device, function; | | 343 | int bus, device, function; |
354 | pcireg_t id; | | 344 | pcireg_t id; |
355 | | | 345 | |
356 | id = pci_conf_read(pc, tag, PCI_ID_REG); | | 346 | id = pci_conf_read(pc, tag, PCI_ID_REG); |
357 | pci_decompose_tag(pc, tag, &bus, &device, &function); | | 347 | pci_decompose_tag(pc, tag, &bus, &device, &function); |
358 | aprint_verbose("%03d:%02d:%d 0x%04x 0x%04x ", bus, device, function, | | 348 | aprint_debug("%03d:%02d:%d 0x%04x 0x%04x ", bus, device, function, |
359 | PCI_VENDOR(id), PCI_PRODUCT(id)); | | 349 | PCI_VENDOR(id), PCI_PRODUCT(id)); |
360 | } | | 350 | } |
361 | | | 351 | |
362 | int | | 352 | static int |
363 | device_is_agp(pci_chipset_tag_t pc, pcitag_t tag) | | 353 | device_is_agp(pci_chipset_tag_t pc, pcitag_t tag) |
364 | { | | 354 | { |
365 | pcireg_t class, status, rval; | | 355 | pcireg_t class, status, rval; |
366 | int off; | | 356 | int off; |
367 | | | 357 | |
368 | /* Check AGP device. */ | | 358 | /* Check AGP device. */ |
369 | class = pci_conf_read(pc, tag, PCI_CLASS_REG); | | 359 | class = pci_conf_read(pc, tag, PCI_CLASS_REG); |
370 | if (PCI_CLASS(class) == PCI_CLASS_DISPLAY) { | | 360 | if (PCI_CLASS(class) == PCI_CLASS_DISPLAY) { |
371 | status = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); | | 361 | status = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); |
372 | if (status & PCI_STATUS_CAPLIST_SUPPORT) { | | 362 | if (status & PCI_STATUS_CAPLIST_SUPPORT) { |
373 | rval = pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG); | | 363 | rval = pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG); |
374 | for (off = PCI_CAPLIST_PTR(rval); | | 364 | for (off = PCI_CAPLIST_PTR(rval); |
375 | off != 0; | | 365 | off != 0; |
376 | off = PCI_CAPLIST_NEXT(rval) ) { | | 366 | off = PCI_CAPLIST_NEXT(rval) ) { |
377 | rval = pci_conf_read(pc, tag, off); | | 367 | rval = pci_conf_read(pc, tag, off); |
378 | if (PCI_CAPLIST_CAP(rval) == PCI_CAP_AGP) | | 368 | if (PCI_CAPLIST_CAP(rval) == PCI_CAP_AGP) |
379 | return (1); | | 369 | return 1; |
380 | } | | 370 | } |
381 | } | | 371 | } |
382 | } | | 372 | } |
383 | return (0); | | 373 | return 0; |
384 | } | | 374 | } |