xref: /freebsd/sys/dev/vmd/vmd.c (revision a96ef4501919d7ac08e94e98dc34b0bdd744802b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright 2019 Cisco Systems, Inc.
5  * 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  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 
41 #include <machine/bus.h>
42 #include <machine/resource.h>
43 #include <sys/rman.h>
44 #include <sys/lock.h>
45 #include <sys/mutex.h>
46 #include <sys/taskqueue.h>
47 
48 #include <sys/pciio.h>
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
51 #include <dev/pci/pci_private.h>
52 #include <dev/pci/pcib_private.h>
53 
54 #define TASK_QUEUE_INTR 1
55 #include <dev/vmd/vmd.h>
56 
57 #include "pcib_if.h"
58 #include "pci_if.h"
59 
60 struct vmd_type {
61 	u_int16_t	vmd_vid;
62 	u_int16_t	vmd_did;
63 	char		*vmd_name;
64 	int		flags;
65 #define BUS_RESTRICT 1
66 };
67 
68 #define INTEL_VENDOR_ID		0x8086
69 #define INTEL_DEVICE_ID_201d	0x201d
70 #define INTEL_DEVICE_ID_28c0	0x28c0
71 #define INTEL_DEVICE_ID_467f	0x467f
72 #define INTEL_DEVICE_ID_4c3d	0x4c3d
73 #define INTEL_DEVICE_ID_9a0b	0x9a0b
74 
75 #define VMD_CAP		0x40
76 #define VMD_BUS_RESTRICT	0x1
77 
78 #define VMD_CONFIG	0x44
79 #define VMD_BUS_START(x)	((x >> 8) & 0x3)
80 
81 #define VMD_LOCK	0x70
82 
83 static struct vmd_type vmd_devs[] = {
84         { INTEL_VENDOR_ID, INTEL_DEVICE_ID_201d, "Intel Volume Management Device", 0 },
85         { INTEL_VENDOR_ID, INTEL_DEVICE_ID_28c0, "Intel Volume Management Device", BUS_RESTRICT },
86         { INTEL_VENDOR_ID, INTEL_DEVICE_ID_467f, "Intel Volume Management Device", BUS_RESTRICT },
87         { INTEL_VENDOR_ID, INTEL_DEVICE_ID_4c3d, "Intel Volume Management Device", BUS_RESTRICT },
88         { INTEL_VENDOR_ID, INTEL_DEVICE_ID_9a0b, "Intel Volume Management Device", BUS_RESTRICT },
89         { 0, 0, NULL, 0 }
90 };
91 
92 static int
93 vmd_probe(device_t dev)
94 {
95 	struct vmd_type *t;
96 	uint16_t vid, did;
97 
98 	t = vmd_devs;
99 	vid = pci_get_vendor(dev);
100 	did = pci_get_device(dev);
101 
102 	while (t->vmd_name != NULL) {
103 		if (vid == t->vmd_vid &&
104 			did == t->vmd_did) {
105 			device_set_desc(dev, t->vmd_name);
106 			return (BUS_PROBE_DEFAULT);
107 		}
108 		t++;
109 	}
110 
111 	return (ENXIO);
112 }
113 
114 static void
115 vmd_free(struct vmd_softc *sc)
116 {
117 	int i;
118 	struct vmd_irq_handler *elm, *tmp;
119 
120 	if (sc->vmd_bus.rman.rm_end != 0)
121 		rman_fini(&sc->vmd_bus.rman);
122 
123 #ifdef TASK_QUEUE_INTR
124 	if (sc->vmd_irq_tq != NULL) {
125 		taskqueue_drain(sc->vmd_irq_tq, &sc->vmd_irq_task);
126 		taskqueue_free(sc->vmd_irq_tq);
127 		sc->vmd_irq_tq = NULL;
128 	}
129 #endif
130 	if (sc->vmd_irq != NULL) {
131 		for (i = 0; i < sc->vmd_msix_count; i++) {
132 			if (sc->vmd_irq[i].vmd_res != NULL) {
133 				bus_teardown_intr(sc->vmd_dev,
134 				    sc->vmd_irq[i].vmd_res,
135 				    sc->vmd_irq[i].vmd_handle);
136 				bus_release_resource(sc->vmd_dev, SYS_RES_IRQ,
137 				    sc->vmd_irq[i].vmd_rid,
138 				    sc->vmd_irq[i].vmd_res);
139 			}
140 		}
141 		TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list ,vmd_link,
142 		    tmp) {
143 			TAILQ_REMOVE(&sc->vmd_irq[0].vmd_list, elm, vmd_link);
144 			free(elm, M_DEVBUF);
145 		}
146 	}
147 	free(sc->vmd_irq, M_DEVBUF);
148 	sc->vmd_irq = NULL;
149 	pci_release_msi(sc->vmd_dev);
150 	for (i = 0; i < VMD_MAX_BAR; i++) {
151 		if (sc->vmd_regs_resource[i] != NULL)
152 			bus_release_resource(sc->vmd_dev, SYS_RES_MEMORY,
153 			    sc->vmd_regs_rid[i],
154 			    sc->vmd_regs_resource[i]);
155 	}
156 	if (sc->vmd_io_resource)
157 		bus_release_resource(device_get_parent(sc->vmd_dev),
158 		    SYS_RES_IOPORT, sc->vmd_io_rid, sc->vmd_io_resource);
159 
160 #ifndef TASK_QUEUE_INTR
161 	if (mtx_initialized(&sc->vmd_irq_lock)) {
162 		mtx_destroy(&sc->vmd_irq_lock);
163 	}
164 #endif
165 }
166 
167 /* Hidden PCI Roots are hidden in BAR(0). */
168 
169 static uint32_t
170 vmd_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width)
171 {
172 
173 	struct vmd_softc *sc;
174 	bus_addr_t offset;
175 
176 	sc = device_get_softc(dev);
177 	if (b < sc->vmd_bus_start)
178 		return (0xffffffff);
179 
180 	offset = ((b - sc->vmd_bus_start) << 20) + (s << 15) + (f << 12) + reg;
181 
182 	switch(width) {
183 	case 4:
184 		return (bus_space_read_4(sc->vmd_btag, sc->vmd_bhandle,
185 		    offset));
186 	case 2:
187 		return (bus_space_read_2(sc->vmd_btag, sc->vmd_bhandle,
188 		    offset));
189 	case 1:
190 		return (bus_space_read_1(sc->vmd_btag, sc->vmd_bhandle,
191 		    offset));
192 	default:
193 		KASSERT(1, ("Invalid width requested"));
194 		return (0xffffffff);
195 	}
196 }
197 
198 static void
199 vmd_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg,
200     uint32_t val, int width)
201 {
202 
203 	struct vmd_softc *sc;
204 	bus_addr_t offset;
205 
206 	sc = device_get_softc(dev);
207 	if (b < sc->vmd_bus_start)
208 		return;
209 
210 	offset = ((b - sc->vmd_bus_start) << 20) + (s << 15) + (f << 12) + reg;
211 
212 	switch(width) {
213 	case 4:
214 		return (bus_space_write_4(sc->vmd_btag, sc->vmd_bhandle,
215 		    offset, val));
216 	case 2:
217 		return (bus_space_write_2(sc->vmd_btag, sc->vmd_bhandle,
218 		    offset, val));
219 	case 1:
220 		return (bus_space_write_1(sc->vmd_btag, sc->vmd_bhandle,
221 		    offset, val));
222 	default:
223 		panic("Failed to specific width");
224 	}
225 }
226 
227 static uint32_t
228 vmd_pci_read_config(device_t dev, device_t child, int reg, int width)
229 {
230 	struct pci_devinfo *dinfo = device_get_ivars(child);
231 	pcicfgregs *cfg = &dinfo->cfg;
232 
233 	return vmd_read_config(dev, cfg->bus, cfg->slot, cfg->func, reg, width);
234 }
235 
236 static void
237 vmd_pci_write_config(device_t dev, device_t child, int reg, uint32_t val,
238     int width)
239 {
240 	struct pci_devinfo *dinfo = device_get_ivars(child);
241 	pcicfgregs *cfg = &dinfo->cfg;
242 
243 	vmd_write_config(dev, cfg->bus, cfg->slot, cfg->func, reg, val, width);
244 }
245 
246 static struct pci_devinfo *
247 vmd_alloc_devinfo(device_t dev)
248 {
249 	struct pci_devinfo *dinfo;
250 
251 	dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
252 	return (dinfo);
253 }
254 
255 static void
256 vmd_intr(void *arg)
257 {
258 	struct vmd_irq  *irq;
259 	struct vmd_softc *sc;
260 #ifndef TASK_QUEUE_INTR
261 	struct vmd_irq_handler *elm, *tmp_elm;
262 #endif
263 
264 	irq = (struct vmd_irq *)arg;
265 	sc = irq->vmd_sc;
266 #ifdef TASK_QUEUE_INTR
267 	taskqueue_enqueue(sc->vmd_irq_tq, &sc->vmd_irq_task);
268 #else
269 	mtx_lock(&sc->vmd_irq_lock);
270 	TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp_elm) {
271 		(elm->vmd_intr)(elm->vmd_arg);
272 	}
273 	mtx_unlock(&sc->vmd_irq_lock);
274 #endif
275 }
276 
277 #ifdef TASK_QUEUE_INTR
278 static void
279 vmd_handle_irq(void *context, int pending)
280 {
281 	struct vmd_irq_handler *elm, *tmp_elm;
282 	struct vmd_softc *sc;
283 
284 	sc = context;
285 
286 	TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp_elm) {
287 		(elm->vmd_intr)(elm->vmd_arg);
288 	}
289 }
290 #endif
291 
292 static int
293 vmd_attach(device_t dev)
294 {
295 	struct vmd_softc *sc;
296 	struct pcib_secbus *bus;
297 	struct vmd_type *t;
298 	uint16_t vid, did;
299 	uint32_t bar;
300 	int i, j, error;
301 	int rid, sec_reg;
302 	static int b;
303 	static int s;
304 	static int f;
305 	int min_count = 1;
306 	char buf[64];
307 
308 	sc = device_get_softc(dev);
309 	bzero(sc, sizeof(*sc));
310 	sc->vmd_dev = dev;
311 	b = s = f = 0;
312 
313 	pci_enable_busmaster(dev);
314 
315 #ifdef TASK_QUEUE_INTR
316 	sc->vmd_irq_tq = taskqueue_create_fast("vmd_taskq", M_NOWAIT,
317 	    taskqueue_thread_enqueue, &sc->vmd_irq_tq);
318 	taskqueue_start_threads(&sc->vmd_irq_tq, 1, PI_DISK, "%s taskq",
319             device_get_nameunit(sc->vmd_dev));
320 	TASK_INIT(&sc->vmd_irq_task, 0, vmd_handle_irq, sc);
321 #else
322 	mtx_init(&sc->vmd_irq_lock, "VMD IRQ lock", NULL, MTX_DEF);
323 #endif
324 	for (i = 0, j = 0; i < VMD_MAX_BAR; i++, j++ ) {
325 		sc->vmd_regs_rid[i] = PCIR_BAR(j);
326 		bar = pci_read_config(dev, PCIR_BAR(0), 4);
327 		if (PCI_BAR_MEM(bar) && (bar & PCIM_BAR_MEM_TYPE) ==
328 		    PCIM_BAR_MEM_64)
329 			j++;
330 		if ((sc->vmd_regs_resource[i] = bus_alloc_resource_any(
331 		    sc->vmd_dev, SYS_RES_MEMORY, &sc->vmd_regs_rid[i],
332 		    RF_ACTIVE)) == NULL) {
333 			device_printf(dev, "Cannot allocate resources\n");
334 			goto fail;
335 		}
336 	}
337 
338 	sc->vmd_io_rid = PCIR_IOBASEL_1;
339 	sc->vmd_io_resource = bus_alloc_resource_any(
340 	    device_get_parent(sc->vmd_dev), SYS_RES_IOPORT, &sc->vmd_io_rid,
341 	    RF_ACTIVE);
342 	if (sc->vmd_io_resource == NULL) {
343 		device_printf(dev, "Cannot allocate IO\n");
344 		goto fail;
345 	}
346 
347 	sc->vmd_btag = rman_get_bustag(sc->vmd_regs_resource[0]);
348 	sc->vmd_bhandle = rman_get_bushandle(sc->vmd_regs_resource[0]);
349 
350 	pci_write_config(dev, PCIR_PRIBUS_2,
351 	    pcib_get_bus(device_get_parent(dev)), 1);
352 
353 	t = vmd_devs;
354 	vid = pci_get_vendor(dev);
355 	did = pci_get_device(dev);
356 
357 	sc->vmd_bus_start = 0;
358 	while (t->vmd_name != NULL) {
359 		if (vid == t->vmd_vid &&
360 			did == t->vmd_did) {
361 			if (t->flags == BUS_RESTRICT) {
362 				if (pci_read_config(dev, VMD_CAP, 2) &
363 				    VMD_BUS_RESTRICT)
364 					switch (VMD_BUS_START(pci_read_config(
365 					    dev, VMD_CONFIG, 2))) {
366 					case 1:
367 						sc->vmd_bus_start = 128;
368 						break;
369 					case 2:
370 						sc->vmd_bus_start = 224;
371 						break;
372 					case 3:
373 						device_printf(dev,
374 						    "Unknown bug offset\n");
375 						goto fail;
376 						break;
377 					}
378 			}
379 		}
380 		t++;
381 	}
382 
383 	device_printf(dev, "VMD bus starts at %d\n", sc->vmd_bus_start);
384 
385 	sec_reg = PCIR_SECBUS_1;
386 	bus = &sc->vmd_bus;
387 	bus->sub_reg = PCIR_SUBBUS_1;
388 	bus->sec = vmd_read_config(dev, b, s, f, sec_reg, 1);
389 	bus->sub = vmd_read_config(dev, b, s, f, bus->sub_reg, 1);
390 	bus->dev = dev;
391 	bus->rman.rm_start = sc->vmd_bus_start;
392 	bus->rman.rm_end = PCI_BUSMAX;
393 	bus->rman.rm_type = RMAN_ARRAY;
394 	snprintf(buf, sizeof(buf), "%s bus numbers", device_get_nameunit(dev));
395 	bus->rman.rm_descr = strdup(buf, M_DEVBUF);
396 	error = rman_init(&bus->rman);
397 	if (error) {
398 		device_printf(dev, "Failed to initialize %s bus number rman\n",
399 		    device_get_nameunit(dev));
400 		bus->rman.rm_end = 0;
401 		goto fail;
402 	}
403 
404 	/*
405 	 * Allocate a bus range.  This will return an existing bus range
406 	 * if one exists, or a new bus range if one does not.
407 	 */
408 	rid = 0;
409 	bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid,
410 	    min_count, 0);
411 	if (bus->res == NULL) {
412 		/*
413 		 * Fall back to just allocating a range of a single bus
414 		 * number.
415 		 */
416 		bus->res = bus_alloc_resource_anywhere(dev, PCI_RES_BUS, &rid,
417 		    1, 0);
418 	} else if (rman_get_size(bus->res) < min_count) {
419 		/*
420 		 * Attempt to grow the existing range to satisfy the
421 		 * minimum desired count.
422 		 */
423 		(void)bus_adjust_resource(dev, PCI_RES_BUS, bus->res,
424 		    rman_get_start(bus->res), rman_get_start(bus->res) +
425 		    min_count - 1);
426 	}
427 
428 	/*
429 	 * Add the initial resource to the rman.
430 	 */
431 	if (bus->res != NULL) {
432 		error = rman_manage_region(&bus->rman, rman_get_start(bus->res),
433 		    rman_get_end(bus->res));
434 		if (error) {
435 			device_printf(dev, "Failed to add resource to rman\n");
436 			goto fail;
437 		}
438 		bus->sec = rman_get_start(bus->res);
439 		bus->sub = rman_get_end(bus->res);
440 	}
441 
442 	sc->vmd_msix_count = pci_msix_count(dev);
443 	if (pci_alloc_msix(dev, &sc->vmd_msix_count) == 0) {
444 		sc->vmd_irq = malloc(sizeof(struct vmd_irq) *
445 		    sc->vmd_msix_count,
446 		    M_DEVBUF, M_WAITOK | M_ZERO);
447 
448 		for (i = 0; i < sc->vmd_msix_count; i++) {
449 			sc->vmd_irq[i].vmd_rid = i + 1;
450 			sc->vmd_irq[i].vmd_sc = sc;
451 			sc->vmd_irq[i].vmd_instance = i;
452 			sc->vmd_irq[i].vmd_res = bus_alloc_resource_any(dev,
453 			    SYS_RES_IRQ, &sc->vmd_irq[i].vmd_rid,
454 			    RF_ACTIVE);
455 			if (sc->vmd_irq[i].vmd_res == NULL) {
456 				device_printf(dev,"Failed to alloc irq\n");
457 				goto fail;
458 			}
459 
460 			TAILQ_INIT(&sc->vmd_irq[i].vmd_list);
461 			if (bus_setup_intr(dev, sc->vmd_irq[i].vmd_res,
462 			    INTR_TYPE_MISC | INTR_MPSAFE, NULL, vmd_intr,
463 			    &sc->vmd_irq[i], &sc->vmd_irq[i].vmd_handle)) {
464 				device_printf(sc->vmd_dev,
465 				    "Cannot set up interrupt\n");
466 				sc->vmd_irq[i].vmd_res = NULL;
467 				goto fail;
468 			}
469 		}
470 	}
471 
472 	sc->vmd_child = device_add_child(dev, NULL, -1);
473 	if (sc->vmd_child == NULL) {
474 		device_printf(dev, "Failed to attach child\n");
475 		goto fail;
476 	}
477 
478 	error = device_probe_and_attach(sc->vmd_child);
479 	if (error) {
480 		device_printf(dev, "Failed to add probe child: %d\n", error);
481 		(void)device_delete_child(dev, sc->vmd_child);
482 		goto fail;
483 	}
484 
485 	return (0);
486 
487 fail:
488 	vmd_free(sc);
489 	return (ENXIO);
490 }
491 
492 static int
493 vmd_detach(device_t dev)
494 {
495 	struct vmd_softc *sc;
496 	int err;
497 
498 	sc = device_get_softc(dev);
499 	if (sc->vmd_child != NULL) {
500 		err = bus_generic_detach(sc->vmd_child);
501 		if (err)
502 			return (err);
503 		err = device_delete_child(dev, sc->vmd_child);
504 		if (err)
505 			return (err);
506 	}
507 	vmd_free(sc);
508 	return (0);
509 }
510 
511 /* Pass request to alloc an MSI-X message up to the parent bridge. */
512 static int
513 vmd_alloc_msix(device_t pcib, device_t dev, int *irq)
514 {
515 	struct vmd_softc *sc = device_get_softc(pcib);
516 	device_t bus;
517 	int ret;
518 
519 	if (sc->vmd_flags & PCIB_DISABLE_MSIX)
520 		return (ENXIO);
521 	bus = device_get_parent(pcib);
522 	ret = PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq);
523         return (ret);
524 }
525 
526 static struct resource *
527 vmd_alloc_resource(device_t dev, device_t child, int type, int *rid,
528     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
529 {
530 	/* Start at max PCI vmd_domain and work down */
531 	if (type == PCI_RES_BUS) {
532 		return (pci_domain_alloc_bus(PCI_DOMAINMAX -
533 		    device_get_unit(dev), child, rid, start, end,
534 		    count, flags));
535 	}
536 
537 	return (pcib_alloc_resource(dev, child, type, rid, start, end,
538 				    count, flags));
539 }
540 
541 static int
542 vmd_adjust_resource(device_t dev, device_t child, int type,
543     struct resource *r, rman_res_t start, rman_res_t end)
544 {
545 	struct resource *res = r;
546 
547 	if (type == PCI_RES_BUS)
548 		return (pci_domain_adjust_bus(PCI_DOMAINMAX -
549 			device_get_unit(dev), child, res, start, end));
550 	return (pcib_adjust_resource(dev, child, type, res, start, end));
551 }
552 
553 static int
554 vmd_release_resource(device_t dev, device_t child, int type, int rid,
555     struct resource *r)
556 {
557 	if (type == PCI_RES_BUS)
558 		return (pci_domain_release_bus(PCI_DOMAINMAX -
559 		    device_get_unit(dev), child, rid, r));
560 	return (pcib_release_resource(dev, child, type, rid, r));
561 }
562 
563 static int
564 vmd_shutdown(device_t dev)
565 {
566 	return (0);
567 }
568 
569 static int
570 vmd_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
571 {
572 	return (pcib_route_interrupt(pcib, dev, pin));
573 }
574 
575 static int
576 vmd_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount,
577     int *irqs)
578 {
579 	return (pcib_alloc_msi(pcib, dev, count, maxcount, irqs));
580 }
581 
582 static int
583 vmd_pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs)
584 {
585 
586 	return (pcib_release_msi(pcib, dev, count, irqs));
587 }
588 
589 static int
590 vmd_pcib_release_msix(device_t pcib, device_t dev, int irq) {
591 	return	pcib_release_msix(pcib, dev, irq);
592 }
593 
594 static int
595 vmd_setup_intr(device_t dev, device_t child, struct resource *irq,
596     int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
597     void **cookiep)
598 {
599 	struct vmd_irq_handler *elm;
600 	struct vmd_softc *sc;
601 	int i;
602 
603 	sc = device_get_softc(dev);
604 
605 	/*
606 	 * There appears to be no steering of VMD interrupts from device
607 	 * to VMD interrupt
608 	 */
609 
610 	i = 0;
611 	elm = malloc(sizeof(*elm), M_DEVBUF, M_NOWAIT|M_ZERO);
612 	elm->vmd_child = child;
613 	elm->vmd_intr = intr;
614 	elm->vmd_rid = rman_get_rid(irq);
615 	elm->vmd_arg = arg;
616 	TAILQ_INSERT_TAIL(&sc->vmd_irq[i].vmd_list, elm, vmd_link);
617 
618 	return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr,
619 	    arg, cookiep));
620 }
621 
622 static int
623 vmd_teardown_intr(device_t dev, device_t child, struct resource *irq,
624     void *cookie)
625 {
626 	struct vmd_irq_handler *elm, *tmp;;
627 	struct vmd_softc *sc;
628 
629 	sc = device_get_softc(dev);
630 	TAILQ_FOREACH_SAFE(elm, &sc->vmd_irq[0].vmd_list, vmd_link, tmp) {
631 		if (elm->vmd_child == child &&
632 		    elm->vmd_rid == rman_get_rid(irq)) {
633 			TAILQ_REMOVE(&sc->vmd_irq[0].vmd_list, elm, vmd_link);
634 			free(elm, M_DEVBUF);
635 		}
636 	}
637 
638 	return (bus_generic_teardown_intr(dev, child, irq, cookie));
639 }
640 
641 static device_method_t vmd_pci_methods[] = {
642 	/* Device interface */
643 	DEVMETHOD(device_probe,			vmd_probe),
644 	DEVMETHOD(device_attach,		vmd_attach),
645 	DEVMETHOD(device_detach,		vmd_detach),
646 	DEVMETHOD(device_shutdown,		vmd_shutdown),
647 
648 	/* Bus interface */
649 	DEVMETHOD(bus_read_ivar,		pcib_read_ivar),
650 	DEVMETHOD(bus_write_ivar,		pcib_write_ivar),
651 	DEVMETHOD(bus_alloc_resource,		vmd_alloc_resource),
652 	DEVMETHOD(bus_adjust_resource,		vmd_adjust_resource),
653 	DEVMETHOD(bus_release_resource,		vmd_release_resource),
654 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
655 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
656 	DEVMETHOD(bus_setup_intr,		vmd_setup_intr),
657 	DEVMETHOD(bus_teardown_intr,		vmd_teardown_intr),
658 
659 	/* pci interface */
660 	DEVMETHOD(pci_read_config,		vmd_pci_read_config),
661 	DEVMETHOD(pci_write_config,		vmd_pci_write_config),
662 	DEVMETHOD(pci_alloc_devinfo,		vmd_alloc_devinfo),
663 
664 	/* pcib interface */
665 	DEVMETHOD(pcib_maxslots,		pcib_maxslots),
666 	DEVMETHOD(pcib_read_config,		vmd_read_config),
667 	DEVMETHOD(pcib_write_config,		vmd_write_config),
668 	DEVMETHOD(pcib_route_interrupt,		vmd_pcib_route_interrupt),
669 	DEVMETHOD(pcib_alloc_msi,		vmd_pcib_alloc_msi),
670 	DEVMETHOD(pcib_release_msi,		vmd_pcib_release_msi),
671 	DEVMETHOD(pcib_alloc_msix,		vmd_alloc_msix),
672 	DEVMETHOD(pcib_release_msix,		vmd_pcib_release_msix),
673 	DEVMETHOD(pcib_map_msi,			pcib_map_msi),
674 
675 	DEVMETHOD_END
676 };
677 
678 static devclass_t vmd_devclass;
679 
680 DEFINE_CLASS_0(vmd, vmd_pci_driver, vmd_pci_methods, sizeof(struct vmd_softc));
681 DRIVER_MODULE(vmd, pci, vmd_pci_driver, vmd_devclass, NULL, NULL);
682 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, vmd,
683     vmd_devs, nitems(vmd_devs) - 1);
684 MODULE_DEPEND(vmd, vmd_bus, 1, 1, 1);
685