xref: /netbsd-src/sys/arch/xen/xen/xpci_xenbus.c (revision e82ab0a323e06ebefb43ff092e875bf6e0222c23)
1 /*      $NetBSD: xpci_xenbus.c,v 1.29 2024/06/23 00:53:34 riastradh Exp $      */
2 
3 /*
4  * Copyright (c) 2009 Manuel Bouyer.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following 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 
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: xpci_xenbus.c,v 1.29 2024/06/23 00:53:34 riastradh Exp $");
29 
30 #include "opt_xen.h"
31 
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/errno.h>
36 #include <sys/kernel.h>
37 #include <sys/bus.h>
38 
39 #include <uvm/uvm_extern.h>
40 
41 #include <machine/bus_private.h>
42 
43 #include <dev/isa/isareg.h>
44 
45 #include <xen/hypervisor.h>
46 #include <xen/evtchn.h>
47 #include <xen/granttables.h>
48 #include <xen/include/public/io/pciif.h>
49 #include <xen/xenbus.h>
50 
51 #include "locators.h"
52 
53 #include <dev/pci/pcivar.h>
54 
55 #undef XPCI_DEBUG
56 #ifdef XPCI_DEBUG
57 #define DPRINTF(x) printf x;
58 #else
59 #define DPRINTF(x)
60 #endif
61 
62 struct xpci_xenbus_softc {
63 	device_t sc_dev;
64 	struct xenbus_device *sc_xbusd;
65 	unsigned int sc_evtchn;
66 	int sc_backend_status; /* our status with backend */
67 #define XPCI_STATE_DISCONNECTED 0
68 #define XPCI_STATE_CONNECTED    1
69 #define XPCI_STATE_SUSPENDED    2
70 	int sc_shutdown;
71 	struct xen_pci_sharedinfo *sc_shared;
72 	grant_ref_t sc_shared_gntref;
73 };
74 #define GRANT_INVALID_REF -1
75 
76 static int  xpci_xenbus_match(device_t, cfdata_t, void *);
77 static void xpci_xenbus_attach(device_t, device_t, void *);
78 static int  xpci_xenbus_detach(device_t, int);
79 
80 static void xpci_backend_changed(void *, XenbusState);
81 static int  xpci_xenbus_resume(void *);
82 static void xpci_connect(struct xpci_xenbus_softc *);
83 static void xpci_attach_pcibus(int, int);
84 
85 static struct xpci_xenbus_softc *xpci_sc = NULL;
86 
87 CFATTACH_DECL_NEW(xpci_xenbus, sizeof(struct xpci_xenbus_softc),
88    xpci_xenbus_match, xpci_xenbus_attach, xpci_xenbus_detach, NULL);
89 
90 struct x86_bus_dma_tag pci_bus_dma_tag = {
91 	._tag_needs_free	= 0,
92 #if defined(_LP64) || defined(PAE)
93 	._bounce_thresh		= PCI32_DMA_BOUNCE_THRESHOLD,
94 	._bounce_alloc_lo	= 0,
95 	._bounce_alloc_hi	= PCI32_DMA_BOUNCE_THRESHOLD,
96 #else
97 	._bounce_thresh		= 0,
98 	._bounce_alloc_lo	= 0,
99 	._bounce_alloc_hi	= 0,
100 #endif
101 	._may_bounce		= NULL,
102 };
103 
104 #ifdef _LP64
105 struct x86_bus_dma_tag pci_bus_dma64_tag = {
106 	._tag_needs_free	= 0,
107 	._bounce_thresh		= 0,
108 	._bounce_alloc_lo	= 0,
109 	._bounce_alloc_hi	= 0,
110 	._may_bounce		= NULL,
111 };
112 #endif
113 
114 static int
xpci_xenbus_match(device_t parent,cfdata_t match,void * aux)115 xpci_xenbus_match(device_t parent, cfdata_t match, void *aux)
116 {
117 	struct xenbusdev_attach_args *xa = aux;
118 
119 	if (strcmp(xa->xa_type, "pci") != 0)
120 		return 0;
121 
122 	if (match->cf_loc[XENBUSCF_ID] != XENBUSCF_ID_DEFAULT &&
123 	    match->cf_loc[XENBUSCF_ID] != xa->xa_id)
124 		return 0;
125 
126 	return 1;
127 }
128 
129 static void
xpci_xenbus_attach(device_t parent,device_t self,void * aux)130 xpci_xenbus_attach(device_t parent, device_t self, void *aux)
131 {
132 	struct xpci_xenbus_softc *sc = device_private(self);
133 	struct xenbusdev_attach_args *xa = aux;
134 
135 	if (xpci_sc != NULL) {
136 		aprint_error("Xen PCI frontend already attached\n");
137 		return;
138 	}
139 	xpci_sc = sc;
140 	DPRINTF(("xpci_sc %p\n", xpci_sc));
141 
142 	config_pending_incr(self);
143 	aprint_normal(": Xen PCI passthrough Interface\n");
144 	sc->sc_dev = self;
145 
146 	sc->sc_xbusd = xa->xa_xbusd;
147 	sc->sc_xbusd->xbusd_otherend_changed = xpci_backend_changed;
148 
149 	sc->sc_backend_status = XPCI_STATE_DISCONNECTED;
150 	sc->sc_shutdown = 1;
151 	/* initialise shared structures and tell backend that we are ready */
152 	xpci_xenbus_resume(sc);
153 }
154 
155 static int
xpci_xenbus_detach(device_t dev,int flags)156 xpci_xenbus_detach(device_t dev, int flags)
157 {
158 	return EBUSY;
159 }
160 
161 static int
xpci_xenbus_resume(void * p)162 xpci_xenbus_resume(void *p)
163 {
164 	struct xpci_xenbus_softc *sc = p;
165 	struct xenbus_transaction *xbt;
166 	int error;
167 	struct xen_pci_sharedinfo *shared;
168 	paddr_t ma;
169 	const char *errmsg;
170 
171 	sc->sc_shared_gntref = GRANT_INVALID_REF;
172 	/* setup device: alloc event channel and shared info structure */
173 	sc->sc_shared = shared = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
174 		 UVM_KMF_ZERO | UVM_KMF_WIRED);
175 	if (shared == NULL)
176 		 panic("xpci_xenbus_resume: can't alloc shared info");
177 
178 	(void)pmap_extract_ma(pmap_kernel(), (vaddr_t)shared, &ma);
179 	error = xenbus_grant_ring(sc->sc_xbusd, ma, &sc->sc_shared_gntref);
180 	if (error)
181 		 return error;
182 	DPRINTF(("shared %p ma 0x%jx ref %#x\n", shared, (uintmax_t)ma,
183 	    sc->sc_shared_gntref));
184 	error = xenbus_alloc_evtchn(sc->sc_xbusd, &sc->sc_evtchn);
185 	if (error)
186 		 return error;
187 	aprint_verbose_dev(sc->sc_dev, "using event channel %d\n",
188 	    sc->sc_evtchn);
189 #if 0
190 	xen_intr_establish_xname(-1, &xen_pic, pbxi->pbx_evtchn, IST_LEVEL,
191 	    IPL_BIO, &xpci_handler, sc, true,
192 	    device_xname(sc->sc_dev));
193 #endif
194 
195 again:
196 	xbt = xenbus_transaction_start();
197 	if (xbt == NULL)
198 		 return ENOMEM;
199 	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
200 	    "pci-op-ref","%u", sc->sc_shared_gntref);
201 	if (error) {
202 		 errmsg = "writing pci-op-ref";
203 		 goto abort_transaction;
204 	}
205 	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
206 	    "event-channel", "%u", sc->sc_evtchn);
207 	if (error) {
208 		 errmsg = "writing event channel";
209 		 goto abort_transaction;
210 	}
211 	error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
212 	    "magic", "%s", XEN_PCI_MAGIC);
213 	if (error) {
214 		 errmsg = "writing magic";
215 		 goto abort_transaction;
216 	}
217 	error = xenbus_switch_state(sc->sc_xbusd, xbt, XenbusStateInitialised);
218 	if (error) {
219 		 errmsg = "writing frontend XenbusStateInitialised";
220 		 goto abort_transaction;
221 	}
222 	error = xenbus_transaction_end(xbt, 0);
223 	if (error == EAGAIN)
224 		 goto again;
225 	if (error) {
226 		 xenbus_dev_fatal(sc->sc_xbusd, error, "completing transaction");
227 		 return -1;
228 	}
229 	return 0;
230 
231 abort_transaction:
232 	xenbus_transaction_end(xbt, 1);
233 	xenbus_dev_fatal(sc->sc_xbusd, error, "%s", errmsg);
234 	return error;
235 }
236 
237 static void
xpci_backend_changed(void * arg,XenbusState new_state)238 xpci_backend_changed(void *arg, XenbusState new_state)
239 {
240 	struct xpci_xenbus_softc *sc = device_private((device_t)arg);
241 	int s;
242 	DPRINTF(("%s: new backend state %d\n", device_xname(sc->sc_dev), new_state));
243 
244 	switch (new_state) {
245 	case XenbusStateUnknown:
246 	case XenbusStateInitialising:
247 	case XenbusStateInitWait:
248 	case XenbusStateInitialised:
249 		break;
250 	case XenbusStateClosing:
251 		s = splbio(); /* XXXSMP */
252 		sc->sc_shutdown = 1;
253 		/* wait for requests to complete */
254 #if 0
255 		while (sc->sc_backend_status == XPCI_STATE_CONNECTED &&
256 		   sc->sc_dksc.sc_dkdev.dk_stats->io_busy > 0)
257 			/* XXXSMP */
258 			tsleep(xpci_xenbus_detach, PRIBIO, "xpcidetach",
259 			   hz/2);
260 #endif
261 		splx(s);
262 		xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosed);
263 		break;
264 	case XenbusStateConnected:
265 		/*
266 		 * note that xpci_backend_changed() can only be called by
267 		 * the xenbus thread.
268 		 */
269 
270 		if (sc->sc_backend_status == XPCI_STATE_CONNECTED)
271 			/* already connected */
272 			return;
273 
274 		sc->sc_shutdown = 0;
275 		xpci_connect(sc);
276 
277 		sc->sc_backend_status = XPCI_STATE_CONNECTED;
278 
279 		/* the devices should be working now */
280 		config_pending_decr(sc->sc_dev);
281 		break;
282 	default:
283 		panic("bad backend state %d", new_state);
284 	}
285 }
286 
287 static void
xpci_connect(struct xpci_xenbus_softc * sc)288 xpci_connect(struct xpci_xenbus_softc *sc)
289 {
290 	u_long num_roots;
291 	int err;
292 	char *domain, *bus, *ep;
293 	char node[10];
294 	u_long busn;
295 	int i;
296 	int s;
297 
298 	err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend,
299 	   "root_num", &num_roots, 10);
300 	if (err == ENOENT) {
301 		aprint_error_dev(sc->sc_dev,
302 		   "No PCI Roots found, trying 0000:00\n");
303 		s = splhigh();
304 		xpci_attach_pcibus(0, 0);
305 		splx(s);
306 		xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected);
307 		return;
308 	} else if (err) {
309 		aprint_error_dev(sc->sc_dev, "can't read root_num: %d\n", err);
310 		return;
311 	}
312 
313 	aprint_verbose_dev(sc->sc_dev, "%lu bus%s\n", num_roots,
314 	    (num_roots > 1) ? "ses" : "");
315 
316 	for (i = 0; i < num_roots; i++) {
317 		char root[32];
318 		snprintf(node, sizeof(node), "root-%d", i);
319 		xenbus_read(NULL, sc->sc_xbusd->xbusd_otherend, node,
320 		    root, sizeof(root));
321 		/* split dddd:bb in 2 strings, a la strtok */
322 		domain = dev;
323 		root[4] = '\0';
324 		bus = &root[5];
325 		if (strcmp(domain, "0000") != 0) {
326 			aprint_error_dev(sc->sc_dev,
327 			   "non-zero PCI domain %s not supported\n", domain);
328 		} else {
329 			busn = strtoul(bus, &ep, 16);
330 			if (*ep != '\0')
331 				aprint_error_dev(sc->sc_dev,
332 				   "%s is not a number\n", bus);
333 			else {
334 				s = splhigh();
335 				xpci_attach_pcibus(0, busn);
336 				splx(s);
337 			}
338 		}
339 	}
340 
341 	xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected);
342 }
343 
344 static void
xpci_attach_pcibus(int domain,int busn)345 xpci_attach_pcibus(int domain, int busn)
346 {
347 	struct pcibus_attach_args pba;
348 
349 	memset(&pba, 0, sizeof(struct pcibus_attach_args));
350 	pba.pba_iot = x86_bus_space_io;
351 	pba.pba_memt = x86_bus_space_mem;
352 	pba.pba_dmat = &pci_bus_dma_tag;
353 #ifdef _LP64
354 	pba.pba_dmat64 = &pci_bus_dma64_tag;
355 #else
356 	pba.pba_dmat64 = NULL;
357 #endif
358 	pba.pba_flags = PCI_FLAGS_MEM_OKAY | PCI_FLAGS_IO_OKAY |
359 	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
360 	pba.pba_bridgetag = NULL;
361 	pba.pba_bus = busn;
362 	config_found(xpci_sc->sc_dev, &pba, pcibusprint, CFARGS_NONE);
363 }
364 
365 /* functions required by the MI PCI system */
366 
367 void
pci_attach_hook(device_t parent,device_t self,struct pcibus_attach_args * pba)368 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
369 {
370 	/* nothing */
371 }
372 
373 int
pci_bus_maxdevs(pci_chipset_tag_t pc,int busno)374 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
375 {
376 	return 32;
377 }
378 
379 pcitag_t
pci_make_tag(pci_chipset_tag_t pc,int bus,int device,int function)380 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
381 {
382 	pcitag_t tag;
383 	KASSERT((function & ~0x7) == 0);
384 	KASSERT((device & ~0x1f) == 0);
385 	KASSERT((bus & ~0xff) == 0);
386 	tag.mode1 = (bus << 8) | (device << 3) | (function << 0);
387 	return tag;
388 }
389 
390 void
pci_decompose_tag(pci_chipset_tag_t pc,pcitag_t tag,int * bp,int * dp,int * fp)391 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag,
392     int *bp, int *dp, int *fp)
393 {
394 	if (bp != NULL)
395 		*bp = (tag.mode1 >> 8) & 0xff;
396 	if (dp != NULL)
397 		*dp = (tag.mode1 >> 3) & 0x1f;
398 	if (fp != NULL)
399 		*fp = (tag.mode1 >> 0) & 0x7;
400 	return;
401 }
402 
403 static void
xpci_do_op(struct xen_pci_op * op)404 xpci_do_op(struct xen_pci_op *op)
405 {
406 	struct xen_pci_op *active_op = &xpci_sc->sc_shared->op;
407 	static __cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED;
408 	int s;
409 
410 	s = splhigh();
411 	__cpu_simple_lock(&pci_conf_lock);
412 
413 	memcpy(active_op, op, sizeof(struct xen_pci_op));
414 	x86_sfence();
415 	xen_atomic_set_bit(&xpci_sc->sc_shared->flags, _XEN_PCIF_active);
416 	hypervisor_notify_via_evtchn(xpci_sc->sc_evtchn);
417 	while (xen_atomic_test_bit(&xpci_sc->sc_shared->flags,
418 	    _XEN_PCIF_active)) {
419 		hypervisor_clear_event(xpci_sc->sc_evtchn);
420 		/* HYPERVISOR_yield(); */
421 	}
422 	memcpy(op, active_op, sizeof(struct xen_pci_op));
423 
424 	__cpu_simple_unlock(&pci_conf_lock);
425 	splx(s);
426 }
427 
428 static int
xpci_conf_read(pci_chipset_tag_t pc,pcitag_t tag,int reg,int size,pcireg_t * value)429 xpci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg, int size,
430     pcireg_t *value)
431 {
432 	int bus, dev, func;
433 	struct xen_pci_op op = {
434 		.cmd    = XEN_PCI_OP_conf_read,
435 		.domain = 0, /* XXX */
436 	};
437 
438 	pci_decompose_tag(pc, tag, &bus, &dev, &func);
439 	DPRINTF(("pci_conf_read %d:%d:%d reg 0x%x", bus, dev, func, reg));
440 
441 	op.bus = bus;
442 	op.devfn = (dev << 3) | func;
443 	op.offset = reg;
444 	op.size = size;
445 	xpci_do_op(&op);
446 
447 	*value = op.value;
448 	DPRINTF((" val 0x%x err %d\n", *value, op.err));
449 
450 	return op.err;
451 }
452 
453 pcireg_t
pci_conf_read(pci_chipset_tag_t pc,pcitag_t tag,int reg)454 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
455 {
456 	pcireg_t v;
457 
458 	xpci_conf_read(pc, tag, reg, 4, &v);
459 	return v;
460 }
461 
462 static int
xpci_conf_write(pci_chipset_tag_t pc,pcitag_t tag,int reg,int size,pcireg_t data)463 xpci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, int size,
464     pcireg_t data)
465 {
466 	int bus, dev, func;
467 	struct xen_pci_op op = {
468 		.cmd    = XEN_PCI_OP_conf_write,
469 		.domain = 0, /* XXX */
470 	};
471 
472 	pci_decompose_tag(pc, tag, &bus, &dev, &func);
473 	DPRINTF(("pci_conf_write %d:%d:%d reg 0x%x val 0x%x", bus, dev, func, reg, data));
474 
475 	op.bus = bus;
476 	op.devfn = (dev << 3) | func;
477 	op.offset = reg;
478 	op.size = size;
479 	op.value = data;
480 	xpci_do_op(&op);
481 
482 	DPRINTF((" err %d\n", op.err));
483 
484 	return op.err;
485 }
486 
487 void
pci_conf_write(pci_chipset_tag_t pc,pcitag_t tag,int reg,pcireg_t data)488 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
489 {
490 	xpci_conf_write(pc, tag, reg, 4, data);
491 }
492 
493 int
xpci_enumerate_bus1(struct pci_softc * sc,const int * locators,int (* match)(void *,const struct pci_attach_args *),void * cookie,struct pci_attach_args * pap)494 xpci_enumerate_bus1(struct pci_softc *sc, const int *locators,
495     int (*match)(void *, const struct pci_attach_args *), void *cookie,
496     struct pci_attach_args *pap)
497 {
498 #if 0
499 	char *string;
500 	char *domain, *bus, *dev, *func, *ep;
501 	u_long busn, devn, funcn;
502 	char node[10];
503 	u_long num_devs;
504 	int i;
505 	int err;
506 	pcitag_t tag;
507 	pci_chipset_tag_t pc = sc->sc_pc;
508 
509 	err = xenbus_read_ul(NULL, xpci_sc->sc_xbusd->xbusd_otherend,
510 	   "num_devs", &num_devs, 10);
511 	if (err) {
512 		aprint_error_dev(xpci_sc->sc_dev,
513 		   "can't read num_devs: %d\n", err);
514 		return err;
515 	}
516 	for (i = 0; i < num_devs; i++) {
517 		char string[32];
518 		snprintf(node, sizeof(node), "dev-%d", i);
519 		xenbus_read(NULL, xpci_sc->sc_xbusd->xbusd_otherend,
520 		   node, string, sizeof(string));
521 		/* split dddd:bb:dd:ff in 4 strings, a la strtok */
522 		domain = string;
523 		string[4] = '\0';
524 		bus = &string[5];
525 		string[7] = '\0';
526 		dev = &string[8];
527 		string[10] = '\0';
528 		func = &string[11];
529 		if (strcmp(domain, "0000") != 0) {
530 			aprint_error_dev(xpci_sc->sc_dev,
531 			   "non-zero PCI domain %s not supported\n", domain);
532 		} else {
533 			busn = strtoul(bus, &ep, 16);
534 			if (*ep != '\0') {
535 				aprint_error_dev(xpci_sc->sc_dev,
536 				   "%s is not a number\n", bus);
537 				goto endfor;
538 			}
539 			devn = strtoul(dev, &ep, 16);
540 			if (*ep != '\0') {
541 				aprint_error_dev(xpci_sc->sc_dev,
542 				   "%s is not a number\n", dev);
543 				goto endfor;
544 			}
545 			funcn = strtoul(func, &ep, 16);
546 			if (*ep != '\0') {
547 				aprint_error_dev(xpci_sc->sc_dev,
548 				   "%s is not a number\n", func);
549 				goto endfor;
550 			}
551 			if (busn != sc->sc_bus)
552 				goto endfor;
553 			tag = pci_make_tag(pc, busn, devn, funcn);
554 			err = pci_probe_device1(sc, tag, match, pap);
555 			if (match != NULL && err != 0)
556 				return (err);
557 		}
558 endfor:
559 	}
560 	return (0);
561 #else
562 	int devn, funcn;
563 	pcitag_t tag;
564 	pci_chipset_tag_t pc = sc->sc_pc;
565 	int err;
566 	/*
567 	 * Xen is lacking an important info: the domain:bus:dev:func
568 	 * present in dev-xx in the store are real PCI bus:dev:func, and
569 	 * xenback may present us fake ones, and unfortunately it's not
570 	 * the list of devices is not published in the store with this
571 	 * information. So we have to scan all dev/func combination :(
572 	 * the MI scan function isn't enough because it doesn't search
573 	 * for functions >= 1 if function 0 is not there.
574 	 */
575 	for (devn = 0; devn < 32; devn++) {
576 		for (funcn = 0; funcn < 8; funcn++) {
577 			pcireg_t csr, bar;
578 			int reg;
579 			tag = pci_make_tag(pc, sc->sc_bus, devn, funcn);
580 			/* try a READ on device ID. if it fails, no device */
581 			if (xpci_conf_read(pc, tag, PCI_ID_REG, 4, &csr) != 0)
582 				continue;
583 			/* check CSR. linux disable the device, sigh */
584 			if (xpci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG, 4,
585 			    &csr) != 0) {
586 				aprint_error(
587 				    "0x%2x:0x%2x:0x%2x failed to read CSR\n",
588 				    sc->sc_bus, devn, funcn);
589 				continue;
590 			}
591 			if ((csr &
592 			    (PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE))
593 			    == 0) {
594 				/* need to enable the device */
595 				for (reg = PCI_MAPREG_START;
596 				    reg < PCI_MAPREG_END;
597 				    reg += 4) {
598 					if (xpci_conf_read(pc, tag, reg, 4,
599 					    &bar) != 0) {
600 						aprint_error(
601 						    "0x%2x:0x%2x:0x%2x "
602 						    "failed to read 0x%x\n",
603 						    sc->sc_bus, devn, funcn,
604 						    reg);
605 						goto next;
606 
607 					}
608 					if (bar & PCI_MAPREG_TYPE_IO)
609 						csr |= PCI_COMMAND_IO_ENABLE;
610 					else if (bar)
611 						csr |= PCI_COMMAND_MEM_ENABLE;
612 				}
613 				DPRINTF(("write CSR 0x%x\n", csr));
614 				if (xpci_conf_write(pc, tag,
615 				    PCI_COMMAND_STATUS_REG, 4, csr)) {
616 					aprint_error(
617 					    "0x%2x:0x%2x:0x%2x "
618 					    "failed to write CSR\n",
619 					     sc->sc_bus, devn, funcn);
620 					goto next;
621 				}
622 			}
623 			err = pci_probe_device1(sc, tag, match, pap);
624 			if (match != NULL && err != 0)
625 				return (err);
626 next:
627 			continue;
628 		}
629 	}
630 	return 0;
631 #endif
632 }
633