Lines Matching +full:qemu +full:- +full:1 +full:- +full:setup

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
10 * 1. Redistributions of source code must retain the above copyright
189 #define vtscsi_modern(_sc) (((_sc)->vtscsi_features & VIRTIO_F_VERSION_1) != 0)
199 * The current QEMU VirtIO SCSI implementation does not cancel in-flight
200 * IO during virtio_stop(). So in-flight requests still complete after the
201 * device reset. We would have to wait for all the in-flight IO to complete,
208 static int vtscsi_bus_reset_disable = 1;
238 MODULE_VERSION(virtio_scsi, 1);
239 MODULE_DEPEND(virtio_scsi, virtio, 1, 1, 1);
240 MODULE_DEPEND(virtio_scsi, cam, 1, 1, 1);
278 sc->vtscsi_dev = dev; in vtscsi_attach()
282 TAILQ_INIT(&sc->vtscsi_req_free); in vtscsi_attach()
289 device_printf(dev, "cannot setup features\n"); in vtscsi_attach()
295 sc->vtscsi_max_channel = scsicfg.max_channel; in vtscsi_attach()
296 sc->vtscsi_max_target = scsicfg.max_target; in vtscsi_attach()
297 sc->vtscsi_max_lun = scsicfg.max_lun; in vtscsi_attach()
298 sc->vtscsi_event_buf_size = scsicfg.event_info_size; in vtscsi_attach()
302 sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max); in vtscsi_attach()
303 sc->vtscsi_sglist = sglist_alloc(sc->vtscsi_max_nsegs, M_NOWAIT); in vtscsi_attach()
304 if (sc->vtscsi_sglist == NULL) { in vtscsi_attach()
338 device_printf(dev, "cannot setup virtqueue interrupts\n"); in vtscsi_attach()
369 sc->vtscsi_flags |= VTSCSI_FLAG_DETACH; in vtscsi_detach()
380 if (sc->vtscsi_sglist != NULL) { in vtscsi_detach()
381 sglist_free(sc->vtscsi_sglist); in vtscsi_detach()
382 sc->vtscsi_sglist = NULL; in vtscsi_detach()
410 dev = sc->vtscsi_dev; in vtscsi_negotiate_features()
413 sc->vtscsi_features = virtio_negotiate_features(dev, features); in vtscsi_negotiate_features()
423 dev = sc->vtscsi_dev; in vtscsi_setup_features()
430 sc->vtscsi_flags |= VTSCSI_FLAG_INDIRECT; in vtscsi_setup_features()
432 sc->vtscsi_flags |= VTSCSI_FLAG_BIDIRECTIONAL; in vtscsi_setup_features()
434 sc->vtscsi_flags |= VTSCSI_FLAG_HOTPLUG; in vtscsi_setup_features()
442 &(_cfg)->_field, sizeof((_cfg)->_field)) \
450 dev = sc->vtscsi_dev; in vtscsi_read_config()
476 nsegs += MIN(seg_max, maxphys / PAGE_SIZE + 1); in vtscsi_maximum_segments()
477 if (sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT) in vtscsi_maximum_segments()
480 nsegs += 1; in vtscsi_maximum_segments()
492 dev = sc->vtscsi_dev; in vtscsi_alloc_virtqueues()
496 &sc->vtscsi_control_vq, "%s control", device_get_nameunit(dev)); in vtscsi_alloc_virtqueues()
498 VQ_ALLOC_INFO_INIT(&vq_info[1], 0, vtscsi_event_vq_intr, sc, in vtscsi_alloc_virtqueues()
499 &sc->vtscsi_event_vq, "%s event", device_get_nameunit(dev)); in vtscsi_alloc_virtqueues()
501 VQ_ALLOC_INFO_INIT(&vq_info[2], sc->vtscsi_max_nsegs, in vtscsi_alloc_virtqueues()
502 vtscsi_request_vq_intr, sc, &sc->vtscsi_request_vq, in vtscsi_alloc_virtqueues()
513 if ((sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT) == 0) { in vtscsi_check_sizes()
518 rqsize = virtqueue_size(sc->vtscsi_request_vq); in vtscsi_check_sizes()
519 if (sc->vtscsi_max_nsegs > rqsize) { in vtscsi_check_sizes()
520 device_printf(sc->vtscsi_dev, in vtscsi_check_sizes()
521 "clamping seg_max (%d %d)\n", sc->vtscsi_max_nsegs, in vtscsi_check_sizes()
523 sc->vtscsi_max_nsegs = rqsize; in vtscsi_check_sizes()
532 virtio_write_dev_config_4(sc->vtscsi_dev, in vtscsi_write_device_config()
540 virtio_write_dev_config_4(sc->vtscsi_dev, in vtscsi_write_device_config()
551 dev = sc->vtscsi_dev; in vtscsi_reinit()
553 error = virtio_reinit(dev, sc->vtscsi_features); in vtscsi_reinit()
574 dev = sc->vtscsi_dev; in vtscsi_alloc_cam()
575 openings = sc->vtscsi_nrequests - VTSCSI_RESERVED_REQUESTS; in vtscsi_alloc_cam()
583 sc->vtscsi_sim = cam_sim_alloc(vtscsi_cam_action, vtscsi_cam_poll, in vtscsi_alloc_cam()
584 "vtscsi", sc, device_get_unit(dev), VTSCSI_MTX(sc), 1, in vtscsi_alloc_cam()
586 if (sc->vtscsi_sim == NULL) { in vtscsi_alloc_cam()
601 dev = sc->vtscsi_dev; in vtscsi_register_cam()
606 if (xpt_bus_register(sc->vtscsi_sim, dev, 0) != CAM_SUCCESS) { in vtscsi_register_cam()
612 registered = 1; in vtscsi_register_cam()
614 if (xpt_create_path(&sc->vtscsi_path, NULL, in vtscsi_register_cam()
615 cam_sim_path(sc->vtscsi_sim), CAM_TARGET_WILDCARD, in vtscsi_register_cam()
633 if (sc->vtscsi_path != NULL) { in vtscsi_register_cam()
634 xpt_free_path(sc->vtscsi_path); in vtscsi_register_cam()
635 sc->vtscsi_path = NULL; in vtscsi_register_cam()
639 xpt_bus_deregister(cam_sim_path(sc->vtscsi_sim)); in vtscsi_register_cam()
652 if (sc->vtscsi_path != NULL) { in vtscsi_free_cam()
655 xpt_free_path(sc->vtscsi_path); in vtscsi_free_cam()
656 sc->vtscsi_path = NULL; in vtscsi_free_cam()
658 xpt_bus_deregister(cam_sim_path(sc->vtscsi_sim)); in vtscsi_free_cam()
661 if (sc->vtscsi_sim != NULL) { in vtscsi_free_cam()
662 cam_sim_free(sc->vtscsi_sim, 1); in vtscsi_free_cam()
663 sc->vtscsi_sim = NULL; in vtscsi_free_cam()
681 * TODO Once QEMU supports event reporting, we should in vtscsi_cam_async()
698 xpt_setup_ccb(&csa.ccb_h, sc->vtscsi_path, 5); in vtscsi_register_async()
702 csa.callback_arg = sc->vtscsi_sim; in vtscsi_register_async()
715 xpt_setup_ccb(&csa.ccb_h, sc->vtscsi_path, 5); in vtscsi_deregister_async()
719 csa.callback_arg = sc->vtscsi_sim; in vtscsi_deregister_async()
731 ccbh = &ccb->ccb_h; in vtscsi_cam_action()
735 if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) { in vtscsi_cam_action()
741 ccbh->status = CAM_NO_HBA; in vtscsi_cam_action()
746 switch (ccbh->func_code) { in vtscsi_cam_action()
752 ccbh->status = CAM_FUNC_NOTAVAIL; in vtscsi_cam_action()
773 cam_calc_geometry(&ccb->ccg, 1); in vtscsi_cam_action()
783 "invalid ccb=%p func=%#x\n", ccb, ccbh->func_code); in vtscsi_cam_action()
785 ccbh->status = CAM_REQ_INVALID; in vtscsi_cam_action()
809 ccbh = &ccb->ccb_h; in vtscsi_cam_scsi_io()
810 csio = &ccb->csio; in vtscsi_cam_scsi_io()
812 if (csio->cdb_len > VIRTIO_SCSI_CDB_SIZE) { in vtscsi_cam_scsi_io()
814 ccbh->status = CAM_REQ_INVALID; in vtscsi_cam_scsi_io()
818 if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_BOTH && in vtscsi_cam_scsi_io()
819 (sc->vtscsi_flags & VTSCSI_FLAG_BIDIRECTIONAL) == 0) { in vtscsi_cam_scsi_io()
821 ccbh->status = CAM_REQ_INVALID; in vtscsi_cam_scsi_io()
830 "error=%d ccb=%p status=%#x\n", error, ccb, ccbh->status); in vtscsi_cam_scsi_io()
841 cts = &ccb->cts; in vtscsi_cam_get_tran_settings()
842 scsi = &cts->proto_specific.scsi; in vtscsi_cam_get_tran_settings()
844 cts->protocol = PROTO_SCSI; in vtscsi_cam_get_tran_settings()
845 cts->protocol_version = SCSI_REV_SPC3; in vtscsi_cam_get_tran_settings()
846 cts->transport = XPORT_SAS; in vtscsi_cam_get_tran_settings()
847 cts->transport_version = 0; in vtscsi_cam_get_tran_settings()
849 scsi->valid = CTS_SCSI_VALID_TQ; in vtscsi_cam_get_tran_settings()
850 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; in vtscsi_cam_get_tran_settings()
852 ccb->ccb_h.status = CAM_REQ_CMP; in vtscsi_cam_get_tran_settings()
863 ccb->ccb_h.status = CAM_REQ_CMP; in vtscsi_cam_reset_bus()
865 ccb->ccb_h.status = CAM_REQ_CMP_ERR; in vtscsi_cam_reset_bus()
868 error, ccb, ccb->ccb_h.status); in vtscsi_cam_reset_bus()
880 ccbh = &ccb->ccb_h; in vtscsi_cam_reset_dev()
889 req->vsr_ccb = ccb; in vtscsi_cam_reset_dev()
902 ccbh->status = CAM_RESRC_UNAVAIL; in vtscsi_cam_reset_dev()
904 ccbh->status = CAM_REQ_CMP_ERR; in vtscsi_cam_reset_dev()
916 ccbh = &ccb->ccb_h; in vtscsi_cam_abort()
925 req->vsr_ccb = ccb; in vtscsi_cam_abort()
938 ccbh->status = CAM_RESRC_UNAVAIL; in vtscsi_cam_abort()
940 ccbh->status = CAM_REQ_CMP_ERR; in vtscsi_cam_abort()
952 dev = sc->vtscsi_dev; in vtscsi_cam_path_inquiry()
953 cpi = &ccb->cpi; in vtscsi_cam_path_inquiry()
957 cpi->version_num = 1; in vtscsi_cam_path_inquiry()
958 cpi->hba_inquiry = PI_TAG_ABLE; in vtscsi_cam_path_inquiry()
959 cpi->target_sprt = 0; in vtscsi_cam_path_inquiry()
960 cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED; in vtscsi_cam_path_inquiry()
962 cpi->hba_misc |= PIM_NOBUSRESET; in vtscsi_cam_path_inquiry()
963 cpi->hba_eng_cnt = 0; in vtscsi_cam_path_inquiry()
965 cpi->max_target = sc->vtscsi_max_target; in vtscsi_cam_path_inquiry()
966 cpi->max_lun = sc->vtscsi_max_lun; in vtscsi_cam_path_inquiry()
967 cpi->initiator_id = cpi->max_target + 1; in vtscsi_cam_path_inquiry()
969 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); in vtscsi_cam_path_inquiry()
970 strlcpy(cpi->hba_vid, "VirtIO", HBA_IDLEN); in vtscsi_cam_path_inquiry()
971 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); in vtscsi_cam_path_inquiry()
973 cpi->unit_number = cam_sim_unit(sim); in vtscsi_cam_path_inquiry()
974 cpi->bus_id = cam_sim_bus(sim); in vtscsi_cam_path_inquiry()
976 cpi->base_transfer_speed = 300000; in vtscsi_cam_path_inquiry()
978 cpi->protocol = PROTO_SCSI; in vtscsi_cam_path_inquiry()
979 cpi->protocol_version = SCSI_REV_SPC3; in vtscsi_cam_path_inquiry()
980 cpi->transport = XPORT_SAS; in vtscsi_cam_path_inquiry()
981 cpi->transport_version = 0; in vtscsi_cam_path_inquiry()
983 cpi->maxio = (sc->vtscsi_max_nsegs - VTSCSI_MIN_SEGMENTS - 1) * in vtscsi_cam_path_inquiry()
986 cpi->hba_vendor = virtio_get_vendor(dev); in vtscsi_cam_path_inquiry()
987 cpi->hba_device = virtio_get_device(dev); in vtscsi_cam_path_inquiry()
988 cpi->hba_subvendor = virtio_get_subvendor(dev); in vtscsi_cam_path_inquiry()
989 cpi->hba_subdevice = virtio_get_subdevice(dev); in vtscsi_cam_path_inquiry()
991 ccb->ccb_h.status = CAM_REQ_CMP; in vtscsi_cam_path_inquiry()
1003 ccbh = &csio->ccb_h; in vtscsi_sg_append_scsi_buf()
1006 switch ((ccbh->flags & CAM_DATA_MASK)) { in vtscsi_sg_append_scsi_buf()
1008 error = sglist_append(sg, csio->data_ptr, csio->dxfer_len); in vtscsi_sg_append_scsi_buf()
1012 (vm_paddr_t)(vm_offset_t) csio->data_ptr, csio->dxfer_len); in vtscsi_sg_append_scsi_buf()
1015 for (i = 0; i < csio->sglist_cnt && error == 0; i++) { in vtscsi_sg_append_scsi_buf()
1016 dseg = &((struct bus_dma_segment *)csio->data_ptr)[i]; in vtscsi_sg_append_scsi_buf()
1018 (void *)(vm_offset_t) dseg->ds_addr, dseg->ds_len); in vtscsi_sg_append_scsi_buf()
1022 for (i = 0; i < csio->sglist_cnt && error == 0; i++) { in vtscsi_sg_append_scsi_buf()
1023 dseg = &((struct bus_dma_segment *)csio->data_ptr)[i]; in vtscsi_sg_append_scsi_buf()
1025 (vm_paddr_t) dseg->ds_addr, dseg->ds_len); in vtscsi_sg_append_scsi_buf()
1029 error = sglist_append_bio(sg, (struct bio *) csio->data_ptr); in vtscsi_sg_append_scsi_buf()
1050 sg = sc->vtscsi_sglist; in vtscsi_fill_scsi_cmd_sglist()
1051 csio = &req->vsr_ccb->csio; in vtscsi_fill_scsi_cmd_sglist()
1052 ccbh = &csio->ccb_h; in vtscsi_fill_scsi_cmd_sglist()
1053 cmd_req = &req->vsr_cmd_req; in vtscsi_fill_scsi_cmd_sglist()
1054 cmd_resp = &req->vsr_cmd_resp; in vtscsi_fill_scsi_cmd_sglist()
1059 if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_OUT) { in vtscsi_fill_scsi_cmd_sglist()
1062 if (error || sg->sg_nseg == sg->sg_maxseg) in vtscsi_fill_scsi_cmd_sglist()
1066 *readable = sg->sg_nseg; in vtscsi_fill_scsi_cmd_sglist()
1069 if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_IN) { in vtscsi_fill_scsi_cmd_sglist()
1075 *writable = sg->sg_nseg - *readable; in vtscsi_fill_scsi_cmd_sglist()
1090 error, req, ccbh, sg->sg_nseg, sg->sg_maxseg); in vtscsi_fill_scsi_cmd_sglist()
1106 sg = sc->vtscsi_sglist; in vtscsi_execute_scsi_cmd()
1107 vq = sc->vtscsi_request_vq; in vtscsi_execute_scsi_cmd()
1108 csio = &req->vsr_ccb->csio; in vtscsi_execute_scsi_cmd()
1109 ccbh = &csio->ccb_h; in vtscsi_execute_scsi_cmd()
1110 cmd_req = &req->vsr_cmd_req; in vtscsi_execute_scsi_cmd()
1111 cmd_resp = &req->vsr_cmd_resp; in vtscsi_execute_scsi_cmd()
1119 req->vsr_complete = vtscsi_complete_scsi_cmd; in vtscsi_execute_scsi_cmd()
1120 cmd_resp->response = -1; in vtscsi_execute_scsi_cmd()
1127 ccbh->status = CAM_REQUEUE_REQ; in vtscsi_execute_scsi_cmd()
1132 ccbh->status |= CAM_SIM_QUEUED; in vtscsi_execute_scsi_cmd()
1133 ccbh->ccbh_vtscsi_req = req; in vtscsi_execute_scsi_cmd()
1137 if (ccbh->timeout != CAM_TIME_INFINITY) { in vtscsi_execute_scsi_cmd()
1138 req->vsr_flags |= VTSCSI_REQ_FLAG_TIMEOUT_SET; in vtscsi_execute_scsi_cmd()
1139 callout_reset_sbt(&req->vsr_callout, SBT_1MS * ccbh->timeout, in vtscsi_execute_scsi_cmd()
1157 ccb->ccb_h.status = CAM_REQUEUE_REQ; in vtscsi_start_scsi_cmd()
1162 req->vsr_ccb = ccb; in vtscsi_start_scsi_cmd()
1179 tmf_resp = &req->vsr_tmf_resp; in vtscsi_complete_abort_timedout_scsi_cmd()
1180 response = tmf_resp->response; in vtscsi_complete_abort_timedout_scsi_cmd()
1181 to_req = req->vsr_timedout_req; in vtscsi_complete_abort_timedout_scsi_cmd()
1192 if (to_req->vsr_state != VTSCSI_REQ_STATE_TIMEDOUT) in vtscsi_complete_abort_timedout_scsi_cmd()
1200 if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) in vtscsi_complete_abort_timedout_scsi_cmd()
1204 if (sc->vtscsi_flags & VTSCSI_FLAG_RESET) in vtscsi_complete_abort_timedout_scsi_cmd()
1221 sg = sc->vtscsi_sglist; in vtscsi_abort_timedout_scsi_cmd()
1222 to_ccbh = &to_req->vsr_ccb->ccb_h; in vtscsi_abort_timedout_scsi_cmd()
1230 tmf_req = &req->vsr_tmf_req; in vtscsi_abort_timedout_scsi_cmd()
1231 tmf_resp = &req->vsr_tmf_resp; in vtscsi_abort_timedout_scsi_cmd()
1240 req->vsr_timedout_req = to_req; in vtscsi_abort_timedout_scsi_cmd()
1241 req->vsr_complete = vtscsi_complete_abort_timedout_scsi_cmd; in vtscsi_abort_timedout_scsi_cmd()
1242 tmf_resp->response = -1; in vtscsi_abort_timedout_scsi_cmd()
1244 error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1, in vtscsi_abort_timedout_scsi_cmd()
1265 sc = to_req->vsr_softc; in vtscsi_timedout_scsi_cmd()
1268 to_req, to_req->vsr_ccb, to_req->vsr_state); in vtscsi_timedout_scsi_cmd()
1271 if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) in vtscsi_timedout_scsi_cmd()
1278 if (to_req->vsr_state != VTSCSI_REQ_STATE_INUSE || in vtscsi_timedout_scsi_cmd()
1279 (to_req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) == 0) in vtscsi_timedout_scsi_cmd()
1286 vtscsi_complete_vq(sc, sc->vtscsi_request_vq); in vtscsi_timedout_scsi_cmd()
1287 if (to_req->vsr_state == VTSCSI_REQ_STATE_FREE) in vtscsi_timedout_scsi_cmd()
1290 sc->vtscsi_stats.scsi_cmd_timeouts++; in vtscsi_timedout_scsi_cmd()
1291 to_req->vsr_state = VTSCSI_REQ_STATE_TIMEDOUT; in vtscsi_timedout_scsi_cmd()
1305 switch (cmd_resp->response) { in vtscsi_scsi_cmd_cam_status()
1344 csio->scsi_status = cmd_resp->status; in vtscsi_complete_scsi_cmd_response()
1345 csio->resid = vtscsi_htog32(sc, cmd_resp->resid); in vtscsi_complete_scsi_cmd_response()
1347 if (csio->scsi_status == SCSI_STATUS_OK) in vtscsi_complete_scsi_cmd_response()
1352 resp_sense_length = vtscsi_htog32(sc, cmd_resp->sense_len); in vtscsi_complete_scsi_cmd_response()
1357 if (resp_sense_length < csio->sense_len) in vtscsi_complete_scsi_cmd_response()
1358 csio->sense_resid = csio->sense_len - resp_sense_length; in vtscsi_complete_scsi_cmd_response()
1360 csio->sense_resid = 0; in vtscsi_complete_scsi_cmd_response()
1362 memcpy(&csio->sense_data, cmd_resp->sense, in vtscsi_complete_scsi_cmd_response()
1363 csio->sense_len - csio->sense_resid); in vtscsi_complete_scsi_cmd_response()
1368 csio, csio->scsi_status, csio->resid, csio->sense_resid); in vtscsi_complete_scsi_cmd_response()
1381 csio = &req->vsr_ccb->csio; in vtscsi_complete_scsi_cmd()
1382 ccbh = &csio->ccb_h; in vtscsi_complete_scsi_cmd()
1383 cmd_resp = &req->vsr_cmd_resp; in vtscsi_complete_scsi_cmd()
1385 KASSERT(ccbh->ccbh_vtscsi_req == req, in vtscsi_complete_scsi_cmd()
1386 ("ccb %p req mismatch %p/%p", ccbh, ccbh->ccbh_vtscsi_req, req)); in vtscsi_complete_scsi_cmd()
1388 if (req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) in vtscsi_complete_scsi_cmd()
1389 callout_stop(&req->vsr_callout); in vtscsi_complete_scsi_cmd()
1393 if (req->vsr_state == VTSCSI_REQ_STATE_TIMEDOUT) in vtscsi_complete_scsi_cmd()
1400 xpt_freeze_devq(ccbh->path, 1); in vtscsi_complete_scsi_cmd()
1409 ccbh->status = status; in vtscsi_complete_scsi_cmd()
1410 xpt_done(req->vsr_ccb); in vtscsi_complete_scsi_cmd()
1419 req->vsr_flags |= VTSCSI_REQ_FLAG_POLLED; in vtscsi_poll_ctrl_req()
1421 vtscsi_complete_vq(sc, sc->vtscsi_control_vq); in vtscsi_poll_ctrl_req()
1422 while ((req->vsr_flags & VTSCSI_REQ_FLAG_COMPLETE) == 0); in vtscsi_poll_ctrl_req()
1424 req->vsr_flags &= ~VTSCSI_REQ_FLAG_POLLED; in vtscsi_poll_ctrl_req()
1434 vq = sc->vtscsi_control_vq; in vtscsi_execute_ctrl_req()
1436 MPASS(flag == VTSCSI_EXECUTE_POLL || req->vsr_complete != NULL); in vtscsi_execute_ctrl_req()
1465 ccb = req->vsr_ccb; in vtscsi_complete_abort_task_cmd()
1466 ccbh = &ccb->ccb_h; in vtscsi_complete_abort_task_cmd()
1467 tmf_resp = &req->vsr_tmf_resp; in vtscsi_complete_abort_task_cmd()
1469 switch (tmf_resp->response) { in vtscsi_complete_abort_task_cmd()
1471 ccbh->status = CAM_REQ_CMP; in vtscsi_complete_abort_task_cmd()
1474 ccbh->status = CAM_UA_ABORT; in vtscsi_complete_abort_task_cmd()
1477 ccbh->status = CAM_REQ_CMP_ERR; in vtscsi_complete_abort_task_cmd()
1498 sg = sc->vtscsi_sglist; in vtscsi_execute_abort_task_cmd()
1499 cab = &req->vsr_ccb->cab; in vtscsi_execute_abort_task_cmd()
1500 ccbh = &cab->ccb_h; in vtscsi_execute_abort_task_cmd()
1501 tmf_req = &req->vsr_tmf_req; in vtscsi_execute_abort_task_cmd()
1502 tmf_resp = &req->vsr_tmf_resp; in vtscsi_execute_abort_task_cmd()
1505 abort_ccbh = &cab->abort_ccb->ccb_h; in vtscsi_execute_abort_task_cmd()
1506 abort_req = abort_ccbh->ccbh_vtscsi_req; in vtscsi_execute_abort_task_cmd()
1508 if (abort_ccbh->func_code != XPT_SCSI_IO || abort_req == NULL) { in vtscsi_execute_abort_task_cmd()
1513 /* Only attempt to abort requests that could be in-flight. */ in vtscsi_execute_abort_task_cmd()
1514 if (abort_req->vsr_state != VTSCSI_REQ_STATE_INUSE) { in vtscsi_execute_abort_task_cmd()
1519 abort_req->vsr_state = VTSCSI_REQ_STATE_ABORTED; in vtscsi_execute_abort_task_cmd()
1520 if (abort_req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) in vtscsi_execute_abort_task_cmd()
1521 callout_stop(&abort_req->vsr_callout); in vtscsi_execute_abort_task_cmd()
1530 req->vsr_complete = vtscsi_complete_abort_task_cmd; in vtscsi_execute_abort_task_cmd()
1531 tmf_resp->response = -1; in vtscsi_execute_abort_task_cmd()
1533 error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1, in vtscsi_execute_abort_task_cmd()
1551 ccb = req->vsr_ccb; in vtscsi_complete_reset_dev_cmd()
1552 ccbh = &ccb->ccb_h; in vtscsi_complete_reset_dev_cmd()
1553 tmf_resp = &req->vsr_tmf_resp; in vtscsi_complete_reset_dev_cmd()
1556 req, ccb, tmf_resp->response); in vtscsi_complete_reset_dev_cmd()
1558 if (tmf_resp->response == VIRTIO_SCSI_S_FUNCTION_COMPLETE) { in vtscsi_complete_reset_dev_cmd()
1559 ccbh->status = CAM_REQ_CMP; in vtscsi_complete_reset_dev_cmd()
1560 vtscsi_announce(sc, AC_SENT_BDR, ccbh->target_id, in vtscsi_complete_reset_dev_cmd()
1561 ccbh->target_lun); in vtscsi_complete_reset_dev_cmd()
1563 ccbh->status = CAM_REQ_CMP_ERR; in vtscsi_complete_reset_dev_cmd()
1581 sg = sc->vtscsi_sglist; in vtscsi_execute_reset_dev_cmd()
1582 crd = &req->vsr_ccb->crd; in vtscsi_execute_reset_dev_cmd()
1583 ccbh = &crd->ccb_h; in vtscsi_execute_reset_dev_cmd()
1584 tmf_req = &req->vsr_tmf_req; in vtscsi_execute_reset_dev_cmd()
1585 tmf_resp = &req->vsr_tmf_resp; in vtscsi_execute_reset_dev_cmd()
1587 if (ccbh->target_lun == CAM_LUN_WILDCARD) in vtscsi_execute_reset_dev_cmd()
1598 req->vsr_complete = vtscsi_complete_reset_dev_cmd; in vtscsi_execute_reset_dev_cmd()
1599 tmf_resp->response = -1; in vtscsi_execute_reset_dev_cmd()
1601 error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1, in vtscsi_execute_reset_dev_cmd()
1614 *target_id = lun[1]; in vtscsi_get_request_lun()
1622 lun[0] = 1; in vtscsi_set_request_lun()
1623 lun[1] = ccbh->target_id; in vtscsi_set_request_lun()
1624 lun[2] = 0x40 | ((ccbh->target_lun >> 8) & 0x3F); in vtscsi_set_request_lun()
1625 lun[3] = ccbh->target_lun & 0xFF; in vtscsi_set_request_lun()
1634 switch (csio->tag_action) { in vtscsi_init_scsi_cmd_req()
1649 vtscsi_set_request_lun(&csio->ccb_h, cmd_req->lun); in vtscsi_init_scsi_cmd_req()
1650 cmd_req->tag = vtscsi_gtoh64(sc, (uintptr_t) csio); in vtscsi_init_scsi_cmd_req()
1651 cmd_req->task_attr = attr; in vtscsi_init_scsi_cmd_req()
1653 memcpy(cmd_req->cdb, in vtscsi_init_scsi_cmd_req()
1654 csio->ccb_h.flags & CAM_CDB_POINTER ? in vtscsi_init_scsi_cmd_req()
1655 csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes, in vtscsi_init_scsi_cmd_req()
1656 csio->cdb_len); in vtscsi_init_scsi_cmd_req()
1664 vtscsi_set_request_lun(ccbh, tmf_req->lun); in vtscsi_init_ctrl_tmf_req()
1666 tmf_req->type = vtscsi_gtoh32(sc, VIRTIO_SCSI_T_TMF); in vtscsi_init_ctrl_tmf_req()
1667 tmf_req->subtype = vtscsi_gtoh32(sc, subtype); in vtscsi_init_ctrl_tmf_req()
1668 tmf_req->tag = vtscsi_gtoh64(sc, tag); in vtscsi_init_ctrl_tmf_req()
1676 frozen = sc->vtscsi_frozen; in vtscsi_freeze_simq()
1679 (sc->vtscsi_frozen & VTSCSI_FROZEN_NO_REQUESTS) == 0) in vtscsi_freeze_simq()
1680 sc->vtscsi_frozen |= VTSCSI_FROZEN_NO_REQUESTS; in vtscsi_freeze_simq()
1683 (sc->vtscsi_frozen & VTSCSI_FROZEN_REQUEST_VQ_FULL) == 0) in vtscsi_freeze_simq()
1684 sc->vtscsi_frozen |= VTSCSI_FROZEN_REQUEST_VQ_FULL; in vtscsi_freeze_simq()
1687 if (frozen == 0 && sc->vtscsi_frozen != 0) { in vtscsi_freeze_simq()
1689 xpt_freeze_simq(sc->vtscsi_sim, 1); in vtscsi_freeze_simq()
1698 if (sc->vtscsi_frozen == 0 || reason == 0) in vtscsi_thaw_simq()
1702 sc->vtscsi_frozen & VTSCSI_FROZEN_NO_REQUESTS) in vtscsi_thaw_simq()
1703 sc->vtscsi_frozen &= ~VTSCSI_FROZEN_NO_REQUESTS; in vtscsi_thaw_simq()
1706 sc->vtscsi_frozen & VTSCSI_FROZEN_REQUEST_VQ_FULL) in vtscsi_thaw_simq()
1707 sc->vtscsi_frozen &= ~VTSCSI_FROZEN_REQUEST_VQ_FULL; in vtscsi_thaw_simq()
1709 thawed = sc->vtscsi_frozen == 0; in vtscsi_thaw_simq()
1724 xpt_async(ac_code, sc->vtscsi_path, NULL); in vtscsi_announce()
1728 if (xpt_create_path(&path, NULL, cam_sim_path(sc->vtscsi_sim), in vtscsi_announce()
1751 status = xpt_create_path(&ccb->ccb_h.path, NULL, in vtscsi_execute_rescan()
1752 cam_sim_path(sc->vtscsi_sim), target_id, lun_id); in vtscsi_execute_rescan()
1775 vtscsi_get_request_lun(event->lun, &target_id, &lun_id); in vtscsi_transport_reset_event()
1777 switch (event->reason) { in vtscsi_transport_reset_event()
1783 device_printf(sc->vtscsi_dev, in vtscsi_transport_reset_event()
1784 "unhandled transport event reason: %d\n", event->reason); in vtscsi_transport_reset_event()
1794 if ((event->event & VIRTIO_SCSI_T_EVENTS_MISSED) == 0) { in vtscsi_handle_event()
1795 switch (event->event) { in vtscsi_handle_event()
1800 device_printf(sc->vtscsi_dev, in vtscsi_handle_event()
1801 "unhandled event: %d\n", event->event); in vtscsi_handle_event()
1824 sg = sc->vtscsi_sglist; in vtscsi_enqueue_event_buf()
1825 vq = sc->vtscsi_event_vq; in vtscsi_enqueue_event_buf()
1826 size = sc->vtscsi_event_buf_size; in vtscsi_enqueue_event_buf()
1835 error = virtqueue_enqueue(vq, event, sg, 0, sg->sg_nseg); in vtscsi_enqueue_event_buf()
1851 * The first release of QEMU with VirtIO SCSI support would crash in vtscsi_init_event_vq()
1855 if (sc->vtscsi_flags & VTSCSI_FLAG_HOTPLUG) in vtscsi_init_event_vq()
1856 size = sc->vtscsi_event_buf_size; in vtscsi_init_event_vq()
1864 event = &sc->vtscsi_event_bufs[i]; in vtscsi_init_event_vq()
1887 if ((sc->vtscsi_flags & VTSCSI_FLAG_HOTPLUG) == 0 || in vtscsi_reinit_event_vq()
1888 sc->vtscsi_event_buf_size < sizeof(struct virtio_scsi_event)) in vtscsi_reinit_event_vq()
1892 event = &sc->vtscsi_event_bufs[i]; in vtscsi_reinit_event_vq()
1908 vq = sc->vtscsi_event_vq; in vtscsi_drain_event_vq()
1923 if (sc->vtscsi_request_vq != NULL) in vtscsi_complete_vqs_locked()
1924 vtscsi_complete_vq(sc, sc->vtscsi_request_vq); in vtscsi_complete_vqs_locked()
1925 if (sc->vtscsi_control_vq != NULL) in vtscsi_complete_vqs_locked()
1926 vtscsi_complete_vq(sc, sc->vtscsi_control_vq); in vtscsi_complete_vqs_locked()
1944 ccb = req->vsr_ccb; in vtscsi_cancel_request()
1955 detach = (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) != 0; in vtscsi_cancel_request()
1961 if (req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) { in vtscsi_cancel_request()
1963 callout_drain(&req->vsr_callout); in vtscsi_cancel_request()
1965 callout_stop(&req->vsr_callout); in vtscsi_cancel_request()
1971 ccb->ccb_h.status = CAM_NO_HBA; in vtscsi_cancel_request()
1973 ccb->ccb_h.status = CAM_REQUEUE_REQ; in vtscsi_cancel_request()
2002 if (sc->vtscsi_control_vq != NULL) in vtscsi_drain_vqs()
2003 vtscsi_drain_vq(sc, sc->vtscsi_control_vq); in vtscsi_drain_vqs()
2004 if (sc->vtscsi_request_vq != NULL) in vtscsi_drain_vqs()
2005 vtscsi_drain_vq(sc, sc->vtscsi_request_vq); in vtscsi_drain_vqs()
2006 if (sc->vtscsi_event_vq != NULL) in vtscsi_drain_vqs()
2015 virtio_stop(sc->vtscsi_dev); in vtscsi_stop()
2026 device_printf(sc->vtscsi_dev, "bus reset disabled\n"); in vtscsi_reset_bus()
2030 sc->vtscsi_flags |= VTSCSI_FLAG_RESET; in vtscsi_reset_bus()
2033 * vtscsi_stop() will cause the in-flight requests to be canceled. in vtscsi_reset_bus()
2048 xpt_release_simq(sc->vtscsi_sim, 0); in vtscsi_reset_bus()
2052 device_printf(sc->vtscsi_dev, in vtscsi_reset_bus()
2059 sc->vtscsi_flags &= ~VTSCSI_FLAG_RESET; in vtscsi_reset_bus()
2071 req_nsegs = sglist_count(&req->vsr_ureq, sizeof(req->vsr_ureq)); in vtscsi_init_request()
2072 resp_nsegs = sglist_count(&req->vsr_uresp, sizeof(req->vsr_uresp)); in vtscsi_init_request()
2074 KASSERT(req_nsegs == 1, ("request crossed page boundary")); in vtscsi_init_request()
2075 KASSERT(resp_nsegs == 1, ("response crossed page boundary")); in vtscsi_init_request()
2078 req->vsr_softc = sc; in vtscsi_init_request()
2079 callout_init_mtx(&req->vsr_callout, VTSCSI_MTX(sc), 0); in vtscsi_init_request()
2094 nreqs = virtqueue_size(sc->vtscsi_request_vq); in vtscsi_alloc_requests()
2095 if ((sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT) == 0) in vtscsi_alloc_requests()
2107 sc->vtscsi_nrequests++; in vtscsi_alloc_requests()
2120 KASSERT(callout_active(&req->vsr_callout) == 0, in vtscsi_free_requests()
2123 sc->vtscsi_nrequests--; in vtscsi_free_requests()
2127 KASSERT(sc->vtscsi_nrequests == 0, ("leaked requests: %d", in vtscsi_free_requests()
2128 sc->vtscsi_nrequests)); in vtscsi_free_requests()
2135 KASSERT(req->vsr_softc == sc, in vtscsi_enqueue_request()
2136 ("non-matching request vsr_softc %p/%p", req->vsr_softc, sc)); in vtscsi_enqueue_request()
2142 xpt_release_simq(sc->vtscsi_sim, 1); in vtscsi_enqueue_request()
2144 req->vsr_ccb = NULL; in vtscsi_enqueue_request()
2145 req->vsr_complete = NULL; in vtscsi_enqueue_request()
2146 req->vsr_ptr0 = NULL; in vtscsi_enqueue_request()
2147 req->vsr_state = VTSCSI_REQ_STATE_FREE; in vtscsi_enqueue_request()
2148 req->vsr_flags = 0; in vtscsi_enqueue_request()
2150 bzero(&req->vsr_ureq, sizeof(req->vsr_ureq)); in vtscsi_enqueue_request()
2151 bzero(&req->vsr_uresp, sizeof(req->vsr_uresp)); in vtscsi_enqueue_request()
2158 TAILQ_INSERT_TAIL(&sc->vtscsi_req_free, req, vsr_link); in vtscsi_enqueue_request()
2166 req = TAILQ_FIRST(&sc->vtscsi_req_free); in vtscsi_dequeue_request()
2168 req->vsr_state = VTSCSI_REQ_STATE_INUSE; in vtscsi_dequeue_request()
2169 TAILQ_REMOVE(&sc->vtscsi_req_free, req, vsr_link); in vtscsi_dequeue_request()
2171 sc->vtscsi_stats.dequeue_no_requests++; in vtscsi_dequeue_request()
2182 if (req->vsr_flags & VTSCSI_REQ_FLAG_POLLED) in vtscsi_complete_request()
2183 req->vsr_flags |= VTSCSI_REQ_FLAG_COMPLETE; in vtscsi_complete_request()
2185 if (req->vsr_complete != NULL) in vtscsi_complete_request()
2186 req->vsr_complete(req->vsr_softc, req); in vtscsi_complete_request()
2207 vq = sc->vtscsi_control_vq; in vtscsi_control_vq_intr()
2212 vtscsi_complete_vq(sc, sc->vtscsi_control_vq); in vtscsi_control_vq_intr()
2231 vq = sc->vtscsi_event_vq; in vtscsi_event_vq_intr()
2255 vq = sc->vtscsi_request_vq; in vtscsi_request_vq_intr()
2260 vtscsi_complete_vq(sc, sc->vtscsi_request_vq); in vtscsi_request_vq_intr()
2275 virtqueue_disable_intr(sc->vtscsi_control_vq); in vtscsi_disable_vqs_intr()
2276 virtqueue_disable_intr(sc->vtscsi_event_vq); in vtscsi_disable_vqs_intr()
2277 virtqueue_disable_intr(sc->vtscsi_request_vq); in vtscsi_disable_vqs_intr()
2284 virtqueue_enable_intr(sc->vtscsi_control_vq); in vtscsi_enable_vqs_intr()
2285 virtqueue_enable_intr(sc->vtscsi_event_vq); in vtscsi_enable_vqs_intr()
2286 virtqueue_enable_intr(sc->vtscsi_request_vq); in vtscsi_enable_vqs_intr()
2294 TUNABLE_INT_FETCH("hw.vtscsi.debug_level", &sc->vtscsi_debug); in vtscsi_get_tunables()
2297 device_get_unit(sc->vtscsi_dev)); in vtscsi_get_tunables()
2298 TUNABLE_INT_FETCH(tmpstr, &sc->vtscsi_debug); in vtscsi_get_tunables()
2310 dev = sc->vtscsi_dev; in vtscsi_setup_sysctl()
2311 stats = &sc->vtscsi_stats; in vtscsi_setup_sysctl()
2317 CTLFLAG_RW, &sc->vtscsi_debug, 0, in vtscsi_setup_sysctl()
2321 CTLFLAG_RD, &stats->scsi_cmd_timeouts, in vtscsi_setup_sysctl()
2324 CTLFLAG_RD, &stats->dequeue_no_requests, in vtscsi_setup_sysctl()
2341 sc = req->vsr_softc; in vtscsi_printf_req()
2342 ccb = req->vsr_ccb; in vtscsi_printf_req()
2349 cam_sim_name(sc->vtscsi_sim), cam_sim_unit(sc->vtscsi_sim), in vtscsi_printf_req()
2350 cam_sim_bus(sc->vtscsi_sim)); in vtscsi_printf_req()
2352 xpt_path_sbuf(ccb->ccb_h.path, &sb); in vtscsi_printf_req()
2353 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in vtscsi_printf_req()
2354 scsi_command_string(&ccb->csio, &sb); in vtscsi_printf_req()
2355 sbuf_printf(&sb, "length %d ", ccb->csio.dxfer_len); in vtscsi_printf_req()
2363 printf("%s: %s: %s", device_get_nameunit(sc->vtscsi_dev), func, in vtscsi_printf_req()