1 | /* $NetBSD: pcivar.h,v 1.108 2016/07/11 06:14:51 knakahara Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. |
5 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. All advertising materials mentioning features or use of this software |
16 | * must display the following acknowledgement: |
17 | * This product includes software developed by Charles M. Hannum. |
18 | * 4. The name of the author may not be used to endorse or promote products |
19 | * derived from this software without specific prior written permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | #ifndef _DEV_PCI_PCIVAR_H_ |
34 | #define _DEV_PCI_PCIVAR_H_ |
35 | |
36 | /* |
37 | * Definitions for PCI autoconfiguration. |
38 | * |
39 | * This file describes types and functions which are used for PCI |
40 | * configuration. Some of this information is machine-specific, and is |
41 | * provided by pci_machdep.h. |
42 | */ |
43 | |
44 | #include <sys/device.h> |
45 | #include <sys/pmf.h> |
46 | #include <sys/bus.h> |
47 | #include <dev/pci/pcireg.h> |
48 | #include <dev/pci/pci_verbose.h> |
49 | |
50 | /* |
51 | * Structures and definitions needed by the machine-dependent header. |
52 | */ |
53 | struct pcibus_attach_args; |
54 | struct pci_attach_args; |
55 | struct pci_softc; |
56 | |
57 | #ifdef _KERNEL |
58 | /* |
59 | * Machine-dependent definitions. |
60 | */ |
61 | #include <machine/pci_machdep.h> |
62 | |
63 | enum pci_override_idx { |
64 | PCI_OVERRIDE_CONF_READ = __BIT(0) |
65 | , PCI_OVERRIDE_CONF_WRITE = __BIT(1) |
66 | , PCI_OVERRIDE_INTR_MAP = __BIT(2) |
67 | , PCI_OVERRIDE_INTR_STRING = __BIT(3) |
68 | , PCI_OVERRIDE_INTR_EVCNT = __BIT(4) |
69 | , PCI_OVERRIDE_INTR_ESTABLISH = __BIT(5) |
70 | , PCI_OVERRIDE_INTR_DISESTABLISH = __BIT(6) |
71 | , PCI_OVERRIDE_MAKE_TAG = __BIT(7) |
72 | , PCI_OVERRIDE_DECOMPOSE_TAG = __BIT(8) |
73 | }; |
74 | |
75 | /* Only add new fields to the end of this structure! */ |
76 | struct pci_overrides { |
77 | pcireg_t (*ov_conf_read)(void *, pci_chipset_tag_t, pcitag_t, int); |
78 | void (*ov_conf_write)(void *, pci_chipset_tag_t, pcitag_t, int, |
79 | pcireg_t); |
80 | int (*ov_intr_map)(void *, const struct pci_attach_args *, |
81 | pci_intr_handle_t *); |
82 | const char *(*ov_intr_string)(void *, pci_chipset_tag_t, |
83 | pci_intr_handle_t, char *, size_t); |
84 | const struct evcnt *(*ov_intr_evcnt)(void *, pci_chipset_tag_t, |
85 | pci_intr_handle_t); |
86 | void *(*ov_intr_establish)(void *, pci_chipset_tag_t, pci_intr_handle_t, |
87 | int, int (*)(void *), void *); |
88 | void (*ov_intr_disestablish)(void *, pci_chipset_tag_t, void *); |
89 | pcitag_t (*ov_make_tag)(void *, pci_chipset_tag_t, int, int, int); |
90 | void (*ov_decompose_tag)(void *, pci_chipset_tag_t, pcitag_t, |
91 | int *, int *, int *); |
92 | }; |
93 | |
94 | /* |
95 | * PCI bus attach arguments. |
96 | */ |
97 | struct pcibus_attach_args { |
98 | char *_pba_busname; /* XXX placeholder */ |
99 | bus_space_tag_t pba_iot; /* pci i/o space tag */ |
100 | bus_space_tag_t pba_memt; /* pci mem space tag */ |
101 | bus_dma_tag_t pba_dmat; /* DMA tag */ |
102 | bus_dma_tag_t pba_dmat64; /* DMA tag */ |
103 | pci_chipset_tag_t pba_pc; |
104 | int pba_flags; /* flags; see below */ |
105 | |
106 | int pba_bus; /* PCI bus number */ |
107 | int pba_sub; /* pba_bus >= pba_sub: no |
108 | * buses are subordinate to |
109 | * pba_bus. |
110 | * |
111 | * pba_bus < pba_sub: buses |
112 | * [pba_bus + 1, pba_sub] are |
113 | * subordinate to pba_bus. |
114 | */ |
115 | |
116 | /* |
117 | * Pointer to the pcitag of our parent bridge. If there is no |
118 | * parent bridge, then we assume we are a root bus. |
119 | */ |
120 | pcitag_t *pba_bridgetag; |
121 | |
122 | /* |
123 | * Interrupt swizzling information. These fields |
124 | * are only used by secondary busses. |
125 | */ |
126 | u_int pba_intrswiz; /* how to swizzle pins */ |
127 | pcitag_t pba_intrtag; /* intr. appears to come from here */ |
128 | }; |
129 | |
130 | /* |
131 | * This is used by <machine/pci_machdep.h> to access the pba_pc member. It |
132 | * can't use it directly since pcibus_attach_args has yet to be defined. |
133 | */ |
134 | static inline pci_chipset_tag_t |
135 | pcibus_attach_args_pc(struct pcibus_attach_args *pba) |
136 | { |
137 | return pba->pba_pc; |
138 | } |
139 | |
140 | /* |
141 | * PCI device attach arguments. |
142 | */ |
143 | struct pci_attach_args { |
144 | bus_space_tag_t pa_iot; /* pci i/o space tag */ |
145 | bus_space_tag_t pa_memt; /* pci mem space tag */ |
146 | bus_dma_tag_t pa_dmat; /* DMA tag */ |
147 | bus_dma_tag_t pa_dmat64; /* DMA tag */ |
148 | pci_chipset_tag_t pa_pc; |
149 | int pa_flags; /* flags; see below */ |
150 | |
151 | u_int pa_bus; |
152 | u_int pa_device; |
153 | u_int pa_function; |
154 | pcitag_t pa_tag; |
155 | pcireg_t pa_id, pa_class; |
156 | |
157 | /* |
158 | * Interrupt information. |
159 | * |
160 | * "Intrline" is used on systems whose firmware puts |
161 | * the right routing data into the line register in |
162 | * configuration space. The rest are used on systems |
163 | * that do not. |
164 | */ |
165 | u_int pa_intrswiz; /* how to swizzle pins if ppb */ |
166 | pcitag_t pa_intrtag; /* intr. appears to come from here */ |
167 | pci_intr_pin_t pa_intrpin; /* intr. appears on this pin */ |
168 | pci_intr_line_t pa_intrline; /* intr. routing information */ |
169 | pci_intr_pin_t pa_rawintrpin; /* unswizzled pin */ |
170 | }; |
171 | |
172 | /* |
173 | * This is used by <machine/pci_machdep.h> to access the pa_pc member. It |
174 | * can't use it directly since pci_attach_args has yet to be defined. |
175 | */ |
176 | static inline pci_chipset_tag_t |
177 | pci_attach_args_pc(const struct pci_attach_args *pa) |
178 | { |
179 | return pa->pa_pc; |
180 | } |
181 | |
182 | /* |
183 | * Flags given in the bus and device attachment args. |
184 | */ |
185 | #define PCI_FLAGS_IO_OKAY 0x01 /* I/O space is okay */ |
186 | #define PCI_FLAGS_MEM_OKAY 0x02 /* memory space is okay */ |
187 | #define PCI_FLAGS_MRL_OKAY 0x04 /* Memory Read Line okay */ |
188 | #define PCI_FLAGS_MRM_OKAY 0x08 /* Memory Read Multiple okay */ |
189 | #define PCI_FLAGS_MWI_OKAY 0x10 /* Memory Write and Invalidate |
190 | okay */ |
191 | #define PCI_FLAGS_MSI_OKAY 0x20 /* Message Signaled Interrupts |
192 | okay */ |
193 | #define PCI_FLAGS_MSIX_OKAY 0x40 /* Message Signaled Interrupts |
194 | (Extended) okay */ |
195 | |
196 | /* |
197 | * PCI device 'quirks'. |
198 | * |
199 | * In general strange behaviour which can be handled by a driver (e.g. |
200 | * a bridge's inability to pass a type of access correctly) should be. |
201 | * The quirks table should only contain information which impacts |
202 | * the operation of the MI PCI code and which can't be pushed lower |
203 | * (e.g. because it's unacceptable to require a driver to be present |
204 | * for the information to be known). |
205 | */ |
206 | struct pci_quirkdata { |
207 | pci_vendor_id_t vendor; /* Vendor ID */ |
208 | pci_product_id_t product; /* Product ID */ |
209 | int quirks; /* quirks; see below */ |
210 | }; |
211 | #define PCI_QUIRK_MULTIFUNCTION 1 |
212 | #define PCI_QUIRK_MONOFUNCTION 2 |
213 | #define PCI_QUIRK_SKIP_FUNC(n) (4 << n) |
214 | #define PCI_QUIRK_SKIP_FUNC0 PCI_QUIRK_SKIP_FUNC(0) |
215 | #define PCI_QUIRK_SKIP_FUNC1 PCI_QUIRK_SKIP_FUNC(1) |
216 | #define PCI_QUIRK_SKIP_FUNC2 PCI_QUIRK_SKIP_FUNC(2) |
217 | #define PCI_QUIRK_SKIP_FUNC3 PCI_QUIRK_SKIP_FUNC(3) |
218 | #define PCI_QUIRK_SKIP_FUNC4 PCI_QUIRK_SKIP_FUNC(4) |
219 | #define PCI_QUIRK_SKIP_FUNC5 PCI_QUIRK_SKIP_FUNC(5) |
220 | #define PCI_QUIRK_SKIP_FUNC6 PCI_QUIRK_SKIP_FUNC(6) |
221 | #define PCI_QUIRK_SKIP_FUNC7 PCI_QUIRK_SKIP_FUNC(7) |
222 | |
223 | struct pci_conf_state { |
224 | pcireg_t reg[16]; |
225 | }; |
226 | |
227 | struct pci_range { |
228 | bus_addr_t r_offset; |
229 | bus_size_t r_size; |
230 | int r_flags; |
231 | }; |
232 | |
233 | struct pci_child { |
234 | device_t c_dev; |
235 | bool c_psok; |
236 | pcireg_t c_powerstate; |
237 | struct pci_conf_state c_conf; |
238 | struct pci_range c_range[8]; |
239 | }; |
240 | |
241 | struct pci_softc { |
242 | device_t sc_dev; |
243 | bus_space_tag_t sc_iot, sc_memt; |
244 | bus_dma_tag_t sc_dmat; |
245 | bus_dma_tag_t sc_dmat64; |
246 | pci_chipset_tag_t sc_pc; |
247 | int sc_bus, sc_maxndevs; |
248 | pcitag_t *sc_bridgetag; |
249 | u_int sc_intrswiz; |
250 | pcitag_t sc_intrtag; |
251 | int sc_flags; |
252 | /* accounting of child devices */ |
253 | struct pci_child sc_devices[32*8]; |
254 | #define PCI_SC_DEVICESC(d, f) sc_devices[(d) * 8 + (f)] |
255 | }; |
256 | |
257 | extern struct cfdriver pci_cd; |
258 | |
259 | int pcibusprint(void *, const char *); |
260 | |
261 | /* |
262 | * Configuration space access and utility functions. (Note that most, |
263 | * e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.) |
264 | */ |
265 | int pci_mapreg_probe(pci_chipset_tag_t, pcitag_t, int, pcireg_t *); |
266 | pcireg_t pci_mapreg_type(pci_chipset_tag_t, pcitag_t, int); |
267 | int pci_mapreg_info(pci_chipset_tag_t, pcitag_t, int, pcireg_t, |
268 | bus_addr_t *, bus_size_t *, int *); |
269 | int pci_mapreg_map(const struct pci_attach_args *, int, pcireg_t, int, |
270 | bus_space_tag_t *, bus_space_handle_t *, bus_addr_t *, |
271 | bus_size_t *); |
272 | int pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int, |
273 | bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, |
274 | bus_addr_t *, bus_size_t *); |
275 | |
276 | |
277 | int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t, |
278 | bus_space_handle_t, bus_size_t, |
279 | int, bus_space_handle_t *, bus_size_t *); |
280 | |
281 | int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *); |
282 | int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *, |
283 | pcireg_t *); |
284 | int pci_get_ext_capability(pci_chipset_tag_t, pcitag_t, int, int *, |
285 | pcireg_t *); |
286 | |
287 | int pci_msi_count(pci_chipset_tag_t, pcitag_t); |
288 | int pci_msix_count(pci_chipset_tag_t, pcitag_t); |
289 | |
290 | /* |
291 | * Helper functions for autoconfiguration. |
292 | */ |
293 | #ifndef PCI_MACHDEP_ENUMERATE_BUS |
294 | int pci_enumerate_bus(struct pci_softc *, const int *, |
295 | int (*)(const struct pci_attach_args *), struct pci_attach_args *); |
296 | #endif |
297 | int pci_probe_device(struct pci_softc *, pcitag_t tag, |
298 | int (*)(const struct pci_attach_args *), |
299 | struct pci_attach_args *); |
300 | void pci_devinfo(pcireg_t, pcireg_t, int, char *, size_t); |
301 | void pci_aprint_devinfo_fancy(const struct pci_attach_args *, |
302 | const char *, const char *, int); |
303 | #define pci_aprint_devinfo(pap, naive) \ |
304 | pci_aprint_devinfo_fancy(pap, naive, NULL, 0); |
305 | void pci_conf_print(pci_chipset_tag_t, pcitag_t, |
306 | void (*)(pci_chipset_tag_t, pcitag_t, const pcireg_t *)); |
307 | const struct pci_quirkdata * |
308 | pci_lookup_quirkdata(pci_vendor_id_t, pci_product_id_t); |
309 | |
310 | /* |
311 | * Helper functions for user access to the PCI bus. |
312 | */ |
313 | struct proc; |
314 | int pci_devioctl(pci_chipset_tag_t, pcitag_t, u_long, void *, |
315 | int flag, struct lwp *); |
316 | |
317 | /* |
318 | * Power Management (PCI 2.2) |
319 | */ |
320 | |
321 | #define PCI_PWR_D0 0 |
322 | #define PCI_PWR_D1 1 |
323 | #define PCI_PWR_D2 2 |
324 | #define PCI_PWR_D3 3 |
325 | int pci_powerstate(pci_chipset_tag_t, pcitag_t, const int *, int *); |
326 | |
327 | /* |
328 | * Vital Product Data (PCI 2.2) |
329 | */ |
330 | int pci_vpd_read(pci_chipset_tag_t, pcitag_t, int, int, pcireg_t *); |
331 | int pci_vpd_write(pci_chipset_tag_t, pcitag_t, int, int, pcireg_t *); |
332 | |
333 | /* |
334 | * Misc. |
335 | */ |
336 | int pci_find_device(struct pci_attach_args *pa, |
337 | int (*match)(const struct pci_attach_args *)); |
338 | int pci_dma64_available(const struct pci_attach_args *); |
339 | void pci_conf_capture(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *); |
340 | void pci_conf_restore(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *); |
341 | int pci_get_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t *); |
342 | int pci_set_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t); |
343 | int pci_activate(pci_chipset_tag_t, pcitag_t, device_t, |
344 | int (*)(pci_chipset_tag_t, pcitag_t, device_t, pcireg_t)); |
345 | int pci_activate_null(pci_chipset_tag_t, pcitag_t, device_t, pcireg_t); |
346 | int pci_chipset_tag_create(pci_chipset_tag_t, uint64_t, |
347 | const struct pci_overrides *, |
348 | void *, pci_chipset_tag_t *); |
349 | void pci_chipset_tag_destroy(pci_chipset_tag_t); |
350 | int pci_bus_devorder(pci_chipset_tag_t, int, uint8_t *, int); |
351 | void *pci_intr_establish_xname(pci_chipset_tag_t, pci_intr_handle_t, |
352 | int, int (*)(void *), void *, const char *); |
353 | #ifndef __HAVE_PCI_MSI_MSIX |
354 | typedef enum { |
355 | PCI_INTR_TYPE_INTX = 0, |
356 | PCI_INTR_TYPE_MSI, |
357 | PCI_INTR_TYPE_MSIX, |
358 | PCI_INTR_TYPE_SIZE, |
359 | } pci_intr_type_t; |
360 | |
361 | pci_intr_type_t |
362 | pci_intr_type(pci_chipset_tag_t, pci_intr_handle_t); |
363 | int pci_intr_alloc(const struct pci_attach_args *, pci_intr_handle_t **, |
364 | int *, pci_intr_type_t); |
365 | void pci_intr_release(pci_chipset_tag_t, pci_intr_handle_t *, int); |
366 | #endif |
367 | |
368 | /* |
369 | * Device abstraction for inheritance by elanpci(4), for example. |
370 | */ |
371 | int pcimatch(device_t, cfdata_t, void *); |
372 | void pciattach(device_t, device_t, void *); |
373 | int pcidetach(device_t, int); |
374 | void pcidevdetached(device_t, device_t); |
375 | int pcirescan(device_t, const char *, const int *); |
376 | |
377 | /* |
378 | * Interrupts. |
379 | */ |
380 | #define PCI_INTR_MPSAFE 1 |
381 | |
382 | int pci_intr_setattr(pci_chipset_tag_t, pci_intr_handle_t *, int, uint64_t); |
383 | |
384 | /* |
385 | * Local constants |
386 | */ |
387 | #define PCI_INTRSTR_LEN 64 |
388 | |
389 | #endif /* _KERNEL */ |
390 | |
391 | #endif /* _DEV_PCI_PCIVAR_H_ */ |
392 | |