FreeBSD/Linux Kernel Cross Reference
sys/pci/pci_compat.c
1 /*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * 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 OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 *
28 */
29
30 #include "opt_bus.h"
31
32 /* for compatibility to FreeBSD-2.2 version of PCI code */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37
38 #include <vm/vm.h>
39 #include <vm/pmap.h>
40 #include <sys/interrupt.h>
41
42 #include <sys/bus.h>
43 #include <machine/bus.h>
44 #include <sys/rman.h>
45 #include <machine/resource.h>
46
47 #include <pci/pcireg.h>
48 #include <pci/pcivar.h>
49
50 #ifdef APIC_IO
51 #include <machine/smp.h>
52 #endif
53
54 #ifdef PCI_COMPAT
55
56 /* ------------------------------------------------------------------------- */
57
58 u_long
59 pci_conf_read(pcici_t cfg, u_long reg)
60 {
61 return (pci_read_config(cfg->dev, reg, 4));
62 }
63
64 void
65 pci_conf_write(pcici_t cfg, u_long reg, u_long data)
66 {
67 pci_write_config(cfg->dev, reg, data, 4);
68 }
69
70 int
71 pci_map_port(pcici_t cfg, u_long reg, pci_port_t* pa)
72 {
73 int rid;
74 struct resource *res;
75
76 rid = reg;
77 res = bus_alloc_resource(cfg->dev, SYS_RES_IOPORT, &rid,
78 0, ~0, 1, RF_ACTIVE);
79 if (res) {
80 *pa = rman_get_start(res);
81 return (1);
82 }
83 return (0);
84 }
85
86 int
87 pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
88 {
89 int rid;
90 struct resource *res;
91
92 rid = reg;
93 res = bus_alloc_resource(cfg->dev, SYS_RES_MEMORY, &rid,
94 0, ~0, 1, RF_ACTIVE);
95 if (res) {
96 *pa = rman_get_start(res);
97 *va = (vm_offset_t) rman_get_virtual(res);
98 return (1);
99 }
100 return (0);
101 }
102
103 int
104 pci_map_int(pcici_t cfg, pci_inthand_t *handler, void *arg, intrmask_t *maskptr)
105 {
106 return (pci_map_int_right(cfg, handler, arg, maskptr, 0));
107 }
108
109 int
110 pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
111 intrmask_t *maskptr, u_int intflags)
112 {
113 int error;
114 #ifdef APIC_IO
115 int nextpin, muxcnt;
116 #endif
117 if (cfg->intpin != 0) {
118 int irq = cfg->intline;
119 int rid = 0;
120 struct resource *res;
121 int flags = 0;
122 int resflags = RF_SHAREABLE|RF_ACTIVE;
123 void *ih;
124
125 #ifdef INTR_FAST
126 if (intflags & INTR_FAST)
127 flags |= INTR_TYPE_FAST;
128 if (intflags & INTR_EXCL)
129 resflags &= ~RF_SHAREABLE;
130 #endif
131
132 res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
133 irq, irq, 1, resflags);
134 if (!res) {
135 printf("pci_map_int: can't allocate interrupt\n");
136 return 0;
137 }
138
139 /*
140 * This is ugly. Translate the mask into an interrupt type.
141 */
142 if (maskptr == &tty_imask)
143 flags |= INTR_TYPE_TTY;
144 else if (maskptr == &bio_imask)
145 flags |= INTR_TYPE_BIO;
146 else if (maskptr == &net_imask)
147 flags |= INTR_TYPE_NET;
148 else if (maskptr == &cam_imask)
149 flags |= INTR_TYPE_CAM;
150
151 error = BUS_SETUP_INTR(device_get_parent(cfg->dev), cfg->dev,
152 res, flags, handler, arg, &ih);
153 if (error != 0)
154 return 0;
155
156 #ifdef NEW_BUS_PCI
157 /*
158 * XXX this apic stuff looks totally busted. It should
159 * move to the nexus code which actually registers the
160 * interrupt.
161 */
162 #endif
163
164 #ifdef APIC_IO
165 nextpin = next_apic_irq(irq);
166
167 if (nextpin < 0)
168 return 1;
169
170 /*
171 * Attempt handling of some broken mp tables.
172 *
173 * It's OK to yell (since the mp tables are broken).
174 *
175 * Hanging in the boot is not OK
176 */
177
178 muxcnt = 2;
179 nextpin = next_apic_irq(nextpin);
180 while (muxcnt < 5 && nextpin >= 0) {
181 muxcnt++;
182 nextpin = next_apic_irq(nextpin);
183 }
184 if (muxcnt >= 5) {
185 printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n");
186 return 0;
187 }
188
189 printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt);
190
191 nextpin = next_apic_irq(irq);
192 while (nextpin >= 0) {
193 rid = 0;
194 res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
195 nextpin, nextpin, 1,
196 resflags);
197 if (!res) {
198 printf("pci_map_int: can't allocate extra interrupt\n");
199 return 0;
200 }
201 error = BUS_SETUP_INTR(device_get_parent(cfg->dev),
202 cfg->dev, res, flags,
203 handler, arg, &ih);
204 if (error != 0) {
205 printf("pci_map_int: BUS_SETUP_INTR failed\n");
206 return 0;
207 }
208 printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
209 nextpin = next_apic_irq(nextpin);
210 }
211 #endif
212 }
213 return (1);
214 }
215
216 int
217 pci_unmap_int(pcici_t cfg)
218 {
219 return (0); /* not supported, yet, since cfg doesn't know about idesc */
220 }
221
222 pcici_t
223 pci_get_parent_from_tag(pcici_t tag)
224 {
225 return (pcici_t)pci_devlist_get_parent(tag);
226 }
227
228 int
229 pci_get_bus_from_tag(pcici_t tag)
230 {
231 return tag->bus;
232 }
233
234 #endif /* PCI_COMPAT */
Cache object: 3df66810c9b715ac3d724a8fd2b81296
|