Home | History | Annotate | Line # | Download | only in pci
ld_virtio.c revision 1.28
      1 /*	$NetBSD: ld_virtio.c,v 1.28 2020/10/24 09:00:35 skrll 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: ld_virtio.c,v 1.28 2020/10/24 09:00:35 skrll Exp $");
     30 
     31 #include <sys/param.h>
     32 #include <sys/systm.h>
     33 #include <sys/kernel.h>
     34 #include <sys/buf.h>
     35 #include <sys/bufq.h>
     36 #include <sys/bus.h>
     37 #include <sys/device.h>
     38 #include <sys/disk.h>
     39 #include <sys/mutex.h>
     40 #include <sys/module.h>
     41 
     42 #include <dev/ldvar.h>
     43 #include <dev/pci/virtioreg.h>
     44 #include <dev/pci/virtiovar.h>
     45 
     46 #include "ioconf.h"
     47 
     48 /*
     49  * ld_virtioreg:
     50  */
     51 /* Configuration registers */
     52 #define VIRTIO_BLK_CONFIG_CAPACITY	0 /* 64bit */
     53 #define VIRTIO_BLK_CONFIG_SIZE_MAX	8 /* 32bit */
     54 #define VIRTIO_BLK_CONFIG_SEG_MAX	12 /* 32bit */
     55 #define VIRTIO_BLK_CONFIG_GEOMETRY_C	16 /* 16bit */
     56 #define VIRTIO_BLK_CONFIG_GEOMETRY_H	18 /* 8bit */
     57 #define VIRTIO_BLK_CONFIG_GEOMETRY_S	19 /* 8bit */
     58 #define VIRTIO_BLK_CONFIG_BLK_SIZE	20 /* 32bit */
     59 #define VIRTIO_BLK_CONFIG_WRITEBACK	32 /* 8bit */
     60 
     61 /* Feature bits */
     62 #define VIRTIO_BLK_F_BARRIER	(1<<0)
     63 #define VIRTIO_BLK_F_SIZE_MAX	(1<<1)
     64 #define VIRTIO_BLK_F_SEG_MAX	(1<<2)
     65 #define VIRTIO_BLK_F_GEOMETRY	(1<<4)
     66 #define VIRTIO_BLK_F_RO		(1<<5)
     67 #define VIRTIO_BLK_F_BLK_SIZE	(1<<6)
     68 #define VIRTIO_BLK_F_SCSI	(1<<7)
     69 #define VIRTIO_BLK_F_FLUSH	(1<<9)
     70 #define VIRTIO_BLK_F_TOPOLOGY	(1<<10)
     71 #define VIRTIO_BLK_F_CONFIG_WCE	(1<<11)
     72 
     73 /*
     74  * Each block request uses at least two segments - one for the header
     75  * and one for the status.
     76 */
     77 #define	VIRTIO_BLK_MIN_SEGMENTS	2
     78 
     79 #define VIRTIO_BLK_FLAG_BITS \
     80 	VIRTIO_COMMON_FLAG_BITS \
     81 	"\x0c""CONFIG_WCE" \
     82 	"\x0b""TOPOLOGY" \
     83 	"\x0a""FLUSH" \
     84 	"\x08""SCSI" \
     85 	"\x07""BLK_SIZE" \
     86 	"\x06""RO" \
     87 	"\x05""GEOMETRY" \
     88 	"\x03""SEG_MAX" \
     89 	"\x02""SIZE_MAX" \
     90 	"\x01""BARRIER"
     91 
     92 /* Command */
     93 #define VIRTIO_BLK_T_IN		0
     94 #define VIRTIO_BLK_T_OUT	1
     95 #define VIRTIO_BLK_T_FLUSH	4
     96 #define VIRTIO_BLK_T_BARRIER	0x80000000
     97 
     98 /* Sector */
     99 #define VIRTIO_BLK_BSIZE	512
    100 
    101 /* Status */
    102 #define VIRTIO_BLK_S_OK		0
    103 #define VIRTIO_BLK_S_IOERR	1
    104 #define VIRTIO_BLK_S_UNSUPP	2
    105 
    106 /* Request header structure */
    107 struct virtio_blk_req_hdr {
    108 	uint32_t	type;	/* VIRTIO_BLK_T_* */
    109 	uint32_t	ioprio;
    110 	uint64_t	sector;
    111 } __packed;
    112 /* payload and 1 byte status follows */
    113 
    114 
    115 /*
    116  * ld_virtiovar:
    117  */
    118 struct virtio_blk_req {
    119 	struct virtio_blk_req_hdr	vr_hdr;
    120 	uint8_t				vr_status;
    121 	struct buf			*vr_bp;
    122 #define DUMMY_VR_BP				((void *)1)
    123 	bus_dmamap_t			vr_cmdsts;
    124 	bus_dmamap_t			vr_payload;
    125 };
    126 
    127 struct ld_virtio_softc {
    128 	struct ld_softc		sc_ld;
    129 	device_t		sc_dev;
    130 
    131 	struct virtio_softc	*sc_virtio;
    132 	struct virtqueue	sc_vq;
    133 
    134 	struct virtio_blk_req	*sc_reqs;
    135 	bus_dma_segment_t	sc_reqs_seg;
    136 
    137 	int			sc_readonly;
    138 
    139 	enum {
    140 		SYNC_FREE, SYNC_BUSY, SYNC_DONE
    141 	}			sc_sync_use;
    142 	kcondvar_t		sc_sync_wait;
    143 	kmutex_t		sc_sync_wait_lock;
    144 	uint8_t			sc_sync_status;
    145 };
    146 
    147 static int	ld_virtio_match(device_t, cfdata_t, void *);
    148 static void	ld_virtio_attach(device_t, device_t, void *);
    149 static int	ld_virtio_detach(device_t, int);
    150 
    151 CFATTACH_DECL_NEW(ld_virtio, sizeof(struct ld_virtio_softc),
    152     ld_virtio_match, ld_virtio_attach, ld_virtio_detach, NULL);
    153 
    154 static int
    155 ld_virtio_match(device_t parent, cfdata_t match, void *aux)
    156 {
    157 	struct virtio_attach_args *va = aux;
    158 
    159 	if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_BLOCK)
    160 		return 1;
    161 
    162 	return 0;
    163 }
    164 
    165 static int ld_virtio_vq_done(struct virtqueue *);
    166 static int ld_virtio_dump(struct ld_softc *, void *, int, int);
    167 static int ld_virtio_start(struct ld_softc *, struct buf *);
    168 static int ld_virtio_ioctl(struct ld_softc *, u_long, void *, int32_t, bool);
    169 
    170 static int
    171 ld_virtio_alloc_reqs(struct ld_virtio_softc *sc, int qsize)
    172 {
    173 	int allocsize, r, rsegs, i;
    174 	struct ld_softc *ld = &sc->sc_ld;
    175 	void *vaddr;
    176 
    177 	allocsize = sizeof(struct virtio_blk_req) * qsize;
    178 	r = bus_dmamem_alloc(virtio_dmat(sc->sc_virtio), allocsize, 0, 0,
    179 			     &sc->sc_reqs_seg, 1, &rsegs, BUS_DMA_WAITOK);
    180 	if (r != 0) {
    181 		aprint_error_dev(sc->sc_dev,
    182 				 "DMA memory allocation failed, size %d, "
    183 				 "error code %d\n", allocsize, r);
    184 		goto err_none;
    185 	}
    186 	r = bus_dmamem_map(virtio_dmat(sc->sc_virtio),
    187 			   &sc->sc_reqs_seg, 1, allocsize,
    188 			   &vaddr, BUS_DMA_WAITOK);
    189 	if (r != 0) {
    190 		aprint_error_dev(sc->sc_dev,
    191 				 "DMA memory map failed, "
    192 				 "error code %d\n", r);
    193 		goto err_dmamem_alloc;
    194 	}
    195 	sc->sc_reqs = vaddr;
    196 	memset(vaddr, 0, allocsize);
    197 	for (i = 0; i < qsize; i++) {
    198 		struct virtio_blk_req *vr = &sc->sc_reqs[i];
    199 		r = bus_dmamap_create(virtio_dmat(sc->sc_virtio),
    200 				      offsetof(struct virtio_blk_req, vr_bp),
    201 				      1,
    202 				      offsetof(struct virtio_blk_req, vr_bp),
    203 				      0,
    204 				      BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW,
    205 				      &vr->vr_cmdsts);
    206 		if (r != 0) {
    207 			aprint_error_dev(sc->sc_dev,
    208 					 "command dmamap creation failed, "
    209 					 "error code %d\n", r);
    210 			goto err_reqs;
    211 		}
    212 		r = bus_dmamap_load(virtio_dmat(sc->sc_virtio), vr->vr_cmdsts,
    213 				    &vr->vr_hdr,
    214 				    offsetof(struct virtio_blk_req, vr_bp),
    215 				    NULL, BUS_DMA_WAITOK);
    216 		if (r != 0) {
    217 			aprint_error_dev(sc->sc_dev,
    218 					 "command dmamap load failed, "
    219 					 "error code %d\n", r);
    220 			goto err_reqs;
    221 		}
    222 		r = bus_dmamap_create(virtio_dmat(sc->sc_virtio),
    223 				      ld->sc_maxxfer,
    224 				      (ld->sc_maxxfer / NBPG) +
    225 				      VIRTIO_BLK_MIN_SEGMENTS,
    226 				      ld->sc_maxxfer,
    227 				      0,
    228 				      BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW,
    229 				      &vr->vr_payload);
    230 		if (r != 0) {
    231 			aprint_error_dev(sc->sc_dev,
    232 					 "payload dmamap creation failed, "
    233 					 "error code %d\n", r);
    234 			goto err_reqs;
    235 		}
    236 	}
    237 	return 0;
    238 
    239 err_reqs:
    240 	for (i = 0; i < qsize; i++) {
    241 		struct virtio_blk_req *vr = &sc->sc_reqs[i];
    242 		if (vr->vr_cmdsts) {
    243 			bus_dmamap_destroy(virtio_dmat(sc->sc_virtio),
    244 					   vr->vr_cmdsts);
    245 			vr->vr_cmdsts = 0;
    246 		}
    247 		if (vr->vr_payload) {
    248 			bus_dmamap_destroy(virtio_dmat(sc->sc_virtio),
    249 					   vr->vr_payload);
    250 			vr->vr_payload = 0;
    251 		}
    252 	}
    253 	bus_dmamem_unmap(virtio_dmat(sc->sc_virtio), sc->sc_reqs, allocsize);
    254 err_dmamem_alloc:
    255 	bus_dmamem_free(virtio_dmat(sc->sc_virtio), &sc->sc_reqs_seg, 1);
    256 err_none:
    257 	return -1;
    258 }
    259 
    260 static void
    261 ld_virtio_attach(device_t parent, device_t self, void *aux)
    262 {
    263 	struct ld_virtio_softc *sc = device_private(self);
    264 	struct ld_softc *ld = &sc->sc_ld;
    265 	struct virtio_softc *vsc = device_private(parent);
    266 	uint32_t features;
    267 	int qsize, maxxfersize, maxnsegs;
    268 
    269 	if (virtio_child(vsc) != NULL) {
    270 		aprint_normal(": child already attached for %s; "
    271 			      "something wrong...\n", device_xname(parent));
    272 		return;
    273 	}
    274 
    275 	sc->sc_dev = self;
    276 	sc->sc_virtio = vsc;
    277 
    278 	virtio_child_attach_start(vsc, self, IPL_BIO, &sc->sc_vq,
    279 	    NULL, virtio_vq_intr, VIRTIO_F_PCI_INTR_MSIX,
    280 	    (VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX |
    281 	     VIRTIO_BLK_F_GEOMETRY | VIRTIO_BLK_F_RO | VIRTIO_BLK_F_BLK_SIZE |
    282 	     VIRTIO_BLK_F_FLUSH | VIRTIO_BLK_F_CONFIG_WCE),
    283 	    VIRTIO_BLK_FLAG_BITS);
    284 
    285 	features = virtio_features(vsc);
    286 
    287 	if (features & VIRTIO_BLK_F_RO)
    288 		sc->sc_readonly = 1;
    289 	else
    290 		sc->sc_readonly = 0;
    291 
    292 	if (features & VIRTIO_BLK_F_BLK_SIZE) {
    293 		ld->sc_secsize = virtio_read_device_config_4(vsc,
    294 					VIRTIO_BLK_CONFIG_BLK_SIZE);
    295 	} else
    296 		ld->sc_secsize = VIRTIO_BLK_BSIZE;
    297 
    298 	/* At least genfs_io assumes maxxfer == MAXPHYS. */
    299 	if (features & VIRTIO_BLK_F_SIZE_MAX) {
    300 		maxxfersize = virtio_read_device_config_4(vsc,
    301 		    VIRTIO_BLK_CONFIG_SIZE_MAX);
    302 		if (maxxfersize < MAXPHYS) {
    303 			aprint_error_dev(sc->sc_dev,
    304 			    "Too small SIZE_MAX %dK minimum is %dK\n",
    305 			    maxxfersize / 1024, MAXPHYS / 1024);
    306 			// goto err;
    307 			maxxfersize = MAXPHYS;
    308 		} else if (maxxfersize > MAXPHYS) {
    309 			aprint_normal_dev(sc->sc_dev,
    310 			    "Clip SEG_MAX from %dK to %dK\n",
    311 			    maxxfersize / 1024,
    312 			    MAXPHYS / 1024);
    313 			maxxfersize = MAXPHYS;
    314 		}
    315 	} else
    316 		maxxfersize = MAXPHYS;
    317 
    318 	if (features & VIRTIO_BLK_F_SEG_MAX) {
    319 		maxnsegs = virtio_read_device_config_4(vsc,
    320 		    VIRTIO_BLK_CONFIG_SEG_MAX);
    321 		if (maxnsegs < VIRTIO_BLK_MIN_SEGMENTS) {
    322 			aprint_error_dev(sc->sc_dev,
    323 			    "Too small SEG_MAX %d minimum is %d\n",
    324 			    maxnsegs, VIRTIO_BLK_MIN_SEGMENTS);
    325 			maxnsegs = maxxfersize / NBPG;
    326 			// goto err;
    327 		}
    328 	} else
    329 		maxnsegs = maxxfersize / NBPG;
    330 
    331 	/* 2 for the minimum size */
    332 	maxnsegs += VIRTIO_BLK_MIN_SEGMENTS;
    333 
    334 	if (virtio_alloc_vq(vsc, &sc->sc_vq, 0, maxxfersize, maxnsegs,
    335 	    "I/O request") != 0) {
    336 		goto err;
    337 	}
    338 	qsize = sc->sc_vq.vq_num;
    339 	sc->sc_vq.vq_done = ld_virtio_vq_done;
    340 
    341 	if (virtio_child_attach_finish(vsc) != 0)
    342 		goto err;
    343 
    344 	ld->sc_dv = self;
    345 	ld->sc_secperunit = virtio_read_device_config_8(vsc,
    346 	    VIRTIO_BLK_CONFIG_CAPACITY) / (ld->sc_secsize / VIRTIO_BLK_BSIZE);
    347 	ld->sc_maxxfer = maxxfersize;
    348 	if (features & VIRTIO_BLK_F_GEOMETRY) {
    349 		ld->sc_ncylinders = virtio_read_device_config_2(vsc,
    350 					VIRTIO_BLK_CONFIG_GEOMETRY_C);
    351 		ld->sc_nheads     = virtio_read_device_config_1(vsc,
    352 					VIRTIO_BLK_CONFIG_GEOMETRY_H);
    353 		ld->sc_nsectors   = virtio_read_device_config_1(vsc,
    354 					VIRTIO_BLK_CONFIG_GEOMETRY_S);
    355 	}
    356 	ld->sc_maxqueuecnt = qsize - 1; /* reserve slot for dumps, flushes */
    357 
    358 	if (ld_virtio_alloc_reqs(sc, qsize) < 0)
    359 		goto err;
    360 
    361 	cv_init(&sc->sc_sync_wait, "vblksync");
    362 	mutex_init(&sc->sc_sync_wait_lock, MUTEX_DEFAULT, IPL_BIO);
    363 	sc->sc_sync_use = SYNC_FREE;
    364 
    365 	ld->sc_dump = ld_virtio_dump;
    366 	ld->sc_start = ld_virtio_start;
    367 	ld->sc_ioctl = ld_virtio_ioctl;
    368 
    369 	ld->sc_flags = LDF_ENABLED | LDF_MPSAFE;
    370 	ldattach(ld, BUFQ_DISK_DEFAULT_STRAT);
    371 
    372 	return;
    373 
    374 err:
    375 	virtio_child_attach_failed(vsc);
    376 	return;
    377 }
    378 
    379 static int
    380 ld_virtio_start(struct ld_softc *ld, struct buf *bp)
    381 {
    382 	/* splbio */
    383 	struct ld_virtio_softc *sc = device_private(ld->sc_dv);
    384 	struct virtio_softc *vsc = sc->sc_virtio;
    385 	struct virtqueue *vq = &sc->sc_vq;
    386 	struct virtio_blk_req *vr;
    387 	int r;
    388 	int isread = (bp->b_flags & B_READ);
    389 	int slot;
    390 
    391 	if (sc->sc_readonly && !isread)
    392 		return EIO;
    393 
    394 	r = virtio_enqueue_prep(vsc, vq, &slot);
    395 	if (r != 0)
    396 		return r;
    397 
    398 	vr = &sc->sc_reqs[slot];
    399 	KASSERT(vr->vr_bp == NULL);
    400 
    401 	r = bus_dmamap_load(virtio_dmat(vsc), vr->vr_payload,
    402 			    bp->b_data, bp->b_bcount, NULL,
    403 			    ((isread?BUS_DMA_READ:BUS_DMA_WRITE)
    404 			     |BUS_DMA_NOWAIT));
    405 	if (r != 0) {
    406 		aprint_error_dev(sc->sc_dev,
    407 		    "payload dmamap failed, error code %d\n", r);
    408 		virtio_enqueue_abort(vsc, vq, slot);
    409 		return r;
    410 	}
    411 
    412 	r = virtio_enqueue_reserve(vsc, vq, slot, vr->vr_payload->dm_nsegs +
    413 	    VIRTIO_BLK_MIN_SEGMENTS);
    414 	if (r != 0) {
    415 		bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload);
    416 		return r;
    417 	}
    418 
    419 	vr->vr_bp = bp;
    420 	vr->vr_hdr.type = isread?VIRTIO_BLK_T_IN:VIRTIO_BLK_T_OUT;
    421 	vr->vr_hdr.ioprio = 0;
    422 	vr->vr_hdr.sector = bp->b_rawblkno * sc->sc_ld.sc_secsize /
    423 	    VIRTIO_BLK_BSIZE;
    424 
    425 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    426 			0, sizeof(struct virtio_blk_req_hdr),
    427 			BUS_DMASYNC_PREWRITE);
    428 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload,
    429 			0, bp->b_bcount,
    430 			isread?BUS_DMASYNC_PREREAD:BUS_DMASYNC_PREWRITE);
    431 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    432 			offsetof(struct virtio_blk_req, vr_status),
    433 			sizeof(uint8_t),
    434 			BUS_DMASYNC_PREREAD);
    435 
    436 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    437 			 0, sizeof(struct virtio_blk_req_hdr),
    438 			 true);
    439 	virtio_enqueue(vsc, vq, slot, vr->vr_payload, !isread);
    440 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    441 			 offsetof(struct virtio_blk_req, vr_status),
    442 			 sizeof(uint8_t),
    443 			 false);
    444 	virtio_enqueue_commit(vsc, vq, slot, true);
    445 
    446 	return 0;
    447 }
    448 
    449 static void
    450 ld_virtio_vq_done1(struct ld_virtio_softc *sc, struct virtio_softc *vsc,
    451 		   struct virtqueue *vq, int slot)
    452 {
    453 	struct virtio_blk_req *vr = &sc->sc_reqs[slot];
    454 	struct buf *bp = vr->vr_bp;
    455 
    456 	vr->vr_bp = NULL;
    457 
    458 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    459 			0, sizeof(struct virtio_blk_req_hdr),
    460 			BUS_DMASYNC_POSTWRITE);
    461 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    462 			sizeof(struct virtio_blk_req_hdr), sizeof(uint8_t),
    463 			BUS_DMASYNC_POSTREAD);
    464 	if (bp == DUMMY_VR_BP) {
    465 		mutex_enter(&sc->sc_sync_wait_lock);
    466 		sc->sc_sync_status = vr->vr_status;
    467 		sc->sc_sync_use = SYNC_DONE;
    468 		cv_broadcast(&sc->sc_sync_wait);
    469 		mutex_exit(&sc->sc_sync_wait_lock);
    470 		virtio_dequeue_commit(vsc, vq, slot);
    471 		return;
    472 	}
    473 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload,
    474 			0, bp->b_bcount,
    475 			(bp->b_flags & B_READ)?BUS_DMASYNC_POSTREAD
    476 					      :BUS_DMASYNC_POSTWRITE);
    477 	bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload);
    478 
    479 	if (vr->vr_status != VIRTIO_BLK_S_OK) {
    480 		bp->b_error = EIO;
    481 		bp->b_resid = bp->b_bcount;
    482 	} else {
    483 		bp->b_error = 0;
    484 		bp->b_resid = 0;
    485 	}
    486 
    487 	virtio_dequeue_commit(vsc, vq, slot);
    488 
    489 	lddone(&sc->sc_ld, bp);
    490 }
    491 
    492 static int
    493 ld_virtio_vq_done(struct virtqueue *vq)
    494 {
    495 	struct virtio_softc *vsc = vq->vq_owner;
    496 	struct ld_virtio_softc *sc = device_private(virtio_child(vsc));
    497 	int r = 0;
    498 	int slot;
    499 
    500 again:
    501 	if (virtio_dequeue(vsc, vq, &slot, NULL))
    502 		return r;
    503 	r = 1;
    504 
    505 	ld_virtio_vq_done1(sc, vsc, vq, slot);
    506 	goto again;
    507 }
    508 
    509 static int
    510 ld_virtio_dump(struct ld_softc *ld, void *data, int blkno, int blkcnt)
    511 {
    512 	struct ld_virtio_softc *sc = device_private(ld->sc_dv);
    513 	struct virtio_softc *vsc = sc->sc_virtio;
    514 	struct virtqueue *vq = &sc->sc_vq;
    515 	struct virtio_blk_req *vr;
    516 	int slot, r;
    517 
    518 	if (sc->sc_readonly)
    519 		return EIO;
    520 
    521 	r = virtio_enqueue_prep(vsc, vq, &slot);
    522 	if (r != 0) {
    523 		if (r == EAGAIN) { /* no free slot; dequeue first */
    524 			delay(100);
    525 			ld_virtio_vq_done(vq);
    526 			r = virtio_enqueue_prep(vsc, vq, &slot);
    527 			if (r != 0)
    528 				return r;
    529 		}
    530 		return r;
    531 	}
    532 	vr = &sc->sc_reqs[slot];
    533 	r = bus_dmamap_load(virtio_dmat(vsc), vr->vr_payload,
    534 			    data, blkcnt*ld->sc_secsize, NULL,
    535 			    BUS_DMA_WRITE|BUS_DMA_NOWAIT);
    536 	if (r != 0)
    537 		return r;
    538 
    539 	r = virtio_enqueue_reserve(vsc, vq, slot, vr->vr_payload->dm_nsegs +
    540 	    VIRTIO_BLK_MIN_SEGMENTS);
    541 	if (r != 0) {
    542 		bus_dmamap_unload(virtio_dmat(vsc), vr->vr_payload);
    543 		return r;
    544 	}
    545 
    546 	vr->vr_bp = (void*)0xdeadbeef;
    547 	vr->vr_hdr.type = VIRTIO_BLK_T_OUT;
    548 	vr->vr_hdr.ioprio = 0;
    549 	vr->vr_hdr.sector = (daddr_t) blkno * ld->sc_secsize /
    550 	    VIRTIO_BLK_BSIZE;
    551 
    552 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    553 			0, sizeof(struct virtio_blk_req_hdr),
    554 			BUS_DMASYNC_PREWRITE);
    555 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload,
    556 			0, blkcnt*ld->sc_secsize,
    557 			BUS_DMASYNC_PREWRITE);
    558 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    559 			offsetof(struct virtio_blk_req, vr_status),
    560 			sizeof(uint8_t),
    561 			BUS_DMASYNC_PREREAD);
    562 
    563 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    564 			 0, sizeof(struct virtio_blk_req_hdr),
    565 			 true);
    566 	virtio_enqueue(vsc, vq, slot, vr->vr_payload, true);
    567 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    568 			 offsetof(struct virtio_blk_req, vr_status),
    569 			 sizeof(uint8_t),
    570 			 false);
    571 	virtio_enqueue_commit(vsc, vq, slot, true);
    572 
    573 	for ( ; ; ) {
    574 		int dslot;
    575 
    576 		r = virtio_dequeue(vsc, vq, &dslot, NULL);
    577 		if (r != 0)
    578 			continue;
    579 		if (dslot != slot) {
    580 			ld_virtio_vq_done1(sc, vsc, vq, dslot);
    581 			continue;
    582 		} else
    583 			break;
    584 	}
    585 
    586 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    587 			0, sizeof(struct virtio_blk_req_hdr),
    588 			BUS_DMASYNC_POSTWRITE);
    589 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_payload,
    590 			0, blkcnt*ld->sc_secsize,
    591 			BUS_DMASYNC_POSTWRITE);
    592 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    593 			offsetof(struct virtio_blk_req, vr_status),
    594 			sizeof(uint8_t),
    595 			BUS_DMASYNC_POSTREAD);
    596 	if (vr->vr_status == VIRTIO_BLK_S_OK)
    597 		r = 0;
    598 	else
    599 		r = EIO;
    600 	virtio_dequeue_commit(vsc, vq, slot);
    601 
    602 	return r;
    603 }
    604 
    605 static int
    606 ld_virtio_detach(device_t self, int flags)
    607 {
    608 	struct ld_virtio_softc *sc = device_private(self);
    609 	struct ld_softc *ld = &sc->sc_ld;
    610 	bus_dma_tag_t dmat = virtio_dmat(sc->sc_virtio);
    611 	int r, i, qsize;
    612 
    613 	qsize = sc->sc_vq.vq_num;
    614 	r = ldbegindetach(ld, flags);
    615 	if (r != 0)
    616 		return r;
    617 	virtio_reset(sc->sc_virtio);
    618 	virtio_free_vq(sc->sc_virtio, &sc->sc_vq);
    619 
    620 	for (i = 0; i < qsize; i++) {
    621 		bus_dmamap_destroy(dmat,
    622 				   sc->sc_reqs[i].vr_cmdsts);
    623 		bus_dmamap_destroy(dmat,
    624 				   sc->sc_reqs[i].vr_payload);
    625 	}
    626 	bus_dmamem_unmap(dmat, sc->sc_reqs,
    627 			 sizeof(struct virtio_blk_req) * qsize);
    628 	bus_dmamem_free(dmat, &sc->sc_reqs_seg, 1);
    629 
    630 	ldenddetach(ld);
    631 
    632 	cv_destroy(&sc->sc_sync_wait);
    633 	mutex_destroy(&sc->sc_sync_wait_lock);
    634 
    635 	virtio_child_detach(sc->sc_virtio);
    636 
    637 	return 0;
    638 }
    639 
    640 static int
    641 ld_virtio_flush(struct ld_softc *ld, bool poll)
    642 {
    643 	struct ld_virtio_softc * const sc = device_private(ld->sc_dv);
    644 	struct virtio_softc * const vsc = sc->sc_virtio;
    645 	const uint32_t features = virtio_features(vsc);
    646 	struct virtqueue *vq = &sc->sc_vq;
    647 	struct virtio_blk_req *vr;
    648 	int slot;
    649 	int r;
    650 
    651 	if ((features & VIRTIO_BLK_F_FLUSH) == 0)
    652 		return 0;
    653 
    654 	mutex_enter(&sc->sc_sync_wait_lock);
    655 	while (sc->sc_sync_use != SYNC_FREE) {
    656 		if (poll) {
    657 			mutex_exit(&sc->sc_sync_wait_lock);
    658 			ld_virtio_vq_done(vq);
    659 			mutex_enter(&sc->sc_sync_wait_lock);
    660 			continue;
    661 		}
    662 		cv_wait(&sc->sc_sync_wait, &sc->sc_sync_wait_lock);
    663 	}
    664 	sc->sc_sync_use = SYNC_BUSY;
    665 	mutex_exit(&sc->sc_sync_wait_lock);
    666 
    667 	r = virtio_enqueue_prep(vsc, vq, &slot);
    668 	if (r != 0) {
    669 		return r;
    670 	}
    671 
    672 	vr = &sc->sc_reqs[slot];
    673 	KASSERT(vr->vr_bp == NULL);
    674 
    675 	r = virtio_enqueue_reserve(vsc, vq, slot, VIRTIO_BLK_MIN_SEGMENTS);
    676 	if (r != 0) {
    677 		return r;
    678 	}
    679 
    680 	vr->vr_bp = DUMMY_VR_BP;
    681 	vr->vr_hdr.type = VIRTIO_BLK_T_FLUSH;
    682 	vr->vr_hdr.ioprio = 0;
    683 	vr->vr_hdr.sector = 0;
    684 
    685 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    686 			0, sizeof(struct virtio_blk_req_hdr),
    687 			BUS_DMASYNC_PREWRITE);
    688 	bus_dmamap_sync(virtio_dmat(vsc), vr->vr_cmdsts,
    689 			offsetof(struct virtio_blk_req, vr_status),
    690 			sizeof(uint8_t),
    691 			BUS_DMASYNC_PREREAD);
    692 
    693 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    694 			 0, sizeof(struct virtio_blk_req_hdr),
    695 			 true);
    696 	virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts,
    697 			 offsetof(struct virtio_blk_req, vr_status),
    698 			 sizeof(uint8_t),
    699 			 false);
    700 	virtio_enqueue_commit(vsc, vq, slot, true);
    701 
    702 	mutex_enter(&sc->sc_sync_wait_lock);
    703 	while (sc->sc_sync_use != SYNC_DONE) {
    704 		if (poll) {
    705 			mutex_exit(&sc->sc_sync_wait_lock);
    706 			ld_virtio_vq_done(vq);
    707 			mutex_enter(&sc->sc_sync_wait_lock);
    708 			continue;
    709 		}
    710 		cv_wait(&sc->sc_sync_wait, &sc->sc_sync_wait_lock);
    711 	}
    712 
    713 	if (sc->sc_sync_status == VIRTIO_BLK_S_OK)
    714 		r = 0;
    715 	else
    716 		r = EIO;
    717 
    718 	sc->sc_sync_use = SYNC_FREE;
    719 	cv_broadcast(&sc->sc_sync_wait);
    720 	mutex_exit(&sc->sc_sync_wait_lock);
    721 
    722 	return r;
    723 }
    724 
    725 static int
    726 ld_virtio_getcache(struct ld_softc *ld, int *bitsp)
    727 {
    728 	struct ld_virtio_softc * const sc = device_private(ld->sc_dv);
    729 	struct virtio_softc * const vsc = sc->sc_virtio;
    730 	const uint32_t features = virtio_features(vsc);
    731 
    732 	*bitsp = DKCACHE_READ;
    733 	if ((features & VIRTIO_BLK_F_CONFIG_WCE) != 0)
    734 		*bitsp |= DKCACHE_WCHANGE;
    735 	if (virtio_read_device_config_1(vsc,
    736 	    VIRTIO_BLK_CONFIG_WRITEBACK) != 0x00)
    737 		*bitsp |= DKCACHE_WRITE;
    738 
    739 	return 0;
    740 }
    741 
    742 static int
    743 ld_virtio_setcache(struct ld_softc *ld, int bits)
    744 {
    745 	struct ld_virtio_softc * const sc = device_private(ld->sc_dv);
    746 	struct virtio_softc * const vsc = sc->sc_virtio;
    747 	const uint8_t wce = (bits & DKCACHE_WRITE) ? 0x01 : 0x00;
    748 
    749 	virtio_write_device_config_1(vsc,
    750 	    VIRTIO_BLK_CONFIG_WRITEBACK, wce);
    751 	if (virtio_read_device_config_1(vsc,
    752 	    VIRTIO_BLK_CONFIG_WRITEBACK) != wce)
    753 		return EIO;
    754 
    755 	return 0;
    756 }
    757 
    758 static int
    759 ld_virtio_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag, bool poll)
    760 {
    761 	int error;
    762 
    763 	switch (cmd) {
    764 	case DIOCCACHESYNC:
    765 		error = ld_virtio_flush(ld, poll);
    766 		break;
    767 
    768 	case DIOCGCACHE:
    769 		error = ld_virtio_getcache(ld, (int *)addr);
    770 		break;
    771 
    772 	case DIOCSCACHE:
    773 		error = ld_virtio_setcache(ld, *(int *)addr);
    774 		break;
    775 
    776 	default:
    777 		error = EPASSTHROUGH;
    778 		break;
    779 	}
    780 
    781 	return error;
    782 }
    783 
    784 MODULE(MODULE_CLASS_DRIVER, ld_virtio, "ld,virtio");
    785 
    786 #ifdef _MODULE
    787 /*
    788  * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_cd"
    789  * XXX it will be defined in the common-code module
    790  */
    791 #undef  CFDRIVER_DECL
    792 #define CFDRIVER_DECL(name, class, attr)
    793 #include "ioconf.c"
    794 #endif
    795 
    796 static int
    797 ld_virtio_modcmd(modcmd_t cmd, void *opaque)
    798 {
    799 #ifdef _MODULE
    800 	/*
    801 	 * We ignore the cfdriver_vec[] that ioconf provides, since
    802 	 * the cfdrivers are attached already.
    803 	 */
    804 	static struct cfdriver * const no_cfdriver_vec[] = { NULL };
    805 #endif
    806 	int error = 0;
    807 
    808 #ifdef _MODULE
    809 	switch (cmd) {
    810 	case MODULE_CMD_INIT:
    811 		error = config_init_component(no_cfdriver_vec,
    812 		    cfattach_ioconf_ld_virtio, cfdata_ioconf_ld_virtio);
    813 		break;
    814 	case MODULE_CMD_FINI:
    815 		error = config_fini_component(no_cfdriver_vec,
    816 		    cfattach_ioconf_ld_virtio, cfdata_ioconf_ld_virtio);
    817 		break;
    818 	default:
    819 		error = ENOTTY;
    820 		break;
    821 	}
    822 #endif
    823 
    824 	return error;
    825 }
    826