Lines Matching refs:req

66     } req;  member
85 static void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) in virtio_scsi_init_req() argument
89 offsetof(VirtIOSCSIReq, resp_iov) + sizeof(req->resp_iov); in virtio_scsi_init_req()
91 req->vq = vq; in virtio_scsi_init_req()
92 req->dev = s; in virtio_scsi_init_req()
93 qemu_sglist_init(&req->qsgl, DEVICE(s), 8, vdev->dma_as); in virtio_scsi_init_req()
94 qemu_iovec_init(&req->resp_iov, 1); in virtio_scsi_init_req()
95 memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip); in virtio_scsi_init_req()
98 static void virtio_scsi_free_req(VirtIOSCSIReq *req) in virtio_scsi_free_req() argument
100 qemu_iovec_destroy(&req->resp_iov); in virtio_scsi_free_req()
101 qemu_sglist_destroy(&req->qsgl); in virtio_scsi_free_req()
102 g_free(req); in virtio_scsi_free_req()
105 static void virtio_scsi_complete_req(VirtIOSCSIReq *req) in virtio_scsi_complete_req() argument
107 VirtIOSCSI *s = req->dev; in virtio_scsi_complete_req()
108 VirtQueue *vq = req->vq; in virtio_scsi_complete_req()
111 qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size); in virtio_scsi_complete_req()
112 virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size); in virtio_scsi_complete_req()
119 if (req->sreq) { in virtio_scsi_complete_req()
120 req->sreq->hba_private = NULL; in virtio_scsi_complete_req()
121 scsi_req_unref(req->sreq); in virtio_scsi_complete_req()
123 virtio_scsi_free_req(req); in virtio_scsi_complete_req()
128 VirtIOSCSIReq *req = opaque; in virtio_scsi_complete_req_bh() local
130 virtio_scsi_complete_req(req); in virtio_scsi_complete_req_bh()
137 static void virtio_scsi_complete_req_from_main_loop(VirtIOSCSIReq *req) in virtio_scsi_complete_req_from_main_loop() argument
139 VirtIOSCSI *s = req->dev; in virtio_scsi_complete_req_from_main_loop()
143 virtio_scsi_complete_req(req); in virtio_scsi_complete_req_from_main_loop()
146 aio_wait_bh_oneshot(s->ctx, virtio_scsi_complete_req_bh, req); in virtio_scsi_complete_req_from_main_loop()
150 static void virtio_scsi_bad_req(VirtIOSCSIReq *req) in virtio_scsi_bad_req() argument
152 virtio_error(VIRTIO_DEVICE(req->dev), "wrong size for virtio-scsi headers"); in virtio_scsi_bad_req()
153 virtqueue_detach_element(req->vq, &req->elem, 0); in virtio_scsi_bad_req()
154 virtio_scsi_free_req(req); in virtio_scsi_bad_req()
157 static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov, in qemu_sgl_concat() argument
160 QEMUSGList *qsgl = &req->qsgl; in qemu_sgl_concat()
180 static int virtio_scsi_parse_req(VirtIOSCSIReq *req, in virtio_scsi_parse_req() argument
183 VirtIODevice *vdev = (VirtIODevice *) req->dev; in virtio_scsi_parse_req()
186 if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0, in virtio_scsi_parse_req()
187 &req->req, req_size) < req_size) { in virtio_scsi_parse_req()
191 if (qemu_iovec_concat_iov(&req->resp_iov, in virtio_scsi_parse_req()
192 req->elem.in_sg, req->elem.in_num, 0, in virtio_scsi_parse_req()
197 req->resp_size = resp_size; in virtio_scsi_parse_req()
210 if (req->elem.out_num) { in virtio_scsi_parse_req()
211 req_size = req->elem.out_sg[0].iov_len; in virtio_scsi_parse_req()
213 if (req->elem.in_num) { in virtio_scsi_parse_req()
214 resp_size = req->elem.in_sg[0].iov_len; in virtio_scsi_parse_req()
218 out_size = qemu_sgl_concat(req, req->elem.out_sg, in virtio_scsi_parse_req()
219 &req->elem.out_addr[0], req->elem.out_num, in virtio_scsi_parse_req()
221 in_size = qemu_sgl_concat(req, req->elem.in_sg, in virtio_scsi_parse_req()
222 &req->elem.in_addr[0], req->elem.in_num, in virtio_scsi_parse_req()
230 req->mode = SCSI_XFER_TO_DEV; in virtio_scsi_parse_req()
232 req->mode = SCSI_XFER_FROM_DEV; in virtio_scsi_parse_req()
241 VirtIOSCSIReq *req; in virtio_scsi_pop_req() local
243 req = virtqueue_pop(vq, sizeof(VirtIOSCSIReq) + vs->cdb_size); in virtio_scsi_pop_req()
244 if (!req) { in virtio_scsi_pop_req()
247 virtio_scsi_init_req(s, vq, req); in virtio_scsi_pop_req()
248 return req; in virtio_scsi_pop_req()
253 VirtIOSCSIReq *req = sreq->hba_private; in virtio_scsi_save_request() local
254 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev); in virtio_scsi_save_request()
255 VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); in virtio_scsi_save_request()
256 uint32_t n = virtio_get_queue_index(req->vq) - VIRTIO_SCSI_VQ_NUM_FIXED; in virtio_scsi_save_request()
260 qemu_put_virtqueue_element(vdev, f, &req->elem); in virtio_scsi_save_request()
269 VirtIOSCSIReq *req; in virtio_scsi_load_request() local
274 req = qemu_get_virtqueue_element(vdev, f, in virtio_scsi_load_request()
276 virtio_scsi_init_req(s, vs->cmd_vqs[n], req); in virtio_scsi_load_request()
278 if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size, in virtio_scsi_load_request()
285 req->sreq = sreq; in virtio_scsi_load_request()
286 if (req->sreq->cmd.mode != SCSI_XFER_NONE) { in virtio_scsi_load_request()
287 assert(req->sreq->cmd.mode == req->mode); in virtio_scsi_load_request()
289 return req; in virtio_scsi_load_request()
304 VirtIOSCSIReq *req = n->tmf_req; in virtio_scsi_cancel_notify() local
306 trace_virtio_scsi_tmf_resp(virtio_scsi_get_lun(req->req.tmf.lun), in virtio_scsi_cancel_notify()
307 req->req.tmf.tag, req->resp.tmf.response); in virtio_scsi_cancel_notify()
308 virtio_scsi_complete_req(req); in virtio_scsi_cancel_notify()
320 static void virtio_scsi_do_one_tmf_bh(VirtIOSCSIReq *req) in virtio_scsi_do_one_tmf_bh() argument
322 VirtIOSCSI *s = req->dev; in virtio_scsi_do_one_tmf_bh()
323 SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); in virtio_scsi_do_one_tmf_bh()
327 switch (req->req.tmf.subtype) { in virtio_scsi_do_one_tmf_bh()
330 req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; in virtio_scsi_do_one_tmf_bh()
333 if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { in virtio_scsi_do_one_tmf_bh()
334 req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; in virtio_scsi_do_one_tmf_bh()
343 target = req->req.tmf.lun[1]; in virtio_scsi_do_one_tmf_bh()
365 virtio_scsi_complete_req_from_main_loop(req); in virtio_scsi_do_one_tmf_bh()
373 VirtIOSCSIReq *req; in virtio_scsi_do_tmf_bh() local
379 QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { in virtio_scsi_do_tmf_bh()
380 QTAILQ_REMOVE(&s->tmf_bh_list, req, next); in virtio_scsi_do_tmf_bh()
381 QTAILQ_INSERT_TAIL(&reqs, req, next); in virtio_scsi_do_tmf_bh()
388 QTAILQ_FOREACH_SAFE(req, &reqs, next, tmp) { in virtio_scsi_do_tmf_bh()
389 QTAILQ_REMOVE(&reqs, req, next); in virtio_scsi_do_tmf_bh()
390 virtio_scsi_do_one_tmf_bh(req); in virtio_scsi_do_tmf_bh()
396 VirtIOSCSIReq *req; in virtio_scsi_reset_tmf_bh() local
407 QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) { in virtio_scsi_reset_tmf_bh()
408 QTAILQ_REMOVE(&s->tmf_bh_list, req, next); in virtio_scsi_reset_tmf_bh()
411 req->resp.tmf.response = VIRTIO_SCSI_S_TARGET_FAILURE; in virtio_scsi_reset_tmf_bh()
412 virtio_scsi_complete_req(req); in virtio_scsi_reset_tmf_bh()
416 static void virtio_scsi_defer_tmf_to_bh(VirtIOSCSIReq *req) in virtio_scsi_defer_tmf_to_bh() argument
418 VirtIOSCSI *s = req->dev; in virtio_scsi_defer_tmf_to_bh()
421 QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next); in virtio_scsi_defer_tmf_to_bh()
433 static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) in virtio_scsi_do_tmf() argument
435 SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); in virtio_scsi_do_tmf()
441 req->resp.tmf.response = VIRTIO_SCSI_S_OK; in virtio_scsi_do_tmf()
447 req->req.tmf.subtype = in virtio_scsi_do_tmf()
448 virtio_tswap32(VIRTIO_DEVICE(s), req->req.tmf.subtype); in virtio_scsi_do_tmf()
450 trace_virtio_scsi_tmf_req(virtio_scsi_get_lun(req->req.tmf.lun), in virtio_scsi_do_tmf()
451 req->req.tmf.tag, req->req.tmf.subtype); in virtio_scsi_do_tmf()
453 switch (req->req.tmf.subtype) { in virtio_scsi_do_tmf()
459 if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { in virtio_scsi_do_tmf()
464 if (cmd_req && cmd_req->req.cmd.tag == req->req.tmf.tag) { in virtio_scsi_do_tmf()
474 if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK) { in virtio_scsi_do_tmf()
478 req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED; in virtio_scsi_do_tmf()
482 req->remaining = 1; in virtio_scsi_do_tmf()
484 notifier->tmf_req = req; in virtio_scsi_do_tmf()
494 virtio_scsi_defer_tmf_to_bh(req); in virtio_scsi_do_tmf()
504 if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) { in virtio_scsi_do_tmf()
513 req->remaining = 1; in virtio_scsi_do_tmf()
516 if (req->req.tmf.subtype == VIRTIO_SCSI_T_TMF_QUERY_TASK_SET) { in virtio_scsi_do_tmf()
520 req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED; in virtio_scsi_do_tmf()
525 req->remaining++; in virtio_scsi_do_tmf()
528 notifier->tmf_req = req; in virtio_scsi_do_tmf()
533 if (--req->remaining > 0) { in virtio_scsi_do_tmf()
540 req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; in virtio_scsi_do_tmf()
548 req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; in virtio_scsi_do_tmf()
553 req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; in virtio_scsi_do_tmf()
558 static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) in virtio_scsi_handle_ctrl_req() argument
564 if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0, in virtio_scsi_handle_ctrl_req()
566 virtio_scsi_bad_req(req); in virtio_scsi_handle_ctrl_req()
572 if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlTMFReq), in virtio_scsi_handle_ctrl_req()
574 virtio_scsi_bad_req(req); in virtio_scsi_handle_ctrl_req()
577 r = virtio_scsi_do_tmf(s, req); in virtio_scsi_handle_ctrl_req()
582 if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICtrlANReq), in virtio_scsi_handle_ctrl_req()
584 virtio_scsi_bad_req(req); in virtio_scsi_handle_ctrl_req()
587 req->req.an.event_requested = in virtio_scsi_handle_ctrl_req()
588 virtio_tswap32(VIRTIO_DEVICE(s), req->req.an.event_requested); in virtio_scsi_handle_ctrl_req()
589 trace_virtio_scsi_an_req(virtio_scsi_get_lun(req->req.an.lun), in virtio_scsi_handle_ctrl_req()
590 req->req.an.event_requested); in virtio_scsi_handle_ctrl_req()
591 req->resp.an.event_actual = 0; in virtio_scsi_handle_ctrl_req()
592 req->resp.an.response = VIRTIO_SCSI_S_OK; in virtio_scsi_handle_ctrl_req()
597 trace_virtio_scsi_tmf_resp(virtio_scsi_get_lun(req->req.tmf.lun), in virtio_scsi_handle_ctrl_req()
598 req->req.tmf.tag, in virtio_scsi_handle_ctrl_req()
599 req->resp.tmf.response); in virtio_scsi_handle_ctrl_req()
602 trace_virtio_scsi_an_resp(virtio_scsi_get_lun(req->req.an.lun), in virtio_scsi_handle_ctrl_req()
603 req->resp.an.response); in virtio_scsi_handle_ctrl_req()
604 virtio_scsi_complete_req(req); in virtio_scsi_handle_ctrl_req()
612 VirtIOSCSIReq *req; in virtio_scsi_handle_ctrl_vq() local
614 while ((req = virtio_scsi_pop_req(s, vq))) { in virtio_scsi_handle_ctrl_vq()
615 virtio_scsi_handle_ctrl_req(s, req); in virtio_scsi_handle_ctrl_vq()
648 static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req) in virtio_scsi_complete_cmd_req() argument
650 trace_virtio_scsi_cmd_resp(virtio_scsi_get_lun(req->req.cmd.lun), in virtio_scsi_complete_cmd_req()
651 req->req.cmd.tag, in virtio_scsi_complete_cmd_req()
652 req->resp.cmd.response, in virtio_scsi_complete_cmd_req()
653 req->resp.cmd.status); in virtio_scsi_complete_cmd_req()
657 req->resp_size = sizeof(VirtIOSCSICmdResp); in virtio_scsi_complete_cmd_req()
658 virtio_scsi_complete_req(req); in virtio_scsi_complete_cmd_req()
663 VirtIOSCSIReq *req = r->hba_private; in virtio_scsi_command_failed() local
669 req->resp.cmd.status = GOOD; in virtio_scsi_command_failed()
672 req->resp.cmd.response = VIRTIO_SCSI_S_INCORRECT_LUN; in virtio_scsi_command_failed()
675 req->resp.cmd.response = VIRTIO_SCSI_S_BUSY; in virtio_scsi_command_failed()
679 req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED; in virtio_scsi_command_failed()
682 req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; in virtio_scsi_command_failed()
685 req->resp.cmd.response = VIRTIO_SCSI_S_RESET; in virtio_scsi_command_failed()
688 req->resp.cmd.response = VIRTIO_SCSI_S_TRANSPORT_FAILURE; in virtio_scsi_command_failed()
691 req->resp.cmd.response = VIRTIO_SCSI_S_TARGET_FAILURE; in virtio_scsi_command_failed()
694 req->resp.cmd.response = VIRTIO_SCSI_S_NEXUS_FAILURE; in virtio_scsi_command_failed()
700 req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE; in virtio_scsi_command_failed()
703 virtio_scsi_complete_cmd_req(req); in virtio_scsi_command_failed()
708 VirtIOSCSIReq *req = r->hba_private; in virtio_scsi_command_complete() local
711 VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); in virtio_scsi_command_complete()
717 req->resp.cmd.response = VIRTIO_SCSI_S_OK; in virtio_scsi_command_complete()
718 req->resp.cmd.status = r->status; in virtio_scsi_command_complete()
719 if (req->resp.cmd.status == GOOD) { in virtio_scsi_command_complete()
720 req->resp.cmd.resid = virtio_tswap32(vdev, resid); in virtio_scsi_command_complete()
722 req->resp.cmd.resid = 0; in virtio_scsi_command_complete()
724 sense_len = MIN(sense_len, req->resp_iov.size - sizeof(req->resp.cmd)); in virtio_scsi_command_complete()
725 qemu_iovec_from_buf(&req->resp_iov, sizeof(req->resp.cmd), in virtio_scsi_command_complete()
727 req->resp.cmd.sense_len = virtio_tswap32(vdev, sense_len); in virtio_scsi_command_complete()
729 virtio_scsi_complete_cmd_req(req); in virtio_scsi_command_complete()
736 VirtIOSCSIReq *req = hba_private; in virtio_scsi_parse_cdb() local
746 cmd->xfer = req->qsgl.size; in virtio_scsi_parse_cdb()
747 cmd->mode = req->mode; in virtio_scsi_parse_cdb()
753 VirtIOSCSIReq *req = r->hba_private; in virtio_scsi_get_sg_list() local
755 return &req->qsgl; in virtio_scsi_get_sg_list()
760 VirtIOSCSIReq *req = r->hba_private; in virtio_scsi_request_cancelled() local
762 if (!req) { in virtio_scsi_request_cancelled()
765 if (qatomic_read(&req->dev->resetting)) { in virtio_scsi_request_cancelled()
766 req->resp.cmd.response = VIRTIO_SCSI_S_RESET; in virtio_scsi_request_cancelled()
768 req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED; in virtio_scsi_request_cancelled()
770 virtio_scsi_complete_cmd_req(req); in virtio_scsi_request_cancelled()
773 static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req) in virtio_scsi_fail_cmd_req() argument
775 req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE; in virtio_scsi_fail_cmd_req()
776 virtio_scsi_complete_cmd_req(req); in virtio_scsi_fail_cmd_req()
779 static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) in virtio_scsi_handle_cmd_req_prepare() argument
785 rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size, in virtio_scsi_handle_cmd_req_prepare()
789 virtio_scsi_fail_cmd_req(req); in virtio_scsi_handle_cmd_req_prepare()
792 virtio_scsi_bad_req(req); in virtio_scsi_handle_cmd_req_prepare()
796 trace_virtio_scsi_cmd_req(virtio_scsi_get_lun(req->req.cmd.lun), in virtio_scsi_handle_cmd_req_prepare()
797 req->req.cmd.tag, req->req.cmd.cdb[0]); in virtio_scsi_handle_cmd_req_prepare()
799 d = virtio_scsi_device_get(s, req->req.cmd.lun); in virtio_scsi_handle_cmd_req_prepare()
801 req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; in virtio_scsi_handle_cmd_req_prepare()
802 virtio_scsi_complete_cmd_req(req); in virtio_scsi_handle_cmd_req_prepare()
806 req->sreq = scsi_req_new(d, req->req.cmd.tag, in virtio_scsi_handle_cmd_req_prepare()
807 virtio_scsi_get_lun(req->req.cmd.lun), in virtio_scsi_handle_cmd_req_prepare()
808 req->req.cmd.cdb, vs->cdb_size, req); in virtio_scsi_handle_cmd_req_prepare()
810 if (req->sreq->cmd.mode != SCSI_XFER_NONE in virtio_scsi_handle_cmd_req_prepare()
811 && (req->sreq->cmd.mode != req->mode || in virtio_scsi_handle_cmd_req_prepare()
812 req->sreq->cmd.xfer > req->qsgl.size)) { in virtio_scsi_handle_cmd_req_prepare()
813 req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; in virtio_scsi_handle_cmd_req_prepare()
814 virtio_scsi_complete_cmd_req(req); in virtio_scsi_handle_cmd_req_prepare()
818 scsi_req_ref(req->sreq); in virtio_scsi_handle_cmd_req_prepare()
824 static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req) in virtio_scsi_handle_cmd_req_submit() argument
826 SCSIRequest *sreq = req->sreq; in virtio_scsi_handle_cmd_req_submit()
836 VirtIOSCSIReq *req, *next; in virtio_scsi_handle_cmd_vq() local
847 while ((req = virtio_scsi_pop_req(s, vq))) { in virtio_scsi_handle_cmd_vq()
848 ret = virtio_scsi_handle_cmd_req_prepare(s, req); in virtio_scsi_handle_cmd_vq()
850 QTAILQ_INSERT_TAIL(&reqs, req, next); in virtio_scsi_handle_cmd_vq()
854 req = QTAILQ_FIRST(&reqs); in virtio_scsi_handle_cmd_vq()
855 QTAILQ_REMOVE(&reqs, req, next); in virtio_scsi_handle_cmd_vq()
857 scsi_req_unref(req->sreq); in virtio_scsi_handle_cmd_vq()
858 virtqueue_detach_element(req->vq, &req->elem, 0); in virtio_scsi_handle_cmd_vq()
859 virtio_scsi_free_req(req); in virtio_scsi_handle_cmd_vq()
869 QTAILQ_FOREACH_SAFE(req, &reqs, next, next) { in virtio_scsi_handle_cmd_vq()
870 virtio_scsi_handle_cmd_req_submit(s, req); in virtio_scsi_handle_cmd_vq()
967 VirtIOSCSIReq *req; in virtio_scsi_push_event() local
977 req = virtio_scsi_pop_req(s, vs->event_vq); in virtio_scsi_push_event()
978 if (!req) { in virtio_scsi_push_event()
988 if (virtio_scsi_parse_req(req, 0, sizeof(VirtIOSCSIEvent))) { in virtio_scsi_push_event()
989 virtio_scsi_bad_req(req); in virtio_scsi_push_event()
993 evt = &req->resp.event; in virtio_scsi_push_event()
1009 virtio_scsi_complete_req(req); in virtio_scsi_push_event()