1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 2013 Nathan Whitehorn 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 AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/kernel.h> 32 #include <sys/malloc.h> 33 #include <sys/module.h> 34 #include <sys/selinfo.h> 35 #include <sys/bus.h> 36 #include <sys/conf.h> 37 #include <sys/eventhandler.h> 38 #include <sys/rman.h> 39 #include <sys/bus_dma.h> 40 #include <sys/bio.h> 41 #include <sys/ioccom.h> 42 #include <sys/uio.h> 43 #include <sys/proc.h> 44 #include <sys/signalvar.h> 45 #include <sys/sysctl.h> 46 #include <sys/endian.h> 47 #include <sys/vmem.h> 48 49 #include <cam/cam.h> 50 #include <cam/cam_ccb.h> 51 #include <cam/cam_debug.h> 52 #include <cam/cam_periph.h> 53 #include <cam/cam_sim.h> 54 #include <cam/cam_xpt_periph.h> 55 #include <cam/cam_xpt_sim.h> 56 #include <cam/scsi/scsi_all.h> 57 #include <cam/scsi/scsi_message.h> 58 59 #include <dev/ofw/openfirm.h> 60 #include <dev/ofw/ofw_bus.h> 61 #include <dev/ofw/ofw_bus_subr.h> 62 63 #include <machine/bus.h> 64 #include <machine/resource.h> 65 66 #include <powerpc/pseries/phyp-hvcall.h> 67 68 struct vscsi_softc; 69 70 /* VSCSI CRQ format from table 260 of PAPR spec 2.4 (page 760) */ 71 struct vscsi_crq { 72 uint8_t valid; 73 uint8_t format; 74 uint8_t reserved; 75 uint8_t status; 76 uint16_t timeout; 77 uint16_t iu_length; 78 uint64_t iu_data; 79 }; 80 81 struct vscsi_xfer { 82 TAILQ_ENTRY(vscsi_xfer) queue; 83 struct vscsi_softc *sc; 84 union ccb *ccb; 85 bus_dmamap_t dmamap; 86 uint64_t tag; 87 88 vmem_addr_t srp_iu_offset; 89 vmem_size_t srp_iu_size; 90 }; 91 92 TAILQ_HEAD(vscsi_xferq, vscsi_xfer); 93 94 struct vscsi_softc { 95 device_t dev; 96 struct cam_devq *devq; 97 struct cam_sim *sim; 98 struct cam_path *path; 99 struct mtx io_lock; 100 101 cell_t unit; 102 int bus_initialized; 103 int bus_logged_in; 104 int max_transactions; 105 106 int irqid; 107 struct resource *irq; 108 void *irq_cookie; 109 110 bus_dma_tag_t crq_tag; 111 struct vscsi_crq *crq_queue; 112 int n_crqs, cur_crq; 113 bus_dmamap_t crq_map; 114 bus_addr_t crq_phys; 115 116 vmem_t *srp_iu_arena; 117 void *srp_iu_queue; 118 bus_addr_t srp_iu_phys; 119 120 bus_dma_tag_t data_tag; 121 122 struct vscsi_xfer loginxp; 123 struct vscsi_xfer *xfer; 124 struct vscsi_xferq active_xferq; 125 struct vscsi_xferq free_xferq; 126 }; 127 128 struct srp_login { 129 uint8_t type; 130 uint8_t reserved[7]; 131 uint64_t tag; 132 uint64_t max_cmd_length; 133 uint32_t reserved2; 134 uint16_t buffer_formats; 135 uint8_t flags; 136 uint8_t reserved3[5]; 137 uint8_t initiator_port_id[16]; 138 uint8_t target_port_id[16]; 139 } __packed; 140 141 struct srp_login_rsp { 142 uint8_t type; 143 uint8_t reserved[3]; 144 uint32_t request_limit_delta; 145 uint8_t tag; 146 uint32_t max_i_to_t_len; 147 uint32_t max_t_to_i_len; 148 uint16_t buffer_formats; 149 uint8_t flags; 150 /* Some reserved bits follow */ 151 } __packed; 152 153 struct srp_cmd { 154 uint8_t type; 155 uint8_t flags1; 156 uint8_t reserved[3]; 157 uint8_t formats; 158 uint8_t out_buffer_count; 159 uint8_t in_buffer_count; 160 uint64_t tag; 161 uint32_t reserved2; 162 uint64_t lun; 163 uint8_t reserved3[3]; 164 uint8_t additional_cdb; 165 uint8_t cdb[16]; 166 uint8_t data_payload[0]; 167 } __packed; 168 169 struct srp_rsp { 170 uint8_t type; 171 uint8_t reserved[3]; 172 uint32_t request_limit_delta; 173 uint64_t tag; 174 uint16_t reserved2; 175 uint8_t flags; 176 uint8_t status; 177 uint32_t data_out_resid; 178 uint32_t data_in_resid; 179 uint32_t sense_data_len; 180 uint32_t response_data_len; 181 uint8_t data_payload[0]; 182 } __packed; 183 184 struct srp_tsk_mgmt { 185 uint8_t type; 186 uint8_t reserved[7]; 187 uint64_t tag; 188 uint32_t reserved2; 189 uint64_t lun; 190 uint8_t reserved3[2]; 191 uint8_t function; 192 uint8_t reserved4; 193 uint64_t manage_tag; 194 uint64_t reserved5; 195 } __packed; 196 197 /* Message code type */ 198 #define SRP_LOGIN_REQ 0x00 199 #define SRP_TSK_MGMT 0x01 200 #define SRP_CMD 0x02 201 #define SRP_I_LOGOUT 0x03 202 203 #define SRP_LOGIN_RSP 0xC0 204 #define SRP_RSP 0xC1 205 #define SRP_LOGIN_REJ 0xC2 206 207 #define SRP_T_LOGOUT 0x80 208 #define SRP_CRED_REQ 0x81 209 #define SRP_AER_REQ 0x82 210 211 #define SRP_CRED_RSP 0x41 212 #define SRP_AER_RSP 0x41 213 214 /* Flags for srp_rsp flags field */ 215 #define SRP_RSPVALID 0x01 216 #define SRP_SNSVALID 0x02 217 #define SRP_DOOVER 0x04 218 #define SRP_DOUNDER 0x08 219 #define SRP_DIOVER 0x10 220 #define SRP_DIUNDER 0x20 221 222 #define MAD_SUCESS 0x00 223 #define MAD_NOT_SUPPORTED 0xf1 224 #define MAD_FAILED 0xf7 225 226 #define MAD_EMPTY_IU 0x01 227 #define MAD_ERROR_LOGGING_REQUEST 0x02 228 #define MAD_ADAPTER_INFO_REQUEST 0x03 229 #define MAD_CAPABILITIES_EXCHANGE 0x05 230 #define MAD_PHYS_ADAP_INFO_REQUEST 0x06 231 #define MAD_TAPE_PASSTHROUGH_REQUEST 0x07 232 #define MAD_ENABLE_FAST_FAIL 0x08 233 234 static int vscsi_probe(device_t); 235 static int vscsi_attach(device_t); 236 static int vscsi_detach(device_t); 237 static void vscsi_cam_action(struct cam_sim *, union ccb *); 238 static void vscsi_cam_poll(struct cam_sim *); 239 static void vscsi_intr(void *arg); 240 static void vscsi_check_response_queue(struct vscsi_softc *sc); 241 static void vscsi_setup_bus(struct vscsi_softc *sc); 242 243 static void vscsi_srp_login(struct vscsi_softc *sc); 244 static void vscsi_crq_load_cb(void *, bus_dma_segment_t *, int, int); 245 static void vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, 246 int nsegs, int err); 247 static void vscsi_task_management(struct vscsi_softc *sc, union ccb *ccb); 248 static void vscsi_srp_response(struct vscsi_xfer *, struct vscsi_crq *); 249 250 static device_method_t vscsi_methods[] = { 251 DEVMETHOD(device_probe, vscsi_probe), 252 DEVMETHOD(device_attach, vscsi_attach), 253 DEVMETHOD(device_detach, vscsi_detach), 254 255 DEVMETHOD_END 256 }; 257 258 static driver_t vscsi_driver = { 259 "vscsi", 260 vscsi_methods, 261 sizeof(struct vscsi_softc) 262 }; 263 264 DRIVER_MODULE(vscsi, vdevice, vscsi_driver, 0, 0); 265 MALLOC_DEFINE(M_VSCSI, "vscsi", "CAM device queue for VSCSI"); 266 267 static int 268 vscsi_probe(device_t dev) 269 { 270 271 if (!ofw_bus_is_compatible(dev, "IBM,v-scsi")) 272 return (ENXIO); 273 274 device_set_desc(dev, "POWER Hypervisor Virtual SCSI Bus"); 275 return (0); 276 } 277 278 static int 279 vscsi_attach(device_t dev) 280 { 281 struct vscsi_softc *sc; 282 struct vscsi_xfer *xp; 283 int error, i; 284 285 sc = device_get_softc(dev); 286 if (sc == NULL) 287 return (EINVAL); 288 289 sc->dev = dev; 290 mtx_init(&sc->io_lock, "vscsi", NULL, MTX_DEF); 291 292 /* Get properties */ 293 OF_getencprop(ofw_bus_get_node(dev), "reg", &sc->unit, 294 sizeof(sc->unit)); 295 296 /* Setup interrupt */ 297 sc->irqid = 0; 298 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, 299 RF_ACTIVE); 300 301 if (!sc->irq) { 302 device_printf(dev, "Could not allocate IRQ\n"); 303 mtx_destroy(&sc->io_lock); 304 return (ENXIO); 305 } 306 307 bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_MPSAFE | 308 INTR_ENTROPY, NULL, vscsi_intr, sc, &sc->irq_cookie); 309 310 /* Data DMA */ 311 error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, 312 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE, 313 256, BUS_SPACE_MAXSIZE_32BIT, 0, busdma_lock_mutex, &sc->io_lock, 314 &sc->data_tag); 315 316 TAILQ_INIT(&sc->active_xferq); 317 TAILQ_INIT(&sc->free_xferq); 318 319 /* First XFER for login data */ 320 sc->loginxp.sc = sc; 321 bus_dmamap_create(sc->data_tag, 0, &sc->loginxp.dmamap); 322 TAILQ_INSERT_TAIL(&sc->free_xferq, &sc->loginxp, queue); 323 324 /* CRQ area */ 325 error = bus_dma_tag_create(bus_get_dma_tag(dev), PAGE_SIZE, 0, 326 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 8*PAGE_SIZE, 327 1, BUS_SPACE_MAXSIZE, 0, NULL, NULL, &sc->crq_tag); 328 error = bus_dmamem_alloc(sc->crq_tag, (void **)&sc->crq_queue, 329 BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->crq_map); 330 sc->crq_phys = 0; 331 sc->n_crqs = 0; 332 error = bus_dmamap_load(sc->crq_tag, sc->crq_map, sc->crq_queue, 333 8*PAGE_SIZE, vscsi_crq_load_cb, sc, 0); 334 335 mtx_lock(&sc->io_lock); 336 vscsi_setup_bus(sc); 337 sc->xfer = malloc(sizeof(sc->xfer[0])*sc->max_transactions, M_VSCSI, 338 M_NOWAIT); 339 for (i = 0; i < sc->max_transactions; i++) { 340 xp = &sc->xfer[i]; 341 xp->sc = sc; 342 343 error = bus_dmamap_create(sc->data_tag, 0, &xp->dmamap); 344 if (error) { 345 device_printf(dev, "Could not create DMA map (%d)\n", 346 error); 347 break; 348 } 349 350 TAILQ_INSERT_TAIL(&sc->free_xferq, xp, queue); 351 } 352 mtx_unlock(&sc->io_lock); 353 354 /* Allocate CAM bits */ 355 if ((sc->devq = cam_simq_alloc(sc->max_transactions)) == NULL) 356 return (ENOMEM); 357 358 sc->sim = cam_sim_alloc(vscsi_cam_action, vscsi_cam_poll, "vscsi", sc, 359 device_get_unit(dev), &sc->io_lock, 360 sc->max_transactions, sc->max_transactions, 361 sc->devq); 362 if (sc->sim == NULL) { 363 cam_simq_free(sc->devq); 364 sc->devq = NULL; 365 device_printf(dev, "CAM SIM attach failed\n"); 366 return (EINVAL); 367 } 368 369 mtx_lock(&sc->io_lock); 370 if (xpt_bus_register(sc->sim, dev, 0) != 0) { 371 device_printf(dev, "XPT bus registration failed\n"); 372 cam_sim_free(sc->sim, FALSE); 373 sc->sim = NULL; 374 cam_simq_free(sc->devq); 375 sc->devq = NULL; 376 mtx_unlock(&sc->io_lock); 377 return (EINVAL); 378 } 379 mtx_unlock(&sc->io_lock); 380 381 return (0); 382 } 383 384 static int 385 vscsi_detach(device_t dev) 386 { 387 struct vscsi_softc *sc; 388 389 sc = device_get_softc(dev); 390 if (sc == NULL) 391 return (EINVAL); 392 393 if (sc->sim != NULL) { 394 mtx_lock(&sc->io_lock); 395 xpt_bus_deregister(cam_sim_path(sc->sim)); 396 cam_sim_free(sc->sim, FALSE); 397 sc->sim = NULL; 398 mtx_unlock(&sc->io_lock); 399 } 400 401 if (sc->devq != NULL) { 402 cam_simq_free(sc->devq); 403 sc->devq = NULL; 404 } 405 406 mtx_destroy(&sc->io_lock); 407 408 return (0); 409 } 410 411 static void 412 vscsi_cam_action(struct cam_sim *sim, union ccb *ccb) 413 { 414 struct vscsi_softc *sc = cam_sim_softc(sim); 415 416 mtx_assert(&sc->io_lock, MA_OWNED); 417 418 switch (ccb->ccb_h.func_code) { 419 case XPT_PATH_INQ: 420 { 421 struct ccb_pathinq *cpi = &ccb->cpi; 422 423 cpi->version_num = 1; 424 cpi->hba_inquiry = PI_TAG_ABLE; 425 cpi->hba_misc = PIM_EXTLUNS; 426 cpi->target_sprt = 0; 427 cpi->hba_eng_cnt = 0; 428 cpi->max_target = 0; 429 cpi->max_lun = 0; 430 cpi->initiator_id = ~0; 431 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 432 strlcpy(cpi->hba_vid, "IBM", HBA_IDLEN); 433 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 434 cpi->unit_number = cam_sim_unit(sim); 435 cpi->bus_id = cam_sim_bus(sim); 436 cpi->base_transfer_speed = 150000; 437 cpi->transport = XPORT_SRP; 438 cpi->transport_version = 0; 439 cpi->protocol = PROTO_SCSI; 440 cpi->protocol_version = SCSI_REV_SPC4; 441 cpi->ccb_h.status = CAM_REQ_CMP; 442 break; 443 } 444 case XPT_RESET_BUS: 445 ccb->ccb_h.status = CAM_REQ_CMP; 446 break; 447 case XPT_RESET_DEV: 448 ccb->ccb_h.status = CAM_REQ_INPROG; 449 vscsi_task_management(sc, ccb); 450 return; 451 case XPT_GET_TRAN_SETTINGS: 452 ccb->cts.protocol = PROTO_SCSI; 453 ccb->cts.protocol_version = SCSI_REV_SPC4; 454 ccb->cts.transport = XPORT_SRP; 455 ccb->cts.transport_version = 0; 456 ccb->cts.proto_specific.valid = 0; 457 ccb->cts.xport_specific.valid = 0; 458 ccb->ccb_h.status = CAM_REQ_CMP; 459 break; 460 case XPT_SET_TRAN_SETTINGS: 461 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 462 break; 463 case XPT_SCSI_IO: 464 { 465 struct vscsi_xfer *xp; 466 467 ccb->ccb_h.status = CAM_REQ_INPROG; 468 469 xp = TAILQ_FIRST(&sc->free_xferq); 470 if (xp == NULL) 471 panic("SCSI queue flooded"); 472 xp->ccb = ccb; 473 TAILQ_REMOVE(&sc->free_xferq, xp, queue); 474 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); 475 bus_dmamap_load_ccb(sc->data_tag, xp->dmamap, 476 ccb, vscsi_scsi_command, xp, 0); 477 478 return; 479 } 480 default: 481 ccb->ccb_h.status = CAM_REQ_INVALID; 482 break; 483 } 484 485 xpt_done(ccb); 486 return; 487 } 488 489 static void 490 vscsi_srp_login(struct vscsi_softc *sc) 491 { 492 struct vscsi_xfer *xp; 493 struct srp_login *login; 494 struct vscsi_crq crq; 495 int err; 496 497 mtx_assert(&sc->io_lock, MA_OWNED); 498 499 xp = TAILQ_FIRST(&sc->free_xferq); 500 if (xp == NULL) 501 panic("SCSI queue flooded"); 502 xp->ccb = NULL; 503 TAILQ_REMOVE(&sc->free_xferq, xp, queue); 504 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); 505 506 /* Set up command */ 507 xp->srp_iu_size = 64; 508 crq.iu_length = htobe16(xp->srp_iu_size); 509 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, 510 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); 511 if (err) 512 panic("Error during VMEM allocation (%d)", err); 513 514 login = (struct srp_login *)((uint8_t *)xp->sc->srp_iu_queue + 515 (uintptr_t)xp->srp_iu_offset); 516 bzero(login, xp->srp_iu_size); 517 login->type = SRP_LOGIN_REQ; 518 login->tag = (uint64_t)(xp); 519 login->max_cmd_length = htobe64(256); 520 login->buffer_formats = htobe16(0x1 | 0x2); /* Direct and indirect */ 521 login->flags = 0; 522 523 /* Create CRQ entry */ 524 crq.valid = 0x80; 525 crq.format = 0x01; 526 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); 527 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); 528 529 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, 530 be64toh(((uint64_t *)(&crq))[0]), 531 be64toh(((uint64_t *)(&crq))[1])); 532 if (err != 0) 533 panic("CRQ send failure (%d)", err); 534 } 535 536 static void 537 vscsi_task_management(struct vscsi_softc *sc, union ccb *ccb) 538 { 539 struct srp_tsk_mgmt *cmd; 540 struct vscsi_xfer *xp; 541 struct vscsi_crq crq; 542 int err; 543 544 mtx_assert(&sc->io_lock, MA_OWNED); 545 546 xp = TAILQ_FIRST(&sc->free_xferq); 547 if (xp == NULL) 548 panic("SCSI queue flooded"); 549 xp->ccb = ccb; 550 TAILQ_REMOVE(&sc->free_xferq, xp, queue); 551 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); 552 553 xp->srp_iu_size = sizeof(*cmd); 554 crq.iu_length = htobe16(xp->srp_iu_size); 555 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, 556 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); 557 if (err) 558 panic("Error during VMEM allocation (%d)", err); 559 560 cmd = (struct srp_tsk_mgmt *)((uint8_t *)xp->sc->srp_iu_queue + 561 (uintptr_t)xp->srp_iu_offset); 562 bzero(cmd, xp->srp_iu_size); 563 cmd->type = SRP_TSK_MGMT; 564 cmd->tag = (uint64_t)xp; 565 cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); 566 567 switch (ccb->ccb_h.func_code) { 568 case XPT_RESET_DEV: 569 cmd->function = 0x08; 570 break; 571 default: 572 panic("Unimplemented code %d", ccb->ccb_h.func_code); 573 break; 574 } 575 576 bus_dmamap_sync(xp->sc->crq_tag, xp->sc->crq_map, BUS_DMASYNC_PREWRITE); 577 578 /* Create CRQ entry */ 579 crq.valid = 0x80; 580 crq.format = 0x01; 581 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); 582 583 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, 584 be64toh(((uint64_t *)(&crq))[0]), 585 be64toh(((uint64_t *)(&crq))[1])); 586 if (err != 0) 587 panic("CRQ send failure (%d)", err); 588 } 589 590 static void 591 vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, int nsegs, int err) 592 { 593 struct vscsi_xfer *xp = xxp; 594 uint8_t *cdb; 595 union ccb *ccb = xp->ccb; 596 struct srp_cmd *cmd; 597 uint64_t chunk_addr; 598 uint32_t chunk_size; 599 int desc_start, i; 600 struct vscsi_crq crq; 601 602 KASSERT(err == 0, ("DMA error %d\n", err)); 603 604 mtx_assert(&xp->sc->io_lock, MA_OWNED); 605 606 cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ? 607 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes; 608 609 /* Command format from Table 20, page 37 of SRP spec */ 610 xp->srp_iu_size = 48 + ((nsegs > 1) ? 20 : 16) + 611 ((ccb->csio.cdb_len > 16) ? (ccb->csio.cdb_len - 16) : 0); 612 crq.iu_length = htobe16(xp->srp_iu_size); 613 if (nsegs > 1) 614 xp->srp_iu_size += nsegs*16; 615 xp->srp_iu_size = roundup(xp->srp_iu_size, 16); 616 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, 617 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); 618 if (err) 619 panic("Error during VMEM allocation (%d)", err); 620 621 cmd = (struct srp_cmd *)((uint8_t *)xp->sc->srp_iu_queue + 622 (uintptr_t)xp->srp_iu_offset); 623 bzero(cmd, xp->srp_iu_size); 624 cmd->type = SRP_CMD; 625 if (ccb->csio.cdb_len > 16) 626 cmd->additional_cdb = (ccb->csio.cdb_len - 16) << 2; 627 memcpy(cmd->cdb, cdb, ccb->csio.cdb_len); 628 629 cmd->tag = (uint64_t)(xp); /* Let the responder find this again */ 630 cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun)); 631 632 if (nsegs > 1) { 633 /* Use indirect descriptors */ 634 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 635 case CAM_DIR_OUT: 636 cmd->formats = (2 << 4); 637 break; 638 case CAM_DIR_IN: 639 cmd->formats = 2; 640 break; 641 default: 642 panic("Does not support bidirectional commands (%d)", 643 ccb->ccb_h.flags & CAM_DIR_MASK); 644 break; 645 } 646 647 desc_start = ((ccb->csio.cdb_len > 16) ? 648 ccb->csio.cdb_len - 16 : 0); 649 chunk_addr = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 20 + 650 desc_start + sizeof(*cmd)); 651 chunk_size = htobe32(16*nsegs); 652 memcpy(&cmd->data_payload[desc_start], &chunk_addr, 8); 653 memcpy(&cmd->data_payload[desc_start+12], &chunk_size, 4); 654 chunk_size = 0; 655 for (i = 0; i < nsegs; i++) 656 chunk_size += segs[i].ds_len; 657 chunk_size = htobe32(chunk_size); 658 memcpy(&cmd->data_payload[desc_start+16], &chunk_size, 4); 659 desc_start += 20; 660 for (i = 0; i < nsegs; i++) { 661 chunk_addr = htobe64(segs[i].ds_addr); 662 chunk_size = htobe32(segs[i].ds_len); 663 664 memcpy(&cmd->data_payload[desc_start + 16*i], 665 &chunk_addr, 8); 666 /* Set handle tag to 0 */ 667 memcpy(&cmd->data_payload[desc_start + 16*i + 12], 668 &chunk_size, 4); 669 } 670 } else if (nsegs == 1) { 671 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 672 case CAM_DIR_OUT: 673 cmd->formats = (1 << 4); 674 break; 675 case CAM_DIR_IN: 676 cmd->formats = 1; 677 break; 678 default: 679 panic("Does not support bidirectional commands (%d)", 680 ccb->ccb_h.flags & CAM_DIR_MASK); 681 break; 682 } 683 684 /* 685 * Memory descriptor: 686 * 8 byte address 687 * 4 byte handle 688 * 4 byte length 689 */ 690 691 chunk_addr = htobe64(segs[0].ds_addr); 692 chunk_size = htobe32(segs[0].ds_len); 693 desc_start = ((ccb->csio.cdb_len > 16) ? 694 ccb->csio.cdb_len - 16 : 0); 695 696 memcpy(&cmd->data_payload[desc_start], &chunk_addr, 8); 697 /* Set handle tag to 0 */ 698 memcpy(&cmd->data_payload[desc_start+12], &chunk_size, 4); 699 KASSERT(xp->srp_iu_size >= 48 + ((ccb->csio.cdb_len > 16) ? 700 ccb->csio.cdb_len : 16), ("SRP IU command length")); 701 } else { 702 cmd->formats = 0; 703 } 704 bus_dmamap_sync(xp->sc->crq_tag, xp->sc->crq_map, BUS_DMASYNC_PREWRITE); 705 706 /* Create CRQ entry */ 707 crq.valid = 0x80; 708 crq.format = 0x01; 709 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); 710 711 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit, 712 be64toh(((uint64_t *)(&crq))[0]), 713 be64toh(((uint64_t *)(&crq))[1])); 714 if (err != 0) 715 panic("CRQ send failure (%d)", err); 716 } 717 718 static void 719 vscsi_crq_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err) 720 { 721 struct vscsi_softc *sc = xsc; 722 723 sc->crq_phys = segs[0].ds_addr; 724 sc->n_crqs = PAGE_SIZE/sizeof(struct vscsi_crq); 725 726 sc->srp_iu_queue = (uint8_t *)(sc->crq_queue); 727 sc->srp_iu_phys = segs[0].ds_addr; 728 sc->srp_iu_arena = vmem_create("VSCSI SRP IU", PAGE_SIZE, 729 segs[0].ds_len - PAGE_SIZE, 16, 0, M_BESTFIT | M_NOWAIT); 730 } 731 732 static void 733 vscsi_setup_bus(struct vscsi_softc *sc) 734 { 735 struct vscsi_crq crq; 736 struct vscsi_xfer *xp; 737 int error; 738 739 struct { 740 uint32_t type; 741 uint16_t status; 742 uint16_t length; 743 uint64_t tag; 744 uint64_t buffer; 745 struct { 746 char srp_version[8]; 747 char partition_name[96]; 748 uint32_t partition_number; 749 uint32_t mad_version; 750 uint32_t os_type; 751 uint32_t port_max_txu[8]; 752 } payload; 753 } mad_adapter_info; 754 755 bzero(&crq, sizeof(crq)); 756 757 /* Init message */ 758 crq.valid = 0xc0; 759 crq.format = 0x01; 760 761 do { 762 error = phyp_hcall(H_FREE_CRQ, sc->unit); 763 } while (error == H_BUSY); 764 765 /* See initialization sequence page 757 */ 766 bzero(sc->crq_queue, sc->n_crqs*sizeof(sc->crq_queue[0])); 767 sc->cur_crq = 0; 768 sc->bus_initialized = 0; 769 sc->bus_logged_in = 0; 770 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); 771 error = phyp_hcall(H_REG_CRQ, sc->unit, sc->crq_phys, 772 sc->n_crqs*sizeof(sc->crq_queue[0])); 773 KASSERT(error == 0, ("CRQ registration success")); 774 775 error = phyp_hcall(H_SEND_CRQ, sc->unit, 776 be64toh(((uint64_t *)(&crq))[0]), 777 be64toh(((uint64_t *)(&crq))[1])); 778 if (error != 0) 779 panic("CRQ setup failure (%d)", error); 780 781 while (sc->bus_initialized == 0) 782 vscsi_check_response_queue(sc); 783 784 /* Send MAD adapter info */ 785 mad_adapter_info.type = htobe32(MAD_ADAPTER_INFO_REQUEST); 786 mad_adapter_info.status = 0; 787 mad_adapter_info.length = htobe16(sizeof(mad_adapter_info.payload)); 788 789 strcpy(mad_adapter_info.payload.srp_version, "16.a"); 790 strcpy(mad_adapter_info.payload.partition_name, "UNKNOWN"); 791 mad_adapter_info.payload.partition_number = -1; 792 mad_adapter_info.payload.mad_version = htobe32(1); 793 mad_adapter_info.payload.os_type = htobe32(2); /* Claim we are Linux */ 794 mad_adapter_info.payload.port_max_txu[0] = 0; 795 /* If this fails, we get the defaults above */ 796 OF_getprop(OF_finddevice("/"), "ibm,partition-name", 797 mad_adapter_info.payload.partition_name, 798 sizeof(mad_adapter_info.payload.partition_name)); 799 OF_getprop(OF_finddevice("/"), "ibm,partition-no", 800 &mad_adapter_info.payload.partition_number, 801 sizeof(mad_adapter_info.payload.partition_number)); 802 803 xp = TAILQ_FIRST(&sc->free_xferq); 804 xp->ccb = NULL; 805 TAILQ_REMOVE(&sc->free_xferq, xp, queue); 806 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue); 807 xp->srp_iu_size = sizeof(mad_adapter_info); 808 crq.iu_length = htobe16(xp->srp_iu_size); 809 vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size, 810 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset); 811 mad_adapter_info.buffer = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 24); 812 mad_adapter_info.tag = (uint64_t)xp; 813 memcpy((uint8_t *)xp->sc->srp_iu_queue + (uintptr_t)xp->srp_iu_offset, 814 &mad_adapter_info, sizeof(mad_adapter_info)); 815 crq.valid = 0x80; 816 crq.format = 0x02; 817 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset); 818 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); 819 phyp_hcall(H_SEND_CRQ, xp->sc->unit, 820 be64toh(((uint64_t *)(&crq))[0]), 821 be64toh(((uint64_t *)(&crq))[1])); 822 823 while (TAILQ_EMPTY(&sc->free_xferq)) 824 vscsi_check_response_queue(sc); 825 826 /* Send SRP login */ 827 vscsi_srp_login(sc); 828 while (sc->bus_logged_in == 0) 829 vscsi_check_response_queue(sc); 830 831 error = phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */ 832 } 833 834 static void 835 vscsi_intr(void *xsc) 836 { 837 struct vscsi_softc *sc = xsc; 838 839 mtx_lock(&sc->io_lock); 840 vscsi_check_response_queue(sc); 841 mtx_unlock(&sc->io_lock); 842 } 843 844 static void 845 vscsi_srp_response(struct vscsi_xfer *xp, struct vscsi_crq *crq) 846 { 847 union ccb *ccb = xp->ccb; 848 struct vscsi_softc *sc = xp->sc; 849 struct srp_rsp *rsp; 850 uint32_t sense_len; 851 852 /* SRP response packet in original request */ 853 rsp = (struct srp_rsp *)((uint8_t *)sc->srp_iu_queue + 854 (uintptr_t)xp->srp_iu_offset); 855 ccb->csio.scsi_status = rsp->status; 856 if (ccb->csio.scsi_status == SCSI_STATUS_OK) 857 ccb->ccb_h.status = CAM_REQ_CMP; 858 else 859 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 860 #ifdef NOTYET 861 /* Collect fast fail codes */ 862 if (crq->status != 0) 863 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 864 #endif 865 866 if (ccb->ccb_h.status != CAM_REQ_CMP) { 867 ccb->ccb_h.status |= CAM_DEV_QFRZN; 868 xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1); 869 } 870 871 if (!(rsp->flags & SRP_RSPVALID)) 872 rsp->response_data_len = 0; 873 if (!(rsp->flags & SRP_SNSVALID)) 874 rsp->sense_data_len = 0; 875 if (!(rsp->flags & (SRP_DOOVER | SRP_DOUNDER))) 876 rsp->data_out_resid = 0; 877 if (!(rsp->flags & (SRP_DIOVER | SRP_DIUNDER))) 878 rsp->data_in_resid = 0; 879 880 if (rsp->flags & SRP_SNSVALID) { 881 bzero(&ccb->csio.sense_data, sizeof(struct scsi_sense_data)); 882 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 883 sense_len = min(be32toh(rsp->sense_data_len), 884 ccb->csio.sense_len); 885 memcpy(&ccb->csio.sense_data, 886 &rsp->data_payload[be32toh(rsp->response_data_len)], 887 sense_len); 888 ccb->csio.sense_resid = ccb->csio.sense_len - 889 be32toh(rsp->sense_data_len); 890 } 891 892 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 893 case CAM_DIR_OUT: 894 ccb->csio.resid = rsp->data_out_resid; 895 break; 896 case CAM_DIR_IN: 897 ccb->csio.resid = rsp->data_in_resid; 898 break; 899 } 900 901 bus_dmamap_sync(sc->data_tag, xp->dmamap, BUS_DMASYNC_POSTREAD); 902 bus_dmamap_unload(sc->data_tag, xp->dmamap); 903 xpt_done(ccb); 904 xp->ccb = NULL; 905 } 906 907 static void 908 vscsi_login_response(struct vscsi_xfer *xp, struct vscsi_crq *crq) 909 { 910 struct vscsi_softc *sc = xp->sc; 911 struct srp_login_rsp *rsp; 912 913 /* SRP response packet in original request */ 914 rsp = (struct srp_login_rsp *)((uint8_t *)sc->srp_iu_queue + 915 (uintptr_t)xp->srp_iu_offset); 916 KASSERT(be16toh(rsp->buffer_formats) & 0x3, ("Both direct and indirect " 917 "buffers supported")); 918 919 sc->max_transactions = be32toh(rsp->request_limit_delta); 920 device_printf(sc->dev, "Queue depth %d commands\n", 921 sc->max_transactions); 922 sc->bus_logged_in = 1; 923 } 924 925 static void 926 vscsi_cam_poll(struct cam_sim *sim) 927 { 928 struct vscsi_softc *sc = cam_sim_softc(sim); 929 930 vscsi_check_response_queue(sc); 931 } 932 933 static void 934 vscsi_check_response_queue(struct vscsi_softc *sc) 935 { 936 struct vscsi_crq *crq; 937 struct vscsi_xfer *xp; 938 int code; 939 940 mtx_assert(&sc->io_lock, MA_OWNED); 941 942 while (sc->crq_queue[sc->cur_crq].valid != 0) { 943 /* The hypercalls at both ends of this are not optimal */ 944 phyp_hcall(H_VIO_SIGNAL, sc->unit, 0); 945 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_POSTREAD); 946 947 crq = &sc->crq_queue[sc->cur_crq]; 948 949 switch (crq->valid) { 950 case 0xc0: 951 if (crq->format == 0x02) 952 sc->bus_initialized = 1; 953 break; 954 case 0x80: 955 /* IU data is set to tag pointer (the XP) */ 956 xp = (struct vscsi_xfer *)crq->iu_data; 957 958 switch (crq->format) { 959 case 0x01: 960 code = *((uint8_t *)sc->srp_iu_queue + 961 (uintptr_t)xp->srp_iu_offset); 962 switch (code) { 963 case SRP_RSP: 964 vscsi_srp_response(xp, crq); 965 break; 966 case SRP_LOGIN_RSP: 967 vscsi_login_response(xp, crq); 968 break; 969 default: 970 device_printf(sc->dev, "Unknown SRP " 971 "response code %d\n", code); 972 break; 973 } 974 break; 975 case 0x02: 976 /* Ignore management datagrams */ 977 break; 978 default: 979 panic("Unknown CRQ format %d\n", crq->format); 980 break; 981 } 982 vmem_free(sc->srp_iu_arena, xp->srp_iu_offset, 983 xp->srp_iu_size); 984 TAILQ_REMOVE(&sc->active_xferq, xp, queue); 985 TAILQ_INSERT_TAIL(&sc->free_xferq, xp, queue); 986 break; 987 default: 988 device_printf(sc->dev, 989 "Unknown CRQ message type %d\n", crq->valid); 990 break; 991 } 992 993 crq->valid = 0; 994 sc->cur_crq = (sc->cur_crq + 1) % sc->n_crqs; 995 996 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); 997 phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); 998 } 999 } 1000