1 /* $OpenBSD: virtio_pci.c,v 1.51 2025/01/29 14:03:18 sf Exp $ */ 2 /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ 3 4 /* 5 * Copyright (c) 2012 Stefan Fritsch. 6 * Copyright (c) 2010 Minoura Makoto. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/device.h> 33 #include <sys/mutex.h> 34 35 #include <dev/pci/pcidevs.h> 36 #include <dev/pci/pcireg.h> 37 #include <dev/pci/pcivar.h> 38 #include <dev/pci/virtio_pcireg.h> 39 40 #include <dev/pv/virtioreg.h> 41 #include <dev/pv/virtiovar.h> 42 43 #define DNPRINTF(n,x...) \ 44 do { if (VIRTIO_DEBUG >= n) printf(x); } while(0) 45 46 47 /* 48 * XXX: Before being used on big endian arches, the access to config registers 49 * XXX: needs to be reviewed/fixed. The non-device specific registers are 50 * XXX: PCI-endian while the device specific registers are native endian. 51 */ 52 53 #define MAX_MSIX_VECS 16 54 55 struct virtio_pci_softc; 56 struct virtio_pci_attach_args; 57 58 int virtio_pci_match(struct device *, void *, void *); 59 void virtio_pci_attach(struct device *, struct device *, void *); 60 int virtio_pci_attach_09(struct virtio_pci_softc *sc, struct pci_attach_args *pa); 61 int virtio_pci_attach_10(struct virtio_pci_softc *sc, struct pci_attach_args *pa); 62 int virtio_pci_detach(struct device *, int); 63 64 void virtio_pci_kick(struct virtio_softc *, uint16_t); 65 int virtio_pci_adjust_config_region(struct virtio_pci_softc *, int offset); 66 uint8_t virtio_pci_read_device_config_1(struct virtio_softc *, int); 67 uint16_t virtio_pci_read_device_config_2(struct virtio_softc *, int); 68 uint32_t virtio_pci_read_device_config_4(struct virtio_softc *, int); 69 uint64_t virtio_pci_read_device_config_8(struct virtio_softc *, int); 70 void virtio_pci_write_device_config_1(struct virtio_softc *, int, uint8_t); 71 void virtio_pci_write_device_config_2(struct virtio_softc *, int, uint16_t); 72 void virtio_pci_write_device_config_4(struct virtio_softc *, int, uint32_t); 73 void virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t); 74 uint16_t virtio_pci_read_queue_size(struct virtio_softc *, uint16_t); 75 void virtio_pci_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); 76 void virtio_pci_setup_intrs(struct virtio_softc *); 77 int virtio_pci_attach_finish(struct virtio_softc *, struct virtio_attach_args *); 78 int virtio_pci_get_status(struct virtio_softc *); 79 void virtio_pci_set_status(struct virtio_softc *, int); 80 int virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_feature_name *); 81 int virtio_pci_negotiate_features_10(struct virtio_softc *, const struct virtio_feature_name *); 82 void virtio_pci_set_msix_queue_vector(struct virtio_pci_softc *, uint32_t, uint16_t); 83 void virtio_pci_set_msix_config_vector(struct virtio_pci_softc *, uint16_t); 84 int virtio_pci_msix_establish(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int, struct cpu_info *, int (*)(void *), void *); 85 int virtio_pci_setup_msix(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int); 86 void virtio_pci_intr_barrier(struct virtio_softc *); 87 int virtio_pci_intr_establish(struct virtio_softc *, struct virtio_attach_args *, int, struct cpu_info *, int (*)(void *), void *); 88 void virtio_pci_free_irqs(struct virtio_pci_softc *); 89 int virtio_pci_poll_intr(void *); 90 int virtio_pci_legacy_intr(void *); 91 int virtio_pci_legacy_intr_mpsafe(void *); 92 int virtio_pci_config_intr(void *); 93 int virtio_pci_queue_intr(void *); 94 int virtio_pci_shared_queue_intr(void *); 95 int virtio_pci_find_cap(struct virtio_pci_softc *sc, int cfg_type, void *buf, int buflen); 96 #if VIRTIO_DEBUG 97 void virtio_pci_dump_caps(struct virtio_pci_softc *sc); 98 #endif 99 100 enum irq_type { 101 IRQ_NO_MSIX, 102 IRQ_MSIX_SHARED, /* vec 0: config irq, vec 1 shared by all vqs */ 103 IRQ_MSIX_PER_VQ, /* vec 0: config irq, vec n: irq of vq[n-1] */ 104 IRQ_MSIX_CHILD, /* assigned by child driver */ 105 }; 106 107 struct virtio_pci_intr { 108 char name[16]; 109 void *ih; 110 }; 111 112 struct virtio_pci_softc { 113 struct virtio_softc sc_sc; 114 pci_chipset_tag_t sc_pc; 115 pcitag_t sc_ptag; 116 117 bus_space_tag_t sc_iot; 118 bus_space_handle_t sc_ioh; 119 bus_size_t sc_iosize; 120 121 bus_space_tag_t sc_bars_iot[4]; 122 bus_space_handle_t sc_bars_ioh[4]; 123 bus_size_t sc_bars_iosize[4]; 124 125 bus_space_tag_t sc_notify_iot; 126 bus_space_handle_t sc_notify_ioh; 127 bus_size_t sc_notify_iosize; 128 unsigned int sc_notify_off_multiplier; 129 130 bus_space_tag_t sc_devcfg_iot; 131 bus_space_handle_t sc_devcfg_ioh; 132 bus_size_t sc_devcfg_iosize; 133 /* 134 * With 0.9, the offset of the devcfg region in the io bar changes 135 * depending on MSI-X being enabled or not. 136 * With 1.0, this field is still used to remember if MSI-X is enabled 137 * or not. 138 */ 139 unsigned int sc_devcfg_offset; 140 141 bus_space_tag_t sc_isr_iot; 142 bus_space_handle_t sc_isr_ioh; 143 bus_size_t sc_isr_iosize; 144 145 struct virtio_pci_intr *sc_intr; 146 int sc_nintr; 147 148 enum irq_type sc_irq_type; 149 }; 150 151 struct virtio_pci_attach_args { 152 struct virtio_attach_args vpa_va; 153 struct pci_attach_args *vpa_pa; 154 }; 155 156 157 const struct cfattach virtio_pci_ca = { 158 sizeof(struct virtio_pci_softc), 159 virtio_pci_match, 160 virtio_pci_attach, 161 virtio_pci_detach, 162 NULL 163 }; 164 165 const struct virtio_ops virtio_pci_ops = { 166 virtio_pci_kick, 167 virtio_pci_read_device_config_1, 168 virtio_pci_read_device_config_2, 169 virtio_pci_read_device_config_4, 170 virtio_pci_read_device_config_8, 171 virtio_pci_write_device_config_1, 172 virtio_pci_write_device_config_2, 173 virtio_pci_write_device_config_4, 174 virtio_pci_write_device_config_8, 175 virtio_pci_read_queue_size, 176 virtio_pci_setup_queue, 177 virtio_pci_setup_intrs, 178 virtio_pci_get_status, 179 virtio_pci_set_status, 180 virtio_pci_negotiate_features, 181 virtio_pci_attach_finish, 182 virtio_pci_poll_intr, 183 virtio_pci_intr_barrier, 184 virtio_pci_intr_establish, 185 }; 186 187 static inline uint64_t 188 _cread(struct virtio_pci_softc *sc, unsigned off, unsigned size) 189 { 190 uint64_t val; 191 switch (size) { 192 case 1: 193 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, off); 194 break; 195 case 2: 196 val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, off); 197 break; 198 case 4: 199 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 200 break; 201 case 8: 202 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 203 off + sizeof(uint32_t)); 204 val <<= 32; 205 val += bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 206 break; 207 } 208 return val; 209 } 210 211 #define CREAD(sc, memb) _cread(sc, offsetof(struct virtio_pci_common_cfg, memb), \ 212 sizeof(((struct virtio_pci_common_cfg *)0)->memb)) 213 214 #define CWRITE(sc, memb, val) \ 215 do { \ 216 struct virtio_pci_common_cfg c; \ 217 size_t off = offsetof(struct virtio_pci_common_cfg, memb); \ 218 size_t size = sizeof(c.memb); \ 219 \ 220 DNPRINTF(2, "%s: %d: off %#zx size %#zx write %#llx\n", \ 221 __func__, __LINE__, off, size, (unsigned long long)val); \ 222 switch (size) { \ 223 case 1: \ 224 bus_space_write_1(sc->sc_iot, sc->sc_ioh, off, val); \ 225 break; \ 226 case 2: \ 227 bus_space_write_2(sc->sc_iot, sc->sc_ioh, off, val); \ 228 break; \ 229 case 4: \ 230 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val); \ 231 break; \ 232 case 8: \ 233 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, \ 234 (val) & 0xffffffff); \ 235 bus_space_write_4(sc->sc_iot, sc->sc_ioh, \ 236 (off) + sizeof(uint32_t), (uint64_t)(val) >> 32); \ 237 break; \ 238 } \ 239 } while (0) 240 241 uint16_t 242 virtio_pci_read_queue_size(struct virtio_softc *vsc, uint16_t idx) 243 { 244 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 245 uint16_t ret; 246 if (sc->sc_sc.sc_version_1) { 247 CWRITE(sc, queue_select, idx); 248 ret = CREAD(sc, queue_size); 249 } else { 250 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 251 VIRTIO_CONFIG_QUEUE_SELECT, idx); 252 ret = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 253 VIRTIO_CONFIG_QUEUE_SIZE); 254 } 255 return ret; 256 } 257 258 void 259 virtio_pci_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, 260 uint64_t addr) 261 { 262 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 263 if (sc->sc_sc.sc_version_1) { 264 CWRITE(sc, queue_select, vq->vq_index); 265 if (addr == 0) { 266 CWRITE(sc, queue_enable, 0); 267 CWRITE(sc, queue_desc, 0); 268 CWRITE(sc, queue_avail, 0); 269 CWRITE(sc, queue_used, 0); 270 } else { 271 CWRITE(sc, queue_desc, addr); 272 CWRITE(sc, queue_avail, addr + vq->vq_availoffset); 273 CWRITE(sc, queue_used, addr + vq->vq_usedoffset); 274 CWRITE(sc, queue_enable, 1); 275 vq->vq_notify_off = CREAD(sc, queue_notify_off); 276 } 277 } else { 278 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 279 VIRTIO_CONFIG_QUEUE_SELECT, vq->vq_index); 280 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 281 VIRTIO_CONFIG_QUEUE_ADDRESS, addr / VIRTIO_PAGE_SIZE); 282 } 283 } 284 285 void 286 virtio_pci_setup_intrs(struct virtio_softc *vsc) 287 { 288 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 289 int i; 290 291 if (sc->sc_irq_type == IRQ_NO_MSIX) 292 return; 293 294 for (i = 0; i < vsc->sc_nvqs; i++) { 295 unsigned vec = vsc->sc_vqs[i].vq_intr_vec; 296 virtio_pci_set_msix_queue_vector(sc, i, vec); 297 } 298 if (vsc->sc_config_change) 299 virtio_pci_set_msix_config_vector(sc, 0); 300 } 301 302 int 303 virtio_pci_get_status(struct virtio_softc *vsc) 304 { 305 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 306 307 if (sc->sc_sc.sc_version_1) 308 return CREAD(sc, device_status); 309 else 310 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, 311 VIRTIO_CONFIG_DEVICE_STATUS); 312 } 313 314 void 315 virtio_pci_set_status(struct virtio_softc *vsc, int status) 316 { 317 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 318 int old = 0; 319 320 if (sc->sc_sc.sc_version_1) { 321 if (status == 0) { 322 CWRITE(sc, device_status, 0); 323 while (CREAD(sc, device_status) != 0) { 324 CPU_BUSY_CYCLE(); 325 } 326 } else { 327 old = CREAD(sc, device_status); 328 CWRITE(sc, device_status, status|old); 329 } 330 } else { 331 if (status == 0) { 332 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 333 VIRTIO_CONFIG_DEVICE_STATUS, status|old); 334 while (bus_space_read_1(sc->sc_iot, sc->sc_ioh, 335 VIRTIO_CONFIG_DEVICE_STATUS) != 0) { 336 CPU_BUSY_CYCLE(); 337 } 338 } else { 339 old = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 340 VIRTIO_CONFIG_DEVICE_STATUS); 341 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 342 VIRTIO_CONFIG_DEVICE_STATUS, status|old); 343 } 344 } 345 } 346 347 int 348 virtio_pci_match(struct device *parent, void *match, void *aux) 349 { 350 struct pci_attach_args *pa; 351 352 pa = (struct pci_attach_args *)aux; 353 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_OPENBSD && 354 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_OPENBSD_CONTROL) 355 return 1; 356 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_QUMRANET) 357 return 0; 358 /* virtio 0.9 */ 359 if (PCI_PRODUCT(pa->pa_id) >= 0x1000 && 360 PCI_PRODUCT(pa->pa_id) <= 0x103f && 361 PCI_REVISION(pa->pa_class) == 0) 362 return 1; 363 /* virtio 1.0 */ 364 if (PCI_PRODUCT(pa->pa_id) >= 0x1040 && 365 PCI_PRODUCT(pa->pa_id) <= 0x107f) 366 return 1; 367 return 0; 368 } 369 370 #if VIRTIO_DEBUG 371 void 372 virtio_pci_dump_caps(struct virtio_pci_softc *sc) 373 { 374 pci_chipset_tag_t pc = sc->sc_pc; 375 pcitag_t tag = sc->sc_ptag; 376 int offset; 377 union { 378 pcireg_t reg[4]; 379 struct virtio_pci_cap vcap; 380 } v; 381 382 if (!pci_get_capability(pc, tag, PCI_CAP_VENDSPEC, &offset, &v.reg[0])) 383 return; 384 385 printf("\n"); 386 do { 387 for (int i = 0; i < 4; i++) 388 v.reg[i] = pci_conf_read(pc, tag, offset + i * 4); 389 printf("%s: cfgoff %#x len %#x type %#x bar %#x: off %#x len %#x\n", 390 __func__, offset, v.vcap.cap_len, v.vcap.cfg_type, v.vcap.bar, 391 v.vcap.offset, v.vcap.length); 392 offset = v.vcap.cap_next; 393 } while (offset != 0); 394 } 395 #endif 396 397 int 398 virtio_pci_find_cap(struct virtio_pci_softc *sc, int cfg_type, void *buf, int buflen) 399 { 400 pci_chipset_tag_t pc = sc->sc_pc; 401 pcitag_t tag = sc->sc_ptag; 402 unsigned int offset, i, len; 403 union { 404 pcireg_t reg[8]; 405 struct virtio_pci_cap vcap; 406 } *v = buf; 407 408 if (buflen < sizeof(struct virtio_pci_cap)) 409 return ERANGE; 410 411 if (!pci_get_capability(pc, tag, PCI_CAP_VENDSPEC, &offset, &v->reg[0])) 412 return ENOENT; 413 414 do { 415 for (i = 0; i < 4; i++) 416 v->reg[i] = pci_conf_read(pc, tag, offset + i * 4); 417 if (v->vcap.cfg_type == cfg_type) 418 break; 419 offset = v->vcap.cap_next; 420 } while (offset != 0); 421 422 if (offset == 0) 423 return ENOENT; 424 425 if (v->vcap.cap_len > sizeof(struct virtio_pci_cap)) { 426 len = roundup(v->vcap.cap_len, sizeof(pcireg_t)); 427 if (len > buflen) { 428 printf("%s: cap too large\n", __func__); 429 return ERANGE; 430 } 431 for (i = 4; i < len / sizeof(pcireg_t); i++) 432 v->reg[i] = pci_conf_read(pc, tag, offset + i * 4); 433 } 434 435 return 0; 436 } 437 438 439 #define NMAPREG ((PCI_MAPREG_END - PCI_MAPREG_START) / \ 440 sizeof(pcireg_t)) 441 442 int 443 virtio_pci_attach_10(struct virtio_pci_softc *sc, struct pci_attach_args *pa) 444 { 445 struct virtio_pci_cap common, isr, device; 446 struct virtio_pci_notify_cap notify; 447 int have_device_cfg = 0; 448 bus_size_t bars[NMAPREG] = { 0 }; 449 int bars_idx[NMAPREG] = { 0 }; 450 struct virtio_pci_cap *caps[] = { &common, &isr, &device, ¬ify.cap }; 451 int i, j = 0, ret = 0; 452 453 if (virtio_pci_find_cap(sc, VIRTIO_PCI_CAP_COMMON_CFG, &common, sizeof(common)) != 0) 454 return ENODEV; 455 456 if (virtio_pci_find_cap(sc, VIRTIO_PCI_CAP_NOTIFY_CFG, ¬ify, sizeof(notify)) != 0) 457 return ENODEV; 458 if (virtio_pci_find_cap(sc, VIRTIO_PCI_CAP_ISR_CFG, &isr, sizeof(isr)) != 0) 459 return ENODEV; 460 if (virtio_pci_find_cap(sc, VIRTIO_PCI_CAP_DEVICE_CFG, &device, sizeof(device)) != 0) 461 memset(&device, 0, sizeof(device)); 462 else 463 have_device_cfg = 1; 464 465 /* 466 * XXX Maybe there are devices that offer the pci caps but not the 467 * XXX VERSION_1 feature bit? Then we should check the feature bit 468 * XXX here and fall back to 0.9 out if not present. 469 */ 470 471 /* Figure out which bars we need to map */ 472 for (i = 0; i < nitems(caps); i++) { 473 int bar = caps[i]->bar; 474 bus_size_t len = caps[i]->offset + caps[i]->length; 475 if (caps[i]->length == 0) 476 continue; 477 if (bars[bar] < len) 478 bars[bar] = len; 479 } 480 481 for (i = 0; i < nitems(bars); i++) { 482 int reg; 483 pcireg_t type; 484 if (bars[i] == 0) 485 continue; 486 reg = PCI_MAPREG_START + i * 4; 487 type = pci_mapreg_type(sc->sc_pc, sc->sc_ptag, reg); 488 if (pci_mapreg_map(pa, reg, type, 0, &sc->sc_bars_iot[j], 489 &sc->sc_bars_ioh[j], NULL, &sc->sc_bars_iosize[j], 490 bars[i])) { 491 printf("%s: can't map bar %u \n", 492 sc->sc_sc.sc_dev.dv_xname, i); 493 ret = EIO; 494 goto err; 495 } 496 bars_idx[i] = j; 497 j++; 498 } 499 500 i = bars_idx[notify.cap.bar]; 501 if (bus_space_subregion(sc->sc_bars_iot[i], sc->sc_bars_ioh[i], 502 notify.cap.offset, notify.cap.length, &sc->sc_notify_ioh) != 0) { 503 printf("%s: can't map notify i/o space\n", 504 sc->sc_sc.sc_dev.dv_xname); 505 ret = EIO; 506 goto err; 507 } 508 sc->sc_notify_iosize = notify.cap.length; 509 sc->sc_notify_iot = sc->sc_bars_iot[i]; 510 sc->sc_notify_off_multiplier = notify.notify_off_multiplier; 511 512 if (have_device_cfg) { 513 i = bars_idx[device.bar]; 514 if (bus_space_subregion(sc->sc_bars_iot[i], sc->sc_bars_ioh[i], 515 device.offset, device.length, &sc->sc_devcfg_ioh) != 0) { 516 printf("%s: can't map devcfg i/o space\n", 517 sc->sc_sc.sc_dev.dv_xname); 518 ret = EIO; 519 goto err; 520 } 521 sc->sc_devcfg_iosize = device.length; 522 sc->sc_devcfg_iot = sc->sc_bars_iot[i]; 523 } 524 525 i = bars_idx[isr.bar]; 526 if (bus_space_subregion(sc->sc_bars_iot[i], sc->sc_bars_ioh[i], 527 isr.offset, isr.length, &sc->sc_isr_ioh) != 0) { 528 printf("%s: can't map isr i/o space\n", 529 sc->sc_sc.sc_dev.dv_xname); 530 ret = EIO; 531 goto err; 532 } 533 sc->sc_isr_iosize = isr.length; 534 sc->sc_isr_iot = sc->sc_bars_iot[i]; 535 536 i = bars_idx[common.bar]; 537 if (bus_space_subregion(sc->sc_bars_iot[i], sc->sc_bars_ioh[i], 538 common.offset, common.length, &sc->sc_ioh) != 0) { 539 printf("%s: can't map common i/o space\n", 540 sc->sc_sc.sc_dev.dv_xname); 541 ret = EIO; 542 goto err; 543 } 544 sc->sc_iosize = common.length; 545 sc->sc_iot = sc->sc_bars_iot[i]; 546 547 sc->sc_sc.sc_version_1 = 1; 548 return 0; 549 550 err: 551 /* there is no pci_mapreg_unmap() */ 552 return ret; 553 } 554 555 int 556 virtio_pci_attach_09(struct virtio_pci_softc *sc, struct pci_attach_args *pa) 557 { 558 struct virtio_softc *vsc = &sc->sc_sc; 559 pcireg_t type; 560 561 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); 562 if (pci_mapreg_map(pa, PCI_MAPREG_START, type, 0, 563 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize, 0)) { 564 printf("%s: can't map i/o space\n", vsc->sc_dev.dv_xname); 565 return EIO; 566 } 567 568 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 569 VIRTIO_CONFIG_QUEUE_NOTIFY, 2, &sc->sc_notify_ioh) != 0) { 570 printf("%s: can't map notify i/o space\n", 571 vsc->sc_dev.dv_xname); 572 return EIO; 573 } 574 sc->sc_notify_iosize = 2; 575 sc->sc_notify_iot = sc->sc_iot; 576 577 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 578 VIRTIO_CONFIG_ISR_STATUS, 1, &sc->sc_isr_ioh) != 0) { 579 printf("%s: can't map isr i/o space\n", 580 vsc->sc_dev.dv_xname); 581 return EIO; 582 } 583 sc->sc_isr_iosize = 1; 584 sc->sc_isr_iot = sc->sc_iot; 585 586 return 0; 587 } 588 589 void 590 virtio_pci_attach(struct device *parent, struct device *self, void *aux) 591 { 592 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self; 593 struct virtio_softc *vsc = &sc->sc_sc; 594 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 595 pci_chipset_tag_t pc = pa->pa_pc; 596 pcitag_t tag = pa->pa_tag; 597 int revision, product, vendor, ret = ENODEV, flags; 598 pcireg_t id; 599 struct virtio_pci_attach_args vpa = { { 0 }, pa }; 600 601 revision = PCI_REVISION(pa->pa_class); 602 product = PCI_PRODUCT(pa->pa_id); 603 vendor = PCI_VENDOR(pa->pa_id); 604 if (vendor == PCI_VENDOR_OPENBSD || 605 (product >= 0x1000 && product <= 0x103f && revision == 0)) { 606 /* OpenBSD VMMCI and virtio 0.9 */ 607 id = PCI_PRODUCT(pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG)); 608 } else if (product >= 0x1040 && product <= 0x107f) { 609 /* virtio 1.0 */ 610 id = product - 0x1040; 611 revision = 1; 612 } else { 613 printf("unknown device prod 0x%04x rev 0x%02x; giving up\n", 614 product, revision); 615 return; 616 } 617 618 sc->sc_pc = pc; 619 sc->sc_ptag = pa->pa_tag; 620 vsc->sc_dmat = pa->pa_dmat; 621 622 #if defined(__i386__) || defined(__amd64__) 623 /* 624 * For virtio, ignore normal MSI black/white-listing depending on the 625 * PCI bridge but enable it unconditionally. 626 */ 627 pa->pa_flags |= PCI_FLAGS_MSI_ENABLED; 628 #endif 629 630 #if VIRTIO_DEBUG 631 virtio_pci_dump_caps(sc); 632 #endif 633 634 sc->sc_nintr = min(MAX_MSIX_VECS, pci_intr_msix_count(pa)); 635 sc->sc_nintr = max(sc->sc_nintr, 1); 636 vpa.vpa_va.va_nintr = sc->sc_nintr; 637 638 sc->sc_intr = mallocarray(sc->sc_nintr, sizeof(*sc->sc_intr), 639 M_DEVBUF, M_WAITOK | M_ZERO); 640 641 vsc->sc_ops = &virtio_pci_ops; 642 flags = vsc->sc_dev.dv_cfdata->cf_flags; 643 if ((flags & VIRTIO_CF_PREFER_VERSION_09) == 0) 644 ret = virtio_pci_attach_10(sc, pa); 645 if (ret != 0 && revision == 0) { 646 /* revision 0 means 0.9 only or both 0.9 and 1.0 */ 647 ret = virtio_pci_attach_09(sc, pa); 648 } 649 if (ret != 0 && (flags & VIRTIO_CF_PREFER_VERSION_09)) 650 ret = virtio_pci_attach_10(sc, pa); 651 if (ret != 0) { 652 printf(": Cannot attach (%d)\n", ret); 653 goto free; 654 } 655 656 sc->sc_irq_type = IRQ_NO_MSIX; 657 if (virtio_pci_adjust_config_region(sc, 658 VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI) != 0) 659 { 660 goto free; 661 } 662 663 virtio_device_reset(vsc); 664 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 665 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 666 667 printf("\n"); 668 vpa.vpa_va.va_devid = id; 669 vsc->sc_child = NULL; 670 config_found(self, &vpa, NULL); 671 if (vsc->sc_child == NULL) { 672 printf("%s: no matching child driver; not configured\n", 673 vsc->sc_dev.dv_xname); 674 goto err; 675 } 676 if (vsc->sc_child == VIRTIO_CHILD_ERROR) { 677 printf("%s: virtio configuration failed\n", 678 vsc->sc_dev.dv_xname); 679 goto err; 680 } 681 682 return; 683 684 err: 685 /* no pci_mapreg_unmap() or pci_intr_unmap() */ 686 virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 687 free: 688 free(sc->sc_intr, M_DEVBUF, sc->sc_nintr * sizeof(*sc->sc_intr)); 689 } 690 691 int 692 virtio_pci_attach_finish(struct virtio_softc *vsc, 693 struct virtio_attach_args *va) 694 { 695 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 696 struct virtio_pci_attach_args *vpa = 697 (struct virtio_pci_attach_args *)va; 698 pci_intr_handle_t ih; 699 pci_chipset_tag_t pc = vpa->vpa_pa->pa_pc; 700 char const *intrstr; 701 702 if (sc->sc_irq_type == IRQ_MSIX_CHILD) { 703 intrstr = "msix"; 704 } else if (virtio_pci_setup_msix(sc, vpa, 0) == 0) { 705 sc->sc_irq_type = IRQ_MSIX_PER_VQ; 706 intrstr = "msix per-VQ"; 707 } else if (virtio_pci_setup_msix(sc, vpa, 1) == 0) { 708 sc->sc_irq_type = IRQ_MSIX_SHARED; 709 intrstr = "msix shared"; 710 } else { 711 int (*ih_func)(void *) = virtio_pci_legacy_intr; 712 if (pci_intr_map_msi(vpa->vpa_pa, &ih) != 0 && 713 pci_intr_map(vpa->vpa_pa, &ih) != 0) { 714 printf("%s: couldn't map interrupt\n", 715 vsc->sc_dev.dv_xname); 716 return -EIO; 717 } 718 intrstr = pci_intr_string(pc, ih); 719 /* 720 * We always set the IPL_MPSAFE flag in order to do the relatively 721 * expensive ISR read without lock, and then grab the kernel lock in 722 * the interrupt handler. 723 */ 724 if (vsc->sc_ipl & IPL_MPSAFE) 725 ih_func = virtio_pci_legacy_intr_mpsafe; 726 sc->sc_intr[0].ih = pci_intr_establish(pc, ih, 727 vsc->sc_ipl | IPL_MPSAFE, ih_func, sc, 728 vsc->sc_child->dv_xname); 729 if (sc->sc_intr[0].ih == NULL) { 730 printf("%s: couldn't establish interrupt", 731 vsc->sc_dev.dv_xname); 732 if (intrstr != NULL) 733 printf(" at %s", intrstr); 734 printf("\n"); 735 return -EIO; 736 } 737 } 738 739 printf("%s: %s\n", vsc->sc_dev.dv_xname, intrstr); 740 return 0; 741 } 742 743 int 744 virtio_pci_detach(struct device *self, int flags) 745 { 746 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)self; 747 struct virtio_softc *vsc = &sc->sc_sc; 748 int r; 749 750 if (vsc->sc_child != 0 && vsc->sc_child != VIRTIO_CHILD_ERROR) { 751 r = config_detach(vsc->sc_child, flags); 752 if (r) 753 return r; 754 } 755 KASSERT(vsc->sc_child == 0 || vsc->sc_child == VIRTIO_CHILD_ERROR); 756 KASSERT(vsc->sc_vqs == 0); 757 virtio_pci_free_irqs(sc); 758 if (sc->sc_iosize) 759 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 760 sc->sc_iosize = 0; 761 762 return 0; 763 } 764 765 int 766 virtio_pci_adjust_config_region(struct virtio_pci_softc *sc, int offset) 767 { 768 if (sc->sc_sc.sc_version_1) 769 return 0; 770 if (sc->sc_devcfg_offset == offset) 771 return 0; 772 sc->sc_devcfg_offset = offset; 773 sc->sc_devcfg_iosize = sc->sc_iosize - offset; 774 sc->sc_devcfg_iot = sc->sc_iot; 775 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, sc->sc_devcfg_offset, 776 sc->sc_devcfg_iosize, &sc->sc_devcfg_ioh) != 0) { 777 printf("%s: can't map config i/o space\n", 778 sc->sc_sc.sc_dev.dv_xname); 779 return 1; 780 } 781 return 0; 782 } 783 784 /* 785 * Feature negotiation. 786 * Prints available / negotiated features if guest_feature_names != NULL and 787 * VIRTIO_DEBUG is 1 788 */ 789 int 790 virtio_pci_negotiate_features(struct virtio_softc *vsc, 791 const struct virtio_feature_name *guest_feature_names) 792 { 793 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 794 uint64_t host, negotiated; 795 796 vsc->sc_active_features = 0; 797 798 /* 799 * We enable indirect descriptors by default. They can be switched 800 * off by setting bit 1 in the driver flags, see config(8) 801 */ 802 if (!(vsc->sc_dev.dv_cfdata->cf_flags & VIRTIO_CF_NO_INDIRECT) && 803 !(vsc->sc_child->dv_cfdata->cf_flags & VIRTIO_CF_NO_INDIRECT)) { 804 vsc->sc_driver_features |= VIRTIO_F_RING_INDIRECT_DESC; 805 } else if (guest_feature_names != NULL) { 806 printf(" RingIndirectDesc disabled by UKC"); 807 } 808 809 /* 810 * The driver must add VIRTIO_F_RING_EVENT_IDX if it supports it. 811 * If it did, check if it is disabled by bit 2 in the driver flags. 812 */ 813 if ((vsc->sc_driver_features & VIRTIO_F_RING_EVENT_IDX) && 814 ((vsc->sc_dev.dv_cfdata->cf_flags & VIRTIO_CF_NO_EVENT_IDX) || 815 (vsc->sc_child->dv_cfdata->cf_flags & VIRTIO_CF_NO_EVENT_IDX))) { 816 if (guest_feature_names != NULL) 817 printf(" RingEventIdx disabled by UKC"); 818 vsc->sc_driver_features &= ~VIRTIO_F_RING_EVENT_IDX; 819 } 820 821 if (vsc->sc_version_1) { 822 return virtio_pci_negotiate_features_10(vsc, 823 guest_feature_names); 824 } 825 826 /* virtio 0.9 only */ 827 host = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 828 VIRTIO_CONFIG_DEVICE_FEATURES); 829 negotiated = host & vsc->sc_driver_features; 830 #if VIRTIO_DEBUG 831 if (guest_feature_names) 832 virtio_log_features(host, negotiated, guest_feature_names); 833 #endif 834 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 835 VIRTIO_CONFIG_GUEST_FEATURES, negotiated); 836 vsc->sc_active_features = negotiated; 837 if (negotiated & VIRTIO_F_RING_INDIRECT_DESC) 838 vsc->sc_indirect = 1; 839 else 840 vsc->sc_indirect = 0; 841 return 0; 842 } 843 844 int 845 virtio_pci_negotiate_features_10(struct virtio_softc *vsc, 846 const struct virtio_feature_name *guest_feature_names) 847 { 848 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 849 uint64_t host, negotiated; 850 851 vsc->sc_driver_features |= VIRTIO_F_VERSION_1; 852 /* 853 * XXX Without this SEV doesn't work with a KVM/qemu hypervisor on 854 * XXX amd64. 855 */ 856 vsc->sc_driver_features |= VIRTIO_F_ACCESS_PLATFORM; 857 /* notify on empty is 0.9 only */ 858 vsc->sc_driver_features &= ~VIRTIO_F_NOTIFY_ON_EMPTY; 859 CWRITE(sc, device_feature_select, 0); 860 host = CREAD(sc, device_feature); 861 CWRITE(sc, device_feature_select, 1); 862 host |= (uint64_t)CREAD(sc, device_feature) << 32; 863 864 negotiated = host & vsc->sc_driver_features; 865 #if VIRTIO_DEBUG 866 if (guest_feature_names) 867 virtio_log_features(host, negotiated, guest_feature_names); 868 #endif 869 CWRITE(sc, driver_feature_select, 0); 870 CWRITE(sc, driver_feature, negotiated & 0xffffffff); 871 CWRITE(sc, driver_feature_select, 1); 872 CWRITE(sc, driver_feature, negotiated >> 32); 873 virtio_pci_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_FEATURES_OK); 874 875 if ((CREAD(sc, device_status) & 876 VIRTIO_CONFIG_DEVICE_STATUS_FEATURES_OK) == 0) { 877 printf("%s: Feature negotiation failed\n", 878 vsc->sc_dev.dv_xname); 879 CWRITE(sc, device_status, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 880 return ENXIO; 881 } 882 vsc->sc_active_features = negotiated; 883 884 if (negotiated & VIRTIO_F_RING_INDIRECT_DESC) 885 vsc->sc_indirect = 1; 886 else 887 vsc->sc_indirect = 0; 888 889 if ((negotiated & VIRTIO_F_VERSION_1) == 0) { 890 #if VIRTIO_DEBUG 891 printf("%s: Host rejected Version_1\n", __func__); 892 #endif 893 CWRITE(sc, device_status, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 894 return EINVAL; 895 } 896 return 0; 897 } 898 899 /* 900 * Device configuration registers. 901 */ 902 uint8_t 903 virtio_pci_read_device_config_1(struct virtio_softc *vsc, int index) 904 { 905 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 906 return bus_space_read_1(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index); 907 } 908 909 uint16_t 910 virtio_pci_read_device_config_2(struct virtio_softc *vsc, int index) 911 { 912 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 913 return bus_space_read_2(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index); 914 } 915 916 uint32_t 917 virtio_pci_read_device_config_4(struct virtio_softc *vsc, int index) 918 { 919 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 920 return bus_space_read_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index); 921 } 922 923 uint64_t 924 virtio_pci_read_device_config_8(struct virtio_softc *vsc, int index) 925 { 926 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 927 uint64_t r; 928 929 r = bus_space_read_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, 930 index + sizeof(uint32_t)); 931 r <<= 32; 932 r += bus_space_read_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index); 933 return r; 934 } 935 936 void 937 virtio_pci_write_device_config_1(struct virtio_softc *vsc, int index, 938 uint8_t value) 939 { 940 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 941 bus_space_write_1(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index, value); 942 } 943 944 void 945 virtio_pci_write_device_config_2(struct virtio_softc *vsc, int index, 946 uint16_t value) 947 { 948 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 949 bus_space_write_2(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index, value); 950 } 951 952 void 953 virtio_pci_write_device_config_4(struct virtio_softc *vsc, 954 int index, uint32_t value) 955 { 956 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 957 bus_space_write_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, index, value); 958 } 959 960 void 961 virtio_pci_write_device_config_8(struct virtio_softc *vsc, 962 int index, uint64_t value) 963 { 964 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 965 bus_space_write_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, 966 index, value & 0xffffffff); 967 bus_space_write_4(sc->sc_devcfg_iot, sc->sc_devcfg_ioh, 968 index + sizeof(uint32_t), value >> 32); 969 } 970 971 int 972 virtio_pci_msix_establish(struct virtio_pci_softc *sc, 973 struct virtio_pci_attach_args *vpa, int idx, struct cpu_info *ci, 974 int (*handler)(void *), void *ih_arg) 975 { 976 struct virtio_softc *vsc = &sc->sc_sc; 977 pci_intr_handle_t ih; 978 int r; 979 980 KASSERT(idx < sc->sc_nintr); 981 982 r = pci_intr_map_msix(vpa->vpa_pa, idx, &ih); 983 if (r != 0) { 984 #if VIRTIO_DEBUG 985 printf("%s[%d]: pci_intr_map_msix failed\n", 986 vsc->sc_dev.dv_xname, idx); 987 #endif 988 return r; 989 } 990 snprintf(sc->sc_intr[idx].name, sizeof(sc->sc_intr[idx].name), "%s:%d", 991 vsc->sc_child->dv_xname, idx); 992 sc->sc_intr[idx].ih = pci_intr_establish_cpu(sc->sc_pc, ih, vsc->sc_ipl, 993 ci, handler, ih_arg, sc->sc_intr[idx].name); 994 if (sc->sc_intr[idx].ih == NULL) { 995 printf("%s[%d]: couldn't establish msix interrupt\n", 996 vsc->sc_child->dv_xname, idx); 997 return ENOMEM; 998 } 999 virtio_pci_adjust_config_region(sc, VIRTIO_CONFIG_DEVICE_CONFIG_MSI); 1000 return 0; 1001 } 1002 1003 void 1004 virtio_pci_set_msix_queue_vector(struct virtio_pci_softc *sc, uint32_t idx, uint16_t vector) 1005 { 1006 if (sc->sc_sc.sc_version_1) { 1007 CWRITE(sc, queue_select, idx); 1008 CWRITE(sc, queue_msix_vector, vector); 1009 } else { 1010 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 1011 VIRTIO_CONFIG_QUEUE_SELECT, idx); 1012 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 1013 VIRTIO_MSI_QUEUE_VECTOR, vector); 1014 } 1015 } 1016 1017 void 1018 virtio_pci_set_msix_config_vector(struct virtio_pci_softc *sc, uint16_t vector) 1019 { 1020 if (sc->sc_sc.sc_version_1) { 1021 CWRITE(sc, config_msix_vector, vector); 1022 } else { 1023 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 1024 VIRTIO_MSI_CONFIG_VECTOR, vector); 1025 } 1026 } 1027 1028 1029 void 1030 virtio_pci_free_irqs(struct virtio_pci_softc *sc) 1031 { 1032 struct virtio_softc *vsc = &sc->sc_sc; 1033 int i; 1034 1035 if (sc->sc_devcfg_offset == VIRTIO_CONFIG_DEVICE_CONFIG_MSI) { 1036 for (i = 0; i < vsc->sc_nvqs; i++) { 1037 virtio_pci_set_msix_queue_vector(sc, i, 1038 VIRTIO_MSI_NO_VECTOR); 1039 } 1040 } 1041 1042 for (i = 0; i < sc->sc_nintr; i++) { 1043 if (sc->sc_intr[i].ih) { 1044 pci_intr_disestablish(sc->sc_pc, sc->sc_intr[i].ih); 1045 sc->sc_intr[i].ih = NULL; 1046 } 1047 } 1048 1049 /* XXX msix_delroute does not unset PCI_MSIX_MC_MSIXE -> leave alone? */ 1050 virtio_pci_adjust_config_region(sc, VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI); 1051 } 1052 1053 int 1054 virtio_pci_setup_msix(struct virtio_pci_softc *sc, 1055 struct virtio_pci_attach_args *vpa, int shared) 1056 { 1057 struct virtio_softc *vsc = &sc->sc_sc; 1058 int i, r = 0; 1059 1060 /* Shared needs config + queue */ 1061 if (shared && vpa->vpa_va.va_nintr < 1 + 1) 1062 return ERANGE; 1063 /* Per VQ needs config + N * queue */ 1064 if (!shared && vpa->vpa_va.va_nintr < 1 + vsc->sc_nvqs) 1065 return ERANGE; 1066 1067 r = virtio_pci_msix_establish(sc, vpa, 0, NULL, virtio_pci_config_intr, vsc); 1068 if (r != 0) 1069 return r; 1070 1071 if (shared) { 1072 r = virtio_pci_msix_establish(sc, vpa, 1, NULL, 1073 virtio_pci_shared_queue_intr, vsc); 1074 if (r != 0) 1075 goto fail; 1076 1077 for (i = 0; i < vsc->sc_nvqs; i++) 1078 vsc->sc_vqs[i].vq_intr_vec = 1; 1079 } else { 1080 for (i = 0; i < vsc->sc_nvqs; i++) { 1081 r = virtio_pci_msix_establish(sc, vpa, i + 1, NULL, 1082 virtio_pci_queue_intr, &vsc->sc_vqs[i]); 1083 if (r != 0) 1084 goto fail; 1085 vsc->sc_vqs[i].vq_intr_vec = i + 1; 1086 } 1087 } 1088 1089 return 0; 1090 fail: 1091 virtio_pci_free_irqs(sc); 1092 return r; 1093 } 1094 1095 int 1096 virtio_pci_intr_establish(struct virtio_softc *vsc, 1097 struct virtio_attach_args *va, int vec, struct cpu_info *ci, 1098 int (*func)(void *), void *arg) 1099 { 1100 struct virtio_pci_attach_args *vpa; 1101 struct virtio_pci_softc *sc; 1102 1103 if (vsc->sc_ops != &virtio_pci_ops) 1104 return ENXIO; 1105 1106 vpa = (struct virtio_pci_attach_args *)va; 1107 sc = (struct virtio_pci_softc *)vsc; 1108 1109 if (vec >= sc->sc_nintr || sc->sc_nintr <= 1) 1110 return ERANGE; 1111 1112 sc->sc_irq_type = IRQ_MSIX_CHILD; 1113 return virtio_pci_msix_establish(sc, vpa, vec, ci, func, arg); 1114 } 1115 1116 void 1117 virtio_pci_intr_barrier(struct virtio_softc *vsc) 1118 { 1119 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 1120 int i; 1121 1122 for (i = 0; i < sc->sc_nintr; i++) { 1123 if (sc->sc_intr[i].ih != NULL) 1124 intr_barrier(sc->sc_intr[i].ih); 1125 } 1126 } 1127 1128 /* 1129 * Interrupt handler. 1130 */ 1131 1132 /* 1133 * Only used without MSI-X 1134 */ 1135 int 1136 virtio_pci_legacy_intr(void *arg) 1137 { 1138 struct virtio_pci_softc *sc = arg; 1139 struct virtio_softc *vsc = &sc->sc_sc; 1140 int isr, r = 0; 1141 1142 /* check and ack the interrupt */ 1143 isr = bus_space_read_1(sc->sc_isr_iot, sc->sc_isr_ioh, 0); 1144 if (isr == 0) 1145 return 0; 1146 KERNEL_LOCK(); 1147 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && 1148 (vsc->sc_config_change != NULL)) { 1149 r = (vsc->sc_config_change)(vsc); 1150 } 1151 r |= virtio_check_vqs(vsc); 1152 KERNEL_UNLOCK(); 1153 1154 return r; 1155 } 1156 1157 int 1158 virtio_pci_legacy_intr_mpsafe(void *arg) 1159 { 1160 struct virtio_pci_softc *sc = arg; 1161 struct virtio_softc *vsc = &sc->sc_sc; 1162 int isr, r = 0; 1163 1164 /* check and ack the interrupt */ 1165 isr = bus_space_read_1(sc->sc_isr_iot, sc->sc_isr_ioh, 0); 1166 if (isr == 0) 1167 return 0; 1168 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && 1169 (vsc->sc_config_change != NULL)) { 1170 r = (vsc->sc_config_change)(vsc); 1171 } 1172 r |= virtio_check_vqs(vsc); 1173 return r; 1174 } 1175 1176 /* 1177 * Only used with MSI-X 1178 */ 1179 int 1180 virtio_pci_config_intr(void *arg) 1181 { 1182 struct virtio_softc *vsc = arg; 1183 1184 if (vsc->sc_config_change != NULL) 1185 return vsc->sc_config_change(vsc); 1186 return 0; 1187 } 1188 1189 /* 1190 * Only used with MSI-X 1191 */ 1192 int 1193 virtio_pci_queue_intr(void *arg) 1194 { 1195 struct virtqueue *vq = arg; 1196 struct virtio_softc *vsc = vq->vq_owner; 1197 1198 return virtio_check_vq(vsc, vq); 1199 } 1200 1201 int 1202 virtio_pci_shared_queue_intr(void *arg) 1203 { 1204 struct virtio_softc *vsc = arg; 1205 1206 return virtio_check_vqs(vsc); 1207 } 1208 1209 /* 1210 * Interrupt handler to be used when polling. 1211 * We cannot use isr here because it is not defined in MSI-X mode. 1212 */ 1213 int 1214 virtio_pci_poll_intr(void *arg) 1215 { 1216 struct virtio_pci_softc *sc = arg; 1217 struct virtio_softc *vsc = &sc->sc_sc; 1218 int r = 0; 1219 1220 if (vsc->sc_config_change != NULL) 1221 r = (vsc->sc_config_change)(vsc); 1222 1223 r |= virtio_check_vqs(vsc); 1224 1225 return r; 1226 } 1227 1228 void 1229 virtio_pci_kick(struct virtio_softc *vsc, uint16_t idx) 1230 { 1231 struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; 1232 unsigned offset = 0; 1233 if (vsc->sc_version_1) { 1234 offset = vsc->sc_vqs[idx].vq_notify_off * 1235 sc->sc_notify_off_multiplier; 1236 } 1237 bus_space_write_2(sc->sc_notify_iot, sc->sc_notify_ioh, offset, idx); 1238 } 1239