virtio.c revision 1.27
1/* $NetBSD: virtio.c,v 1.27 2017/03/28 04:10:33 ozaki-r Exp $ */ 2 3/* 4 * Copyright (c) 2010 Minoura Makoto. 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 ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.27 2017/03/28 04:10:33 ozaki-r Exp $"); 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/atomic.h> 35#include <sys/bus.h> 36#include <sys/device.h> 37#include <sys/kmem.h> 38#include <sys/module.h> 39 40#include <dev/pci/pcidevs.h> 41#include <dev/pci/pcireg.h> 42#include <dev/pci/pcivar.h> 43 44#define VIRTIO_PRIVATE 45 46#include <dev/pci/virtioreg.h> 47#include <dev/pci/virtiovar.h> 48 49#define MINSEG_INDIRECT 2 /* use indirect if nsegs >= this value */ 50 51static int virtio_match(device_t, cfdata_t, void *); 52static void virtio_attach(device_t, device_t, void *); 53static int virtio_rescan(device_t, const char *, const int *); 54static int virtio_detach(device_t, int); 55static int virtio_intr(void *arg); 56static int virtio_msix_queue_intr(void *); 57static int virtio_msix_config_intr(void *); 58static int virtio_setup_msix_vectors(struct virtio_softc *); 59static int virtio_setup_msix_interrupts(struct virtio_softc *, 60 struct pci_attach_args *); 61static int virtio_setup_intx_interrupt(struct virtio_softc *, 62 struct pci_attach_args *); 63static int virtio_setup_interrupts(struct virtio_softc *); 64static void virtio_free_interrupts(struct virtio_softc *); 65static void virtio_soft_intr(void *arg); 66static void virtio_init_vq(struct virtio_softc *, 67 struct virtqueue *, const bool); 68 69CFATTACH_DECL3_NEW(virtio, sizeof(struct virtio_softc), 70 virtio_match, virtio_attach, virtio_detach, NULL, virtio_rescan, NULL, 71 DVF_DETACH_SHUTDOWN); 72 73/* we use the legacy virtio spec, so the pci registers are host native 74 * byte order, not pci (i.e. LE) byte order */ 75static inline uint16_t 76nbo_bus_space_read_2(bus_space_tag_t space, bus_space_handle_t handle, 77 bus_size_t offset) 78{ 79 return le16toh(bus_space_read_2(space, handle, offset)); 80} 81 82static inline uint32_t 83nbo_bus_space_read_4(bus_space_tag_t space, bus_space_handle_t handle, 84 bus_size_t offset) 85{ 86 return le32toh(bus_space_read_4(space, handle, offset)); 87} 88 89static void 90nbo_bus_space_write_2(bus_space_tag_t space, bus_space_handle_t handle, 91 bus_size_t offset, uint16_t value) 92{ 93 bus_space_write_2(space, handle, offset, htole16(value)); 94} 95 96static void 97nbo_bus_space_write_4(bus_space_tag_t space, bus_space_handle_t handle, 98 bus_size_t offset, uint32_t value) 99{ 100 bus_space_write_4(space, handle, offset, htole32(value)); 101} 102 103/* some functions access registers at 4 byte offset for little/high halves */ 104#if BYTE_ORDER == BIG_ENDIAN 105#define REG_HI_OFF 0 106#define REG_LO_OFF 4 107#else 108#define REG_HI_OFF 4 109#define REG_LO_OFF 0 110#endif 111 112static void 113virtio_set_status(struct virtio_softc *sc, int status) 114{ 115 int old = 0; 116 117 if (status != 0) 118 old = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 119 VIRTIO_CONFIG_DEVICE_STATUS); 120 bus_space_write_1(sc->sc_iot, sc->sc_ioh, VIRTIO_CONFIG_DEVICE_STATUS, 121 status|old); 122} 123 124#define virtio_device_reset(sc) virtio_set_status((sc), 0) 125 126static int 127virtio_match(device_t parent, cfdata_t match, void *aux) 128{ 129 struct pci_attach_args *pa; 130 131 pa = (struct pci_attach_args *)aux; 132 switch (PCI_VENDOR(pa->pa_id)) { 133 case PCI_VENDOR_QUMRANET: 134 if ((PCI_PRODUCT_QUMRANET_VIRTIO_1000 <= 135 PCI_PRODUCT(pa->pa_id)) && 136 (PCI_PRODUCT(pa->pa_id) <= 137 PCI_PRODUCT_QUMRANET_VIRTIO_103F)) 138 return 1; 139 break; 140 } 141 142 return 0; 143} 144 145static const char *virtio_device_name[] = { 146 "Unknown (0)", /* 0 */ 147 "Network", /* 1 */ 148 "Block", /* 2 */ 149 "Console", /* 3 */ 150 "Entropy", /* 4 */ 151 "Memory Balloon", /* 5 */ 152 "I/O Memory", /* 6 */ 153 "Remote Processor Messaging", /* 7 */ 154 "SCSI", /* 8 */ 155 "9P Transport", /* 9 */ 156 "mac80211 wlan", /* 10 */ 157}; 158#define NDEVNAMES __arraycount(virtio_device_name) 159 160#define VIRTIO_MSIX_CONFIG_VECTOR_INDEX 0 161#define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1 162 163static int 164virtio_setup_msix_vectors(struct virtio_softc *sc) 165{ 166 int offset, vector, ret, qid; 167 168 offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR; 169 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 170 171 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector); 172 ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset); 173 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n", 174 vector, ret); 175 if (ret != vector) 176 return -1; 177 178 for (qid = 0; qid < sc->sc_nvqs; qid++) { 179 offset = VIRTIO_CONFIG_QUEUE_SELECT; 180 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, qid); 181 182 offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR; 183 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 184 185 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, offset, vector); 186 ret = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, offset); 187 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n", 188 vector, ret); 189 if (ret != vector) 190 return -1; 191 } 192 193 return 0; 194} 195 196static int 197virtio_setup_msix_interrupts(struct virtio_softc *sc, 198 struct pci_attach_args *pa) 199{ 200 device_t self = sc->sc_dev; 201 pci_chipset_tag_t pc = pa->pa_pc; 202 char intrbuf[PCI_INTRSTR_LEN]; 203 char const *intrstr; 204 int idx; 205 206 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 207 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE) 208 pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true); 209 210 sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx], 211 sc->sc_ipl, virtio_msix_config_intr, sc, device_xname(sc->sc_dev)); 212 if (sc->sc_ihs[idx] == NULL) { 213 aprint_error_dev(self, "couldn't establish MSI-X for config\n"); 214 goto error; 215 } 216 217 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 218 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE) 219 pci_intr_setattr(pc, &sc->sc_ihp[idx], PCI_INTR_MPSAFE, true); 220 221 sc->sc_ihs[idx] = pci_intr_establish_xname(pc, sc->sc_ihp[idx], 222 sc->sc_ipl, virtio_msix_queue_intr, sc, device_xname(sc->sc_dev)); 223 if (sc->sc_ihs[idx] == NULL) { 224 aprint_error_dev(self, "couldn't establish MSI-X for queues\n"); 225 goto error; 226 } 227 228 if (virtio_setup_msix_vectors(sc) != 0) { 229 aprint_error_dev(self, "couldn't setup MSI-X vectors\n"); 230 goto error; 231 } 232 233 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 234 intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); 235 aprint_normal_dev(self, "config interrupting at %s\n", intrstr); 236 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 237 intrstr = pci_intr_string(pc, sc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); 238 aprint_normal_dev(self, "queues interrupting at %s\n", intrstr); 239 240 return 0; 241 242error: 243 idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 244 if (sc->sc_ihs[idx] != NULL) 245 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]); 246 idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 247 if (sc->sc_ihs[idx] != NULL) 248 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[idx]); 249 250 return -1; 251} 252 253static int 254virtio_setup_intx_interrupt(struct virtio_softc *sc, 255 struct pci_attach_args *pa) 256{ 257 device_t self = sc->sc_dev; 258 pci_chipset_tag_t pc = pa->pa_pc; 259 char intrbuf[PCI_INTRSTR_LEN]; 260 char const *intrstr; 261 262 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE) 263 pci_intr_setattr(pc, &sc->sc_ihp[0], PCI_INTR_MPSAFE, true); 264 265 sc->sc_ihs[0] = pci_intr_establish_xname(pc, sc->sc_ihp[0], 266 sc->sc_ipl, virtio_intr, sc, device_xname(sc->sc_dev)); 267 if (sc->sc_ihs[0] == NULL) { 268 aprint_error_dev(self, "couldn't establish INTx\n"); 269 return -1; 270 } 271 272 intrstr = pci_intr_string(pc, sc->sc_ihp[0], intrbuf, sizeof(intrbuf)); 273 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 274 275 return 0; 276} 277 278static int 279virtio_setup_interrupts(struct virtio_softc *sc) 280{ 281 device_t self = sc->sc_dev; 282 pci_chipset_tag_t pc = sc->sc_pa.pa_pc; 283 int error; 284 int nmsix; 285 int counts[PCI_INTR_TYPE_SIZE]; 286 pci_intr_type_t max_type; 287 288 nmsix = pci_msix_count(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag); 289 aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix); 290 291 /* We need at least two: one for config and the other for queues */ 292 if ((sc->sc_flags & VIRTIO_F_PCI_INTR_MSIX) == 0 || nmsix < 2) { 293 /* Try INTx only */ 294 max_type = PCI_INTR_TYPE_INTX; 295 counts[PCI_INTR_TYPE_INTX] = 1; 296 } else { 297 /* Try MSI-X first and INTx second */ 298 max_type = PCI_INTR_TYPE_MSIX; 299 counts[PCI_INTR_TYPE_MSIX] = 2; 300 counts[PCI_INTR_TYPE_MSI] = 0; 301 counts[PCI_INTR_TYPE_INTX] = 1; 302 } 303 304 retry: 305 error = pci_intr_alloc(&sc->sc_pa, &sc->sc_ihp, counts, max_type); 306 if (error != 0) { 307 aprint_error_dev(self, "couldn't map interrupt\n"); 308 return -1; 309 } 310 311 if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) { 312 sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 2, 313 KM_SLEEP); 314 if (sc->sc_ihs == NULL) { 315 pci_intr_release(pc, sc->sc_ihp, 2); 316 317 /* Retry INTx */ 318 max_type = PCI_INTR_TYPE_INTX; 319 counts[PCI_INTR_TYPE_INTX] = 1; 320 goto retry; 321 } 322 323 error = virtio_setup_msix_interrupts(sc, &sc->sc_pa); 324 if (error != 0) { 325 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 2); 326 pci_intr_release(pc, sc->sc_ihp, 2); 327 328 /* Retry INTx */ 329 max_type = PCI_INTR_TYPE_INTX; 330 counts[PCI_INTR_TYPE_INTX] = 1; 331 goto retry; 332 } 333 334 sc->sc_ihs_num = 2; 335 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI; 336 } else if (pci_intr_type(pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) { 337 sc->sc_ihs = kmem_alloc(sizeof(*sc->sc_ihs) * 1, 338 KM_SLEEP); 339 if (sc->sc_ihs == NULL) { 340 pci_intr_release(pc, sc->sc_ihp, 1); 341 return -1; 342 } 343 344 error = virtio_setup_intx_interrupt(sc, &sc->sc_pa); 345 if (error != 0) { 346 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * 1); 347 pci_intr_release(pc, sc->sc_ihp, 1); 348 return -1; 349 } 350 351 sc->sc_ihs_num = 1; 352 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; 353 } 354 355 KASSERT(sc->sc_soft_ih == NULL); 356 if (sc->sc_flags & VIRTIO_F_PCI_INTR_SOFTINT) { 357 u_int flags = SOFTINT_NET; 358 if (sc->sc_flags & VIRTIO_F_PCI_INTR_MPSAFE) 359 flags |= SOFTINT_MPSAFE; 360 361 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc); 362 if (sc->sc_soft_ih == NULL) { 363 virtio_free_interrupts(sc); 364 aprint_error_dev(sc->sc_dev, 365 "failed to establish soft interrupt\n"); 366 return -1; 367 } 368 } 369 370 return 0; 371} 372 373static void 374virtio_free_interrupts(struct virtio_softc *sc) 375{ 376 for (int i = 0; i < sc->sc_ihs_num; i++) { 377 if (sc->sc_ihs[i] == NULL) 378 continue; 379 pci_intr_disestablish(sc->sc_pc, sc->sc_ihs[i]); 380 sc->sc_ihs[i] = NULL; 381 } 382 383 if (sc->sc_ihs_num > 0) 384 pci_intr_release(sc->sc_pc, sc->sc_ihp, sc->sc_ihs_num); 385 386 if (sc->sc_soft_ih) { 387 softint_disestablish(sc->sc_soft_ih); 388 sc->sc_soft_ih = NULL; 389 } 390 391 if (sc->sc_ihs != NULL) { 392 kmem_free(sc->sc_ihs, sizeof(*sc->sc_ihs) * sc->sc_ihs_num); 393 sc->sc_ihs = NULL; 394 } 395 sc->sc_ihs_num = 0; 396} 397 398static void 399virtio_attach(device_t parent, device_t self, void *aux) 400{ 401 struct virtio_softc *sc = device_private(self); 402 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 403 pci_chipset_tag_t pc = pa->pa_pc; 404 pcitag_t tag = pa->pa_tag; 405 int revision; 406 pcireg_t id; 407 408 revision = PCI_REVISION(pa->pa_class); 409 if (revision != 0) { 410 aprint_normal(": unknown revision 0x%02x; giving up\n", 411 revision); 412 return; 413 } 414 aprint_normal("\n"); 415 aprint_naive("\n"); 416 417 /* subsystem ID shows what I am */ 418 id = pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG); 419 aprint_normal_dev(self, "Virtio %s Device (rev. 0x%02x)\n", 420 (PCI_SUBSYS_ID(id) < NDEVNAMES? 421 virtio_device_name[PCI_SUBSYS_ID(id)] : "Unknown"), 422 revision); 423 424 sc->sc_dev = self; 425 sc->sc_pc = pc; 426 sc->sc_tag = tag; 427 sc->sc_iot = pa->pa_iot; 428 if (pci_dma64_available(pa)) 429 sc->sc_dmat = pa->pa_dmat64; 430 else 431 sc->sc_dmat = pa->pa_dmat; 432 sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; 433 434 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0, 435 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) { 436 aprint_error_dev(self, "can't map i/o space\n"); 437 return; 438 } 439 440 virtio_device_reset(sc); 441 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 442 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 443 444 sc->sc_childdevid = PCI_SUBSYS_ID(id); 445 sc->sc_child = NULL; 446 sc->sc_pa = *pa; 447 virtio_rescan(self, "virtio", 0); 448 return; 449} 450 451/* ARGSUSED */ 452static int 453virtio_rescan(device_t self, const char *attr, const int *scan_flags) 454{ 455 struct virtio_softc *sc; 456 struct virtio_attach_args va; 457 458 sc = device_private(self); 459 if (sc->sc_child) /* Child already attached? */ 460 return 0; 461 462 memset(&va, 0, sizeof(va)); 463 va.sc_childdevid = sc->sc_childdevid; 464 465 config_found_ia(self, attr, &va, NULL); 466 467 if (sc->sc_child == NULL) { 468 aprint_error_dev(self, 469 "no matching child driver; not configured\n"); 470 return 0; 471 } 472 473 if (sc->sc_child == VIRTIO_CHILD_FAILED) { 474 aprint_error_dev(self, 475 "virtio configuration failed\n"); 476 return 0; 477 } 478 479 /* 480 * Make sure child drivers initialize interrupts via call 481 * to virtio_child_attach_finish(). 482 */ 483 KASSERT(sc->sc_ihs_num != 0); 484 485 return 0; 486} 487 488static int 489virtio_detach(device_t self, int flags) 490{ 491 struct virtio_softc *sc = device_private(self); 492 int r; 493 494 if (sc->sc_child != NULL) { 495 r = config_detach(sc->sc_child, flags); 496 if (r) 497 return r; 498 } 499 500 /* Check that child detached properly */ 501 KASSERT(sc->sc_child == NULL); 502 KASSERT(sc->sc_vqs == NULL); 503 KASSERT(sc->sc_ihs_num == 0); 504 505 if (sc->sc_iosize) 506 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 507 sc->sc_iosize = 0; 508 509 return 0; 510} 511 512/* 513 * Reset the device. 514 */ 515/* 516 * To reset the device to a known state, do following: 517 * virtio_reset(sc); // this will stop the device activity 518 * <dequeue finished requests>; // virtio_dequeue() still can be called 519 * <revoke pending requests in the vqs if any>; 520 * virtio_reinit_begin(sc); // dequeue prohibitted 521 * newfeatures = virtio_negotiate_features(sc, requestedfeatures); 522 * <some other initialization>; 523 * virtio_reinit_end(sc); // device activated; enqueue allowed 524 * Once attached, feature negotiation can only be allowed after virtio_reset. 525 */ 526void 527virtio_reset(struct virtio_softc *sc) 528{ 529 virtio_device_reset(sc); 530} 531 532void 533virtio_reinit_start(struct virtio_softc *sc) 534{ 535 int i; 536 537 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 538 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 539 for (i = 0; i < sc->sc_nvqs; i++) { 540 int n; 541 struct virtqueue *vq = &sc->sc_vqs[i]; 542 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, 543 VIRTIO_CONFIG_QUEUE_SELECT, 544 vq->vq_index); 545 n = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, 546 VIRTIO_CONFIG_QUEUE_SIZE); 547 if (n == 0) /* vq disappeared */ 548 continue; 549 if (n != vq->vq_num) { 550 panic("%s: virtqueue size changed, vq index %d\n", 551 device_xname(sc->sc_dev), 552 vq->vq_index); 553 } 554 virtio_init_vq(sc, vq, true); 555 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 556 VIRTIO_CONFIG_QUEUE_ADDRESS, 557 (vq->vq_dmamap->dm_segs[0].ds_addr 558 / VIRTIO_PAGE_SIZE)); 559 } 560 561 /* MSI-X should have more than one handles where INTx has just one */ 562 if (sc->sc_ihs_num > 1) { 563 if (virtio_setup_msix_vectors(sc) != 0) { 564 aprint_error_dev(sc->sc_dev, 565 "couldn't setup MSI-X vectors\n"); 566 return; 567 } 568 } 569} 570 571void 572virtio_reinit_end(struct virtio_softc *sc) 573{ 574 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 575} 576 577/* 578 * Feature negotiation. 579 */ 580uint32_t 581virtio_negotiate_features(struct virtio_softc *sc, uint32_t guest_features) 582{ 583 uint32_t r; 584 585 if (!(device_cfdata(sc->sc_dev)->cf_flags & 1) && 586 !(device_cfdata(sc->sc_child)->cf_flags & 1)) /* XXX */ 587 guest_features |= VIRTIO_F_RING_INDIRECT_DESC; 588 r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh, 589 VIRTIO_CONFIG_DEVICE_FEATURES); 590 r &= guest_features; 591 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 592 VIRTIO_CONFIG_GUEST_FEATURES, r); 593 sc->sc_features = r; 594 if (r & VIRTIO_F_RING_INDIRECT_DESC) 595 sc->sc_indirect = true; 596 else 597 sc->sc_indirect = false; 598 599 return r; 600} 601 602/* 603 * Device configuration registers. 604 */ 605uint8_t 606virtio_read_device_config_1(struct virtio_softc *sc, int index) 607{ 608 return bus_space_read_1(sc->sc_iot, sc->sc_ioh, 609 sc->sc_config_offset + index); 610} 611 612uint16_t 613virtio_read_device_config_2(struct virtio_softc *sc, int index) 614{ 615 return nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, 616 sc->sc_config_offset + index); 617} 618 619uint32_t 620virtio_read_device_config_4(struct virtio_softc *sc, int index) 621{ 622 return nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh, 623 sc->sc_config_offset + index); 624} 625 626uint64_t 627virtio_read_device_config_8(struct virtio_softc *sc, int index) 628{ 629 uint64_t r; 630 631 r = nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh, 632 sc->sc_config_offset + index + REG_HI_OFF); 633 r <<= 32; 634 r |= nbo_bus_space_read_4(sc->sc_iot, sc->sc_ioh, 635 sc->sc_config_offset + index + REG_LO_OFF); 636 637 return r; 638} 639 640void 641virtio_write_device_config_1(struct virtio_softc *sc, 642 int index, uint8_t value) 643{ 644 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 645 sc->sc_config_offset + index, value); 646} 647 648void 649virtio_write_device_config_2(struct virtio_softc *sc, 650 int index, uint16_t value) 651{ 652 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, 653 sc->sc_config_offset + index, value); 654} 655 656void 657virtio_write_device_config_4(struct virtio_softc *sc, 658 int index, uint32_t value) 659{ 660 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 661 sc->sc_config_offset + index, value); 662} 663 664void 665virtio_write_device_config_8(struct virtio_softc *sc, 666 int index, uint64_t value) 667{ 668 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 669 sc->sc_config_offset + index + REG_LO_OFF, 670 value & 0xffffffff); 671 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 672 sc->sc_config_offset + index + REG_HI_OFF, 673 value >> 32); 674} 675 676/* 677 * Interrupt handler. 678 */ 679static int 680virtio_intr(void *arg) 681{ 682 struct virtio_softc *sc = arg; 683 int isr, r = 0; 684 685 /* check and ack the interrupt */ 686 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 687 VIRTIO_CONFIG_ISR_STATUS); 688 if (isr == 0) 689 return 0; 690 if ((isr & VIRTIO_CONFIG_ISR_CONFIG_CHANGE) && 691 (sc->sc_config_change != NULL)) 692 r = (sc->sc_config_change)(sc); 693 if (sc->sc_intrhand != NULL) { 694 if (sc->sc_soft_ih != NULL) 695 softint_schedule(sc->sc_soft_ih); 696 else 697 r |= (sc->sc_intrhand)(sc); 698 } 699 700 return r; 701} 702 703static int 704virtio_msix_queue_intr(void *arg) 705{ 706 struct virtio_softc *sc = arg; 707 int r = 0; 708 709 if (sc->sc_intrhand != NULL) { 710 if (sc->sc_soft_ih != NULL) 711 softint_schedule(sc->sc_soft_ih); 712 else 713 r |= (sc->sc_intrhand)(sc); 714 } 715 716 return r; 717} 718 719static int 720virtio_msix_config_intr(void *arg) 721{ 722 struct virtio_softc *sc = arg; 723 int r = 0; 724 725 if (sc->sc_config_change != NULL) 726 r = (sc->sc_config_change)(sc); 727 return r; 728} 729 730static void 731virtio_soft_intr(void *arg) 732{ 733 struct virtio_softc *sc = arg; 734 735 KASSERT(sc->sc_intrhand != NULL); 736 737 (sc->sc_intrhand)(sc); 738} 739 740/* 741 * dmamap sync operations for a virtqueue. 742 */ 743static inline void 744vq_sync_descs(struct virtio_softc *sc, struct virtqueue *vq, int ops) 745{ 746 /* availoffset == sizeof(vring_desc)*vq_num */ 747 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, 0, vq->vq_availoffset, 748 ops); 749} 750 751static inline void 752vq_sync_aring(struct virtio_softc *sc, struct virtqueue *vq, int ops) 753{ 754 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, 755 vq->vq_availoffset, 756 offsetof(struct vring_avail, ring) 757 + vq->vq_num * sizeof(uint16_t), 758 ops); 759} 760 761static inline void 762vq_sync_uring(struct virtio_softc *sc, struct virtqueue *vq, int ops) 763{ 764 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, 765 vq->vq_usedoffset, 766 offsetof(struct vring_used, ring) 767 + vq->vq_num * sizeof(struct vring_used_elem), 768 ops); 769} 770 771static inline void 772vq_sync_indirect(struct virtio_softc *sc, struct virtqueue *vq, int slot, 773 int ops) 774{ 775 int offset = vq->vq_indirectoffset 776 + sizeof(struct vring_desc) * vq->vq_maxnsegs * slot; 777 778 bus_dmamap_sync(sc->sc_dmat, vq->vq_dmamap, 779 offset, sizeof(struct vring_desc) * vq->vq_maxnsegs, 780 ops); 781} 782 783/* 784 * Can be used as sc_intrhand. 785 */ 786/* 787 * Scan vq, bus_dmamap_sync for the vqs (not for the payload), 788 * and calls (*vq_done)() if some entries are consumed. 789 */ 790int 791virtio_vq_intr(struct virtio_softc *sc) 792{ 793 struct virtqueue *vq; 794 int i, r = 0; 795 796 for (i = 0; i < sc->sc_nvqs; i++) { 797 vq = &sc->sc_vqs[i]; 798 if (vq->vq_queued) { 799 vq->vq_queued = 0; 800 vq_sync_aring(sc, vq, BUS_DMASYNC_POSTWRITE); 801 } 802 vq_sync_uring(sc, vq, BUS_DMASYNC_POSTREAD); 803 membar_consumer(); 804 if (vq->vq_used_idx != vq->vq_used->idx) { 805 if (vq->vq_done) 806 r |= (vq->vq_done)(vq); 807 } 808 } 809 810 return r; 811} 812 813/* 814 * Start/stop vq interrupt. No guarantee. 815 */ 816void 817virtio_stop_vq_intr(struct virtio_softc *sc, struct virtqueue *vq) 818{ 819 vq->vq_avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; 820 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 821 vq->vq_queued++; 822} 823 824void 825virtio_start_vq_intr(struct virtio_softc *sc, struct virtqueue *vq) 826{ 827 vq->vq_avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; 828 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 829 vq->vq_queued++; 830} 831 832/* 833 * Initialize vq structure. 834 */ 835static void 836virtio_init_vq(struct virtio_softc *sc, struct virtqueue *vq, 837 const bool reinit) 838{ 839 int i, j; 840 int vq_size = vq->vq_num; 841 842 memset(vq->vq_vaddr, 0, vq->vq_bytesize); 843 844 /* build the indirect descriptor chain */ 845 if (vq->vq_indirect != NULL) { 846 struct vring_desc *vd; 847 848 for (i = 0; i < vq_size; i++) { 849 vd = vq->vq_indirect; 850 vd += vq->vq_maxnsegs * i; 851 for (j = 0; j < vq->vq_maxnsegs-1; j++) { 852 vd[j].next = j + 1; 853 } 854 } 855 } 856 857 /* free slot management */ 858 SIMPLEQ_INIT(&vq->vq_freelist); 859 for (i = 0; i < vq_size; i++) { 860 SIMPLEQ_INSERT_TAIL(&vq->vq_freelist, 861 &vq->vq_entries[i], qe_list); 862 vq->vq_entries[i].qe_index = i; 863 } 864 if (!reinit) 865 mutex_init(&vq->vq_freelist_lock, MUTEX_SPIN, sc->sc_ipl); 866 867 /* enqueue/dequeue status */ 868 vq->vq_avail_idx = 0; 869 vq->vq_used_idx = 0; 870 vq->vq_queued = 0; 871 if (!reinit) { 872 mutex_init(&vq->vq_aring_lock, MUTEX_SPIN, sc->sc_ipl); 873 mutex_init(&vq->vq_uring_lock, MUTEX_SPIN, sc->sc_ipl); 874 } 875 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 876 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD); 877 vq->vq_queued++; 878} 879 880/* 881 * Allocate/free a vq. 882 */ 883int 884virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index, 885 int maxsegsize, int maxnsegs, const char *name) 886{ 887 int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0; 888 int rsegs, r; 889#define VIRTQUEUE_ALIGN(n) (((n)+(VIRTIO_PAGE_SIZE-1))& \ 890 ~(VIRTIO_PAGE_SIZE-1)) 891 892 /* Make sure callers allocate vqs in order */ 893 KASSERT(sc->sc_nvqs == index); 894 895 memset(vq, 0, sizeof(*vq)); 896 897 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, 898 VIRTIO_CONFIG_QUEUE_SELECT, index); 899 vq_size = nbo_bus_space_read_2(sc->sc_iot, sc->sc_ioh, 900 VIRTIO_CONFIG_QUEUE_SIZE); 901 if (vq_size == 0) { 902 aprint_error_dev(sc->sc_dev, 903 "virtqueue not exist, index %d for %s\n", 904 index, name); 905 goto err; 906 } 907 /* allocsize1: descriptor table + avail ring + pad */ 908 allocsize1 = VIRTQUEUE_ALIGN(sizeof(struct vring_desc)*vq_size 909 + sizeof(uint16_t)*(2+vq_size)); 910 /* allocsize2: used ring + pad */ 911 allocsize2 = VIRTQUEUE_ALIGN(sizeof(uint16_t)*2 912 + sizeof(struct vring_used_elem)*vq_size); 913 /* allocsize3: indirect table */ 914 if (sc->sc_indirect && maxnsegs >= MINSEG_INDIRECT) 915 allocsize3 = sizeof(struct vring_desc) * maxnsegs * vq_size; 916 else 917 allocsize3 = 0; 918 allocsize = allocsize1 + allocsize2 + allocsize3; 919 920 /* alloc and map the memory */ 921 r = bus_dmamem_alloc(sc->sc_dmat, allocsize, VIRTIO_PAGE_SIZE, 0, 922 &vq->vq_segs[0], 1, &rsegs, BUS_DMA_NOWAIT); 923 if (r != 0) { 924 aprint_error_dev(sc->sc_dev, 925 "virtqueue %d for %s allocation failed, " 926 "error code %d\n", index, name, r); 927 goto err; 928 } 929 r = bus_dmamem_map(sc->sc_dmat, &vq->vq_segs[0], 1, allocsize, 930 &vq->vq_vaddr, BUS_DMA_NOWAIT); 931 if (r != 0) { 932 aprint_error_dev(sc->sc_dev, 933 "virtqueue %d for %s map failed, " 934 "error code %d\n", index, name, r); 935 goto err; 936 } 937 r = bus_dmamap_create(sc->sc_dmat, allocsize, 1, allocsize, 0, 938 BUS_DMA_NOWAIT, &vq->vq_dmamap); 939 if (r != 0) { 940 aprint_error_dev(sc->sc_dev, 941 "virtqueue %d for %s dmamap creation failed, " 942 "error code %d\n", index, name, r); 943 goto err; 944 } 945 r = bus_dmamap_load(sc->sc_dmat, vq->vq_dmamap, 946 vq->vq_vaddr, allocsize, NULL, BUS_DMA_NOWAIT); 947 if (r != 0) { 948 aprint_error_dev(sc->sc_dev, 949 "virtqueue %d for %s dmamap load failed, " 950 "error code %d\n", index, name, r); 951 goto err; 952 } 953 954 /* set the vq address */ 955 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 956 VIRTIO_CONFIG_QUEUE_ADDRESS, 957 (vq->vq_dmamap->dm_segs[0].ds_addr 958 / VIRTIO_PAGE_SIZE)); 959 960 /* remember addresses and offsets for later use */ 961 vq->vq_owner = sc; 962 vq->vq_num = vq_size; 963 vq->vq_index = index; 964 vq->vq_desc = vq->vq_vaddr; 965 vq->vq_availoffset = sizeof(struct vring_desc)*vq_size; 966 vq->vq_avail = (void*)(((char*)vq->vq_desc) + vq->vq_availoffset); 967 vq->vq_usedoffset = allocsize1; 968 vq->vq_used = (void*)(((char*)vq->vq_desc) + vq->vq_usedoffset); 969 if (allocsize3 > 0) { 970 vq->vq_indirectoffset = allocsize1 + allocsize2; 971 vq->vq_indirect = (void*)(((char*)vq->vq_desc) 972 + vq->vq_indirectoffset); 973 } 974 vq->vq_bytesize = allocsize; 975 vq->vq_maxsegsize = maxsegsize; 976 vq->vq_maxnsegs = maxnsegs; 977 978 /* free slot management */ 979 vq->vq_entries = kmem_zalloc(sizeof(struct vq_entry)*vq_size, 980 KM_NOSLEEP); 981 if (vq->vq_entries == NULL) { 982 r = ENOMEM; 983 goto err; 984 } 985 986 virtio_init_vq(sc, vq, false); 987 988 aprint_verbose_dev(sc->sc_dev, 989 "allocated %u byte for virtqueue %d for %s, " 990 "size %d\n", allocsize, index, name, vq_size); 991 if (allocsize3 > 0) 992 aprint_verbose_dev(sc->sc_dev, 993 "using %d byte (%d entries) " 994 "indirect descriptors\n", 995 allocsize3, maxnsegs * vq_size); 996 997 sc->sc_nvqs++; 998 999 return 0; 1000 1001err: 1002 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 1003 VIRTIO_CONFIG_QUEUE_ADDRESS, 0); 1004 if (vq->vq_dmamap) 1005 bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); 1006 if (vq->vq_vaddr) 1007 bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, allocsize); 1008 if (vq->vq_segs[0].ds_addr) 1009 bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); 1010 memset(vq, 0, sizeof(*vq)); 1011 1012 return -1; 1013} 1014 1015int 1016virtio_free_vq(struct virtio_softc *sc, struct virtqueue *vq) 1017{ 1018 struct vq_entry *qe; 1019 int i = 0; 1020 1021 /* device must be already deactivated */ 1022 /* confirm the vq is empty */ 1023 SIMPLEQ_FOREACH(qe, &vq->vq_freelist, qe_list) { 1024 i++; 1025 } 1026 if (i != vq->vq_num) { 1027 printf("%s: freeing non-empty vq, index %d\n", 1028 device_xname(sc->sc_dev), vq->vq_index); 1029 return EBUSY; 1030 } 1031 1032 /* tell device that there's no virtqueue any longer */ 1033 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, 1034 VIRTIO_CONFIG_QUEUE_SELECT, vq->vq_index); 1035 nbo_bus_space_write_4(sc->sc_iot, sc->sc_ioh, 1036 VIRTIO_CONFIG_QUEUE_ADDRESS, 0); 1037 1038 kmem_free(vq->vq_entries, sizeof(*vq->vq_entries) * vq->vq_num); 1039 bus_dmamap_unload(sc->sc_dmat, vq->vq_dmamap); 1040 bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); 1041 bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, vq->vq_bytesize); 1042 bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); 1043 mutex_destroy(&vq->vq_freelist_lock); 1044 mutex_destroy(&vq->vq_uring_lock); 1045 mutex_destroy(&vq->vq_aring_lock); 1046 memset(vq, 0, sizeof(*vq)); 1047 1048 sc->sc_nvqs--; 1049 1050 return 0; 1051} 1052 1053/* 1054 * Free descriptor management. 1055 */ 1056static struct vq_entry * 1057vq_alloc_entry(struct virtqueue *vq) 1058{ 1059 struct vq_entry *qe; 1060 1061 mutex_enter(&vq->vq_freelist_lock); 1062 if (SIMPLEQ_EMPTY(&vq->vq_freelist)) { 1063 mutex_exit(&vq->vq_freelist_lock); 1064 return NULL; 1065 } 1066 qe = SIMPLEQ_FIRST(&vq->vq_freelist); 1067 SIMPLEQ_REMOVE_HEAD(&vq->vq_freelist, qe_list); 1068 mutex_exit(&vq->vq_freelist_lock); 1069 1070 return qe; 1071} 1072 1073static void 1074vq_free_entry(struct virtqueue *vq, struct vq_entry *qe) 1075{ 1076 mutex_enter(&vq->vq_freelist_lock); 1077 SIMPLEQ_INSERT_TAIL(&vq->vq_freelist, qe, qe_list); 1078 mutex_exit(&vq->vq_freelist_lock); 1079 1080 return; 1081} 1082 1083/* 1084 * Enqueue several dmamaps as a single request. 1085 */ 1086/* 1087 * Typical usage: 1088 * <queue size> number of followings are stored in arrays 1089 * - command blocks (in dmamem) should be pre-allocated and mapped 1090 * - dmamaps for command blocks should be pre-allocated and loaded 1091 * - dmamaps for payload should be pre-allocated 1092 * r = virtio_enqueue_prep(sc, vq, &slot); // allocate a slot 1093 * if (r) // currently 0 or EAGAIN 1094 * return r; 1095 * r = bus_dmamap_load(dmat, dmamap_payload[slot], data, count, ..); 1096 * if (r) { 1097 * virtio_enqueue_abort(sc, vq, slot); 1098 * return r; 1099 * } 1100 * r = virtio_enqueue_reserve(sc, vq, slot, 1101 * dmamap_payload[slot]->dm_nsegs+1); 1102 * // ^ +1 for command 1103 * if (r) { // currently 0 or EAGAIN 1104 * bus_dmamap_unload(dmat, dmamap_payload[slot]); 1105 * return r; // do not call abort() 1106 * } 1107 * <setup and prepare commands> 1108 * bus_dmamap_sync(dmat, dmamap_cmd[slot],... BUS_DMASYNC_PREWRITE); 1109 * bus_dmamap_sync(dmat, dmamap_payload[slot],...); 1110 * virtio_enqueue(sc, vq, slot, dmamap_cmd[slot], false); 1111 * virtio_enqueue(sc, vq, slot, dmamap_payload[slot], iswrite); 1112 * virtio_enqueue_commit(sc, vq, slot, true); 1113 */ 1114 1115/* 1116 * enqueue_prep: allocate a slot number 1117 */ 1118int 1119virtio_enqueue_prep(struct virtio_softc *sc, struct virtqueue *vq, int *slotp) 1120{ 1121 struct vq_entry *qe1; 1122 1123 KASSERT(slotp != NULL); 1124 1125 qe1 = vq_alloc_entry(vq); 1126 if (qe1 == NULL) 1127 return EAGAIN; 1128 /* next slot is not allocated yet */ 1129 qe1->qe_next = -1; 1130 *slotp = qe1->qe_index; 1131 1132 return 0; 1133} 1134 1135/* 1136 * enqueue_reserve: allocate remaining slots and build the descriptor chain. 1137 */ 1138int 1139virtio_enqueue_reserve(struct virtio_softc *sc, struct virtqueue *vq, 1140 int slot, int nsegs) 1141{ 1142 int indirect; 1143 struct vq_entry *qe1 = &vq->vq_entries[slot]; 1144 1145 KASSERT(qe1->qe_next == -1); 1146 KASSERT(1 <= nsegs && nsegs <= vq->vq_num); 1147 1148 if ((vq->vq_indirect != NULL) && 1149 (nsegs >= MINSEG_INDIRECT) && 1150 (nsegs <= vq->vq_maxnsegs)) 1151 indirect = 1; 1152 else 1153 indirect = 0; 1154 qe1->qe_indirect = indirect; 1155 1156 if (indirect) { 1157 struct vring_desc *vd; 1158 int i; 1159 1160 vd = &vq->vq_desc[qe1->qe_index]; 1161 vd->addr = vq->vq_dmamap->dm_segs[0].ds_addr 1162 + vq->vq_indirectoffset; 1163 vd->addr += sizeof(struct vring_desc) 1164 * vq->vq_maxnsegs * qe1->qe_index; 1165 vd->len = sizeof(struct vring_desc) * nsegs; 1166 vd->flags = VRING_DESC_F_INDIRECT; 1167 1168 vd = vq->vq_indirect; 1169 vd += vq->vq_maxnsegs * qe1->qe_index; 1170 qe1->qe_desc_base = vd; 1171 1172 for (i = 0; i < nsegs-1; i++) { 1173 vd[i].flags = VRING_DESC_F_NEXT; 1174 } 1175 vd[i].flags = 0; 1176 qe1->qe_next = 0; 1177 1178 return 0; 1179 } else { 1180 struct vring_desc *vd; 1181 struct vq_entry *qe; 1182 int i, s; 1183 1184 vd = &vq->vq_desc[0]; 1185 qe1->qe_desc_base = vd; 1186 qe1->qe_next = qe1->qe_index; 1187 s = slot; 1188 for (i = 0; i < nsegs - 1; i++) { 1189 qe = vq_alloc_entry(vq); 1190 if (qe == NULL) { 1191 vd[s].flags = 0; 1192 virtio_enqueue_abort(sc, vq, slot); 1193 return EAGAIN; 1194 } 1195 vd[s].flags = VRING_DESC_F_NEXT; 1196 vd[s].next = qe->qe_index; 1197 s = qe->qe_index; 1198 } 1199 vd[s].flags = 0; 1200 1201 return 0; 1202 } 1203} 1204 1205/* 1206 * enqueue: enqueue a single dmamap. 1207 */ 1208int 1209virtio_enqueue(struct virtio_softc *sc, struct virtqueue *vq, int slot, 1210 bus_dmamap_t dmamap, bool write) 1211{ 1212 struct vq_entry *qe1 = &vq->vq_entries[slot]; 1213 struct vring_desc *vd = qe1->qe_desc_base; 1214 int i; 1215 int s = qe1->qe_next; 1216 1217 KASSERT(s >= 0); 1218 KASSERT(dmamap->dm_nsegs > 0); 1219 1220 for (i = 0; i < dmamap->dm_nsegs; i++) { 1221 vd[s].addr = dmamap->dm_segs[i].ds_addr; 1222 vd[s].len = dmamap->dm_segs[i].ds_len; 1223 if (!write) 1224 vd[s].flags |= VRING_DESC_F_WRITE; 1225 s = vd[s].next; 1226 } 1227 qe1->qe_next = s; 1228 1229 return 0; 1230} 1231 1232int 1233virtio_enqueue_p(struct virtio_softc *sc, struct virtqueue *vq, int slot, 1234 bus_dmamap_t dmamap, bus_addr_t start, bus_size_t len, 1235 bool write) 1236{ 1237 struct vq_entry *qe1 = &vq->vq_entries[slot]; 1238 struct vring_desc *vd = qe1->qe_desc_base; 1239 int s = qe1->qe_next; 1240 1241 KASSERT(s >= 0); 1242 KASSERT(dmamap->dm_nsegs == 1); /* XXX */ 1243 KASSERT((dmamap->dm_segs[0].ds_len > start) && 1244 (dmamap->dm_segs[0].ds_len >= start + len)); 1245 1246 vd[s].addr = dmamap->dm_segs[0].ds_addr + start; 1247 vd[s].len = len; 1248 if (!write) 1249 vd[s].flags |= VRING_DESC_F_WRITE; 1250 qe1->qe_next = vd[s].next; 1251 1252 return 0; 1253} 1254 1255/* 1256 * enqueue_commit: add it to the aring. 1257 */ 1258int 1259virtio_enqueue_commit(struct virtio_softc *sc, struct virtqueue *vq, int slot, 1260 bool notifynow) 1261{ 1262 struct vq_entry *qe1; 1263 1264 if (slot < 0) { 1265 mutex_enter(&vq->vq_aring_lock); 1266 goto notify; 1267 } 1268 vq_sync_descs(sc, vq, BUS_DMASYNC_PREWRITE); 1269 qe1 = &vq->vq_entries[slot]; 1270 if (qe1->qe_indirect) 1271 vq_sync_indirect(sc, vq, slot, BUS_DMASYNC_PREWRITE); 1272 mutex_enter(&vq->vq_aring_lock); 1273 vq->vq_avail->ring[(vq->vq_avail_idx++) % vq->vq_num] = slot; 1274 1275notify: 1276 if (notifynow) { 1277 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 1278 vq_sync_uring(sc, vq, BUS_DMASYNC_PREREAD); 1279 membar_producer(); 1280 vq->vq_avail->idx = vq->vq_avail_idx; 1281 vq_sync_aring(sc, vq, BUS_DMASYNC_PREWRITE); 1282 membar_producer(); 1283 vq->vq_queued++; 1284 vq_sync_uring(sc, vq, BUS_DMASYNC_POSTREAD); 1285 membar_consumer(); 1286 if (!(vq->vq_used->flags & VRING_USED_F_NO_NOTIFY)) 1287 nbo_bus_space_write_2(sc->sc_iot, sc->sc_ioh, 1288 VIRTIO_CONFIG_QUEUE_NOTIFY, 1289 vq->vq_index); 1290 } 1291 mutex_exit(&vq->vq_aring_lock); 1292 1293 return 0; 1294} 1295 1296/* 1297 * enqueue_abort: rollback. 1298 */ 1299int 1300virtio_enqueue_abort(struct virtio_softc *sc, struct virtqueue *vq, int slot) 1301{ 1302 struct vq_entry *qe = &vq->vq_entries[slot]; 1303 struct vring_desc *vd; 1304 int s; 1305 1306 if (qe->qe_next < 0) { 1307 vq_free_entry(vq, qe); 1308 return 0; 1309 } 1310 1311 s = slot; 1312 vd = &vq->vq_desc[0]; 1313 while (vd[s].flags & VRING_DESC_F_NEXT) { 1314 s = vd[s].next; 1315 vq_free_entry(vq, qe); 1316 qe = &vq->vq_entries[s]; 1317 } 1318 vq_free_entry(vq, qe); 1319 return 0; 1320} 1321 1322/* 1323 * Dequeue a request. 1324 */ 1325/* 1326 * dequeue: dequeue a request from uring; dmamap_sync for uring is 1327 * already done in the interrupt handler. 1328 */ 1329int 1330virtio_dequeue(struct virtio_softc *sc, struct virtqueue *vq, 1331 int *slotp, int *lenp) 1332{ 1333 uint16_t slot, usedidx; 1334 struct vq_entry *qe; 1335 1336 if (vq->vq_used_idx == vq->vq_used->idx) 1337 return ENOENT; 1338 mutex_enter(&vq->vq_uring_lock); 1339 usedidx = vq->vq_used_idx++; 1340 mutex_exit(&vq->vq_uring_lock); 1341 usedidx %= vq->vq_num; 1342 slot = vq->vq_used->ring[usedidx].id; 1343 qe = &vq->vq_entries[slot]; 1344 1345 if (qe->qe_indirect) 1346 vq_sync_indirect(sc, vq, slot, BUS_DMASYNC_POSTWRITE); 1347 1348 if (slotp) 1349 *slotp = slot; 1350 if (lenp) 1351 *lenp = vq->vq_used->ring[usedidx].len; 1352 1353 return 0; 1354} 1355 1356/* 1357 * dequeue_commit: complete dequeue; the slot is recycled for future use. 1358 * if you forget to call this the slot will be leaked. 1359 */ 1360int 1361virtio_dequeue_commit(struct virtio_softc *sc, struct virtqueue *vq, int slot) 1362{ 1363 struct vq_entry *qe = &vq->vq_entries[slot]; 1364 struct vring_desc *vd = &vq->vq_desc[0]; 1365 int s = slot; 1366 1367 while (vd[s].flags & VRING_DESC_F_NEXT) { 1368 s = vd[s].next; 1369 vq_free_entry(vq, qe); 1370 qe = &vq->vq_entries[s]; 1371 } 1372 vq_free_entry(vq, qe); 1373 1374 return 0; 1375} 1376 1377/* 1378 * Attach a child, fill all the members. 1379 */ 1380void 1381virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl, 1382 struct virtqueue *vqs, 1383 virtio_callback config_change, 1384 virtio_callback intr_hand, 1385 int req_flags, int req_features, const char *feat_bits) 1386{ 1387 char buf[256]; 1388 int features; 1389 1390 sc->sc_child = child; 1391 sc->sc_ipl = ipl; 1392 sc->sc_vqs = vqs; 1393 sc->sc_config_change = config_change; 1394 sc->sc_intrhand = intr_hand; 1395 sc->sc_flags = req_flags; 1396 1397 features = virtio_negotiate_features(sc, req_features); 1398 snprintb(buf, sizeof(buf), feat_bits, features); 1399 aprint_normal(": Features: %s\n", buf); 1400 aprint_naive("\n"); 1401} 1402 1403int 1404virtio_child_attach_finish(struct virtio_softc *sc) 1405{ 1406 int r; 1407 1408 r = virtio_setup_interrupts(sc); 1409 if (r != 0) { 1410 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n"); 1411 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 1412 return 1; 1413 } 1414 1415 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 1416 1417 return 0; 1418} 1419 1420void 1421virtio_child_detach(struct virtio_softc *sc) 1422{ 1423 sc->sc_child = NULL; 1424 sc->sc_vqs = NULL; 1425 1426 virtio_device_reset(sc); 1427 1428 virtio_free_interrupts(sc); 1429} 1430 1431void 1432virtio_child_attach_failed(struct virtio_softc *sc) 1433{ 1434 virtio_child_detach(sc); 1435 1436 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); 1437 1438 sc->sc_child = VIRTIO_CHILD_FAILED; 1439} 1440 1441bus_dma_tag_t 1442virtio_dmat(struct virtio_softc *sc) 1443{ 1444 return sc->sc_dmat; 1445} 1446 1447device_t 1448virtio_child(struct virtio_softc *sc) 1449{ 1450 return sc->sc_child; 1451} 1452 1453int 1454virtio_intrhand(struct virtio_softc *sc) 1455{ 1456 return (sc->sc_intrhand)(sc); 1457} 1458 1459uint32_t 1460virtio_features(struct virtio_softc *sc) 1461{ 1462 return sc->sc_features; 1463} 1464 1465MODULE(MODULE_CLASS_DRIVER, virtio, "pci"); 1466 1467#ifdef _MODULE 1468#include "ioconf.c" 1469#endif 1470 1471static int 1472virtio_modcmd(modcmd_t cmd, void *opaque) 1473{ 1474 int error = 0; 1475 1476#ifdef _MODULE 1477 switch (cmd) { 1478 case MODULE_CMD_INIT: 1479 error = config_init_component(cfdriver_ioconf_virtio, 1480 cfattach_ioconf_virtio, cfdata_ioconf_virtio); 1481 break; 1482 case MODULE_CMD_FINI: 1483 error = config_fini_component(cfdriver_ioconf_virtio, 1484 cfattach_ioconf_virtio, cfdata_ioconf_virtio); 1485 break; 1486 default: 1487 error = ENOTTY; 1488 break; 1489 } 1490#endif 1491 1492 return error; 1493} 1494