xref: /openbsd/sys/arch/sparc64/dev/vdsk.c (revision 404b540a)
1 /*	$OpenBSD: vdsk.c,v 1.12 2009/05/12 20:20:35 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2009 Mark Kettenis
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/buf.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 #include <sys/systm.h>
23 
24 #include <machine/autoconf.h>
25 #include <machine/hypervisor.h>
26 
27 #include <uvm/uvm.h>
28 
29 #include <scsi/scsi_all.h>
30 #include <scsi/scsi_disk.h>
31 #include <scsi/scsiconf.h>
32 
33 #include <sparc64/dev/cbusvar.h>
34 #include <sparc64/dev/ldcvar.h>
35 #include <sparc64/dev/viovar.h>
36 
37 #ifdef VDSK_DEBUG
38 #define DPRINTF(x)	printf x
39 #else
40 #define DPRINTF(x)
41 #endif
42 
43 #define VDSK_TX_ENTRIES		32
44 #define VDSK_RX_ENTRIES		32
45 
46 struct vd_attr_info {
47 	struct vio_msg_tag	tag;
48 	uint8_t			xfer_mode;
49 	uint8_t			vd_type;
50 	uint8_t			vd_mtype;
51 	uint8_t			_reserved1;
52 	uint32_t		vdisk_block_size;
53 	uint64_t		operations;
54 	uint64_t		vdisk_size;
55 	uint64_t		max_xfer_sz;
56 	uint64_t		_reserved2[2];
57 };
58 
59 #define VD_DISK_TYPE_SLICE	0x01
60 #define VD_DISK_TYPE_DISK	0x02
61 
62 #define VD_MEDIA_TYPE_FIXED	0x01
63 #define VD_MEDIA_TYPE_CD	0x02
64 #define VD_MEDIA_TYPE_DVD	0x03
65 
66 /* vDisk version 1.0. */
67 #define VD_OP_BREAD		0x01
68 #define VD_OP_BWRITE		0x02
69 #define VD_OP_FLUSH		0x03
70 #define VD_OP_GET_WCE		0x04
71 #define VD_OP_SET_WCE		0x05
72 #define VD_OP_GET_VTOC		0x06
73 #define VD_OP_SET_VTOC		0x07
74 #define VD_OP_GET_DISKGEOM	0x08
75 #define VD_OP_SET_DISKGEOM	0x09
76 #define VD_OP_GET_DEVID		0x0b
77 #define VD_OP_GET_EFI		0x0c
78 #define VD_OP_SET_EFI		0x0d
79 
80 /* vDisk version 1.1 */
81 #define VD_OP_SCSICMD		0x0a
82 #define VD_OP_RESET		0x0e
83 #define VD_OP_GET_ACCESS	0x0f
84 #define VD_OP_SET_ACCESS	0x10
85 #define VD_OP_GET_CAPACITY	0x11
86 
87 struct vd_desc {
88 	struct vio_dring_hdr	hdr;
89 	uint64_t		req_id;
90 	uint8_t			operation;
91 	uint8_t			slice;
92 	uint16_t		_reserved1;
93 	uint32_t		status;
94 	uint64_t		offset;
95 	uint64_t		size;
96 	uint32_t		ncookies;
97 	uint32_t		_reserved2;
98 	struct ldc_cookie	cookie[MAXPHYS / PAGE_SIZE];
99 };
100 
101 #define VD_SLICE_NONE		0xff
102 
103 struct vdsk_dring {
104 	bus_dmamap_t		vd_map;
105 	bus_dma_segment_t	vd_seg;
106 	struct vd_desc		*vd_desc;
107 	int			vd_nentries;
108 };
109 
110 struct vdsk_dring *vdsk_dring_alloc(bus_dma_tag_t, int);
111 void	vdsk_dring_free(bus_dma_tag_t, struct vdsk_dring *);
112 
113 /*
114  * For now, we only support vDisk 1.0.
115  */
116 #define VDSK_MAJOR	1
117 #define VDSK_MINOR	0
118 
119 struct vdsk_soft_desc {
120 	int		vsd_map_idx[MAXPHYS / PAGE_SIZE];
121 	struct scsi_xfer *vsd_xs;
122 };
123 
124 struct vdsk_softc {
125 	struct device	sc_dv;
126 	bus_space_tag_t	sc_bustag;
127 	bus_dma_tag_t	sc_dmatag;
128 
129 	void		*sc_tx_ih;
130 	void		*sc_rx_ih;
131 
132 	struct ldc_conn	sc_lc;
133 
134 	uint16_t	sc_vio_state;
135 #define VIO_SND_VER_INFO	0x0001
136 #define VIO_ACK_VER_INFO	0x0002
137 #define VIO_SND_ATTR_INFO	0x0004
138 #define VIO_ACK_ATTR_INFO	0x0008
139 #define VIO_SND_DRING_REG	0x0010
140 #define VIO_ACK_DRING_REG	0x0020
141 #define VIO_SND_RDX		0x0040
142 #define VIO_ACK_RDX		0x0080
143 #define VIO_ESTABLISHED		0x00ff
144 
145 	uint32_t	sc_local_sid;
146 	uint64_t	sc_dring_ident;
147 	uint64_t	sc_seq_no;
148 
149 	int		sc_tx_cnt;
150 	int		sc_tx_prod;
151 	int		sc_tx_cons;
152 
153 	struct ldc_map	*sc_lm;
154 	struct vdsk_dring *sc_vd;
155 	struct vdsk_soft_desc *sc_vsd;
156 
157 	struct scsi_adapter sc_switch;
158 	struct scsi_link sc_link;
159 
160 	uint32_t	sc_vdisk_block_size;
161 	uint64_t	sc_vdisk_size;
162 };
163 
164 int	vdsk_match(struct device *, void *, void *);
165 void	vdsk_attach(struct device *, struct device *, void *);
166 
167 struct cfattach vdsk_ca = {
168 	sizeof(struct vdsk_softc), vdsk_match, vdsk_attach
169 };
170 
171 struct cfdriver vdsk_cd = {
172 	NULL, "vdsk", DV_DULL
173 };
174 
175 struct scsi_device vdsk_device = {
176 	NULL, NULL, NULL, NULL
177 };
178 
179 int	vdsk_tx_intr(void *);
180 int	vdsk_rx_intr(void *);
181 
182 void	vdsk_rx_data(struct ldc_conn *, struct ldc_pkt *);
183 void	vdsk_rx_vio_ctrl(struct vdsk_softc *, struct vio_msg *);
184 void	vdsk_rx_vio_ver_info(struct vdsk_softc *, struct vio_msg_tag *);
185 void	vdsk_rx_vio_attr_info(struct vdsk_softc *, struct vio_msg_tag *);
186 void	vdsk_rx_vio_dring_reg(struct vdsk_softc *, struct vio_msg_tag *);
187 void	vdsk_rx_vio_rdx(struct vdsk_softc *sc, struct vio_msg_tag *);
188 void	vdsk_rx_vio_data(struct vdsk_softc *sc, struct vio_msg *);
189 void	vdsk_rx_vio_dring_data(struct vdsk_softc *sc, struct vio_msg_tag *);
190 
191 void	vdsk_ldc_reset(struct ldc_conn *);
192 void	vdsk_ldc_start(struct ldc_conn *);
193 
194 void	vdsk_sendmsg(struct vdsk_softc *, void *, size_t);
195 void	vdsk_send_ver_info(struct vdsk_softc *, uint16_t, uint16_t);
196 void	vdsk_send_attr_info(struct vdsk_softc *);
197 void	vdsk_send_dring_reg(struct vdsk_softc *);
198 void	vdsk_send_rdx(struct vdsk_softc *);
199 
200 int	vdsk_scsi_cmd(struct scsi_xfer *);
201 int	vdsk_dev_probe(struct scsi_link *);
202 void	vdsk_dev_free(struct scsi_link *);
203 int	vdsk_ioctl(struct scsi_link *, u_long, caddr_t, int, struct proc *);
204 
205 int	vdsk_scsi_inq(struct scsi_xfer *);
206 int	vdsk_scsi_inquiry(struct scsi_xfer *);
207 int	vdsk_scsi_capacity(struct scsi_xfer *);
208 int	vdsk_scsi_done(struct scsi_xfer *, int);
209 
210 int
211 vdsk_match(struct device *parent, void *match, void *aux)
212 {
213 	struct cbus_attach_args *ca = aux;
214 
215 	if (strcmp(ca->ca_name, "disk") == 0)
216 		return (1);
217 
218 	return (0);
219 }
220 
221 void
222 vdsk_attach(struct device *parent, struct device *self, void *aux)
223 {
224 	struct vdsk_softc *sc = (struct vdsk_softc *)self;
225 	struct cbus_attach_args *ca = aux;
226 	struct scsibus_attach_args saa;
227 	struct ldc_conn *lc;
228 	uint64_t sysino[2];
229 	int err, s;
230 	int timeout;
231 
232 	sc->sc_bustag = ca->ca_bustag;
233 	sc->sc_dmatag = ca->ca_dmatag;
234 
235 	if (cbus_intr_map(ca->ca_node, ca->ca_tx_ino, &sysino[0]) ||
236 	    cbus_intr_map(ca->ca_node, ca->ca_rx_ino, &sysino[1])) {
237 		printf(": can't map interrupt\n");
238 		return;
239 	}
240 	printf(": ivec 0x%lx, 0x%lx", sysino[0], sysino[1]);
241 
242 	/*
243 	 * Un-configure queues before registering interrupt handlers,
244 	 * such that we dont get any stale LDC packets or events.
245 	 */
246 	hv_ldc_tx_qconf(ca->ca_id, 0, 0);
247 	hv_ldc_rx_qconf(ca->ca_id, 0, 0);
248 
249 	sc->sc_tx_ih = bus_intr_establish(ca->ca_bustag, sysino[0], IPL_BIO,
250 	    0, vdsk_tx_intr, sc, sc->sc_dv.dv_xname);
251 	sc->sc_rx_ih = bus_intr_establish(ca->ca_bustag, sysino[1], IPL_BIO,
252 	    0, vdsk_rx_intr, sc, sc->sc_dv.dv_xname);
253 	if (sc->sc_tx_ih == NULL || sc->sc_rx_ih == NULL) {
254 		printf(", can't establish interrupt\n");
255 		return;
256 	}
257 
258 	lc = &sc->sc_lc;
259 	lc->lc_id = ca->ca_id;
260 	lc->lc_sc = sc;
261 	lc->lc_reset = vdsk_ldc_reset;
262 	lc->lc_start = vdsk_ldc_start;
263 	lc->lc_rx_data = vdsk_rx_data;
264 
265 	lc->lc_txq = ldc_queue_alloc(sc->sc_dmatag, VDSK_TX_ENTRIES);
266 	if (lc->lc_txq == NULL) {
267 		printf(", can't allocate tx queue\n");
268 		return;
269 	}
270 
271 	lc->lc_rxq = ldc_queue_alloc(sc->sc_dmatag, VDSK_RX_ENTRIES);
272 	if (lc->lc_rxq == NULL) {
273 		printf(", can't allocate rx queue\n");
274 		goto free_txqueue;
275 	}
276 
277 	sc->sc_lm = ldc_map_alloc(sc->sc_dmatag, 2048);
278 	if (sc->sc_lm == NULL) {
279 		printf(", can't allocate LDC mapping table\n");
280 		goto free_rxqueue;
281 	}
282 
283 	err = hv_ldc_set_map_table(lc->lc_id,
284 	    sc->sc_lm->lm_map->dm_segs[0].ds_addr, sc->sc_lm->lm_nentries);
285 	if (err != H_EOK) {
286 		printf("hv_ldc_set_map_table %d\n", err);
287 		goto free_map;
288 	}
289 
290 	sc->sc_vd = vdsk_dring_alloc(sc->sc_dmatag, 32);
291 	if (sc->sc_vd == NULL) {
292 		printf(", can't allocate dring\n");
293 		goto free_map;
294 	}
295 	sc->sc_vsd = malloc(32 * sizeof(*sc->sc_vsd), M_DEVBUF, M_NOWAIT);
296 	if (sc->sc_vsd == NULL) {
297 		printf(", can't allocate software ring\n");
298 		goto free_dring;
299 	}
300 
301 	sc->sc_lm->lm_slot[0].entry = sc->sc_vd->vd_map->dm_segs[0].ds_addr;
302 	sc->sc_lm->lm_slot[0].entry &= LDC_MTE_RA_MASK;
303 	sc->sc_lm->lm_slot[0].entry |= LDC_MTE_CPR | LDC_MTE_CPW;
304 	sc->sc_lm->lm_slot[0].entry |= LDC_MTE_R | LDC_MTE_W;
305 	sc->sc_lm->lm_next = 1;
306 	sc->sc_lm->lm_count = 1;
307 
308 	err = hv_ldc_tx_qconf(lc->lc_id,
309 	    lc->lc_txq->lq_map->dm_segs[0].ds_addr, lc->lc_txq->lq_nentries);
310 	if (err != H_EOK)
311 		printf("hv_ldc_tx_qconf %d\n", err);
312 
313 	err = hv_ldc_rx_qconf(lc->lc_id,
314 	    lc->lc_rxq->lq_map->dm_segs[0].ds_addr, lc->lc_rxq->lq_nentries);
315 	if (err != H_EOK)
316 		printf("hv_ldc_rx_qconf %d\n", err);
317 
318 	ldc_send_vers(lc);
319 
320 	printf("\n");
321 
322 	/*
323 	 * Interrupts aren't enabled during autoconf, so poll for VIO
324 	 * peer-to-peer hanshake completion.
325 	 */
326 	s = splbio();
327 	timeout = 1000;
328 	do {
329 		if (vdsk_rx_intr(sc) && sc->sc_vio_state == VIO_ESTABLISHED)
330 			break;
331 
332 		delay(1000);
333 	} while(--timeout > 0);
334 	splx(s);
335 
336 	if (sc->sc_vio_state != VIO_ESTABLISHED)
337 		return;
338 
339 	sc->sc_switch.scsi_cmd = vdsk_scsi_cmd;
340 	sc->sc_switch.scsi_minphys = scsi_minphys;
341 	sc->sc_switch.dev_probe = vdsk_dev_probe;
342 	sc->sc_switch.dev_free = vdsk_dev_free;
343 	sc->sc_switch.ioctl = vdsk_ioctl;
344 
345 	sc->sc_link.device = &vdsk_device;
346 	sc->sc_link.adapter = &sc->sc_switch;
347 	sc->sc_link.adapter_softc = self;
348 	sc->sc_link.adapter_buswidth = 2;
349 	sc->sc_link.luns = 1; /* XXX slices should be presented as luns? */
350 	sc->sc_link.adapter_target = 2;
351 	sc->sc_link.openings = sc->sc_vd->vd_nentries - 1;
352 
353 	bzero(&saa, sizeof(saa));
354 	saa.saa_sc_link = &sc->sc_link;
355 	config_found(self, &saa, scsiprint);
356 
357 	return;
358 
359 free_dring:
360 	vdsk_dring_free(sc->sc_dmatag, sc->sc_vd);
361 free_map:
362 	hv_ldc_set_map_table(lc->lc_id, 0, 0);
363 	ldc_map_free(sc->sc_dmatag, sc->sc_lm);
364 free_rxqueue:
365 	ldc_queue_free(sc->sc_dmatag, lc->lc_rxq);
366 free_txqueue:
367 	ldc_queue_free(sc->sc_dmatag, lc->lc_txq);
368 }
369 
370 int
371 vdsk_tx_intr(void *arg)
372 {
373 	struct vdsk_softc *sc = arg;
374 	struct ldc_conn *lc = &sc->sc_lc;
375 	uint64_t tx_head, tx_tail, tx_state;
376 
377 	hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
378 	if (tx_state != lc->lc_tx_state) {
379 		switch (tx_state) {
380 		case LDC_CHANNEL_DOWN:
381 			DPRINTF(("Tx link down\n"));
382 			break;
383 		case LDC_CHANNEL_UP:
384 			DPRINTF(("Tx link up\n"));
385 			break;
386 		case LDC_CHANNEL_RESET:
387 			DPRINTF(("Tx link reset\n"));
388 			break;
389 		}
390 		lc->lc_tx_state = tx_state;
391 	}
392 
393 	return (1);
394 }
395 
396 int
397 vdsk_rx_intr(void *arg)
398 {
399 	struct vdsk_softc *sc = arg;
400 	struct ldc_conn *lc = &sc->sc_lc;
401 	uint64_t rx_head, rx_tail, rx_state;
402 	struct ldc_pkt *lp;
403 	int err;
404 
405 	err = hv_ldc_rx_get_state(lc->lc_id, &rx_head, &rx_tail, &rx_state);
406 	if (err == H_EINVAL)
407 		return (0);
408 	if (err != H_EOK) {
409 		printf("hv_ldc_rx_get_state %d\n", err);
410 		return (0);
411 	}
412 
413 	if (rx_state != lc->lc_rx_state) {
414 		sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
415 		sc->sc_vio_state = 0;
416 		lc->lc_tx_seqid = 0;
417 		lc->lc_state = 0;
418 		switch (rx_state) {
419 		case LDC_CHANNEL_DOWN:
420 			DPRINTF(("Rx link down\n"));
421 			break;
422 		case LDC_CHANNEL_UP:
423 			DPRINTF(("Rx link up\n"));
424 			ldc_send_vers(lc);
425 			break;
426 		case LDC_CHANNEL_RESET:
427 			DPRINTF(("Rx link reset\n"));
428 			break;
429 		}
430 		lc->lc_rx_state = rx_state;
431 		hv_ldc_rx_set_qhead(lc->lc_id, rx_tail);
432 		return (1);
433 	}
434 
435 	if (rx_head == rx_tail)
436 		return (0);
437 
438 	lp = (struct ldc_pkt *)(lc->lc_rxq->lq_va + rx_head);
439 	switch (lp->type) {
440 	case LDC_CTRL:
441 		ldc_rx_ctrl(lc, lp);
442 		break;
443 
444 	case LDC_DATA:
445 		ldc_rx_data(lc, lp);
446 		break;
447 
448 	default:
449 		DPRINTF(("%0x02/%0x02/%0x02\n", lp->type, lp->stype,
450 		    lp->ctrl));
451 		ldc_reset(lc);
452 		break;
453 	}
454 
455 	if (lc->lc_state == 0)
456 		return (1);
457 
458 	rx_head += sizeof(*lp);
459 	rx_head &= ((lc->lc_rxq->lq_nentries * sizeof(*lp)) - 1);
460 	err = hv_ldc_rx_set_qhead(lc->lc_id, rx_head);
461 	if (err != H_EOK)
462 		printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err);
463 
464 	return (1);
465 }
466 
467 void
468 vdsk_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp)
469 {
470 	struct vio_msg *vm = (struct vio_msg *)lp;
471 
472 	switch (vm->type) {
473 	case VIO_TYPE_CTRL:
474 		if ((lp->env & LDC_FRAG_START) == 0 &&
475 		    (lp->env & LDC_FRAG_STOP) == 0)
476 			return;
477 		vdsk_rx_vio_ctrl(lc->lc_sc, vm);
478 		break;
479 
480 	case VIO_TYPE_DATA:
481 		if((lp->env & LDC_FRAG_START) == 0)
482 			return;
483 		vdsk_rx_vio_data(lc->lc_sc, vm);
484 		break;
485 
486 	default:
487 		DPRINTF(("Unhandled packet type 0x%02x\n", vm->type));
488 		ldc_reset(lc);
489 		break;
490 	}
491 }
492 
493 void
494 vdsk_rx_vio_ctrl(struct vdsk_softc *sc, struct vio_msg *vm)
495 {
496 	struct vio_msg_tag *tag = (struct vio_msg_tag *)&vm->type;
497 
498 	switch (tag->stype_env) {
499 	case VIO_VER_INFO:
500 		vdsk_rx_vio_ver_info(sc, tag);
501 		break;
502 	case VIO_ATTR_INFO:
503 		vdsk_rx_vio_attr_info(sc, tag);
504 		break;
505 	case VIO_DRING_REG:
506 		vdsk_rx_vio_dring_reg(sc, tag);
507 		break;
508 	case VIO_RDX:
509 		vdsk_rx_vio_rdx(sc, tag);
510 		break;
511 	default:
512 		DPRINTF(("CTRL/0x%02x/0x%04x\n", tag->stype, tag->stype_env));
513 		break;
514 	}
515 }
516 
517 void
518 vdsk_rx_vio_ver_info(struct vdsk_softc *sc, struct vio_msg_tag *tag)
519 {
520 	struct vio_ver_info *vi = (struct vio_ver_info *)tag;
521 
522 	switch (vi->tag.stype) {
523 	case VIO_SUBTYPE_INFO:
524 		DPRINTF(("CTRL/INFO/VER_INFO\n"));
525 		break;
526 
527 	case VIO_SUBTYPE_ACK:
528 		DPRINTF(("CTRL/ACK/VER_INFO\n"));
529 		if (!ISSET(sc->sc_vio_state, VIO_SND_VER_INFO)) {
530 			ldc_reset(&sc->sc_lc);
531 			break;
532 		}
533 		sc->sc_vio_state |= VIO_ACK_VER_INFO;
534 		break;
535 
536 	default:
537 		DPRINTF(("CTRL/0x%02x/VER_INFO\n", vi->tag.stype));
538 		break;
539 	}
540 
541 	if (ISSET(sc->sc_vio_state, VIO_ACK_VER_INFO))
542 		vdsk_send_attr_info(sc);
543 }
544 
545 void
546 vdsk_rx_vio_attr_info(struct vdsk_softc *sc, struct vio_msg_tag *tag)
547 {
548 	struct vd_attr_info *ai = (struct vd_attr_info *)tag;
549 
550 	switch (ai->tag.stype) {
551 	case VIO_SUBTYPE_INFO:
552 		DPRINTF(("CTRL/INFO/ATTR_INFO\n"));
553 		break;
554 
555 	case VIO_SUBTYPE_ACK:
556 		DPRINTF(("CTRL/ACK/ATTR_INFO\n"));
557 		if (!ISSET(sc->sc_vio_state, VIO_SND_ATTR_INFO)) {
558 			ldc_reset(&sc->sc_lc);
559 			break;
560 		}
561 
562 		sc->sc_vdisk_block_size = ai->vdisk_block_size;
563 		sc->sc_vdisk_size = ai->vdisk_size;
564 
565 		sc->sc_vio_state |= VIO_ACK_ATTR_INFO;
566 		break;
567 
568 	default:
569 		DPRINTF(("CTRL/0x%02x/ATTR_INFO\n", ai->tag.stype));
570 		break;
571 	}
572 
573 	if (ISSET(sc->sc_vio_state, VIO_ACK_ATTR_INFO))
574 		vdsk_send_dring_reg(sc);
575 
576 }
577 
578 void
579 vdsk_rx_vio_dring_reg(struct vdsk_softc *sc, struct vio_msg_tag *tag)
580 {
581 	struct vio_dring_reg *dr = (struct vio_dring_reg *)tag;
582 
583 	switch (dr->tag.stype) {
584 	case VIO_SUBTYPE_INFO:
585 		DPRINTF(("CTRL/INFO/DRING_REG\n"));
586 		break;
587 
588 	case VIO_SUBTYPE_ACK:
589 		DPRINTF(("CTRL/ACK/DRING_REG\n"));
590 		if (!ISSET(sc->sc_vio_state, VIO_SND_DRING_REG)) {
591 			ldc_reset(&sc->sc_lc);
592 			break;
593 		}
594 
595 		sc->sc_dring_ident = dr->dring_ident;
596 		sc->sc_seq_no = 1;
597 
598 		sc->sc_vio_state |= VIO_ACK_DRING_REG;
599 		break;
600 
601 	default:
602 		DPRINTF(("CTRL/0x%02x/DRING_REG\n", dr->tag.stype));
603 		break;
604 	}
605 
606 	if (ISSET(sc->sc_vio_state, VIO_ACK_DRING_REG))
607 		vdsk_send_rdx(sc);
608 }
609 
610 void
611 vdsk_rx_vio_rdx(struct vdsk_softc *sc, struct vio_msg_tag *tag)
612 {
613 	switch(tag->stype) {
614 	case VIO_SUBTYPE_INFO:
615 		DPRINTF(("CTRL/INFO/RDX\n"));
616 		break;
617 
618 	case VIO_SUBTYPE_ACK:
619 		DPRINTF(("CTRL/ACK/RDX\n"));
620 		if (!ISSET(sc->sc_vio_state, VIO_SND_RDX)) {
621 			ldc_reset(&sc->sc_lc);
622 			break;
623 		}
624 		sc->sc_vio_state |= VIO_ACK_RDX;
625 		break;
626 
627 	default:
628 		DPRINTF(("CTRL/0x%02x/RDX (VIO)\n", tag->stype));
629 		break;
630 	}
631 }
632 
633 void
634 vdsk_rx_vio_data(struct vdsk_softc *sc, struct vio_msg *vm)
635 {
636 	struct vio_msg_tag *tag = (struct vio_msg_tag *)&vm->type;
637 
638 	if (sc->sc_vio_state != VIO_ESTABLISHED) {
639 		DPRINTF(("Spurious DATA/0x%02x/0x%04x\n", tag->stype,
640 		    tag->stype_env));
641 		return;
642 	}
643 
644 	switch(tag->stype_env) {
645 	case VIO_DRING_DATA:
646 		vdsk_rx_vio_dring_data(sc, tag);
647 		break;
648 
649 	default:
650 		DPRINTF(("DATA/0x%02x/0x%04x\n", tag->stype, tag->stype_env));
651 		break;
652 	}
653 }
654 
655 void
656 vdsk_rx_vio_dring_data(struct vdsk_softc *sc, struct vio_msg_tag *tag)
657 {
658 	switch(tag->stype) {
659 	case VIO_SUBTYPE_INFO:
660 		DPRINTF(("DATA/INFO/DRING_DATA\n"));
661 		break;
662 
663 	case VIO_SUBTYPE_ACK:
664 	{
665 		struct scsi_xfer *xs;
666 		struct ldc_map *map = sc->sc_lm;
667 		int cons, error;
668 		int cookie, idx;
669 		int len;
670 
671 		cons = sc->sc_tx_cons;
672 		while (sc->sc_vd->vd_desc[cons].hdr.dstate == VIO_DESC_DONE) {
673 			xs = sc->sc_vsd[cons].vsd_xs;
674 
675 			cookie = 0;
676 			len = xs->datalen;
677 			while (len > 0) {
678 				idx = sc->sc_vsd[cons].vsd_map_idx[cookie++];
679 				map->lm_slot[idx].entry = 0;
680 				map->lm_count--;
681 				len -= PAGE_SIZE;
682 			}
683 
684 			error = XS_NOERROR;
685 			if (sc->sc_vd->vd_desc[cons].status != 0)
686 				error = XS_DRIVER_STUFFUP;
687 			xs->resid = xs->datalen -
688 			    sc->sc_vd->vd_desc[cons].size;
689 			vdsk_scsi_done(xs, error);
690 
691 			sc->sc_vd->vd_desc[cons++].hdr.dstate = VIO_DESC_FREE;
692 			cons &= (sc->sc_vd->vd_nentries - 1);
693 			sc->sc_tx_cnt--;
694 		}
695 		sc->sc_tx_cons = cons;
696 		break;
697 	}
698 
699 	case VIO_SUBTYPE_NACK:
700 		DPRINTF(("DATA/NACK/DRING_DATA\n"));
701 		break;
702 
703 	default:
704 		DPRINTF(("DATA/0x%02x/DRING_DATA\n", tag->stype));
705 		break;
706 	}
707 }
708 
709 void
710 vdsk_ldc_reset(struct ldc_conn *lc)
711 {
712 	struct vdsk_softc *sc = lc->lc_sc;
713 
714 	sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
715 	sc->sc_vio_state = 0;
716 }
717 
718 void
719 vdsk_ldc_start(struct ldc_conn *lc)
720 {
721 	struct vdsk_softc *sc = lc->lc_sc;
722 
723 	vdsk_send_ver_info(sc, VDSK_MAJOR, VDSK_MINOR);
724 }
725 
726 void
727 vdsk_sendmsg(struct vdsk_softc *sc, void *msg, size_t len)
728 {
729 	struct ldc_conn *lc = &sc->sc_lc;
730 	struct ldc_pkt *lp;
731 	uint64_t tx_head, tx_tail, tx_state;
732 	int err;
733 
734 	err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state);
735 	if (err != H_EOK)
736 		return;
737 
738 	lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail);
739 	bzero(lp, sizeof(struct ldc_pkt));
740 	lp->type = LDC_DATA;
741 	lp->stype = LDC_INFO;
742 	KASSERT((len & ~LDC_LEN_MASK) == 0);
743 	lp->env = len | LDC_FRAG_STOP | LDC_FRAG_START;
744 	lp->seqid = lc->lc_tx_seqid++;
745 	bcopy(msg, &lp->major, len);
746 
747 	tx_tail += sizeof(*lp);
748 	tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1);
749 	err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail);
750 	if (err != H_EOK)
751 		printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err);
752 }
753 
754 void
755 vdsk_send_ver_info(struct vdsk_softc *sc, uint16_t major, uint16_t minor)
756 {
757 	struct vio_ver_info vi;
758 
759 	/* Allocate new session ID. */
760 	sc->sc_local_sid = tick();
761 
762 	bzero(&vi, sizeof(vi));
763 	vi.tag.type = VIO_TYPE_CTRL;
764 	vi.tag.stype = VIO_SUBTYPE_INFO;
765 	vi.tag.stype_env = VIO_VER_INFO;
766 	vi.tag.sid = sc->sc_local_sid;
767 	vi.major = major;
768 	vi.minor = minor;
769 	vi.dev_class = VDEV_DISK;
770 	vdsk_sendmsg(sc, &vi, sizeof(vi));
771 
772 	sc->sc_vio_state |= VIO_SND_VER_INFO;
773 }
774 
775 void
776 vdsk_send_attr_info(struct vdsk_softc *sc)
777 {
778 	struct vd_attr_info ai;
779 
780 	bzero(&ai, sizeof(ai));
781 	ai.tag.type = VIO_TYPE_CTRL;
782 	ai.tag.stype = VIO_SUBTYPE_INFO;
783 	ai.tag.stype_env = VIO_ATTR_INFO;
784 	ai.tag.sid = sc->sc_local_sid;
785 	ai.xfer_mode = VIO_DRING_MODE;
786 	ai.vdisk_block_size = DEV_BSIZE;
787 	ai.max_xfer_sz = MAXPHYS / DEV_BSIZE;
788 	vdsk_sendmsg(sc, &ai, sizeof(ai));
789 
790 	sc->sc_vio_state |= VIO_SND_ATTR_INFO;
791 }
792 
793 void
794 vdsk_send_dring_reg(struct vdsk_softc *sc)
795 {
796 	struct vio_dring_reg dr;
797 
798 	bzero(&dr, sizeof(dr));
799 	dr.tag.type = VIO_TYPE_CTRL;
800 	dr.tag.stype = VIO_SUBTYPE_INFO;
801 	dr.tag.stype_env = VIO_DRING_REG;
802 	dr.tag.sid = sc->sc_local_sid;
803 	dr.dring_ident = 0;
804 	dr.num_descriptors = sc->sc_vd->vd_nentries;
805 	dr.descriptor_size = sizeof(struct vd_desc);
806 	dr.options = VIO_TX_RING | VIO_RX_RING;
807 	dr.ncookies = 1;
808 	dr.cookie[0].addr = 0;
809 	dr.cookie[0].size = PAGE_SIZE;
810 	vdsk_sendmsg(sc, &dr, sizeof(dr));
811 
812 	sc->sc_vio_state |= VIO_SND_DRING_REG;
813 };
814 
815 void
816 vdsk_send_rdx(struct vdsk_softc *sc)
817 {
818 	struct vio_rdx rdx;
819 
820 	bzero(&rdx, sizeof(rdx));
821 	rdx.tag.type = VIO_TYPE_CTRL;
822 	rdx.tag.stype = VIO_SUBTYPE_INFO;
823 	rdx.tag.stype_env = VIO_RDX;
824 	rdx.tag.sid = sc->sc_local_sid;
825 	vdsk_sendmsg(sc, &rdx, sizeof(rdx));
826 
827 	sc->sc_vio_state |= VIO_SND_RDX;
828 }
829 
830 struct vdsk_dring *
831 vdsk_dring_alloc(bus_dma_tag_t t, int nentries)
832 {
833 	struct vdsk_dring *vd;
834 	bus_size_t size;
835 	caddr_t va;
836 	int nsegs;
837 	int i;
838 
839 	vd = malloc(sizeof(struct vdsk_dring), M_DEVBUF, M_NOWAIT);
840 	if (vd == NULL)
841 		return NULL;
842 
843 	size = roundup(nentries * sizeof(struct vd_desc), PAGE_SIZE);
844 
845 	if (bus_dmamap_create(t, size, 1, size, 0,
846 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &vd->vd_map) != 0)
847 		return (NULL);
848 
849 	if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &vd->vd_seg, 1,
850 	    &nsegs, BUS_DMA_NOWAIT) != 0)
851 		goto destroy;
852 
853 	if (bus_dmamem_map(t, &vd->vd_seg, 1, size, &va,
854 	    BUS_DMA_NOWAIT) != 0)
855 		goto free;
856 
857 	if (bus_dmamap_load(t, vd->vd_map, va, size, NULL,
858 	    BUS_DMA_NOWAIT) != 0)
859 		goto unmap;
860 
861 	vd->vd_desc = (struct vd_desc *)va;
862 	vd->vd_nentries = nentries;
863 	bzero(vd->vd_desc, nentries * sizeof(struct vd_desc));
864 	for (i = 0; i < vd->vd_nentries; i++)
865 		vd->vd_desc[i].hdr.dstate = VIO_DESC_FREE;
866 	return (vd);
867 
868 unmap:
869 	bus_dmamem_unmap(t, va, size);
870 free:
871 	bus_dmamem_free(t, &vd->vd_seg, 1);
872 destroy:
873 	bus_dmamap_destroy(t, vd->vd_map);
874 
875 	return (NULL);
876 }
877 
878 void
879 vdsk_dring_free(bus_dma_tag_t t, struct vdsk_dring *vd)
880 {
881 	bus_size_t size;
882 
883 	size = vd->vd_nentries * sizeof(struct vd_desc);
884 	size = roundup(size, PAGE_SIZE);
885 
886 	bus_dmamap_unload(t, vd->vd_map);
887 	bus_dmamem_unmap(t, (caddr_t)vd->vd_desc, size);
888 	bus_dmamem_free(t, &vd->vd_seg, 1);
889 	bus_dmamap_destroy(t, vd->vd_map);
890 	free(vd, M_DEVBUF);
891 }
892 
893 int
894 vdsk_scsi_cmd(struct scsi_xfer *xs)
895 {
896 	struct scsi_rw *rw;
897 	struct scsi_rw_big *rwb;
898 	u_int64_t lba;
899 	u_int32_t sector_count;
900 	uint8_t operation;
901 
902 	switch (xs->cmd->opcode) {
903 	case READ_BIG:
904 	case READ_COMMAND:
905 		operation = VD_OP_BREAD;
906 		break;
907 	case WRITE_BIG:
908 	case WRITE_COMMAND:
909 		operation = VD_OP_BWRITE;
910 		break;
911 
912 	case SYNCHRONIZE_CACHE:
913 		operation = VD_OP_FLUSH;
914 		break;
915 
916 	case INQUIRY:
917 		return (vdsk_scsi_inq(xs));
918 	case READ_CAPACITY:
919 		return (vdsk_scsi_capacity(xs));
920 
921 	case TEST_UNIT_READY:
922 	case START_STOP:
923 	case PREVENT_ALLOW:
924 		return (vdsk_scsi_done(xs, XS_NOERROR));
925 
926 	default:
927 		printf("%s cmd 0x%02x\n", __func__, xs->cmd->opcode);
928 	case MODE_SENSE:
929 	case MODE_SENSE_BIG:
930 	case REPORT_LUNS:
931 		return (vdsk_scsi_done(xs, XS_DRIVER_STUFFUP));
932 	}
933 
934 	if (xs->cmdlen == 6) {
935 		rw = (struct scsi_rw *)xs->cmd;
936 		lba = _3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff);
937 		sector_count = rw->length ? rw->length : 0x100;
938 	} else {
939 		rwb = (struct scsi_rw_big *)xs->cmd;
940 		lba = _4btol(rwb->addr);
941 		sector_count = _2btol(rwb->length);
942 	}
943 
944 {
945 	struct vdsk_softc *sc = xs->sc_link->adapter_softc;
946 	struct ldc_map *map = sc->sc_lm;
947 	struct vio_dring_msg dm;
948 	vaddr_t va;
949 	paddr_t pa;
950 	int len, ncookies;
951 	int desc, s;
952 	int timeout;
953 
954 	if (sc->sc_tx_cnt >= sc->sc_vd->vd_nentries)
955 		return (NO_CCB);
956 
957 	desc = sc->sc_tx_prod;
958 
959 	ncookies = 0;
960 	len = xs->datalen;
961 	va = (vaddr_t)xs->data;
962 	while (len > 0) {
963 		pmap_extract(pmap_kernel(), va, &pa);
964 		while (map->lm_slot[map->lm_next].entry != 0) {
965 			map->lm_next++;
966 			map->lm_next &= (map->lm_nentries - 1);
967 		}
968 		map->lm_slot[map->lm_next].entry = (pa & LDC_MTE_RA_MASK);
969 		map->lm_slot[map->lm_next].entry |= LDC_MTE_CPR | LDC_MTE_CPW;
970 		map->lm_slot[map->lm_next].entry |= LDC_MTE_IOR | LDC_MTE_IOW;
971 		map->lm_slot[map->lm_next].entry |= LDC_MTE_R | LDC_MTE_W;
972 		map->lm_count++;
973 
974 		sc->sc_vd->vd_desc[desc].cookie[ncookies].addr =
975 		    map->lm_next << PAGE_SHIFT | (pa & PAGE_MASK);
976 		sc->sc_vd->vd_desc[desc].cookie[ncookies].size =
977 		    min(len, PAGE_SIZE);
978 
979 		sc->sc_vsd[desc].vsd_map_idx[ncookies] = map->lm_next;
980 		va += PAGE_SIZE;
981 		len -= PAGE_SIZE;
982 		ncookies++;
983 	}
984 
985 	sc->sc_vd->vd_desc[desc].hdr.ack = 1;
986 	sc->sc_vd->vd_desc[desc].operation = operation;
987 	sc->sc_vd->vd_desc[desc].slice = VD_SLICE_NONE;
988 	sc->sc_vd->vd_desc[desc].status = 0xffffffff;
989 	sc->sc_vd->vd_desc[desc].offset = lba;
990 	sc->sc_vd->vd_desc[desc].size = xs->datalen;
991 	sc->sc_vd->vd_desc[desc].ncookies = ncookies;
992 	membar(Sync);
993 	sc->sc_vd->vd_desc[desc].hdr.dstate = VIO_DESC_READY;
994 
995 	sc->sc_vsd[desc].vsd_xs = xs;
996 
997 	sc->sc_tx_prod++;
998 	sc->sc_tx_prod &= (sc->sc_vd->vd_nentries - 1);
999 	sc->sc_tx_cnt++;
1000 
1001 	bzero(&dm, sizeof(dm));
1002 	dm.tag.type = VIO_TYPE_DATA;
1003 	dm.tag.stype = VIO_SUBTYPE_INFO;
1004 	dm.tag.stype_env = VIO_DRING_DATA;
1005 	dm.tag.sid = sc->sc_local_sid;
1006 	dm.seq_no = sc->sc_seq_no++;
1007 	dm.dring_ident = sc->sc_dring_ident;
1008 	dm.start_idx = dm.end_idx = desc;
1009 	vdsk_sendmsg(sc, &dm, sizeof(dm));
1010 
1011 	if (!ISSET(xs->flags, SCSI_POLL))
1012 		return (SUCCESSFULLY_QUEUED);
1013 
1014 	s = splbio();
1015 	timeout = 1000;
1016 	do {
1017 		if (vdsk_rx_intr(sc) &&
1018 		    sc->sc_vd->vd_desc[desc].status == VIO_DESC_FREE)
1019 			break;
1020 
1021 		delay(1000);
1022 	} while(--timeout > 0);
1023 	splx(s);
1024 
1025 	return (COMPLETE);
1026 }
1027 }
1028 
1029 int
1030 vdsk_scsi_inq(struct scsi_xfer *xs)
1031 {
1032 	struct scsi_inquiry *inq = (struct scsi_inquiry *)xs->cmd;
1033 
1034 	if (ISSET(inq->flags, SI_EVPD))
1035 		return (vdsk_scsi_done(xs, XS_DRIVER_STUFFUP));
1036 
1037 	return (vdsk_scsi_inquiry(xs));
1038 }
1039 
1040 int
1041 vdsk_scsi_inquiry(struct scsi_xfer *xs)
1042 {
1043 	struct scsi_inquiry_data inq;
1044 
1045 	bzero(&inq, sizeof(inq));
1046 
1047 	inq.device = T_DIRECT;
1048 	inq.version = 0x05; /* SPC-3 */
1049 	inq.response_format = 2;
1050 	inq.additional_length = 32;
1051 	bcopy("SUN     ", inq.vendor, sizeof(inq.vendor));
1052 	bcopy("Virtual Disk    ", inq.product, sizeof(inq.product));
1053 	bcopy("1.0 ", inq.revision, sizeof(inq.revision));
1054 
1055 	bcopy(&inq, xs->data, MIN(sizeof(inq), xs->datalen));
1056 
1057 	return (vdsk_scsi_done(xs, XS_NOERROR));
1058 }
1059 
1060 int
1061 vdsk_scsi_capacity(struct scsi_xfer *xs)
1062 {
1063 	struct vdsk_softc *sc = xs->sc_link->adapter_softc;
1064 	struct scsi_read_cap_data rcd;
1065 	uint64_t capacity;
1066 
1067 	bzero(&rcd, sizeof(rcd));
1068 
1069 	capacity = sc->sc_vdisk_size;
1070 	if (capacity > 0xffffffff)
1071 		capacity = 0xffffffff;
1072 
1073 	_lto4b(capacity - 1, rcd.addr);
1074 	_lto4b(sc->sc_vdisk_block_size, rcd.length);
1075 
1076 	bcopy(&rcd, xs->data, MIN(sizeof(rcd), xs->datalen));
1077 
1078 	return (vdsk_scsi_done(xs, XS_NOERROR));
1079 }
1080 
1081 int
1082 vdsk_scsi_done(struct scsi_xfer *xs, int error)
1083 {
1084 	int s;
1085 
1086 	xs->error = error;
1087 	xs->flags |= ITSDONE;
1088 
1089 	s = splbio();
1090 	scsi_done(xs);
1091 	splx(s);
1092 	return (COMPLETE);
1093 }
1094 
1095 int
1096 vdsk_dev_probe(struct scsi_link *link)
1097 {
1098 	KASSERT(link->lun == 0);
1099 
1100 	if (link->target == 0)
1101 		return (0);
1102 
1103 	return (ENODEV);
1104 }
1105 
1106 void
1107 vdsk_dev_free(struct scsi_link *link)
1108 {
1109 	printf("%s\n", __func__);
1110 }
1111 
1112 int
1113 vdsk_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flags,
1114     struct proc *p)
1115 {
1116 	printf("%s\n", __func__);
1117 	return (ENOTTY);
1118 }
1119 
1120