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