1 /*
2 * Copyright 2022, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _OBSD_COMPAT_DEV_PCI_PCIVAR_H_
6 #define _OBSD_COMPAT_DEV_PCI_PCIVAR_H_
7
8
9 #include_next <dev/pci/pcivar.h>
10 #include <dev/pci/pcireg.h>
11
12 #include <sys/rman.h>
13
14
15 typedef u_int32_t pcireg_t;
16
17
18 struct pci_matchid {
19 pci_vendor_id_t pm_vid;
20 pci_product_id_t pm_pid;
21 };
22
23 typedef struct {
24 int rid;
25 } pci_intr_handle_t;
26
27
28 #define pci_conf_read(pct, pcitag, reg) \
29 pci_read_config(SC_DEV_FOR_PCI, reg, sizeof(pcireg_t))
30 #define pci_conf_write(pct, pcitag, reg, val) \
31 pci_write_config(SC_DEV_FOR_PCI, reg, val, sizeof(pcireg_t))
32 #define pci_get_capability(pct, pcitag, capability, offset, value) \
33 pci_get_capability_openbsd(SC_DEV_FOR_PCI, capability, offset, value)
34 #define pci_mapreg_type(pct, pcitag, reg) \
35 pci_mapreg_type_openbsd(SC_DEV_FOR_PCI, reg)
36 #define pci_mapreg_map(pa, reg, type, flags, tagp, handlep, basep, sizep, maxsize) \
37 pci_mapreg_map_openbsd(SC_DEV_FOR_PCI, reg, type, flags, tagp, handlep, basep, sizep, maxsize)
38 #define pci_intr_establish(pa, ih, level, func, arg, what) \
39 pci_intr_establish_openbsd(SC_DEV_FOR_PCI, ih, level, func, arg, what)
40
41 #define pci_intr_string(...) NULL
42
43 static int
pci_get_capability_openbsd(device_t dev,int capability,int * offset,pcireg_t * value)44 pci_get_capability_openbsd(device_t dev, int capability, int* offset, pcireg_t* value)
45 {
46 int res = pci_find_cap(dev, capability, offset);
47 if (res != 0)
48 return 0;
49
50 if (value)
51 *value = pci_read_config(dev, *offset, sizeof(pcireg_t));
52 return 1;
53 }
54
55 static pcireg_t
pci_mapreg_type_openbsd(device_t dev,int reg)56 pci_mapreg_type_openbsd(device_t dev, int reg)
57 {
58 return (_PCI_MAPREG_TYPEBITS(pci_read_config(dev, reg, sizeof(pcireg_t))));
59 }
60
61 static int
pci_mapreg_map_openbsd(device_t dev,int reg,pcireg_t type,int flags,bus_space_tag_t * tagp,bus_space_handle_t * handlep,bus_addr_t * basep,bus_size_t * sizep,bus_size_t maxsize)62 pci_mapreg_map_openbsd(device_t dev, int reg, pcireg_t type, int flags,
63 bus_space_tag_t* tagp, bus_space_handle_t* handlep, bus_addr_t* basep,
64 bus_size_t* sizep, bus_size_t maxsize)
65 {
66 struct resource* res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, ®, RF_ACTIVE);
67 if (res == NULL)
68 return -1;
69
70 *tagp = rman_get_bustag(res);
71 *handlep = rman_get_bushandle(res);
72 if (basep != NULL)
73 *basep = rman_get_start(res);
74 if (sizep != NULL)
75 *sizep = rman_get_size(res);
76 return 0;
77 }
78
79 static int
pci_intr_map_msix(device_t dev,int vec,pci_intr_handle_t * ihp)80 pci_intr_map_msix(device_t dev, int vec, pci_intr_handle_t* ihp)
81 {
82 if (vec != 0)
83 return -1;
84
85 int count = 1;
86 ihp->rid = 1;
87 return pci_alloc_msix(dev, &count);
88 }
89
90 static int
pci_intr_map_msi(device_t dev,pci_intr_handle_t * ihp)91 pci_intr_map_msi(device_t dev, pci_intr_handle_t* ihp)
92 {
93 int count = 1;
94 ihp->rid = 1;
95 return pci_alloc_msi(dev, &count);
96 }
97
98 static int
pci_intr_map(device_t dev,pci_intr_handle_t * ihp)99 pci_intr_map(device_t dev, pci_intr_handle_t* ihp)
100 {
101 // No need to map legacy interrupts.
102 ihp->rid = 0;
103 return 0;
104 }
105
106 static void*
pci_intr_establish_openbsd(device_t dev,pci_intr_handle_t ih,int level,int (* func)(void *),void * arg,const char * what)107 pci_intr_establish_openbsd(device_t dev, pci_intr_handle_t ih, int level,
108 int(*func)(void*), void* arg, const char* what)
109 {
110 struct resource* irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &ih.rid,
111 RF_ACTIVE | (ih.rid != 0 ? 0 : RF_SHAREABLE));
112 if (irq == NULL)
113 return NULL;
114
115 int flags = INTR_TYPE_NET;
116 if ((level & IPL_MPSAFE) != 0)
117 flags |= INTR_MPSAFE;
118
119 void* ihp = NULL;
120 bus_setup_intr(dev, irq, flags, NULL, (driver_intr_t*)func, arg, &ihp);
121 return ihp;
122 }
123
124
125 #endif /* _OBSD_COMPAT_DEV_PCI_PCIVAR_H_ */
126