| @@ -1,375 +1,375 @@ | | | @@ -1,375 +1,375 @@ |
1 | /*- | | 1 | /*- |
2 | * Copyright (c) 2003 | | 2 | * Copyright (c) 2003 |
3 | * Bill Paul <wpaul@windriver.com>. All rights reserved. | | 3 | * Bill Paul <wpaul@windriver.com>. All rights reserved. |
4 | * | | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | | 6 | * modification, are permitted provided that the following conditions |
7 | * are met: | | 7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright | | 8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. | | 9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright | | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the | | 11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. | | 12 | * documentation and/or other materials provided with the distribution. |
13 | * 3. All advertising materials mentioning features or use of this software | | 13 | * 3. All advertising materials mentioning features or use of this software |
14 | * must display the following acknowledgement: | | 14 | * must display the following acknowledgement: |
15 | * This product includes software developed by Bill Paul. | | 15 | * This product includes software developed by Bill Paul. |
16 | * 4. Neither the name of the author nor the names of any co-contributors | | 16 | * 4. Neither the name of the author nor the names of any co-contributors |
17 | * may be used to endorse or promote products derived from this software | | 17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. | | 18 | * without specific prior written permission. |
19 | * | | 19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND | | 20 | * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD | | 23 | * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
30 | * THE POSSIBILITY OF SUCH DAMAGE. | | 30 | * THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: if_ndis_pci.c,v 1.21 2015/04/04 15:22:02 christos Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: if_ndis_pci.c,v 1.22 2016/10/15 08:37:55 maxv Exp $"); |
35 | #ifdef __FreeBSD__ | | 35 | #ifdef __FreeBSD__ |
36 | __FBSDID("$FreeBSD: src/sys/dev/if_ndis/if_ndis_pci.c,v 1.8.2.3 2005/03/31 04:24:36 wpaul Exp $"); | | 36 | __FBSDID("$FreeBSD: src/sys/dev/if_ndis/if_ndis_pci.c,v 1.8.2.3 2005/03/31 04:24:36 wpaul Exp $"); |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/systm.h> | | 40 | #include <sys/systm.h> |
41 | #include <sys/kernel.h> | | 41 | #include <sys/kernel.h> |
42 | #include <sys/module.h> | | 42 | #include <sys/module.h> |
43 | #include <sys/socket.h> | | 43 | #include <sys/socket.h> |
44 | #include <sys/queue.h> | | 44 | #include <sys/queue.h> |
45 | #include <sys/sysctl.h> | | 45 | #include <sys/sysctl.h> |
46 | | | 46 | |
47 | #include <net/if.h> | | 47 | #include <net/if.h> |
48 | #include <net/if_arp.h> | | 48 | #include <net/if_arp.h> |
49 | #include <net/if_media.h> | | 49 | #include <net/if_media.h> |
50 | | | 50 | |
51 | #include <sys/bus.h> | | 51 | #include <sys/bus.h> |
52 | | | 52 | |
53 | #include <sys/kthread.h> | | 53 | #include <sys/kthread.h> |
54 | #include <net/if_ether.h> | | 54 | #include <net/if_ether.h> |
55 | | | 55 | |
56 | #include <net80211/ieee80211_var.h> | | 56 | #include <net80211/ieee80211_var.h> |
57 | | | 57 | |
58 | #include <dev/pci/pcireg.h> | | 58 | #include <dev/pci/pcireg.h> |
59 | #include <dev/pci/pcivar.h> | | 59 | #include <dev/pci/pcivar.h> |
60 | | | 60 | |
61 | #include <compat/ndis/pe_var.h> | | 61 | #include <compat/ndis/pe_var.h> |
62 | #include <compat/ndis/resource_var.h> | | 62 | #include <compat/ndis/resource_var.h> |
63 | #include <compat/ndis/ntoskrnl_var.h> | | 63 | #include <compat/ndis/ntoskrnl_var.h> |
64 | #include <compat/ndis/ndis_var.h> | | 64 | #include <compat/ndis/ndis_var.h> |
65 | #include <compat/ndis/cfg_var.h> | | 65 | #include <compat/ndis/cfg_var.h> |
66 | #include <dev/if_ndis/if_ndisvar.h> | | 66 | #include <dev/if_ndis/if_ndisvar.h> |
67 | | | 67 | |
68 | #include "ndis_driver_data.h" | | 68 | #include "ndis_driver_data.h" |
69 | | | 69 | |
70 | #ifndef _MODULE | | 70 | #ifndef _MODULE |
71 | #include <compat/ndis/hal_var.h> | | 71 | #include <compat/ndis/hal_var.h> |
72 | #endif | | 72 | #endif |
73 | | | 73 | |
74 | #ifdef NDIS_PCI_DEV_TABLE | | 74 | #ifdef NDIS_PCI_DEV_TABLE |
75 | | | 75 | |
76 | | | 76 | |
77 | /* | | 77 | /* |
78 | * Various supported device vendors/types and their names. | | 78 | * Various supported device vendors/types and their names. |
79 | * These are defined in the ndis_driver_data.h file. | | 79 | * These are defined in the ndis_driver_data.h file. |
80 | */ | | 80 | */ |
81 | static struct ndis_pci_type ndis_devs[] = { | | 81 | static struct ndis_pci_type ndis_devs[] = { |
82 | #ifdef NDIS_PCI_DEV_TABLE | | 82 | #ifdef NDIS_PCI_DEV_TABLE |
83 | NDIS_PCI_DEV_TABLE | | 83 | NDIS_PCI_DEV_TABLE |
84 | #endif | | 84 | #endif |
85 | { 0, 0, 0, NULL } | | 85 | { 0, 0, 0, NULL } |
86 | }; | | 86 | }; |
87 | | | 87 | |
88 | /*static*/ int ndis_probe_pci(device_t parent, | | 88 | /*static*/ int ndis_probe_pci(device_t parent, |
89 | cfdata_t match, | | 89 | cfdata_t match, |
90 | void *aux); | | 90 | void *aux); |
91 | /*static*/ void ndis_attach_pci(device_t parent, | | 91 | /*static*/ void ndis_attach_pci(device_t parent, |
92 | device_t self, | | 92 | device_t self, |
93 | void *aux); | | 93 | void *aux); |
94 | extern void ndis_attach (void *); | | 94 | extern void ndis_attach (void *); |
95 | extern int ndis_shutdown (device_t); | | 95 | extern int ndis_shutdown (device_t); |
96 | extern int ndis_detach (device_t, int); | | 96 | extern int ndis_detach (device_t, int); |
97 | extern int ndis_suspend (device_t); | | 97 | extern int ndis_suspend (device_t); |
98 | extern int ndis_resume (device_t); | | 98 | extern int ndis_resume (device_t); |
99 | | | 99 | |
100 | extern int ndis_intr(void *); | | 100 | extern int ndis_intr(void *); |
101 | | | 101 | |
102 | extern unsigned char drv_data[]; | | 102 | extern unsigned char drv_data[]; |
103 | | | 103 | |
104 | #ifndef _MODULE | | 104 | #ifndef _MODULE |
105 | //static funcptr ndis_txeof_wrap; | | 105 | //static funcptr ndis_txeof_wrap; |
106 | //static funcptr ndis_rxeof_wrap; | | 106 | //static funcptr ndis_rxeof_wrap; |
107 | //static funcptr ndis_linksts_wrap; | | 107 | //static funcptr ndis_linksts_wrap; |
108 | //static funcptr ndis_linksts_done_wrap; | | 108 | //static funcptr ndis_linksts_done_wrap; |
109 | #endif | | 109 | #endif |
110 | | | 110 | |
111 | | | 111 | |
112 | CFATTACH_DECL_NEW( | | 112 | CFATTACH_DECL_NEW( |
113 | #ifdef NDIS_DEVNAME | | 113 | #ifdef NDIS_DEVNAME |
114 | NDIS_DEVNAME, | | 114 | NDIS_DEVNAME, |
115 | #else | | 115 | #else |
116 | ndis, | | 116 | ndis, |
117 | #endif | | 117 | #endif |
118 | sizeof(struct ndis_softc), | | 118 | sizeof(struct ndis_softc), |
119 | ndis_probe_pci, | | 119 | ndis_probe_pci, |
120 | ndis_attach_pci, | | 120 | ndis_attach_pci, |
121 | ndis_detach, | | 121 | ndis_detach, |
122 | NULL); | | 122 | NULL); |
123 | | | 123 | |
124 | | | 124 | |
125 | | | 125 | |
126 | #ifdef _MODULE | | 126 | #ifdef _MODULE |
127 | extern int | | 127 | extern int |
128 | ndisdrv_modevent(module_t mod, int cmd); | | 128 | ndisdrv_modevent(module_t mod, int cmd); |
129 | | | 129 | |
130 | /* | | 130 | /* |
131 | * These are just for the in-kernel version, to delay calling | | 131 | * These are just for the in-kernel version, to delay calling |
132 | * these functions untill enough context is built up. | | 132 | * these functions untill enough context is built up. |
133 | */ | | 133 | */ |
134 | void load_ndisapi(void *); | | 134 | void load_ndisapi(void *); |
135 | void load_ndisdrv(void *); | | 135 | void load_ndisdrv(void *); |
136 | | | 136 | |
137 | void load_ndisapi(void *arg) | | 137 | void load_ndisapi(void *arg) |
138 | { | | 138 | { |
139 | ndis_lkm_handle(NULL, MOD_LOAD); | | 139 | ndis_lkm_handle(NULL, MOD_LOAD); |
140 | } | | 140 | } |
141 | void load_ndisdrv(void *arg) | | 141 | void load_ndisdrv(void *arg) |
142 | { | | 142 | { |
143 | ndisdrv_modevent(NULL, MOD_LOAD); | | 143 | ndisdrv_modevent(NULL, MOD_LOAD); |
144 | } | | 144 | } |
145 | #endif | | 145 | #endif |
146 | | | 146 | |
147 | /*static*/ int | | 147 | /*static*/ int |
148 | ndis_probe_pci(device_t parent, cfdata_t match, void *aux) | | 148 | ndis_probe_pci(device_t parent, cfdata_t match, void *aux) |
149 | { | | 149 | { |
150 | struct pci_attach_args *pa = aux; | | 150 | struct pci_attach_args *pa = aux; |
151 | int vendor = PCI_VENDOR(pa->pa_id); | | 151 | int vendor = PCI_VENDOR(pa->pa_id); |
152 | int product = PCI_PRODUCT(pa->pa_id); | | 152 | int product = PCI_PRODUCT(pa->pa_id); |
153 | | | 153 | |
154 | struct ndis_pci_type *t = ndis_devs; | | 154 | struct ndis_pci_type *t = ndis_devs; |
155 | driver_object *drv = NULL; /* = windrv_lookup(0, "PCI Bus");**/ | | 155 | driver_object *drv = NULL; /* = windrv_lookup(0, "PCI Bus");**/ |
156 | | | 156 | |
157 | #ifdef NDIS_DBG | | 157 | #ifdef NDIS_DBG |
158 | printf("in ndis_probe_pci\n"); | | 158 | printf("in ndis_probe_pci\n"); |
159 | printf("vendor = %x, product = %x\n", vendor, product); | | 159 | printf("vendor = %x, product = %x\n", vendor, product); |
160 | #endif | | 160 | #endif |
161 | | | 161 | |
162 | while(t->ndis_name != NULL) { | | 162 | while(t->ndis_name != NULL) { |
163 | #ifdef NDIS_DBG | | 163 | #ifdef NDIS_DBG |
164 | printf("t->ndis_vid = %x, t->ndis_did = %x\n", | | 164 | printf("t->ndis_vid = %x, t->ndis_did = %x\n", |
165 | t->ndis_vid, t->ndis_did); | | 165 | t->ndis_vid, t->ndis_did); |
166 | #endif | | 166 | #endif |
167 | if((vendor == t->ndis_vid) && (product == t->ndis_did)) { | | 167 | if((vendor == t->ndis_vid) && (product == t->ndis_did)) { |
168 | #ifdef _MODULE | | 168 | #ifdef _MODULE |
169 | ndisdrv_modevent(NULL, MOD_LOAD); | | 169 | ndisdrv_modevent(NULL, MOD_LOAD); |
170 | //kthread_create(load_ndisdrv, NULL); | | 170 | //kthread_create(load_ndisdrv, NULL); |
171 | #endif /* _MODULE */ | | 171 | #endif /* _MODULE */ |
172 | | | 172 | |
173 | drv = windrv_lookup(0, "PCI Bus"); | | 173 | drv = windrv_lookup(0, "PCI Bus"); |
174 | printf("Matching vendor: %x, product: %x, name: %s\n", vendor, product, t->ndis_name); | | 174 | printf("Matching vendor: %x, product: %x, name: %s\n", vendor, product, t->ndis_name); |
175 | windrv_create_pdo(drv, parent); | | 175 | windrv_create_pdo(drv, parent); |
176 | return 1; | | 176 | return 1; |
177 | } | | 177 | } |
178 | t++; | | 178 | t++; |
179 | } | | 179 | } |
180 | | | 180 | |
181 | return 0; /* dosen't match */ | | 181 | return 0; /* dosen't match */ |
182 | } | | 182 | } |
183 | | | 183 | |
184 | /* 6 BADR's + 1 IRQ (so far) */ | | 184 | /* 6 BADR's + 1 IRQ (so far) */ |
185 | #define MAX_RESOURCES 7 | | 185 | #define MAX_RESOURCES 7 |
186 | | | 186 | |
187 | /*static*/ | | 187 | /*static*/ |
188 | void ndis_attach_pci(device_t parent, device_t self, void *aux) | | 188 | void ndis_attach_pci(device_t parent, device_t self, void *aux) |
189 | { | | 189 | { |
190 | struct ndis_softc *sc = device_private(self); | | 190 | struct ndis_softc *sc = device_private(self); |
191 | struct pci_attach_args *pa = aux; | | 191 | struct pci_attach_args *pa = aux; |
192 | #ifdef NDIS_DBG | | 192 | #ifdef NDIS_DBG |
193 | char devinfo[256]; | | 193 | char devinfo[256]; |
194 | #endif | | 194 | #endif |
195 | pci_intr_handle_t ih; | | 195 | pci_intr_handle_t ih; |
196 | pcireg_t type; | | 196 | pcireg_t type; |
197 | bus_addr_t base; | | 197 | bus_addr_t base; |
198 | bus_size_t size; | | 198 | bus_size_t size; |
199 | int flags; | | 199 | int flags; |
200 | ndis_resource_list *rl = NULL; | | 200 | ndis_resource_list *rl = NULL; |
201 | struct cm_partial_resource_desc *prd = NULL; | | 201 | struct cm_partial_resource_desc *prd = NULL; |
202 | #ifdef NDIS_DBG | | 202 | #ifdef NDIS_DBG |
203 | struct pci_conf_state conf_state; | | 203 | struct pci_conf_state conf_state; |
204 | int revision, i; | | 204 | int revision, i; |
205 | #endif | | 205 | #endif |
206 | int bar; | | 206 | int bar; |
207 | size_t rllen; | | 207 | size_t rllen; |
208 | | | 208 | |
209 | printf("in ndis_attach_pci()\n"); | | 209 | printf("in ndis_attach_pci()\n"); |
210 | | | 210 | |
211 | /* initalize the softc */ | | 211 | /* initalize the softc */ |
212 | //sc->ndis_hardware_type = NDIS_PCI; | | 212 | //sc->ndis_hardware_type = NDIS_PCI; |
213 | sc->ndis_dev = self; | | 213 | sc->ndis_dev = self; |
214 | sc->ndis_iftype = PCIBus; | | 214 | sc->ndis_iftype = PCIBus; |
215 | sc->ndis_res_pc = pa->pa_pc; | | 215 | sc->ndis_res_pc = pa->pa_pc; |
216 | sc->ndis_res_pctag = pa->pa_tag; | | 216 | sc->ndis_res_pctag = pa->pa_tag; |
217 | /* TODO: is this correct? All are just pa->pa_dmat? */ | | 217 | /* TODO: is this correct? All are just pa->pa_dmat? */ |
218 | sc->ndis_mtag = pa->pa_dmat; | | 218 | sc->ndis_mtag = pa->pa_dmat; |
219 | sc->ndis_ttag = pa->pa_dmat; | | 219 | sc->ndis_ttag = pa->pa_dmat; |
220 | sc->ndis_parent_tag = pa->pa_dmat; | | 220 | sc->ndis_parent_tag = pa->pa_dmat; |
221 | sc->ndis_res_io = NULL; | | 221 | sc->ndis_res_io = NULL; |
222 | sc->ndis_res_mem = NULL; | | 222 | sc->ndis_res_mem = NULL; |
223 | sc->ndis_res_altmem = NULL; | | 223 | sc->ndis_res_altmem = NULL; |
224 | sc->ndis_block = NULL; | | 224 | sc->ndis_block = NULL; |
225 | sc->ndis_shlist = NULL; | | 225 | sc->ndis_shlist = NULL; |
226 | | | 226 | |
227 | ndis_in_isr = FALSE; | | 227 | ndis_in_isr = FALSE; |
228 | | | 228 | |
229 | printf("sc->ndis_mtag = %x\n", (unsigned int)sc->ndis_mtag); | | 229 | printf("sc->ndis_mtag = %x\n", (unsigned int)sc->ndis_mtag); |
230 | | | 230 | |
231 | rllen = sizeof(ndis_resource_list) + | | 231 | rllen = sizeof(ndis_resource_list) + |
232 | sizeof(cm_partial_resource_desc) * (MAX_RESOURCES - 1); | | 232 | sizeof(cm_partial_resource_desc) * (MAX_RESOURCES - 1); |
233 | rl = malloc(rllen, M_DEVBUF, M_NOWAIT|M_ZERO); | | 233 | rl = malloc(rllen, M_DEVBUF, M_NOWAIT|M_ZERO); |
234 | | | 234 | |
235 | if(rl == NULL) { | | 235 | if(rl == NULL) { |
236 | sc->error = ENOMEM; | | 236 | sc->error = ENOMEM; |
237 | //printf("error: out of memory\n"); | | 237 | //printf("error: out of memory\n"); |
238 | return; | | 238 | return; |
239 | } | | 239 | } |
240 | | | 240 | |
241 | rl->cprl_version = 5; | | 241 | rl->cprl_version = 5; |
242 | rl->cprl_version = 1; | | 242 | rl->cprl_version = 1; |
243 | rl->cprl_count = 0; | | 243 | rl->cprl_count = 0; |
244 | prd = rl->cprl_partial_descs; | | 244 | prd = rl->cprl_partial_descs; |
245 | | | 245 | |
246 | #ifdef NDIS_DBG | | 246 | #ifdef NDIS_DBG |
247 | pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo); | | 247 | pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo); |
248 | revision = PCI_REVISION(pa->pa_class); | | 248 | revision = PCI_REVISION(pa->pa_class); |
249 | printf(": %s (rev. 0x%02x)\n", devinfo, revision); | | 249 | printf(": %s (rev. 0x%02x)\n", devinfo, revision); |
250 | | | 250 | |
251 | pci_conf_print(sc->ndis_res_pc, sc->ndis_res_pctag, NULL); | | 251 | pci_conf_print(sc->ndis_res_pc, sc->ndis_res_pctag, NULL); |
252 | | | 252 | |
253 | pci_conf_capture(sc->ndis_res_pc, sc->ndis_res_pctag, &conf_state); | | 253 | pci_conf_capture(sc->ndis_res_pc, sc->ndis_res_pctag, &conf_state); |
254 | for(i=0; i<16; i++) { | | 254 | for(i=0; i<16; i++) { |
255 | printf("conf_state.reg[%d] = %x\n", i, conf_state.reg[i]); | | 255 | printf("conf_state.reg[%d] = %x\n", i, conf_state.reg[i]); |
256 | } | | 256 | } |
257 | #endif | | 257 | #endif |
258 | | | 258 | |
259 | /* just do the conversion work in attach instead of calling ndis_convert_res() */ | | 259 | /* just do the conversion work in attach instead of calling ndis_convert_res() */ |
260 | for(bar = 0x10; bar <= 0x24; bar += 0x04) { | | 260 | for(bar = 0x10; bar <= 0x24; bar += 0x04) { |
261 | type = pci_mapreg_type(sc->ndis_res_pc, sc->ndis_res_pctag, bar); | | 261 | type = pci_mapreg_type(sc->ndis_res_pc, sc->ndis_res_pctag, bar); |
262 | if(pci_mapreg_info(sc->ndis_res_pc, sc->ndis_res_pctag, bar, type, &base, | | 262 | if(pci_mapreg_info(sc->ndis_res_pc, sc->ndis_res_pctag, bar, type, &base, |
263 | &size, &flags)) { | | 263 | &size, &flags)) { |
264 | printf("pci_mapreg_info() failed on BAR 0x%x!\n", bar); | | 264 | printf("pci_mapreg_info() failed on BAR 0x%x!\n", bar); |
265 | } else { | | 265 | } else { |
266 | switch(type) { | | 266 | switch(type) { |
267 | case PCI_MAPREG_TYPE_IO: | | 267 | case PCI_MAPREG_TYPE_IO: |
268 | prd->cprd_type = CmResourceTypePort; | | 268 | prd->cprd_type = CmResourceTypePort; |
269 | prd->cprd_flags = CM_RESOURCE_PORT_IO; | | 269 | prd->cprd_flags = CM_RESOURCE_PORT_IO; |
270 | prd->u.cprd_port.cprd_start.np_quad = (uint64_t)base; | | 270 | prd->u.cprd_port.cprd_start.np_quad = (uint64_t)base; |
271 | prd->u.cprd_port.cprd_len = (uint32_t)size; | | 271 | prd->u.cprd_port.cprd_len = (uint32_t)size; |
272 | if((sc->ndis_res_io = | | 272 | if((sc->ndis_res_io = |
273 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { | | 273 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { |
274 | //printf("error: out of memory\n"); | | 274 | //printf("error: out of memory\n"); |
275 | sc->error = ENOMEM; | | 275 | sc->error = ENOMEM; |
276 | goto out; | | 276 | goto out; |
277 | } | | 277 | } |
278 | sc->ndis_res_io->res_base = base; | | 278 | sc->ndis_res_io->res_base = base; |
279 | sc->ndis_res_io->res_size = size; | | 279 | sc->ndis_res_io->res_size = size; |
280 | sc->ndis_res_io->res_tag = x86_bus_space_io; | | 280 | sc->ndis_res_io->res_tag = x86_bus_space_io; |
281 | bus_space_map(sc->ndis_res_io->res_tag, | | 281 | bus_space_map(sc->ndis_res_io->res_tag, |
282 | sc->ndis_res_io->res_base, | | 282 | sc->ndis_res_io->res_base, |
283 | sc->ndis_res_io->res_size, | | 283 | sc->ndis_res_io->res_size, |
284 | flags, | | 284 | flags, |
285 | &sc->ndis_res_io->res_handle); | | 285 | &sc->ndis_res_io->res_handle); |
286 | break; | | 286 | break; |
287 | case PCI_MAPREG_TYPE_MEM: | | 287 | case PCI_MAPREG_TYPE_MEM: |
288 | prd->cprd_type = CmResourceTypeMemory; | | 288 | prd->cprd_type = CmResourceTypeMemory; |
289 | prd->cprd_flags = CM_RESOURCE_MEMORY_READ_WRITE; | | 289 | prd->cprd_flags = CM_RESOURCE_MEMORY_READ_WRITE; |
290 | prd->u.cprd_mem.cprd_start.np_quad = (uint64_t)base; | | 290 | prd->u.cprd_mem.cprd_start.np_quad = (uint64_t)base; |
291 | prd->u.cprd_mem.cprd_len = (uint32_t)size; | | 291 | prd->u.cprd_mem.cprd_len = (uint32_t)size; |
292 | | | 292 | |
293 | if(sc->ndis_res_mem != NULL && | | 293 | if(sc->ndis_res_mem != NULL && |
294 | sc->ndis_res_altmem != NULL) { | | 294 | sc->ndis_res_altmem != NULL) { |
295 | printf("too many resources\n"); | | 295 | printf("too many resources\n"); |
296 | sc->error = ENXIO; | | 296 | sc->error = ENXIO; |
297 | goto out; | | 297 | goto out; |
298 | } | | 298 | } |
299 | if(sc->ndis_res_mem) { | | 299 | if(sc->ndis_res_mem) { |
300 | if((sc->ndis_res_altmem = | | 300 | if((sc->ndis_res_altmem = |
301 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { | | 301 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { |
302 | sc->error = ENOMEM; | | 302 | sc->error = ENOMEM; |
303 | return; | | 303 | goto out; |
304 | } | | 304 | } |
305 | sc->ndis_res_altmem->res_base = base; | | 305 | sc->ndis_res_altmem->res_base = base; |
306 | sc->ndis_res_altmem->res_size = size; | | 306 | sc->ndis_res_altmem->res_size = size; |
307 | sc->ndis_res_altmem->res_tag = x86_bus_space_mem; | | 307 | sc->ndis_res_altmem->res_tag = x86_bus_space_mem; |
308 | | | 308 | |
309 | | | 309 | |
310 | if(bus_space_map(sc->ndis_res_altmem->res_tag, | | 310 | if(bus_space_map(sc->ndis_res_altmem->res_tag, |
311 | sc->ndis_res_altmem->res_base, | | 311 | sc->ndis_res_altmem->res_base, |
312 | sc->ndis_res_altmem->res_size, | | 312 | sc->ndis_res_altmem->res_size, |
313 | flags|BUS_SPACE_MAP_LINEAR, | | 313 | flags|BUS_SPACE_MAP_LINEAR, |
314 | &sc->ndis_res_altmem->res_handle)) { | | 314 | &sc->ndis_res_altmem->res_handle)) { |
315 | printf("bus_space_map failed\n"); | | 315 | printf("bus_space_map failed\n"); |
316 | } | | 316 | } |
317 | } else { | | 317 | } else { |
318 | if((sc->ndis_res_mem = | | 318 | if((sc->ndis_res_mem = |
319 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { | | 319 | malloc(sizeof(struct ndis_resource), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { |
320 | sc->error = ENOMEM; | | 320 | sc->error = ENOMEM; |
321 | goto out; | | 321 | goto out; |
322 | } | | 322 | } |
323 | sc->ndis_res_mem->res_base = base; | | 323 | sc->ndis_res_mem->res_base = base; |
324 | sc->ndis_res_mem->res_size = size; | | 324 | sc->ndis_res_mem->res_size = size; |
325 | sc->ndis_res_mem->res_tag = x86_bus_space_mem; | | 325 | sc->ndis_res_mem->res_tag = x86_bus_space_mem; |
326 | | | 326 | |
327 | if(bus_space_map(sc->ndis_res_mem->res_tag, | | 327 | if(bus_space_map(sc->ndis_res_mem->res_tag, |
328 | sc->ndis_res_mem->res_base, | | 328 | sc->ndis_res_mem->res_base, |
329 | sc->ndis_res_mem->res_size, | | 329 | sc->ndis_res_mem->res_size, |
330 | flags|BUS_SPACE_MAP_LINEAR, | | 330 | flags|BUS_SPACE_MAP_LINEAR, |
331 | &sc->ndis_res_mem->res_handle)) { | | 331 | &sc->ndis_res_mem->res_handle)) { |
332 | printf("bus_space_map failed\n"); | | 332 | printf("bus_space_map failed\n"); |
333 | } | | 333 | } |
334 | } | | 334 | } |
335 | break; | | 335 | break; |
336 | | | 336 | |
337 | default: | | 337 | default: |
338 | printf("unknown type\n"); | | 338 | printf("unknown type\n"); |
339 | } | | 339 | } |
340 | prd->cprd_sharedisp = CmResourceShareDeviceExclusive; | | 340 | prd->cprd_sharedisp = CmResourceShareDeviceExclusive; |
341 | | | 341 | |
342 | rl->cprl_count++; | | 342 | rl->cprl_count++; |
343 | prd++; | | 343 | prd++; |
344 | } | | 344 | } |
345 | } | | 345 | } |
346 | | | 346 | |
347 | /* add the interrupt to the list */ | | 347 | /* add the interrupt to the list */ |
348 | prd->cprd_type = CmResourceTypeInterrupt; | | 348 | prd->cprd_type = CmResourceTypeInterrupt; |
349 | prd->cprd_flags = 0; | | 349 | prd->cprd_flags = 0; |
350 | /* TODO: is this all we need to save for the interrupt? */ | | 350 | /* TODO: is this all we need to save for the interrupt? */ |
351 | prd->u.cprd_intr.cprd_level = pa->pa_intrline; | | 351 | prd->u.cprd_intr.cprd_level = pa->pa_intrline; |
352 | prd->u.cprd_intr.cprd_vector = pa->pa_intrline; | | 352 | prd->u.cprd_intr.cprd_vector = pa->pa_intrline; |
353 | prd->u.cprd_intr.cprd_affinity = 0; | | 353 | prd->u.cprd_intr.cprd_affinity = 0; |
354 | rl->cprl_count++; | | 354 | rl->cprl_count++; |
355 | | | 355 | |
356 | pci_intr_map(pa, &ih); | | 356 | pci_intr_map(pa, &ih); |
357 | sc->ndis_intrhand = pci_intr_establish(pa->pa_pc, ih, IPL_NET /*| PCATCH*/, ndis_intr, sc); | | 357 | sc->ndis_intrhand = pci_intr_establish(pa->pa_pc, ih, IPL_NET /*| PCATCH*/, ndis_intr, sc); |
358 | sc->ndis_irq = (void *)sc->ndis_intrhand; | | 358 | sc->ndis_irq = (void *)sc->ndis_intrhand; |
359 | | | 359 | |
360 | printf("pci interrupt: %s\n", pci_intr_string(pa->pa_pc, ih)); | | 360 | printf("pci interrupt: %s\n", pci_intr_string(pa->pa_pc, ih)); |
361 | | | 361 | |
362 | /* save resource list in the softc */ | | 362 | /* save resource list in the softc */ |
363 | sc->ndis_rl = rl; | | 363 | sc->ndis_rl = rl; |
364 | sc->ndis_rescnt = rl->cprl_count; | | 364 | sc->ndis_rescnt = rl->cprl_count; |
365 | | | 365 | |
366 | kthread_create(PRI_NONE, 0, NULL, ndis_attach, (void *)sc, | | 366 | kthread_create(PRI_NONE, 0, NULL, ndis_attach, (void *)sc, |
367 | NULL, "ndis_attach"); | | 367 | NULL, "ndis_attach"); |
368 | return; | | 368 | return; |
369 | out: | | 369 | out: |
370 | free(rl, M_DEVBUF); | | 370 | free(rl, M_DEVBUF); |
371 | return; | | 371 | return; |
372 | } | | 372 | } |
373 | | | 373 | |
374 | | | 374 | |
375 | #endif /* NDIS_PCI_DEV_TABLE */ | | 375 | #endif /* NDIS_PCI_DEV_TABLE */ |