virtio_scsi.c revision 315813
11558Srgrimes/*-
292058Sobrien * Copyright (c) 2012, Bryan Venteicher <bryanv@FreeBSD.org>
392058Sobrien * All rights reserved.
492058Sobrien *
51558Srgrimes * Redistribution and use in source and binary forms, with or without
61558Srgrimes * modification, are permitted provided that the following conditions
71558Srgrimes * are met:
81558Srgrimes * 1. Redistributions of source code must retain the above copyright
91558Srgrimes *    notice unmodified, this list of conditions, and the following
101558Srgrimes *    disclaimer.
111558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121558Srgrimes *    notice, this list of conditions and the following disclaimer in the
131558Srgrimes *    documentation and/or other materials provided with the distribution.
141558Srgrimes *
151558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161558Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171558Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181558Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
191558Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
201558Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
211558Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
221558Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2392058Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
241558Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251558Srgrimes */
261558Srgrimes
271558Srgrimes/* Driver for VirtIO SCSI devices. */
281558Srgrimes
291558Srgrimes#include <sys/cdefs.h>
301558Srgrimes__FBSDID("$FreeBSD: stable/10/sys/dev/virtio/scsi/virtio_scsi.c 315813 2017-03-23 06:41:13Z mav $");
311558Srgrimes
321558Srgrimes#include <sys/param.h>
331558Srgrimes#include <sys/systm.h>
341558Srgrimes#include <sys/kernel.h>
351558Srgrimes#include <sys/kthread.h>
361558Srgrimes#include <sys/malloc.h>
371558Srgrimes#include <sys/module.h>
381558Srgrimes#include <sys/sglist.h>
3992058Sobrien#include <sys/sysctl.h>
4092058Sobrien#include <sys/lock.h>
411558Srgrimes#include <sys/mutex.h>
421558Srgrimes#include <sys/callout.h>
43115449Sobrien#include <sys/queue.h>
441558Srgrimes#include <sys/sbuf.h>
4536632Scharnier
461558Srgrimes#include <machine/stdarg.h>
471558Srgrimes
481558Srgrimes#include <machine/bus.h>
491558Srgrimes#include <machine/resource.h>
501558Srgrimes#include <sys/bus.h>
511558Srgrimes#include <sys/rman.h>
521558Srgrimes
53115449Sobrien#include <cam/cam.h>
5436632Scharnier#include <cam/cam_ccb.h>
5599365Smarkm#include <cam/cam_sim.h>
5699365Smarkm#include <cam/cam_periph.h>
5799365Smarkm#include <cam/cam_xpt_sim.h>
581558Srgrimes#include <cam/cam_debug.h>
59114552Sphk#include <cam/scsi/scsi_all.h>
601558Srgrimes#include <cam/scsi/scsi_message.h>
611558Srgrimes
6213544Sjoerg#include <dev/virtio/virtio.h>
63103669Sphk#include <dev/virtio/virtqueue.h>
641558Srgrimes#include <dev/virtio/scsi/virtio_scsi.h>
65101994Sbmilekic#include <dev/virtio/scsi/virtio_scsivar.h>
661558Srgrimes
67112307Sru#include "virtio_if.h"
681558Srgrimes
691558Srgrimesstatic int	vtscsi_modevent(module_t, int, void *);
701558Srgrimes
71114569Sphkstatic int	vtscsi_probe(device_t);
7213544Sjoergstatic int	vtscsi_attach(device_t);
7313544Sjoergstatic int	vtscsi_detach(device_t);
7413544Sjoergstatic int	vtscsi_suspend(device_t);
751558Srgrimesstatic int	vtscsi_resume(device_t);
7626542Scharnier
7759216Simpstatic void	vtscsi_negotiate_features(struct vtscsi_softc *);
7899365Smarkmstatic void	vtscsi_read_config(struct vtscsi_softc *,
791558Srgrimes		    struct virtio_scsi_config *);
801558Srgrimesstatic int	vtscsi_maximum_segments(struct vtscsi_softc *, int);
81114571Sphkstatic int	vtscsi_alloc_virtqueues(struct vtscsi_softc *);
82114571Sphkstatic void	vtscsi_write_device_config(struct vtscsi_softc *);
83133347Sdesstatic int	vtscsi_reinit(struct vtscsi_softc *);
84114571Sphk
85133347Sdesstatic int	vtscsi_alloc_cam(struct vtscsi_softc *);
86114571Sphkstatic int	vtscsi_register_cam(struct vtscsi_softc *);
87121222Sphkstatic void	vtscsi_free_cam(struct vtscsi_softc *);
88114571Sphkstatic void	vtscsi_cam_async(void *, uint32_t, struct cam_path *, void *);
89114571Sphkstatic int	vtscsi_register_async(struct vtscsi_softc *);
90114571Sphkstatic void	vtscsi_deregister_async(struct vtscsi_softc *);
91114571Sphkstatic void	vtscsi_cam_action(struct cam_sim *, union ccb *);
92114571Sphkstatic void	vtscsi_cam_poll(struct cam_sim *);
93114571Sphk
94114571Sphkstatic void	vtscsi_cam_scsi_io(struct vtscsi_softc *, struct cam_sim *,
9513544Sjoerg		    union ccb *);
961558Srgrimesstatic void	vtscsi_cam_get_tran_settings(struct vtscsi_softc *,
971558Srgrimes		    union ccb *);
98114571Sphkstatic void	vtscsi_cam_reset_bus(struct vtscsi_softc *, union ccb *);
99114571Sphkstatic void	vtscsi_cam_reset_dev(struct vtscsi_softc *, union ccb *);
100114571Sphkstatic void	vtscsi_cam_abort(struct vtscsi_softc *, union ccb *);
1011558Srgrimesstatic void	vtscsi_cam_path_inquiry(struct vtscsi_softc *,
102114571Sphk		    struct cam_sim *, union ccb *);
103114571Sphk
104114574Sphkstatic int	vtscsi_sg_append_scsi_buf(struct vtscsi_softc *,
105114574Sphk		    struct sglist *, struct ccb_scsiio *);
106114571Sphkstatic int	vtscsi_fill_scsi_cmd_sglist(struct vtscsi_softc *,
107114571Sphk		    struct vtscsi_request *, int *, int *);
1081558Srgrimesstatic int	vtscsi_execute_scsi_cmd(struct vtscsi_softc *,
10973034Sjwd		    struct vtscsi_request *);
11073034Sjwdstatic int	vtscsi_start_scsi_cmd(struct vtscsi_softc *, union ccb *);
111114571Sphkstatic void	vtscsi_complete_abort_timedout_scsi_cmd(struct vtscsi_softc *,
112114571Sphk		    struct vtscsi_request *);
113114571Sphkstatic int	vtscsi_abort_timedout_scsi_cmd(struct vtscsi_softc *,
11473034Sjwd		    struct vtscsi_request *);
115114571Sphkstatic void	vtscsi_timedout_scsi_cmd(void *);
116114574Sphkstatic cam_status vtscsi_scsi_cmd_cam_status(struct virtio_scsi_cmd_resp *);
117114571Sphkstatic cam_status vtscsi_complete_scsi_cmd_response(struct vtscsi_softc *,
1181558Srgrimes		    struct ccb_scsiio *, struct virtio_scsi_cmd_resp *);
119114673Sphkstatic void	vtscsi_complete_scsi_cmd(struct vtscsi_softc *,
120115995Sphk		    struct vtscsi_request *);
121115995Sphk
122115995Sphkstatic void	vtscsi_poll_ctrl_req(struct vtscsi_softc *,
123115995Sphk		    struct vtscsi_request *);
124115995Sphkstatic int	vtscsi_execute_ctrl_req(struct vtscsi_softc *,
125115995Sphk		    struct vtscsi_request *, struct sglist *, int, int, int);
126115696Sphkstatic void	vtscsi_complete_abort_task_cmd(struct vtscsi_softc *c,
127115696Sphk		    struct vtscsi_request *);
128114551Sphkstatic int	vtscsi_execute_abort_task_cmd(struct vtscsi_softc *,
129114551Sphk		    struct vtscsi_request *);
130114551Sphkstatic int	vtscsi_execute_reset_dev_cmd(struct vtscsi_softc *,
131114551Sphk		    struct vtscsi_request *);
132114551Sphk
133114551Sphkstatic void	vtscsi_get_request_lun(uint8_t [], target_id_t *, lun_id_t *);
134114551Sphkstatic void	vtscsi_set_request_lun(struct ccb_hdr *, uint8_t []);
135114550Sphkstatic void	vtscsi_init_scsi_cmd_req(struct ccb_scsiio *,
1361558Srgrimes		    struct virtio_scsi_cmd_req *);
137109872Sphkstatic void	vtscsi_init_ctrl_tmf_req(struct ccb_hdr *, uint32_t,
1381558Srgrimes		    uintptr_t, struct virtio_scsi_ctrl_tmf_req *);
1391558Srgrimes
140112307Srustatic void	vtscsi_freeze_simq(struct vtscsi_softc *, int);
141114571Sphkstatic int	vtscsi_thaw_simq(struct vtscsi_softc *, int);
142127650Sluigi
1431558Srgrimesstatic void	vtscsi_announce(struct vtscsi_softc *, uint32_t, target_id_t,
14413544Sjoerg		    lun_id_t);
14592541Simpstatic void	vtscsi_execute_rescan(struct vtscsi_softc *, target_id_t,
1461558Srgrimes		    lun_id_t);
1471558Srgrimesstatic void	vtscsi_execute_rescan_bus(struct vtscsi_softc *);
148114569Sphk
149114571Sphkstatic void	vtscsi_handle_event(struct vtscsi_softc *,
1501558Srgrimes		    struct virtio_scsi_event *);
151127650Sluigistatic int	vtscsi_enqueue_event_buf(struct vtscsi_softc *,
1521558Srgrimes		    struct virtio_scsi_event *);
153114574Sphkstatic int	vtscsi_init_event_vq(struct vtscsi_softc *);
154114574Sphkstatic void	vtscsi_reinit_event_vq(struct vtscsi_softc *);
155114574Sphkstatic void	vtscsi_drain_event_vq(struct vtscsi_softc *);
1561558Srgrimes
1571558Srgrimesstatic void	vtscsi_complete_vqs_locked(struct vtscsi_softc *);
1581558Srgrimesstatic void	vtscsi_complete_vqs(struct vtscsi_softc *);
1591558Srgrimesstatic void	vtscsi_drain_vqs(struct vtscsi_softc *);
1601558Srgrimesstatic void	vtscsi_cancel_request(struct vtscsi_softc *,
1611558Srgrimes		    struct vtscsi_request *);
162127650Sluigistatic void	vtscsi_drain_vq(struct vtscsi_softc *, struct virtqueue *);
163127650Sluigistatic void	vtscsi_stop(struct vtscsi_softc *);
164127650Sluigistatic int	vtscsi_reset_bus(struct vtscsi_softc *);
165112307Sru
166115948Sphkstatic void	vtscsi_init_request(struct vtscsi_softc *,
167115948Sphk		    struct vtscsi_request *);
168115948Sphkstatic int	vtscsi_alloc_requests(struct vtscsi_softc *);
169115948Sphkstatic void	vtscsi_free_requests(struct vtscsi_softc *);
170115696Sphkstatic void	vtscsi_enqueue_request(struct vtscsi_softc *,
171115696Sphk		    struct vtscsi_request *);
172114550Sphkstatic struct vtscsi_request * vtscsi_dequeue_request(struct vtscsi_softc *);
173114551Sphk
174114550Sphkstatic void	vtscsi_complete_request(struct vtscsi_request *);
175115696Sphkstatic void	vtscsi_complete_vq(struct vtscsi_softc *, struct virtqueue *);
176114550Sphk
177114550Sphkstatic void	vtscsi_control_vq_intr(void *);
178114550Sphkstatic void	vtscsi_event_vq_intr(void *);
179114571Sphkstatic void	vtscsi_request_vq_intr(void *);
180114571Sphkstatic void	vtscsi_disable_vqs_intr(struct vtscsi_softc *);
181114550Sphkstatic void	vtscsi_enable_vqs_intr(struct vtscsi_softc *);
182112307Sru
18373034Sjwdstatic void	vtscsi_get_tunables(struct vtscsi_softc *);
18473034Sjwdstatic void	vtscsi_add_sysctl(struct vtscsi_softc *);
18573034Sjwd
1861558Srgrimesstatic void	vtscsi_printf_req(struct vtscsi_request *, const char *,
1871558Srgrimes		    const char *, ...);
1881558Srgrimes
1891558Srgrimes/* Global tunables. */
1901558Srgrimes/*
1911558Srgrimes * The current QEMU VirtIO SCSI implementation does not cancel in-flight
1921558Srgrimes * IO during virtio_stop(). So in-flight requests still complete after the
1931558Srgrimes * device reset. We would have to wait for all the in-flight IO to complete,
1941558Srgrimes * which defeats the typical purpose of a bus reset. We could simulate the
1951558Srgrimes * bus reset with either I_T_NEXUS_RESET of all the targets, or with
1961558Srgrimes * LOGICAL_UNIT_RESET of all the LUNs (assuming there is space in the
197114571Sphk * control virtqueue). But this isn't very useful if things really go off
198114571Sphk * the rails, so default to disabled for now.
199114571Sphk */
200114571Sphkstatic int vtscsi_bus_reset_disable = 1;
2011558SrgrimesTUNABLE_INT("hw.vtscsi.bus_reset_disable", &vtscsi_bus_reset_disable);
2021558Srgrimes
2031558Srgrimesstatic struct virtio_feature_desc vtscsi_feature_desc[] = {
2041558Srgrimes	{ VIRTIO_SCSI_F_INOUT,		"InOut"		},
2051558Srgrimes	{ VIRTIO_SCSI_F_HOTPLUG,	"Hotplug"	},
2061558Srgrimes
2071558Srgrimes	{ 0, NULL }
2081558Srgrimes};
2091558Srgrimes
2101558Srgrimesstatic device_method_t vtscsi_methods[] = {
2111558Srgrimes	/* Device methods. */
2121558Srgrimes	DEVMETHOD(device_probe,		vtscsi_probe),
213114571Sphk	DEVMETHOD(device_attach,	vtscsi_attach),
2141558Srgrimes	DEVMETHOD(device_detach,	vtscsi_detach),
2151558Srgrimes	DEVMETHOD(device_suspend,	vtscsi_suspend),
216115995Sphk	DEVMETHOD(device_resume,	vtscsi_resume),
217115995Sphk
2181558Srgrimes	DEVMETHOD_END
219114569Sphk};
220127650Sluigi
221127650Sluigistatic driver_t vtscsi_driver = {
222127650Sluigi	"vtscsi",
223114569Sphk	vtscsi_methods,
224114569Sphk	sizeof(struct vtscsi_softc)
225114569Sphk};
226114569Sphkstatic devclass_t vtscsi_devclass;
227114569Sphk
228114569SphkDRIVER_MODULE(virtio_scsi, virtio_pci, vtscsi_driver, vtscsi_devclass,
2291558Srgrimes    vtscsi_modevent, 0);
2301558SrgrimesMODULE_VERSION(virtio_scsi, 1);
231114571SphkMODULE_DEPEND(virtio_scsi, virtio, 1, 1, 1);
232114571SphkMODULE_DEPEND(virtio_scsi, cam, 1, 1, 1);
233114571Sphk
234114571Sphkstatic int
235114571Sphkvtscsi_modevent(module_t mod, int type, void *unused)
2361558Srgrimes{
2371558Srgrimes	int error;
23848957Sbillf
23948957Sbillf	switch (type) {
24048957Sbillf	case MOD_LOAD:
2411558Srgrimes	case MOD_QUIESCE:
2421558Srgrimes	case MOD_UNLOAD:
2431558Srgrimes	case MOD_SHUTDOWN:
244114571Sphk		error = 0;
245121222Sphk		break;
246114571Sphk	default:
2471558Srgrimes		error = EOPNOTSUPP;
2481558Srgrimes		break;
2491558Srgrimes	}
2501558Srgrimes
2511558Srgrimes	return (error);
252114571Sphk}
253114571Sphk
254114571Sphkstatic int
2551558Srgrimesvtscsi_probe(device_t dev)
2561558Srgrimes{
2571558Srgrimes
2581558Srgrimes	if (virtio_get_device_type(dev) != VIRTIO_ID_SCSI)
2591558Srgrimes		return (ENXIO);
2601558Srgrimes
261114569Sphk	device_set_desc(dev, "VirtIO SCSI Adapter");
262114571Sphk
26337865Sbde	return (BUS_PROBE_DEFAULT);
26437865Sbde}
265114571Sphk
2661558Srgrimesstatic int
2671558Srgrimesvtscsi_attach(device_t dev)
2681558Srgrimes{
269114571Sphk	struct vtscsi_softc *sc;
270114571Sphk	struct virtio_scsi_config scsicfg;
271114571Sphk	int error;
272114571Sphk
273114571Sphk	sc = device_get_softc(dev);
2741558Srgrimes	sc->vtscsi_dev = dev;
275114571Sphk
276114571Sphk	VTSCSI_LOCK_INIT(sc, device_get_nameunit(dev));
277121222Sphk	TAILQ_INIT(&sc->vtscsi_req_free);
278114571Sphk
279114571Sphk	vtscsi_get_tunables(sc);
2801558Srgrimes	vtscsi_add_sysctl(sc);
2811558Srgrimes
2821558Srgrimes	virtio_set_feature_desc(dev, vtscsi_feature_desc);
2831558Srgrimes	vtscsi_negotiate_features(sc);
284114571Sphk
285121222Sphk	if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC))
2861558Srgrimes		sc->vtscsi_flags |= VTSCSI_FLAG_INDIRECT;
287114571Sphk	if (virtio_with_feature(dev, VIRTIO_SCSI_F_INOUT))
288114571Sphk		sc->vtscsi_flags |= VTSCSI_FLAG_BIDIRECTIONAL;
289114571Sphk	if (virtio_with_feature(dev, VIRTIO_SCSI_F_HOTPLUG))
2901558Srgrimes		sc->vtscsi_flags |= VTSCSI_FLAG_HOTPLUG;
2911558Srgrimes
2921558Srgrimes	vtscsi_read_config(sc, &scsicfg);
2931558Srgrimes
2941558Srgrimes	sc->vtscsi_max_channel = scsicfg.max_channel;
295121222Sphk	sc->vtscsi_max_target = scsicfg.max_target;
296121222Sphk	sc->vtscsi_max_lun = scsicfg.max_lun;
297121222Sphk	sc->vtscsi_event_buf_size = scsicfg.event_info_size;
298121222Sphk
299121222Sphk	vtscsi_write_device_config(sc);
300121222Sphk
301121222Sphk	sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max);
302121222Sphk	sc->vtscsi_sglist = sglist_alloc(sc->vtscsi_max_nsegs, M_NOWAIT);
303121222Sphk	if (sc->vtscsi_sglist == NULL) {
304121222Sphk		error = ENOMEM;
305121222Sphk		device_printf(dev, "cannot allocate sglist\n");
306121222Sphk		goto fail;
307121222Sphk	}
308121222Sphk
309121222Sphk	error = vtscsi_alloc_virtqueues(sc);
310121222Sphk	if (error) {
311121222Sphk		device_printf(dev, "cannot allocate virtqueues\n");
312121222Sphk		goto fail;
3131558Srgrimes	}
314111286Sru
3151558Srgrimes	error = vtscsi_init_event_vq(sc);
316114571Sphk	if (error) {
317114571Sphk		device_printf(dev, "cannot populate the eventvq\n");
3181558Srgrimes		goto fail;
31992541Simp	}
32013550Sjoerg
32113550Sjoerg	error = vtscsi_alloc_requests(sc);
32213550Sjoerg	if (error) {
32313550Sjoerg		device_printf(dev, "cannot allocate requests\n");
32413544Sjoerg		goto fail;
32536632Scharnier	}
32636632Scharnier
3271558Srgrimes	error = vtscsi_alloc_cam(sc);
3281558Srgrimes	if (error) {
3291558Srgrimes		device_printf(dev, "cannot allocate CAM structures\n");
3301558Srgrimes		goto fail;
331114571Sphk	}
332114571Sphk
3331558Srgrimes	error = virtio_setup_intr(dev, INTR_TYPE_CAM);
334114571Sphk	if (error) {
335114571Sphk		device_printf(dev, "cannot setup virtqueue interrupts\n");
336127044Sjhb		goto fail;
337114571Sphk	}
338114571Sphk
339114571Sphk	vtscsi_enable_vqs_intr(sc);
340114571Sphk
341114571Sphk	/*
342114571Sphk	 * Register with CAM after interrupts are enabled so we will get
343114571Sphk	 * notified of the probe responses.
344114860Sphk	 */
345114860Sphk	error = vtscsi_register_cam(sc);
346114860Sphk	if (error) {
347114571Sphk		device_printf(dev, "cannot register with CAM\n");
348127044Sjhb		goto fail;
349127044Sjhb	}
350127044Sjhb
351127044Sjhbfail:
352127044Sjhb	if (error)
353127044Sjhb		vtscsi_detach(dev);
354127044Sjhb
355127044Sjhb	return (error);
356127044Sjhb}
357114571Sphk
358114860Sphkstatic int
359114860Sphkvtscsi_detach(device_t dev)
360114860Sphk{
361114571Sphk	struct vtscsi_softc *sc;
362114571Sphk
363133347Sdes	sc = device_get_softc(dev);
364114571Sphk
365114571Sphk	VTSCSI_LOCK(sc);
366114571Sphk	sc->vtscsi_flags |= VTSCSI_FLAG_DETACH;
367114571Sphk	if (device_is_attached(dev))
368114571Sphk		vtscsi_stop(sc);
369114571Sphk	VTSCSI_UNLOCK(sc);
370112307Sru
371114569Sphk	vtscsi_complete_vqs(sc);
372114569Sphk	vtscsi_drain_vqs(sc);
373114569Sphk
374114571Sphk	vtscsi_free_cam(sc);
37538384Sdfr	vtscsi_free_requests(sc);
37673034Sjwd
377114574Sphk	if (sc->vtscsi_sglist != NULL) {
378114571Sphk		sglist_free(sc->vtscsi_sglist);
37973034Sjwd		sc->vtscsi_sglist = NULL;
380109878Sphk	}
381109878Sphk
382109878Sphk	VTSCSI_LOCK_DESTROY(sc);
383109878Sphk
384109878Sphk	return (0);
385109878Sphk}
386114571Sphk
387114571Sphkstatic int
388114673Sphkvtscsi_suspend(device_t dev)
389114673Sphk{
390114673Sphk
391115696Sphk	return (0);
392115696Sphk}
393114552Sphk
394114569Sphkstatic int
395114571Sphkvtscsi_resume(device_t dev)
396112307Sru{
397112307Sru
398112307Sru	return (0);
399114569Sphk}
400114569Sphk
401114569Sphkstatic void
402127650Sluigivtscsi_negotiate_features(struct vtscsi_softc *sc)
403127650Sluigi{
404127650Sluigi	device_t dev;
405127650Sluigi	uint64_t features;
406115624Sphk
407115624Sphk	dev = sc->vtscsi_dev;
408114569Sphk	features = virtio_negotiate_features(dev, VTSCSI_FEATURES);
409114569Sphk	sc->vtscsi_features = features;
410133347Sdes}
411115696Sphk
412114569Sphk#define VTSCSI_GET_CONFIG(_dev, _field, _cfg)			\
413114571Sphk	virtio_read_device_config(_dev,				\
414114571Sphk	    offsetof(struct virtio_scsi_config, _field),	\
415114571Sphk	    &(_cfg)->_field, sizeof((_cfg)->_field))		\
416114571Sphk
417114571Sphkstatic void
418114569Sphkvtscsi_read_config(struct vtscsi_softc *sc,
419114569Sphk    struct virtio_scsi_config *scsicfg)
420115624Sphk{
421115624Sphk	device_t dev;
422114569Sphk
423114569Sphk	dev = sc->vtscsi_dev;
424114571Sphk
425114569Sphk	bzero(scsicfg, sizeof(struct virtio_scsi_config));
426114571Sphk
427114571Sphk	VTSCSI_GET_CONFIG(dev, num_queues, scsicfg);
428114571Sphk	VTSCSI_GET_CONFIG(dev, seg_max, scsicfg);
429114571Sphk	VTSCSI_GET_CONFIG(dev, max_sectors, scsicfg);
430114571Sphk	VTSCSI_GET_CONFIG(dev, cmd_per_lun, scsicfg);
431114569Sphk	VTSCSI_GET_CONFIG(dev, event_info_size, scsicfg);
432114569Sphk	VTSCSI_GET_CONFIG(dev, sense_size, scsicfg);
433114569Sphk	VTSCSI_GET_CONFIG(dev, cdb_size, scsicfg);
434114571Sphk	VTSCSI_GET_CONFIG(dev, max_channel, scsicfg);
435114569Sphk	VTSCSI_GET_CONFIG(dev, max_target, scsicfg);
436114569Sphk	VTSCSI_GET_CONFIG(dev, max_lun, scsicfg);
437114569Sphk}
438114569Sphk
439114569Sphk#undef VTSCSI_GET_CONFIG
440109878Sphk
4411558Srgrimesstatic int
4421558Srgrimesvtscsi_maximum_segments(struct vtscsi_softc *sc, int seg_max)
4431558Srgrimes{
444127650Sluigi	int nsegs;
445127650Sluigi
446127650Sluigi	nsegs = VTSCSI_MIN_SEGMENTS;
447127650Sluigi
448127650Sluigi	if (seg_max > 0) {
449127650Sluigi		nsegs += MIN(seg_max, MAXPHYS / PAGE_SIZE + 1);
450127650Sluigi		if (sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT)
451127650Sluigi			nsegs = MIN(nsegs, VIRTIO_MAX_INDIRECT);
452127650Sluigi	} else
453127650Sluigi		nsegs += 1;
454127650Sluigi
455127650Sluigi	return (nsegs);
456127650Sluigi}
457127650Sluigi
458127650Sluigistatic int
4591558Srgrimesvtscsi_alloc_virtqueues(struct vtscsi_softc *sc)
4601558Srgrimes{
4611558Srgrimes	device_t dev;
4621558Srgrimes	struct vq_alloc_info vq_info[3];
463114571Sphk	int nvqs;
464114571Sphk
4651558Srgrimes	dev = sc->vtscsi_dev;
466114673Sphk	nvqs = 3;
467114569Sphk
468114673Sphk	VQ_ALLOC_INFO_INIT(&vq_info[0], 0, vtscsi_control_vq_intr, sc,
469114673Sphk	    &sc->vtscsi_control_vq, "%s control", device_get_nameunit(dev));
4701558Srgrimes
471114569Sphk	VQ_ALLOC_INFO_INIT(&vq_info[1], 0, vtscsi_event_vq_intr, sc,
472114569Sphk	    &sc->vtscsi_event_vq, "%s event", device_get_nameunit(dev));
473114569Sphk
474127650Sluigi	VQ_ALLOC_INFO_INIT(&vq_info[2], sc->vtscsi_max_nsegs,
475127650Sluigi	    vtscsi_request_vq_intr, sc, &sc->vtscsi_request_vq,
476127650Sluigi	    "%s request", device_get_nameunit(dev));
477115696Sphk
478115696Sphk	return (virtio_alloc_virtqueues(dev, 0, nvqs, vq_info));
479115696Sphk}
480114550Sphk
481114571Sphkstatic void
482114569Sphkvtscsi_write_device_config(struct vtscsi_softc *sc)
483114569Sphk{
484115696Sphk
485115696Sphk	virtio_write_dev_config_4(sc->vtscsi_dev,
486115696Sphk	    offsetof(struct virtio_scsi_config, sense_size),
487114571Sphk	    VIRTIO_SCSI_SENSE_SIZE);
488114571Sphk
489114673Sphk	/*
490115624Sphk	 * This is the size in the virtio_scsi_cmd_req structure. Note
491115624Sphk	 * this value (32) is larger than the maximum CAM CDB size (16).
492114673Sphk	 */
493114673Sphk	virtio_write_dev_config_4(sc->vtscsi_dev,
494114673Sphk	    offsetof(struct virtio_scsi_config, cdb_size),
495114673Sphk	    VIRTIO_SCSI_CDB_SIZE);
496114673Sphk}
497114673Sphk
498114673Sphkstatic int
499114673Sphkvtscsi_reinit(struct vtscsi_softc *sc)
500114673Sphk{
501114673Sphk	device_t dev;
502114673Sphk	int error;
503114673Sphk
504114673Sphk	dev = sc->vtscsi_dev;
505114673Sphk
506114571Sphk	error = virtio_reinit(dev, sc->vtscsi_features);
5071558Srgrimes	if (error == 0) {
5081558Srgrimes		vtscsi_write_device_config(sc);
5091558Srgrimes		vtscsi_reinit_event_vq(sc);
510114571Sphk		virtio_reinit_complete(dev);
51192541Simp
5121558Srgrimes		vtscsi_enable_vqs_intr(sc);
51392541Simp	}
51492541Simp
5151558Srgrimes	vtscsi_dprintf(sc, VTSCSI_TRACE, "error=%d\n", error);
516114571Sphk
517114571Sphk	return (error);
518114571Sphk}
5191558Srgrimes
520114574Sphkstatic int
521114574Sphkvtscsi_alloc_cam(struct vtscsi_softc *sc)
522114574Sphk{
523114574Sphk	device_t dev;
524114574Sphk	struct cam_devq *devq;
525114574Sphk	int openings;
526114574Sphk
527114574Sphk	dev = sc->vtscsi_dev;
528114574Sphk	openings = sc->vtscsi_nrequests - VTSCSI_RESERVED_REQUESTS;
529114574Sphk
530114574Sphk	devq = cam_simq_alloc(openings);
531114574Sphk	if (devq == NULL) {
532114574Sphk		device_printf(dev, "cannot allocate SIM queue\n");
533114574Sphk		return (ENOMEM);
534114574Sphk	}
535114574Sphk
536114574Sphk	sc->vtscsi_sim = cam_sim_alloc(vtscsi_cam_action, vtscsi_cam_poll,
537114574Sphk	    "vtscsi", sc, device_get_unit(dev), VTSCSI_MTX(sc), 1,
538114574Sphk	    openings, devq);
539114574Sphk	if (sc->vtscsi_sim == NULL) {
540114574Sphk		cam_simq_free(devq);
541114574Sphk		device_printf(dev, "cannot allocate SIM\n");
542114574Sphk		return (ENOMEM);
543114574Sphk	}
544114574Sphk
545114574Sphk	return (0);
546114574Sphk}
547114574Sphk
548114574Sphkstatic int
549114574Sphkvtscsi_register_cam(struct vtscsi_softc *sc)
550114574Sphk{
551114574Sphk	device_t dev;
552114574Sphk	int registered, error;
553114574Sphk
554114574Sphk	dev = sc->vtscsi_dev;
555114574Sphk	registered = 0;
556114574Sphk
557114574Sphk	VTSCSI_LOCK(sc);
558114574Sphk
559114574Sphk	if (xpt_bus_register(sc->vtscsi_sim, dev, 0) != CAM_SUCCESS) {
560114574Sphk		error = ENOMEM;
561114574Sphk		device_printf(dev, "cannot register XPT bus\n");
5621558Srgrimes		goto fail;
5635393Sgibbs	}
5641558Srgrimes
5651558Srgrimes	registered = 1;
5661558Srgrimes
56737234Sbde	if (xpt_create_path(&sc->vtscsi_path, NULL,
56837234Sbde	    cam_sim_path(sc->vtscsi_sim), CAM_TARGET_WILDCARD,
569107041Sjulian	    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
5701558Srgrimes		error = ENOMEM;
5711558Srgrimes		device_printf(dev, "cannot create bus path\n");
5721558Srgrimes		goto fail;
5731558Srgrimes	}
5741558Srgrimes
5751558Srgrimes	if (vtscsi_register_async(sc) != CAM_REQ_CMP) {
57637234Sbde		error = EIO;
57737234Sbde		device_printf(dev, "cannot register async callback\n");
57837234Sbde		goto fail;
5791558Srgrimes	}
5801558Srgrimes
5811558Srgrimes	VTSCSI_UNLOCK(sc);
58237234Sbde
58337234Sbde	return (0);
58437234Sbde
5851558Srgrimesfail:
5861558Srgrimes	if (sc->vtscsi_path != NULL) {
5871558Srgrimes		xpt_free_path(sc->vtscsi_path);
5885393Sgibbs		sc->vtscsi_path = NULL;
58937234Sbde	}
59037234Sbde
59137234Sbde	if (registered != 0)
5925393Sgibbs		xpt_bus_deregister(cam_sim_path(sc->vtscsi_sim));
5935393Sgibbs
5945393Sgibbs	VTSCSI_UNLOCK(sc);
5951558Srgrimes
5961558Srgrimes	return (error);
5971558Srgrimes}
5981558Srgrimes
599114574Sphkstatic void
600114574Sphkvtscsi_free_cam(struct vtscsi_softc *sc)
601114574Sphk{
602114571Sphk
6031558Srgrimes	VTSCSI_LOCK(sc);
6041558Srgrimes
6051558Srgrimes	if (sc->vtscsi_path != NULL) {
6061558Srgrimes		vtscsi_deregister_async(sc);
6071558Srgrimes
608114571Sphk		xpt_free_path(sc->vtscsi_path);
609114571Sphk		sc->vtscsi_path = NULL;
6101558Srgrimes
61192541Simp		xpt_bus_deregister(cam_sim_path(sc->vtscsi_sim));
6121558Srgrimes	}
61324180Simp
6141558Srgrimes	if (sc->vtscsi_sim != NULL) {
61524180Simp		cam_sim_free(sc->vtscsi_sim, 1);
61624180Simp		sc->vtscsi_sim = NULL;
61736632Scharnier	}
6181558Srgrimes
6191558Srgrimes	VTSCSI_UNLOCK(sc);
620114571Sphk}
62124180Simp
6221558Srgrimesstatic void
6231558Srgrimesvtscsi_cam_async(void *cb_arg, uint32_t code, struct cam_path *path, void *arg)
6241558Srgrimes{
62524180Simp	struct cam_sim *sim;
62624180Simp	struct vtscsi_softc *sc;
62736632Scharnier
6281558Srgrimes	sim = cb_arg;
6291558Srgrimes	sc = cam_sim_softc(sim);
6301558Srgrimes
631114571Sphk	vtscsi_dprintf(sc, VTSCSI_TRACE, "code=%u\n", code);
632114571Sphk
633114571Sphk	/*
634114571Sphk	 * TODO Once QEMU supports event reporting, we should
635114571Sphk	 *      (un)subscribe to events here.
6361558Srgrimes	 */
6371558Srgrimes	switch (code) {
6381558Srgrimes	case AC_FOUND_DEVICE:
6391558Srgrimes		break;
640114571Sphk	case AC_LOST_DEVICE:
641114571Sphk		break;
6421558Srgrimes	}
6431558Srgrimes}
6441558Srgrimes
6451558Srgrimesstatic int
6461558Srgrimesvtscsi_register_async(struct vtscsi_softc *sc)
6471558Srgrimes{
6481558Srgrimes	struct ccb_setasync csa;
6491558Srgrimes
6501558Srgrimes	xpt_setup_ccb(&csa.ccb_h, sc->vtscsi_path, 5);
6511558Srgrimes	csa.ccb_h.func_code = XPT_SASYNC_CB;
6521558Srgrimes	csa.event_enable = AC_LOST_DEVICE | AC_FOUND_DEVICE;
653114571Sphk	csa.callback = vtscsi_cam_async;
65492541Simp	csa.callback_arg = sc->vtscsi_sim;
6551558Srgrimes
65692541Simp	xpt_action((union ccb *) &csa);
65799365Smarkm
65899365Smarkm	return (csa.ccb_h.status);
6591558Srgrimes}
6601558Srgrimes
6611558Srgrimesstatic void
6621558Srgrimesvtscsi_deregister_async(struct vtscsi_softc *sc)
66336632Scharnier{
6641558Srgrimes	struct ccb_setasync csa;
6651558Srgrimes
6661558Srgrimes	xpt_setup_ccb(&csa.ccb_h, sc->vtscsi_path, 5);
66736632Scharnier	csa.ccb_h.func_code = XPT_SASYNC_CB;
6681558Srgrimes	csa.event_enable = 0;
6691558Srgrimes	csa.callback = vtscsi_cam_async;
6701558Srgrimes	csa.callback_arg = sc->vtscsi_sim;
6711558Srgrimes
6721558Srgrimes	xpt_action((union ccb *) &csa);
6731558Srgrimes}
6741558Srgrimes
6751558Srgrimesstatic void
6761558Srgrimesvtscsi_cam_action(struct cam_sim *sim, union ccb *ccb)
6771558Srgrimes{
67879452Sbrian	struct vtscsi_softc *sc;
67936632Scharnier	struct ccb_hdr *ccbh;
6801558Srgrimes
68199365Smarkm	sc = cam_sim_softc(sim);
6821558Srgrimes	ccbh = &ccb->ccb_h;
6831558Srgrimes
6841558Srgrimes	VTSCSI_LOCK_OWNED(sc);
68599365Smarkm
6861558Srgrimes	if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) {
6871558Srgrimes		/*
688114571Sphk		 * The VTSCSI_MTX is briefly dropped between setting
68992541Simp		 * VTSCSI_FLAG_DETACH and deregistering with CAM, so
6901558Srgrimes		 * drop any CCBs that come in during that window.
6911558Srgrimes		 */
6921558Srgrimes		ccbh->status = CAM_NO_HBA;
6931558Srgrimes		xpt_done(ccb);
6941558Srgrimes		return;
69592541Simp	}
6961558Srgrimes
6971558Srgrimes	switch (ccbh->func_code) {
6981558Srgrimes	case XPT_SCSI_IO:
699114571Sphk		vtscsi_cam_scsi_io(sc, sim, ccb);
70092541Simp		break;
7011558Srgrimes
70292541Simp	case XPT_SET_TRAN_SETTINGS:
7031558Srgrimes		ccbh->status = CAM_FUNC_NOTAVAIL;
7041558Srgrimes		xpt_done(ccb);
7051558Srgrimes		break;
7061558Srgrimes
7071558Srgrimes	case XPT_GET_TRAN_SETTINGS:
7081558Srgrimes		vtscsi_cam_get_tran_settings(sc, ccb);
7091558Srgrimes		break;
7101558Srgrimes
71192541Simp	case XPT_RESET_BUS:
7121558Srgrimes		vtscsi_cam_reset_bus(sc, ccb);
7131558Srgrimes		break;
7141558Srgrimes
7151558Srgrimes	case XPT_RESET_DEV:
7161558Srgrimes		vtscsi_cam_reset_dev(sc, ccb);
7171558Srgrimes		break;
7181558Srgrimes
719114571Sphk	case XPT_ABORT:
72092541Simp		vtscsi_cam_abort(sc, ccb);
7211558Srgrimes		break;
72294065Sphk
72394065Sphk	case XPT_CALC_GEOMETRY:
724107041Sjulian		cam_calc_geometry(&ccb->ccg, 1);
72594065Sphk		xpt_done(ccb);
726107041Sjulian		break;
727107041Sjulian
72892541Simp	case XPT_PATH_INQ:
7291558Srgrimes		vtscsi_cam_path_inquiry(sc, sim, ccb);
730114862Sphk		break;
731109378Sdes
732109378Sdes	default:
733109378Sdes		vtscsi_dprintf(sc, VTSCSI_ERROR,
7341558Srgrimes		    "invalid ccb=%p func=%#x\n", ccb, ccbh->func_code);
73596475Sphk
7361558Srgrimes		ccbh->status = CAM_REQ_INVALID;
7371558Srgrimes		xpt_done(ccb);
73813544Sjoerg		break;
7391558Srgrimes	}
7401558Srgrimes}
7411558Srgrimes
7421558Srgrimesstatic void
7431558Srgrimesvtscsi_cam_poll(struct cam_sim *sim)
7441558Srgrimes{
7451558Srgrimes	struct vtscsi_softc *sc;
7461558Srgrimes
7471558Srgrimes	sc = cam_sim_softc(sim);
7481558Srgrimes
7491558Srgrimes	vtscsi_complete_vqs_locked(sc);
750114571Sphk}
7511558Srgrimes
75299365Smarkmstatic void
7531558Srgrimesvtscsi_cam_scsi_io(struct vtscsi_softc *sc, struct cam_sim *sim,
7541558Srgrimes    union ccb *ccb)
755114571Sphk{
7561558Srgrimes	struct ccb_hdr *ccbh;
75797855Siedowse	struct ccb_scsiio *csio;
7581558Srgrimes	int error;
75997855Siedowse
76097855Siedowse	ccbh = &ccb->ccb_h;
761107041Sjulian	csio = &ccb->csio;
762107041Sjulian
763107041Sjulian	if (csio->cdb_len > VIRTIO_SCSI_CDB_SIZE) {
7641558Srgrimes		error = EINVAL;
7651558Srgrimes		ccbh->status = CAM_REQ_INVALID;
7661558Srgrimes		goto done;
7671558Srgrimes	}
768114571Sphk
7691558Srgrimes	if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_BOTH &&
7701558Srgrimes	    (sc->vtscsi_flags & VTSCSI_FLAG_BIDIRECTIONAL) == 0) {
771114571Sphk		error = EINVAL;
7721558Srgrimes		ccbh->status = CAM_REQ_INVALID;
773114571Sphk		goto done;
7741558Srgrimes	}
775114571Sphk
7761558Srgrimes	error = vtscsi_start_scsi_cmd(sc, ccb);
7771558Srgrimes
7781558Srgrimesdone:
7791558Srgrimes	if (error) {
7801558Srgrimes		vtscsi_dprintf(sc, VTSCSI_ERROR,
7811558Srgrimes		    "error=%d ccb=%p status=%#x\n", error, ccb, ccbh->status);
7821558Srgrimes		xpt_done(ccb);
7831558Srgrimes	}
7841558Srgrimes}
7851558Srgrimes
7861558Srgrimesstatic void
787114571Sphkvtscsi_cam_get_tran_settings(struct vtscsi_softc *sc, union ccb *ccb)
7881558Srgrimes{
789107041Sjulian	struct ccb_trans_settings *cts;
7901558Srgrimes	struct ccb_trans_settings_scsi *scsi;
7911558Srgrimes
7921558Srgrimes	cts = &ccb->cts;
7931558Srgrimes	scsi = &cts->proto_specific.scsi;
794107041Sjulian
795107041Sjulian	cts->protocol = PROTO_SCSI;
7961558Srgrimes	cts->protocol_version = SCSI_REV_SPC3;
7971558Srgrimes	cts->transport = XPORT_SAS;
7981558Srgrimes	cts->transport_version = 0;
7991558Srgrimes
8001558Srgrimes	scsi->valid = CTS_SCSI_VALID_TQ;
8011558Srgrimes	scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
8021558Srgrimes
8031558Srgrimes	ccb->ccb_h.status = CAM_REQ_CMP;
8041558Srgrimes	xpt_done(ccb);
80599365Smarkm}
806114571Sphk
8071558Srgrimesstatic void
8081558Srgrimesvtscsi_cam_reset_bus(struct vtscsi_softc *sc, union ccb *ccb)
8091558Srgrimes{
810114571Sphk	int error;
8111558Srgrimes
8121558Srgrimes	error = vtscsi_reset_bus(sc);
8131558Srgrimes	if (error == 0)
814114571Sphk		ccb->ccb_h.status = CAM_REQ_CMP;
815107041Sjulian	else
816107041Sjulian		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
8171558Srgrimes
8181558Srgrimes	vtscsi_dprintf(sc, VTSCSI_TRACE, "error=%d ccb=%p status=%#x\n",
8191558Srgrimes	    error, ccb, ccb->ccb_h.status);
8201558Srgrimes
8211558Srgrimes	xpt_done(ccb);
8221558Srgrimes}
8231558Srgrimes
8241558Srgrimesstatic void
825114571Sphkvtscsi_cam_reset_dev(struct vtscsi_softc *sc, union ccb *ccb)
826107041Sjulian{
827107041Sjulian	struct ccb_hdr *ccbh;
828133347Sdes	struct vtscsi_request *req;
829107041Sjulian	int error;
830133347Sdes
831107041Sjulian	ccbh = &ccb->ccb_h;
832133347Sdes
8331558Srgrimes	req = vtscsi_dequeue_request(sc);
8341558Srgrimes	if (req == NULL) {
8351558Srgrimes		error = EAGAIN;
8361558Srgrimes		vtscsi_freeze_simq(sc, VTSCSI_REQUEST);
8371558Srgrimes		goto fail;
8381558Srgrimes	}
8391558Srgrimes
840114571Sphk	req->vsr_ccb = ccb;
841107041Sjulian
842107041Sjulian	error = vtscsi_execute_reset_dev_cmd(sc, req);
8431558Srgrimes	if (error == 0)
8441558Srgrimes		return;
8451558Srgrimes
8461558Srgrimes	vtscsi_enqueue_request(sc, req);
8471558Srgrimes
8481558Srgrimesfail:
8491558Srgrimes	vtscsi_dprintf(sc, VTSCSI_ERROR, "error=%d req=%p ccb=%p\n",
850114571Sphk	    error, req, ccb);
851107041Sjulian
852107041Sjulian	if (error == EAGAIN)
8531558Srgrimes		ccbh->status = CAM_RESRC_UNAVAIL;
8541558Srgrimes	else
8551558Srgrimes		ccbh->status = CAM_REQ_CMP_ERR;
8561558Srgrimes
8571558Srgrimes	xpt_done(ccb);
8581558Srgrimes}
8591558Srgrimes
860114571Sphkstatic void
861107041Sjulianvtscsi_cam_abort(struct vtscsi_softc *sc, union ccb *ccb)
862107041Sjulian{
8631558Srgrimes	struct vtscsi_request *req;
8641558Srgrimes	struct ccb_hdr *ccbh;
8651558Srgrimes	int error;
8661558Srgrimes
8671558Srgrimes	ccbh = &ccb->ccb_h;
8681558Srgrimes
8691558Srgrimes	req = vtscsi_dequeue_request(sc);
870114571Sphk	if (req == NULL) {
871107041Sjulian		error = EAGAIN;
872107041Sjulian		vtscsi_freeze_simq(sc, VTSCSI_REQUEST);
8736643Sbde		goto fail;
8746643Sbde	}
8756643Sbde
8766643Sbde	req->vsr_ccb = ccb;
8776643Sbde
8786643Sbde	error = vtscsi_execute_abort_task_cmd(sc, req);
8796643Sbde	if (error == 0)
880114571Sphk		return;
881107041Sjulian
882107041Sjulian	vtscsi_enqueue_request(sc, req);
8831558Srgrimes
8841558Srgrimesfail:
8851558Srgrimes	vtscsi_dprintf(sc, VTSCSI_ERROR, "error=%d req=%p ccb=%p\n",
8861558Srgrimes	    error, req, ccb);
8871558Srgrimes
8881558Srgrimes	if (error == EAGAIN)
8891558Srgrimes		ccbh->status = CAM_RESRC_UNAVAIL;
890114571Sphk	else
891107041Sjulian		ccbh->status = CAM_REQ_CMP_ERR;
892107041Sjulian
8931558Srgrimes	xpt_done(ccb);
8941558Srgrimes}
8951558Srgrimes
8961558Srgrimesstatic void
8971558Srgrimesvtscsi_cam_path_inquiry(struct vtscsi_softc *sc, struct cam_sim *sim,
8981558Srgrimes    union ccb *ccb)
8991558Srgrimes{
900114571Sphk	device_t dev;
901107041Sjulian	struct ccb_pathinq *cpi;
902107041Sjulian
9031558Srgrimes	dev = sc->vtscsi_dev;
9041558Srgrimes	cpi = &ccb->cpi;
9051558Srgrimes
9061558Srgrimes	vtscsi_dprintf(sc, VTSCSI_TRACE, "sim=%p ccb=%p\n", sim, ccb);
9071558Srgrimes
9081558Srgrimes	cpi->version_num = 1;
9091558Srgrimes	cpi->hba_inquiry = PI_TAG_ABLE;
910114571Sphk	cpi->target_sprt = 0;
911107041Sjulian	cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED;
912107041Sjulian	if (vtscsi_bus_reset_disable != 0)
9131558Srgrimes		cpi->hba_misc |= PIM_NOBUSRESET;
9141558Srgrimes	cpi->hba_eng_cnt = 0;
9151558Srgrimes
9161558Srgrimes	cpi->max_target = sc->vtscsi_max_target;
9171558Srgrimes	cpi->max_lun = sc->vtscsi_max_lun;
9181558Srgrimes	cpi->initiator_id = VTSCSI_INITIATOR_ID;
9191558Srgrimes
920114571Sphk	strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
921107041Sjulian	strlcpy(cpi->hba_vid, "VirtIO", HBA_IDLEN);
922107041Sjulian	strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
9231558Srgrimes
9241558Srgrimes	cpi->unit_number = cam_sim_unit(sim);
925114571Sphk	cpi->bus_id = cam_sim_bus(sim);
926107041Sjulian
927107041Sjulian	cpi->base_transfer_speed = 300000;
9281558Srgrimes
9291558Srgrimes	cpi->protocol = PROTO_SCSI;
93073034Sjwd	cpi->protocol_version = SCSI_REV_SPC3;
93197534Siedowse	cpi->transport = XPORT_SAS;
93297534Siedowse	cpi->transport_version = 0;
93397534Siedowse
93497534Siedowse	cpi->maxio = (sc->vtscsi_max_nsegs - VTSCSI_MIN_SEGMENTS - 1) *
93597534Siedowse	    PAGE_SIZE;
93697534Siedowse
93797534Siedowse	cpi->hba_vendor = virtio_get_vendor(dev);
93897534Siedowse	cpi->hba_device = virtio_get_device(dev);
93997534Siedowse	cpi->hba_subvendor = virtio_get_subvendor(dev);
94097534Siedowse	cpi->hba_subdevice = virtio_get_subdevice(dev);
94197534Siedowse
94297534Siedowse	ccb->ccb_h.status = CAM_REQ_CMP;
94397534Siedowse	xpt_done(ccb);
94497534Siedowse}
94597534Siedowse
94697534Siedowsestatic int
94797534Siedowsevtscsi_sg_append_scsi_buf(struct vtscsi_softc *sc, struct sglist *sg,
94897534Siedowse    struct ccb_scsiio *csio)
94997534Siedowse{
95097534Siedowse	struct ccb_hdr *ccbh;
95197534Siedowse	struct bus_dma_segment *dseg;
95297534Siedowse	int i, error;
95397534Siedowse
95497534Siedowse	ccbh = &csio->ccb_h;
95597534Siedowse	error = 0;
95697534Siedowse
95797534Siedowse	switch ((ccbh->flags & CAM_DATA_MASK)) {
95897534Siedowse	case CAM_DATA_VADDR:
95997534Siedowse		error = sglist_append(sg, csio->data_ptr, csio->dxfer_len);
9603111Spst		break;
9613111Spst	case CAM_DATA_PADDR:
96297534Siedowse		error = sglist_append_phys(sg,
9633111Spst		    (vm_paddr_t)(vm_offset_t) csio->data_ptr, csio->dxfer_len);
9643111Spst		break;
965107041Sjulian	case CAM_DATA_SG:
9663111Spst		for (i = 0; i < csio->sglist_cnt && error == 0; i++) {
96797534Siedowse			dseg = &((struct bus_dma_segment *)csio->data_ptr)[i];
96897534Siedowse			error = sglist_append(sg,
96973034Sjwd			    (void *)(vm_offset_t) dseg->ds_addr, dseg->ds_len);
97097534Siedowse		}
97173034Sjwd		break;
97273034Sjwd	case CAM_DATA_SG_PADDR:
97397534Siedowse		for (i = 0; i < csio->sglist_cnt && error == 0; i++) {
97473034Sjwd			dseg = &((struct bus_dma_segment *)csio->data_ptr)[i];
975133347Sdes			error = sglist_append_phys(sg,
97673034Sjwd			    (vm_paddr_t) dseg->ds_addr, dseg->ds_len);
977133347Sdes		}
97873034Sjwd		break;
97973034Sjwd	case CAM_DATA_BIO:
98097534Siedowse		error = sglist_append_bio(sg, (struct bio *) csio->data_ptr);
9811558Srgrimes		break;
98297534Siedowse	default:
98397534Siedowse		error = EINVAL;
98497534Siedowse		break;
98597534Siedowse	}
986114571Sphk
98797534Siedowse	return (error);
98897534Siedowse}
98997534Siedowse
99097534Siedowsestatic int
99197534Siedowsevtscsi_fill_scsi_cmd_sglist(struct vtscsi_softc *sc, struct vtscsi_request *req,
992107041Sjulian    int *readable, int *writable)
9931558Srgrimes{
99497534Siedowse	struct sglist *sg;
99597534Siedowse	struct ccb_hdr *ccbh;
9961558Srgrimes	struct ccb_scsiio *csio;
99797534Siedowse	struct virtio_scsi_cmd_req *cmd_req;
99897534Siedowse	struct virtio_scsi_cmd_resp *cmd_resp;
999107041Sjulian	int error;
1000107041Sjulian
1001107041Sjulian	sg = sc->vtscsi_sglist;
100297534Siedowse	csio = &req->vsr_ccb->csio;
100397534Siedowse	ccbh = &csio->ccb_h;
100497534Siedowse	cmd_req = &req->vsr_cmd_req;
100597534Siedowse	cmd_resp = &req->vsr_cmd_resp;
100697534Siedowse
100797534Siedowse	sglist_reset(sg);
1008107041Sjulian
1009107041Sjulian	sglist_append(sg, cmd_req, sizeof(struct virtio_scsi_cmd_req));
1010107041Sjulian	if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1011107041Sjulian		error = vtscsi_sg_append_scsi_buf(sc, sg, csio);
101297534Siedowse		/* At least one segment must be left for the response. */
101397534Siedowse		if (error || sg->sg_nseg == sg->sg_maxseg)
101497534Siedowse			goto fail;
1015112945Syar	}
1016112945Syar
1017112945Syar	*readable = sg->sg_nseg;
1018112945Syar
101997534Siedowse	sglist_append(sg, cmd_resp, sizeof(struct virtio_scsi_cmd_resp));
102097534Siedowse	if ((ccbh->flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1021114571Sphk		error = vtscsi_sg_append_scsi_buf(sc, sg, csio);
102297534Siedowse		if (error)
102397534Siedowse			goto fail;
102497534Siedowse	}
102597534Siedowse
102697534Siedowse	*writable = sg->sg_nseg - *readable;
1027107041Sjulian
102897534Siedowse	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p ccb=%p readable=%d "
102997534Siedowse	    "writable=%d\n", req, ccbh, *readable, *writable);
1030107041Sjulian
103197534Siedowse	return (0);
1032102231Strhodes
103397534Siedowsefail:
103497534Siedowse	/*
103597534Siedowse	 * This should never happen unless maxio was incorrectly set.
103697534Siedowse	 */
103797534Siedowse	vtscsi_set_ccb_status(ccbh, CAM_REQ_TOO_BIG, 0);
103897534Siedowse
103997534Siedowse	vtscsi_dprintf(sc, VTSCSI_ERROR, "error=%d req=%p ccb=%p "
104097534Siedowse	    "nseg=%d maxseg=%d\n",
1041120821Siedowse	    error, req, ccbh, sg->sg_nseg, sg->sg_maxseg);
1042120821Siedowse
1043120821Siedowse	return (EFBIG);
104497534Siedowse}
104597534Siedowse
104697534Siedowsestatic int
104797534Siedowsevtscsi_execute_scsi_cmd(struct vtscsi_softc *sc, struct vtscsi_request *req)
104897534Siedowse{
104997534Siedowse	struct sglist *sg;
1050120821Siedowse	struct virtqueue *vq;
1051120821Siedowse	struct ccb_scsiio *csio;
105297534Siedowse	struct ccb_hdr *ccbh;
105397534Siedowse	struct virtio_scsi_cmd_req *cmd_req;
105497534Siedowse	struct virtio_scsi_cmd_resp *cmd_resp;
105597534Siedowse	int readable, writable, error;
105697534Siedowse
10571558Srgrimes	sg = sc->vtscsi_sglist;
105897534Siedowse	vq = sc->vtscsi_request_vq;
10591558Srgrimes	csio = &req->vsr_ccb->csio;
10601558Srgrimes	ccbh = &csio->ccb_h;
10611558Srgrimes	cmd_req = &req->vsr_cmd_req;
10621558Srgrimes	cmd_resp = &req->vsr_cmd_resp;
10631558Srgrimes
10641558Srgrimes	vtscsi_init_scsi_cmd_req(csio, cmd_req);
1065114571Sphk
106692541Simp	error = vtscsi_fill_scsi_cmd_sglist(sc, req, &readable, &writable);
10671558Srgrimes	if (error)
106892541Simp		return (error);
10691558Srgrimes
10701558Srgrimes	req->vsr_complete = vtscsi_complete_scsi_cmd;
1071107041Sjulian	cmd_resp->response = -1;
107273034Sjwd
107373034Sjwd	error = virtqueue_enqueue(vq, req, sg, readable, writable);
107473034Sjwd	if (error) {
107573034Sjwd		vtscsi_dprintf(sc, VTSCSI_ERROR,
10761558Srgrimes		    "enqueue error=%d req=%p ccb=%p\n", error, req, ccbh);
1077114571Sphk
1078114571Sphk		ccbh->status = CAM_REQUEUE_REQ;
1079114571Sphk		vtscsi_freeze_simq(sc, VTSCSI_REQUEST_VQ);
1080114574Sphk		return (error);
1081114574Sphk	}
1082114574Sphk
1083114574Sphk	ccbh->status |= CAM_SIM_QUEUED;
1084114574Sphk	ccbh->ccbh_vtscsi_req = req;
1085114574Sphk
1086114574Sphk	virtqueue_notify(vq);
1087114574Sphk
1088114574Sphk	if (ccbh->timeout != CAM_TIME_INFINITY) {
1089114574Sphk		req->vsr_flags |= VTSCSI_REQ_FLAG_TIMEOUT_SET;
1090114574Sphk		callout_reset_sbt(&req->vsr_callout, SBT_1MS * ccbh->timeout,
1091114574Sphk		    0, vtscsi_timedout_scsi_cmd, req, 0);
1092114574Sphk	}
1093114574Sphk
1094114574Sphk	vtscsi_dprintf_req(req, VTSCSI_TRACE, "enqueued req=%p ccb=%p\n",
1095114574Sphk	    req, ccbh);
1096114574Sphk
1097114574Sphk	return (0);
1098114574Sphk}
1099114574Sphk
1100114574Sphkstatic int
1101114574Sphkvtscsi_start_scsi_cmd(struct vtscsi_softc *sc, union ccb *ccb)
1102114574Sphk{
1103114574Sphk	struct vtscsi_request *req;
1104114574Sphk	int error;
1105114574Sphk
1106114574Sphk	req = vtscsi_dequeue_request(sc);
1107114574Sphk	if (req == NULL) {
1108114574Sphk		ccb->ccb_h.status = CAM_REQUEUE_REQ;
1109114574Sphk		vtscsi_freeze_simq(sc, VTSCSI_REQUEST);
1110114574Sphk		return (ENOBUFS);
1111114574Sphk	}
1112114574Sphk
1113114574Sphk	req->vsr_ccb = ccb;
1114114574Sphk
1115114574Sphk	error = vtscsi_execute_scsi_cmd(sc, req);
1116114574Sphk	if (error)
1117114574Sphk		vtscsi_enqueue_request(sc, req);
1118114574Sphk
1119114574Sphk	return (error);
1120114574Sphk}
1121114574Sphk
1122114574Sphkstatic void
1123114574Sphkvtscsi_complete_abort_timedout_scsi_cmd(struct vtscsi_softc *sc,
1124114574Sphk    struct vtscsi_request *req)
1125114574Sphk{
11261558Srgrimes	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
112773034Sjwd	struct vtscsi_request *to_req;
1128114574Sphk	uint8_t response;
112973034Sjwd
113073034Sjwd	tmf_resp = &req->vsr_tmf_resp;
113173034Sjwd	response = tmf_resp->response;
113273034Sjwd	to_req = req->vsr_timedout_req;
113373034Sjwd
11341558Srgrimes	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p to_req=%p response=%d\n",
113573034Sjwd	    req, to_req, response);
113673034Sjwd
113773034Sjwd	vtscsi_enqueue_request(sc, req);
113894065Sphk
113973034Sjwd	/*
114073034Sjwd	 * The timedout request could have completed between when the
114173034Sjwd	 * abort task was sent and when the host processed it.
1142114574Sphk	 */
114373034Sjwd	if (to_req->vsr_state != VTSCSI_REQ_STATE_TIMEDOUT)
114473034Sjwd		return;
114573034Sjwd
114673034Sjwd	/* The timedout request was successfully aborted. */
114773034Sjwd	if (response == VIRTIO_SCSI_S_FUNCTION_COMPLETE)
114873573Simp		return;
114973034Sjwd
115073034Sjwd	/* Don't bother if the device is going away. */
115173034Sjwd	if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH)
115273034Sjwd		return;
115373034Sjwd
115473034Sjwd	/* The timedout request will be aborted by the reset. */
1155133348Sdes	if (sc->vtscsi_flags & VTSCSI_FLAG_RESET)
1156133348Sdes		return;
1157133348Sdes
1158133348Sdes	vtscsi_reset_bus(sc);
1159133348Sdes}
1160133348Sdes
1161133348Sdesstatic int
1162133348Sdesvtscsi_abort_timedout_scsi_cmd(struct vtscsi_softc *sc,
1163133348Sdes    struct vtscsi_request *to_req)
1164133348Sdes{
1165133348Sdes	struct sglist *sg;
1166133348Sdes	struct ccb_hdr *to_ccbh;
116773034Sjwd	struct vtscsi_request *req;
116873034Sjwd	struct virtio_scsi_ctrl_tmf_req *tmf_req;
116973573Simp	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
117073034Sjwd	int error;
117173034Sjwd
117273034Sjwd	sg = sc->vtscsi_sglist;
117373034Sjwd	to_ccbh = &to_req->vsr_ccb->ccb_h;
1174133348Sdes
1175133348Sdes	req = vtscsi_dequeue_request(sc);
117673034Sjwd	if (req == NULL) {
117773034Sjwd		error = ENOBUFS;
117873034Sjwd		goto fail;
117973034Sjwd	}
118073034Sjwd
118173034Sjwd	tmf_req = &req->vsr_tmf_req;
118273034Sjwd	tmf_resp = &req->vsr_tmf_resp;
118373034Sjwd
118473034Sjwd	vtscsi_init_ctrl_tmf_req(to_ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
118573034Sjwd	    (uintptr_t) to_ccbh, tmf_req);
1186114574Sphk
118773034Sjwd	sglist_reset(sg);
118873034Sjwd	sglist_append(sg, tmf_req, sizeof(struct virtio_scsi_ctrl_tmf_req));
118973034Sjwd	sglist_append(sg, tmf_resp, sizeof(struct virtio_scsi_ctrl_tmf_resp));
119073034Sjwd
119173034Sjwd	req->vsr_timedout_req = to_req;
119294065Sphk	req->vsr_complete = vtscsi_complete_abort_timedout_scsi_cmd;
119373034Sjwd	tmf_resp->response = -1;
119473034Sjwd
119573034Sjwd	error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1,
119673034Sjwd	    VTSCSI_EXECUTE_ASYNC);
119773034Sjwd	if (error == 0)
119873034Sjwd		return (0);
119973034Sjwd
120073034Sjwd	vtscsi_enqueue_request(sc, req);
120173034Sjwd
120294065Sphkfail:
120373034Sjwd	vtscsi_dprintf(sc, VTSCSI_ERROR, "error=%d req=%p "
120473034Sjwd	    "timedout req=%p ccb=%p\n", error, req, to_req, to_ccbh);
120573034Sjwd
120673034Sjwd	return (error);
120773034Sjwd}
120873034Sjwd
120973034Sjwdstatic void
121073034Sjwdvtscsi_timedout_scsi_cmd(void *xreq)
121173034Sjwd{
121273034Sjwd	struct vtscsi_softc *sc;
121373034Sjwd	struct vtscsi_request *to_req;
121473034Sjwd
121573034Sjwd	to_req = xreq;
121673034Sjwd	sc = to_req->vsr_softc;
121773034Sjwd
121873034Sjwd	vtscsi_dprintf(sc, VTSCSI_INFO, "timedout req=%p ccb=%p state=%#x\n",
121973034Sjwd	    to_req, to_req->vsr_ccb, to_req->vsr_state);
122073034Sjwd
122194065Sphk	/* Don't bother if the device is going away. */
122273034Sjwd	if (sc->vtscsi_flags & VTSCSI_FLAG_DETACH)
122373034Sjwd		return;
122473034Sjwd
122573034Sjwd	/*
122673034Sjwd	 * Bail if the request is not in use. We likely raced when
122773034Sjwd	 * stopping the callout handler or it has already been aborted.
122873034Sjwd	 */
122973034Sjwd	if (to_req->vsr_state != VTSCSI_REQ_STATE_INUSE ||
123073034Sjwd	    (to_req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) == 0)
123173034Sjwd		return;
123273034Sjwd
123373034Sjwd	/*
123473034Sjwd	 * Complete the request queue in case the timedout request is
123573034Sjwd	 * actually just pending.
123673034Sjwd	 */
12371558Srgrimes	vtscsi_complete_vq(sc, sc->vtscsi_request_vq);
12381558Srgrimes	if (to_req->vsr_state == VTSCSI_REQ_STATE_FREE)
123973034Sjwd		return;
124073034Sjwd
124194065Sphk	sc->vtscsi_stats.scsi_cmd_timeouts++;
124273034Sjwd	to_req->vsr_state = VTSCSI_REQ_STATE_TIMEDOUT;
124373034Sjwd
124473034Sjwd	if (vtscsi_abort_timedout_scsi_cmd(sc, to_req) == 0)
124573034Sjwd		return;
124673034Sjwd
124773034Sjwd	vtscsi_dprintf(sc, VTSCSI_ERROR, "resetting bus\n");
124873034Sjwd	vtscsi_reset_bus(sc);
1249133347Sdes}
1250107534Sgrog
1251107534Sgrogstatic cam_status
125273034Sjwdvtscsi_scsi_cmd_cam_status(struct virtio_scsi_cmd_resp *cmd_resp)
125394065Sphk{
125494065Sphk	cam_status status;
125573034Sjwd
125673034Sjwd	switch (cmd_resp->response) {
125773034Sjwd	case VIRTIO_SCSI_S_OK:
125873034Sjwd		status = CAM_REQ_CMP;
125994065Sphk		break;
1260133347Sdes	case VIRTIO_SCSI_S_OVERRUN:
1261133347Sdes		status = CAM_DATA_RUN_ERR;
126273034Sjwd		break;
126373034Sjwd	case VIRTIO_SCSI_S_ABORTED:
1264114574Sphk		status = CAM_REQ_ABORTED;
126573034Sjwd		break;
126694065Sphk	case VIRTIO_SCSI_S_BAD_TARGET:
126773034Sjwd		status = CAM_SEL_TIMEOUT;
126873034Sjwd		break;
126994065Sphk	case VIRTIO_SCSI_S_RESET:
1270133347Sdes		status = CAM_SCSI_BUS_RESET;
127173034Sjwd		break;
127273034Sjwd	case VIRTIO_SCSI_S_BUSY:
127373034Sjwd		status = CAM_SCSI_BUSY;
127473034Sjwd		break;
127573034Sjwd	case VIRTIO_SCSI_S_TRANSPORT_FAILURE:
127673034Sjwd	case VIRTIO_SCSI_S_TARGET_FAILURE:
12771558Srgrimes	case VIRTIO_SCSI_S_NEXUS_FAILURE:
1278114574Sphk		status = CAM_SCSI_IT_NEXUS_LOST;
127937234Sbde		break;
12801558Srgrimes	default: /* VIRTIO_SCSI_S_FAILURE */
12811558Srgrimes		status = CAM_REQ_CMP_ERR;
1282114574Sphk		break;
12831558Srgrimes	}
12841558Srgrimes
1285114574Sphk	return (status);
12861558Srgrimes}
12871558Srgrimes
12881558Srgrimesstatic cam_status
12891558Srgrimesvtscsi_complete_scsi_cmd_response(struct vtscsi_softc *sc,
12901558Srgrimes    struct ccb_scsiio *csio, struct virtio_scsi_cmd_resp *cmd_resp)
12911558Srgrimes{
12921558Srgrimes	cam_status status;
12931558Srgrimes
12941558Srgrimes	csio->scsi_status = cmd_resp->status;
129513544Sjoerg	csio->resid = cmd_resp->resid;
12961558Srgrimes
12971558Srgrimes	if (csio->scsi_status == SCSI_STATUS_OK)
12981558Srgrimes		status = CAM_REQ_CMP;
1299114574Sphk	else
130073034Sjwd		status = CAM_SCSI_STATUS_ERROR;
1301114574Sphk
130273034Sjwd	if (cmd_resp->sense_len > 0) {
1303114574Sphk		status |= CAM_AUTOSNS_VALID;
130473034Sjwd
1305114574Sphk		if (cmd_resp->sense_len < csio->sense_len)
130673034Sjwd			csio->sense_resid = csio->sense_len -
130773034Sjwd			    cmd_resp->sense_len;
130873034Sjwd		else
1309114574Sphk			csio->sense_resid = 0;
131073034Sjwd
131173034Sjwd		bzero(&csio->sense_data, sizeof(csio->sense_data));
131273034Sjwd		memcpy(cmd_resp->sense, &csio->sense_data,
131373034Sjwd		    csio->sense_len - csio->sense_resid);
131473034Sjwd	}
131573034Sjwd
131673034Sjwd	vtscsi_dprintf(sc, status == CAM_REQ_CMP ? VTSCSI_TRACE : VTSCSI_ERROR,
1317107534Sgrog	    "ccb=%p scsi_status=%#x resid=%u sense_resid=%u\n",
1318133347Sdes	    csio, csio->scsi_status, csio->resid, csio->sense_resid);
1319107534Sgrog
1320107534Sgrog	return (status);
132173034Sjwd}
132273034Sjwd
132373034Sjwdstatic void
132473034Sjwdvtscsi_complete_scsi_cmd(struct vtscsi_softc *sc, struct vtscsi_request *req)
132573034Sjwd{
132673034Sjwd	struct ccb_hdr *ccbh;
132773034Sjwd	struct ccb_scsiio *csio;
132873034Sjwd	struct virtio_scsi_cmd_resp *cmd_resp;
132973034Sjwd	cam_status status;
133073034Sjwd
13311558Srgrimes	csio = &req->vsr_ccb->csio;
13321558Srgrimes	ccbh = &csio->ccb_h;
13331558Srgrimes	cmd_resp = &req->vsr_cmd_resp;
13341558Srgrimes
13351558Srgrimes	KASSERT(ccbh->ccbh_vtscsi_req == req,
1336114574Sphk	    ("ccb %p req mismatch %p/%p", ccbh, ccbh->ccbh_vtscsi_req, req));
133737234Sbde
13381558Srgrimes	if (req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET)
13391558Srgrimes		callout_stop(&req->vsr_callout);
13401558Srgrimes
13411558Srgrimes	status = vtscsi_scsi_cmd_cam_status(cmd_resp);
13421558Srgrimes	if (status == CAM_REQ_ABORTED) {
134313550Sjoerg		if (req->vsr_state == VTSCSI_REQ_STATE_TIMEDOUT)
134413550Sjoerg			status = CAM_CMD_TIMEOUT;
134513550Sjoerg	} else if (status == CAM_REQ_CMP)
134613550Sjoerg		status = vtscsi_complete_scsi_cmd_response(sc, csio, cmd_resp);
134713550Sjoerg
134813550Sjoerg	if ((status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
134913550Sjoerg		status |= CAM_DEV_QFRZN;
135013550Sjoerg		xpt_freeze_devq(ccbh->path, 1);
1351114571Sphk	}
135213550Sjoerg
135313550Sjoerg	if (vtscsi_thaw_simq(sc, VTSCSI_REQUEST | VTSCSI_REQUEST_VQ) != 0)
135499365Smarkm		status |= CAM_RELEASE_SIMQ;
1355103669Sphk
135613550Sjoerg	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p ccb=%p status=%#x\n",
1357114574Sphk	    req, ccbh, status);
135813550Sjoerg
1359114571Sphk	ccbh->status = status;
1360114571Sphk	xpt_done(req->vsr_ccb);
136116431Sbde	vtscsi_enqueue_request(sc, req);
136213550Sjoerg}
136368044Sjkh
1364127650Sluigistatic void
1365127650Sluigivtscsi_poll_ctrl_req(struct vtscsi_softc *sc, struct vtscsi_request *req)
1366127650Sluigi{
1367103669Sphk
1368103669Sphk	/* XXX We probably shouldn't poll forever. */
1369103669Sphk	req->vsr_flags |= VTSCSI_REQ_FLAG_POLLED;
1370103669Sphk	do
1371103669Sphk		vtscsi_complete_vq(sc, sc->vtscsi_control_vq);
1372103669Sphk	while ((req->vsr_flags & VTSCSI_REQ_FLAG_COMPLETE) == 0);
1373103669Sphk
1374103669Sphk	req->vsr_flags &= ~VTSCSI_REQ_FLAG_POLLED;
1375103669Sphk}
1376103669Sphk
137768044Sjkhstatic int
1378103669Sphkvtscsi_execute_ctrl_req(struct vtscsi_softc *sc, struct vtscsi_request *req,
1379103669Sphk    struct sglist *sg, int readable, int writable, int flag)
1380103669Sphk{
1381103669Sphk	struct virtqueue *vq;
138268044Sjkh	int error;
1383103669Sphk
1384103669Sphk	vq = sc->vtscsi_control_vq;
1385103669Sphk
1386103669Sphk	MPASS(flag == VTSCSI_EXECUTE_POLL || req->vsr_complete != NULL);
1387103669Sphk
1388103669Sphk	error = virtqueue_enqueue(vq, req, sg, readable, writable);
1389103669Sphk	if (error) {
1390103669Sphk		/*
1391103669Sphk		 * Return EAGAIN when the virtqueue does not have enough
1392103669Sphk		 * descriptors available.
1393103669Sphk		 */
1394103669Sphk		if (error == ENOSPC || error == EMSGSIZE)
1395103669Sphk			error = EAGAIN;
1396103669Sphk
1397103669Sphk		return (error);
1398103669Sphk	}
1399103669Sphk
1400103669Sphk	virtqueue_notify(vq);
1401103669Sphk	if (flag == VTSCSI_EXECUTE_POLL)
1402114574Sphk		vtscsi_poll_ctrl_req(sc, req);
1403103669Sphk
1404103669Sphk	return (0);
1405103669Sphk}
1406103669Sphk
1407103669Sphkstatic void
1408103669Sphkvtscsi_complete_abort_task_cmd(struct vtscsi_softc *sc,
1409103669Sphk    struct vtscsi_request *req)
141099365Smarkm{
141113550Sjoerg	union ccb *ccb;
141213550Sjoerg	struct ccb_hdr *ccbh;
1413114571Sphk	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
141492541Simp
14151558Srgrimes	ccb = req->vsr_ccb;
1416112307Sru	ccbh = &ccb->ccb_h;
1417112307Sru	tmf_resp = &req->vsr_tmf_resp;
1418112307Sru
1419114569Sphk	switch (tmf_resp->response) {
1420112307Sru	case VIRTIO_SCSI_S_FUNCTION_COMPLETE:
1421114571Sphk		ccbh->status = CAM_REQ_CMP;
1422112307Sru		break;
1423114569Sphk	case VIRTIO_SCSI_S_FUNCTION_REJECTED:
1424112307Sru		ccbh->status = CAM_UA_ABORT;
1425114569Sphk		break;
1426112307Sru	default:
1427113680Sphk		ccbh->status = CAM_REQ_CMP_ERR;
1428112307Sru		break;
1429114571Sphk	}
1430112307Sru
1431113680Sphk	xpt_done(ccb);
1432109878Sphk	vtscsi_enqueue_request(sc, req);
1433109878Sphk}
14341558Srgrimes
14351558Srgrimesstatic int
1436vtscsi_execute_abort_task_cmd(struct vtscsi_softc *sc,
1437    struct vtscsi_request *req)
1438{
1439	struct sglist *sg;
1440	struct ccb_abort *cab;
1441	struct ccb_hdr *ccbh;
1442	struct ccb_hdr *abort_ccbh;
1443	struct vtscsi_request *abort_req;
1444	struct virtio_scsi_ctrl_tmf_req *tmf_req;
1445	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
1446	int error;
1447
1448	sg = sc->vtscsi_sglist;
1449	cab = &req->vsr_ccb->cab;
1450	ccbh = &cab->ccb_h;
1451	tmf_req = &req->vsr_tmf_req;
1452	tmf_resp = &req->vsr_tmf_resp;
1453
1454	/* CCB header and request that's to be aborted. */
1455	abort_ccbh = &cab->abort_ccb->ccb_h;
1456	abort_req = abort_ccbh->ccbh_vtscsi_req;
1457
1458	if (abort_ccbh->func_code != XPT_SCSI_IO || abort_req == NULL) {
1459		error = EINVAL;
1460		goto fail;
1461	}
1462
1463	/* Only attempt to abort requests that could be in-flight. */
1464	if (abort_req->vsr_state != VTSCSI_REQ_STATE_INUSE) {
1465		error = EALREADY;
1466		goto fail;
1467	}
1468
1469	abort_req->vsr_state = VTSCSI_REQ_STATE_ABORTED;
1470	if (abort_req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET)
1471		callout_stop(&abort_req->vsr_callout);
1472
1473	vtscsi_init_ctrl_tmf_req(ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK,
1474	    (uintptr_t) abort_ccbh, tmf_req);
1475
1476	sglist_reset(sg);
1477	sglist_append(sg, tmf_req, sizeof(struct virtio_scsi_ctrl_tmf_req));
1478	sglist_append(sg, tmf_resp, sizeof(struct virtio_scsi_ctrl_tmf_resp));
1479
1480	req->vsr_complete = vtscsi_complete_abort_task_cmd;
1481	tmf_resp->response = -1;
1482
1483	error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1,
1484	    VTSCSI_EXECUTE_ASYNC);
1485
1486fail:
1487	vtscsi_dprintf(sc, VTSCSI_TRACE, "error=%d req=%p abort_ccb=%p "
1488	    "abort_req=%p\n", error, req, abort_ccbh, abort_req);
1489
1490	return (error);
1491}
1492
1493static void
1494vtscsi_complete_reset_dev_cmd(struct vtscsi_softc *sc,
1495    struct vtscsi_request *req)
1496{
1497	union ccb *ccb;
1498	struct ccb_hdr *ccbh;
1499	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
1500
1501	ccb = req->vsr_ccb;
1502	ccbh = &ccb->ccb_h;
1503	tmf_resp = &req->vsr_tmf_resp;
1504
1505	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p ccb=%p response=%d\n",
1506	    req, ccb, tmf_resp->response);
1507
1508	if (tmf_resp->response == VIRTIO_SCSI_S_FUNCTION_COMPLETE) {
1509		ccbh->status = CAM_REQ_CMP;
1510		vtscsi_announce(sc, AC_SENT_BDR, ccbh->target_id,
1511		    ccbh->target_lun);
1512	} else
1513		ccbh->status = CAM_REQ_CMP_ERR;
1514
1515	xpt_done(ccb);
1516	vtscsi_enqueue_request(sc, req);
1517}
1518
1519static int
1520vtscsi_execute_reset_dev_cmd(struct vtscsi_softc *sc,
1521    struct vtscsi_request *req)
1522{
1523	struct sglist *sg;
1524	struct ccb_resetdev *crd;
1525	struct ccb_hdr *ccbh;
1526	struct virtio_scsi_ctrl_tmf_req *tmf_req;
1527	struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
1528	uint32_t subtype;
1529	int error;
1530
1531	sg = sc->vtscsi_sglist;
1532	crd = &req->vsr_ccb->crd;
1533	ccbh = &crd->ccb_h;
1534	tmf_req = &req->vsr_tmf_req;
1535	tmf_resp = &req->vsr_tmf_resp;
1536
1537	if (ccbh->target_lun == CAM_LUN_WILDCARD)
1538		subtype = VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET;
1539	else
1540		subtype = VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET;
1541
1542	vtscsi_init_ctrl_tmf_req(ccbh, subtype, 0, tmf_req);
1543
1544	sglist_reset(sg);
1545	sglist_append(sg, tmf_req, sizeof(struct virtio_scsi_ctrl_tmf_req));
1546	sglist_append(sg, tmf_resp, sizeof(struct virtio_scsi_ctrl_tmf_resp));
1547
1548	req->vsr_complete = vtscsi_complete_reset_dev_cmd;
1549	tmf_resp->response = -1;
1550
1551	error = vtscsi_execute_ctrl_req(sc, req, sg, 1, 1,
1552	    VTSCSI_EXECUTE_ASYNC);
1553
1554	vtscsi_dprintf(sc, VTSCSI_TRACE, "error=%d req=%p ccb=%p\n",
1555	    error, req, ccbh);
1556
1557	return (error);
1558}
1559
1560static void
1561vtscsi_get_request_lun(uint8_t lun[], target_id_t *target_id, lun_id_t *lun_id)
1562{
1563
1564	*target_id = lun[1];
1565	*lun_id = (lun[2] << 8) | lun[3];
1566}
1567
1568static void
1569vtscsi_set_request_lun(struct ccb_hdr *ccbh, uint8_t lun[])
1570{
1571
1572	lun[0] = 1;
1573	lun[1] = ccbh->target_id;
1574	lun[2] = 0x40 | ((ccbh->target_lun >> 8) & 0x3F);
1575	lun[3] = ccbh->target_lun & 0xFF;
1576}
1577
1578static void
1579vtscsi_init_scsi_cmd_req(struct ccb_scsiio *csio,
1580    struct virtio_scsi_cmd_req *cmd_req)
1581{
1582	uint8_t attr;
1583
1584	switch (csio->tag_action) {
1585	case MSG_HEAD_OF_Q_TAG:
1586		attr = VIRTIO_SCSI_S_HEAD;
1587		break;
1588	case MSG_ORDERED_Q_TAG:
1589		attr = VIRTIO_SCSI_S_ORDERED;
1590		break;
1591	case MSG_ACA_TASK:
1592		attr = VIRTIO_SCSI_S_ACA;
1593		break;
1594	default: /* MSG_SIMPLE_Q_TAG */
1595		attr = VIRTIO_SCSI_S_SIMPLE;
1596		break;
1597	}
1598
1599	vtscsi_set_request_lun(&csio->ccb_h, cmd_req->lun);
1600	cmd_req->tag = (uintptr_t) csio;
1601	cmd_req->task_attr = attr;
1602
1603	memcpy(cmd_req->cdb,
1604	    csio->ccb_h.flags & CAM_CDB_POINTER ?
1605	        csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes,
1606	    csio->cdb_len);
1607}
1608
1609static void
1610vtscsi_init_ctrl_tmf_req(struct ccb_hdr *ccbh, uint32_t subtype,
1611    uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req)
1612{
1613
1614	vtscsi_set_request_lun(ccbh, tmf_req->lun);
1615
1616	tmf_req->type = VIRTIO_SCSI_T_TMF;
1617	tmf_req->subtype = subtype;
1618	tmf_req->tag = tag;
1619}
1620
1621static void
1622vtscsi_freeze_simq(struct vtscsi_softc *sc, int reason)
1623{
1624	int frozen;
1625
1626	frozen = sc->vtscsi_frozen;
1627
1628	if (reason & VTSCSI_REQUEST &&
1629	    (sc->vtscsi_frozen & VTSCSI_FROZEN_NO_REQUESTS) == 0)
1630		sc->vtscsi_frozen |= VTSCSI_FROZEN_NO_REQUESTS;
1631
1632	if (reason & VTSCSI_REQUEST_VQ &&
1633	    (sc->vtscsi_frozen & VTSCSI_FROZEN_REQUEST_VQ_FULL) == 0)
1634		sc->vtscsi_frozen |= VTSCSI_FROZEN_REQUEST_VQ_FULL;
1635
1636	/* Freeze the SIMQ if transitioned to frozen. */
1637	if (frozen == 0 && sc->vtscsi_frozen != 0) {
1638		vtscsi_dprintf(sc, VTSCSI_INFO, "SIMQ frozen\n");
1639		xpt_freeze_simq(sc->vtscsi_sim, 1);
1640	}
1641}
1642
1643static int
1644vtscsi_thaw_simq(struct vtscsi_softc *sc, int reason)
1645{
1646	int thawed;
1647
1648	if (sc->vtscsi_frozen == 0 || reason == 0)
1649		return (0);
1650
1651	if (reason & VTSCSI_REQUEST &&
1652	    sc->vtscsi_frozen & VTSCSI_FROZEN_NO_REQUESTS)
1653		sc->vtscsi_frozen &= ~VTSCSI_FROZEN_NO_REQUESTS;
1654
1655	if (reason & VTSCSI_REQUEST_VQ &&
1656	    sc->vtscsi_frozen & VTSCSI_FROZEN_REQUEST_VQ_FULL)
1657		sc->vtscsi_frozen &= ~VTSCSI_FROZEN_REQUEST_VQ_FULL;
1658
1659	thawed = sc->vtscsi_frozen == 0;
1660	if (thawed != 0)
1661		vtscsi_dprintf(sc, VTSCSI_INFO, "SIMQ thawed\n");
1662
1663	return (thawed);
1664}
1665
1666static void
1667vtscsi_announce(struct vtscsi_softc *sc, uint32_t ac_code,
1668    target_id_t target_id, lun_id_t lun_id)
1669{
1670	struct cam_path *path;
1671
1672	/* Use the wildcard path from our softc for bus announcements. */
1673	if (target_id == CAM_TARGET_WILDCARD && lun_id == CAM_LUN_WILDCARD) {
1674		xpt_async(ac_code, sc->vtscsi_path, NULL);
1675		return;
1676	}
1677
1678	if (xpt_create_path(&path, NULL, cam_sim_path(sc->vtscsi_sim),
1679	    target_id, lun_id) != CAM_REQ_CMP) {
1680		vtscsi_dprintf(sc, VTSCSI_ERROR, "cannot create path\n");
1681		return;
1682	}
1683
1684	xpt_async(ac_code, path, NULL);
1685	xpt_free_path(path);
1686}
1687
1688static void
1689vtscsi_execute_rescan(struct vtscsi_softc *sc, target_id_t target_id,
1690    lun_id_t lun_id)
1691{
1692	union ccb *ccb;
1693	cam_status status;
1694
1695	ccb = xpt_alloc_ccb_nowait();
1696	if (ccb == NULL) {
1697		vtscsi_dprintf(sc, VTSCSI_ERROR, "cannot allocate CCB\n");
1698		return;
1699	}
1700
1701	status = xpt_create_path(&ccb->ccb_h.path, NULL,
1702	    cam_sim_path(sc->vtscsi_sim), target_id, lun_id);
1703	if (status != CAM_REQ_CMP) {
1704		xpt_free_ccb(ccb);
1705		return;
1706	}
1707
1708	xpt_rescan(ccb);
1709}
1710
1711static void
1712vtscsi_execute_rescan_bus(struct vtscsi_softc *sc)
1713{
1714
1715	vtscsi_execute_rescan(sc, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
1716}
1717
1718static void
1719vtscsi_transport_reset_event(struct vtscsi_softc *sc,
1720    struct virtio_scsi_event *event)
1721{
1722	target_id_t target_id;
1723	lun_id_t lun_id;
1724
1725	vtscsi_get_request_lun(event->lun, &target_id, &lun_id);
1726
1727	switch (event->reason) {
1728	case VIRTIO_SCSI_EVT_RESET_RESCAN:
1729	case VIRTIO_SCSI_EVT_RESET_REMOVED:
1730		vtscsi_execute_rescan(sc, target_id, lun_id);
1731		break;
1732	default:
1733		device_printf(sc->vtscsi_dev,
1734		    "unhandled transport event reason: %d\n", event->reason);
1735		break;
1736	}
1737}
1738
1739static void
1740vtscsi_handle_event(struct vtscsi_softc *sc, struct virtio_scsi_event *event)
1741{
1742	int error;
1743
1744	if ((event->event & VIRTIO_SCSI_T_EVENTS_MISSED) == 0) {
1745		switch (event->event) {
1746		case VIRTIO_SCSI_T_TRANSPORT_RESET:
1747			vtscsi_transport_reset_event(sc, event);
1748			break;
1749		default:
1750			device_printf(sc->vtscsi_dev,
1751			    "unhandled event: %d\n", event->event);
1752			break;
1753		}
1754	} else
1755		vtscsi_execute_rescan_bus(sc);
1756
1757	/*
1758	 * This should always be successful since the buffer
1759	 * was just dequeued.
1760	 */
1761	error = vtscsi_enqueue_event_buf(sc, event);
1762	KASSERT(error == 0,
1763	    ("cannot requeue event buffer: %d", error));
1764}
1765
1766static int
1767vtscsi_enqueue_event_buf(struct vtscsi_softc *sc,
1768    struct virtio_scsi_event *event)
1769{
1770	struct sglist *sg;
1771	struct virtqueue *vq;
1772	int size, error;
1773
1774	sg = sc->vtscsi_sglist;
1775	vq = sc->vtscsi_event_vq;
1776	size = sc->vtscsi_event_buf_size;
1777
1778	bzero(event, size);
1779
1780	sglist_reset(sg);
1781	error = sglist_append(sg, event, size);
1782	if (error)
1783		return (error);
1784
1785	error = virtqueue_enqueue(vq, event, sg, 0, sg->sg_nseg);
1786	if (error)
1787		return (error);
1788
1789	virtqueue_notify(vq);
1790
1791	return (0);
1792}
1793
1794static int
1795vtscsi_init_event_vq(struct vtscsi_softc *sc)
1796{
1797	struct virtio_scsi_event *event;
1798	int i, size, error;
1799
1800	/*
1801	 * The first release of QEMU with VirtIO SCSI support would crash
1802	 * when attempting to notify the event virtqueue. This was fixed
1803	 * when hotplug support was added.
1804	 */
1805	if (sc->vtscsi_flags & VTSCSI_FLAG_HOTPLUG)
1806		size = sc->vtscsi_event_buf_size;
1807	else
1808		size = 0;
1809
1810	if (size < sizeof(struct virtio_scsi_event))
1811		return (0);
1812
1813	for (i = 0; i < VTSCSI_NUM_EVENT_BUFS; i++) {
1814		event = &sc->vtscsi_event_bufs[i];
1815
1816		error = vtscsi_enqueue_event_buf(sc, event);
1817		if (error)
1818			break;
1819	}
1820
1821	/*
1822	 * Even just one buffer is enough. Missed events are
1823	 * denoted with the VIRTIO_SCSI_T_EVENTS_MISSED flag.
1824	 */
1825	if (i > 0)
1826		error = 0;
1827
1828	return (error);
1829}
1830
1831static void
1832vtscsi_reinit_event_vq(struct vtscsi_softc *sc)
1833{
1834	struct virtio_scsi_event *event;
1835	int i, error;
1836
1837	if ((sc->vtscsi_flags & VTSCSI_FLAG_HOTPLUG) == 0 ||
1838	    sc->vtscsi_event_buf_size < sizeof(struct virtio_scsi_event))
1839		return;
1840
1841	for (i = 0; i < VTSCSI_NUM_EVENT_BUFS; i++) {
1842		event = &sc->vtscsi_event_bufs[i];
1843
1844		error = vtscsi_enqueue_event_buf(sc, event);
1845		if (error)
1846			break;
1847	}
1848
1849	KASSERT(i > 0, ("cannot reinit event vq: %d", error));
1850}
1851
1852static void
1853vtscsi_drain_event_vq(struct vtscsi_softc *sc)
1854{
1855	struct virtqueue *vq;
1856	int last;
1857
1858	vq = sc->vtscsi_event_vq;
1859	last = 0;
1860
1861	while (virtqueue_drain(vq, &last) != NULL)
1862		;
1863
1864	KASSERT(virtqueue_empty(vq), ("eventvq not empty"));
1865}
1866
1867static void
1868vtscsi_complete_vqs_locked(struct vtscsi_softc *sc)
1869{
1870
1871	VTSCSI_LOCK_OWNED(sc);
1872
1873	if (sc->vtscsi_request_vq != NULL)
1874		vtscsi_complete_vq(sc, sc->vtscsi_request_vq);
1875	if (sc->vtscsi_control_vq != NULL)
1876		vtscsi_complete_vq(sc, sc->vtscsi_control_vq);
1877}
1878
1879static void
1880vtscsi_complete_vqs(struct vtscsi_softc *sc)
1881{
1882
1883	VTSCSI_LOCK(sc);
1884	vtscsi_complete_vqs_locked(sc);
1885	VTSCSI_UNLOCK(sc);
1886}
1887
1888static void
1889vtscsi_cancel_request(struct vtscsi_softc *sc, struct vtscsi_request *req)
1890{
1891	union ccb *ccb;
1892	int detach;
1893
1894	ccb = req->vsr_ccb;
1895
1896	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p ccb=%p\n", req, ccb);
1897
1898	/*
1899	 * The callout must be drained when detaching since the request is
1900	 * about to be freed. The VTSCSI_MTX must not be held for this in
1901	 * case the callout is pending because there is a deadlock potential.
1902	 * Otherwise, the virtqueue is being drained because of a bus reset
1903	 * so we only need to attempt to stop the callouts.
1904	 */
1905	detach = (sc->vtscsi_flags & VTSCSI_FLAG_DETACH) != 0;
1906	if (detach != 0)
1907		VTSCSI_LOCK_NOTOWNED(sc);
1908	else
1909		VTSCSI_LOCK_OWNED(sc);
1910
1911	if (req->vsr_flags & VTSCSI_REQ_FLAG_TIMEOUT_SET) {
1912		if (detach != 0)
1913			callout_drain(&req->vsr_callout);
1914		else
1915			callout_stop(&req->vsr_callout);
1916	}
1917
1918	if (ccb != NULL) {
1919		if (detach != 0) {
1920			VTSCSI_LOCK(sc);
1921			ccb->ccb_h.status = CAM_NO_HBA;
1922		} else
1923			ccb->ccb_h.status = CAM_REQUEUE_REQ;
1924		xpt_done(ccb);
1925		if (detach != 0)
1926			VTSCSI_UNLOCK(sc);
1927	}
1928
1929	vtscsi_enqueue_request(sc, req);
1930}
1931
1932static void
1933vtscsi_drain_vq(struct vtscsi_softc *sc, struct virtqueue *vq)
1934{
1935	struct vtscsi_request *req;
1936	int last;
1937
1938	last = 0;
1939
1940	vtscsi_dprintf(sc, VTSCSI_TRACE, "vq=%p\n", vq);
1941
1942	while ((req = virtqueue_drain(vq, &last)) != NULL)
1943		vtscsi_cancel_request(sc, req);
1944
1945	KASSERT(virtqueue_empty(vq), ("virtqueue not empty"));
1946}
1947
1948static void
1949vtscsi_drain_vqs(struct vtscsi_softc *sc)
1950{
1951
1952	if (sc->vtscsi_control_vq != NULL)
1953		vtscsi_drain_vq(sc, sc->vtscsi_control_vq);
1954	if (sc->vtscsi_request_vq != NULL)
1955		vtscsi_drain_vq(sc, sc->vtscsi_request_vq);
1956	if (sc->vtscsi_event_vq != NULL)
1957		vtscsi_drain_event_vq(sc);
1958}
1959
1960static void
1961vtscsi_stop(struct vtscsi_softc *sc)
1962{
1963
1964	vtscsi_disable_vqs_intr(sc);
1965	virtio_stop(sc->vtscsi_dev);
1966}
1967
1968static int
1969vtscsi_reset_bus(struct vtscsi_softc *sc)
1970{
1971	int error;
1972
1973	VTSCSI_LOCK_OWNED(sc);
1974
1975	if (vtscsi_bus_reset_disable != 0) {
1976		device_printf(sc->vtscsi_dev, "bus reset disabled\n");
1977		return (0);
1978	}
1979
1980	sc->vtscsi_flags |= VTSCSI_FLAG_RESET;
1981
1982	/*
1983	 * vtscsi_stop() will cause the in-flight requests to be canceled.
1984	 * Those requests are then completed here so CAM will retry them
1985	 * after the reset is complete.
1986	 */
1987	vtscsi_stop(sc);
1988	vtscsi_complete_vqs_locked(sc);
1989
1990	/* Rid the virtqueues of any remaining requests. */
1991	vtscsi_drain_vqs(sc);
1992
1993	/*
1994	 * Any resource shortage that froze the SIMQ cannot persist across
1995	 * a bus reset so ensure it gets thawed here.
1996	 */
1997	if (vtscsi_thaw_simq(sc, VTSCSI_REQUEST | VTSCSI_REQUEST_VQ) != 0)
1998		xpt_release_simq(sc->vtscsi_sim, 0);
1999
2000	error = vtscsi_reinit(sc);
2001	if (error) {
2002		device_printf(sc->vtscsi_dev,
2003		    "reinitialization failed, stopping device...\n");
2004		vtscsi_stop(sc);
2005	} else
2006		vtscsi_announce(sc, AC_BUS_RESET, CAM_TARGET_WILDCARD,
2007		    CAM_LUN_WILDCARD);
2008
2009	sc->vtscsi_flags &= ~VTSCSI_FLAG_RESET;
2010
2011	return (error);
2012}
2013
2014static void
2015vtscsi_init_request(struct vtscsi_softc *sc, struct vtscsi_request *req)
2016{
2017
2018#ifdef INVARIANTS
2019	int req_nsegs, resp_nsegs;
2020
2021	req_nsegs = sglist_count(&req->vsr_ureq, sizeof(req->vsr_ureq));
2022	resp_nsegs = sglist_count(&req->vsr_uresp, sizeof(req->vsr_uresp));
2023
2024	KASSERT(req_nsegs == 1, ("request crossed page boundary"));
2025	KASSERT(resp_nsegs == 1, ("response crossed page boundary"));
2026#endif
2027
2028	req->vsr_softc = sc;
2029	callout_init_mtx(&req->vsr_callout, VTSCSI_MTX(sc), 0);
2030}
2031
2032static int
2033vtscsi_alloc_requests(struct vtscsi_softc *sc)
2034{
2035	struct vtscsi_request *req;
2036	int i, nreqs;
2037
2038	/*
2039	 * Commands destined for either the request or control queues come
2040	 * from the same SIM queue. Use the size of the request virtqueue
2041	 * as it (should) be much more frequently used. Some additional
2042	 * requests are allocated for internal (TMF) use.
2043	 */
2044	nreqs = virtqueue_size(sc->vtscsi_request_vq);
2045	if ((sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT) == 0)
2046		nreqs /= VTSCSI_MIN_SEGMENTS;
2047	nreqs += VTSCSI_RESERVED_REQUESTS;
2048
2049	for (i = 0; i < nreqs; i++) {
2050		req = malloc(sizeof(struct vtscsi_request), M_DEVBUF,
2051		    M_NOWAIT);
2052		if (req == NULL)
2053			return (ENOMEM);
2054
2055		vtscsi_init_request(sc, req);
2056
2057		sc->vtscsi_nrequests++;
2058		vtscsi_enqueue_request(sc, req);
2059	}
2060
2061	return (0);
2062}
2063
2064static void
2065vtscsi_free_requests(struct vtscsi_softc *sc)
2066{
2067	struct vtscsi_request *req;
2068
2069	while ((req = vtscsi_dequeue_request(sc)) != NULL) {
2070		KASSERT(callout_active(&req->vsr_callout) == 0,
2071		    ("request callout still active"));
2072
2073		sc->vtscsi_nrequests--;
2074		free(req, M_DEVBUF);
2075	}
2076
2077	KASSERT(sc->vtscsi_nrequests == 0, ("leaked requests: %d",
2078	    sc->vtscsi_nrequests));
2079}
2080
2081static void
2082vtscsi_enqueue_request(struct vtscsi_softc *sc, struct vtscsi_request *req)
2083{
2084
2085	KASSERT(req->vsr_softc == sc,
2086	    ("non-matching request vsr_softc %p/%p", req->vsr_softc, sc));
2087
2088	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p\n", req);
2089
2090	/* A request is available so the SIMQ could be released. */
2091	if (vtscsi_thaw_simq(sc, VTSCSI_REQUEST) != 0)
2092		xpt_release_simq(sc->vtscsi_sim, 1);
2093
2094	req->vsr_ccb = NULL;
2095	req->vsr_complete = NULL;
2096	req->vsr_ptr0 = NULL;
2097	req->vsr_state = VTSCSI_REQ_STATE_FREE;
2098	req->vsr_flags = 0;
2099
2100	bzero(&req->vsr_ureq, sizeof(req->vsr_ureq));
2101	bzero(&req->vsr_uresp, sizeof(req->vsr_uresp));
2102
2103	/*
2104	 * We insert at the tail of the queue in order to make it
2105	 * very unlikely a request will be reused if we race with
2106	 * stopping its callout handler.
2107	 */
2108	TAILQ_INSERT_TAIL(&sc->vtscsi_req_free, req, vsr_link);
2109}
2110
2111static struct vtscsi_request *
2112vtscsi_dequeue_request(struct vtscsi_softc *sc)
2113{
2114	struct vtscsi_request *req;
2115
2116	req = TAILQ_FIRST(&sc->vtscsi_req_free);
2117	if (req != NULL) {
2118		req->vsr_state = VTSCSI_REQ_STATE_INUSE;
2119		TAILQ_REMOVE(&sc->vtscsi_req_free, req, vsr_link);
2120	} else
2121		sc->vtscsi_stats.dequeue_no_requests++;
2122
2123	vtscsi_dprintf(sc, VTSCSI_TRACE, "req=%p\n", req);
2124
2125	return (req);
2126}
2127
2128static void
2129vtscsi_complete_request(struct vtscsi_request *req)
2130{
2131
2132	if (req->vsr_flags & VTSCSI_REQ_FLAG_POLLED)
2133		req->vsr_flags |= VTSCSI_REQ_FLAG_COMPLETE;
2134
2135	if (req->vsr_complete != NULL)
2136		req->vsr_complete(req->vsr_softc, req);
2137}
2138
2139static void
2140vtscsi_complete_vq(struct vtscsi_softc *sc, struct virtqueue *vq)
2141{
2142	struct vtscsi_request *req;
2143
2144	VTSCSI_LOCK_OWNED(sc);
2145
2146	while ((req = virtqueue_dequeue(vq, NULL)) != NULL)
2147		vtscsi_complete_request(req);
2148}
2149
2150static void
2151vtscsi_control_vq_intr(void *xsc)
2152{
2153	struct vtscsi_softc *sc;
2154	struct virtqueue *vq;
2155
2156	sc = xsc;
2157	vq = sc->vtscsi_control_vq;
2158
2159again:
2160	VTSCSI_LOCK(sc);
2161
2162	vtscsi_complete_vq(sc, sc->vtscsi_control_vq);
2163
2164	if (virtqueue_enable_intr(vq) != 0) {
2165		virtqueue_disable_intr(vq);
2166		VTSCSI_UNLOCK(sc);
2167		goto again;
2168	}
2169
2170	VTSCSI_UNLOCK(sc);
2171}
2172
2173static void
2174vtscsi_event_vq_intr(void *xsc)
2175{
2176	struct vtscsi_softc *sc;
2177	struct virtqueue *vq;
2178	struct virtio_scsi_event *event;
2179
2180	sc = xsc;
2181	vq = sc->vtscsi_event_vq;
2182
2183again:
2184	VTSCSI_LOCK(sc);
2185
2186	while ((event = virtqueue_dequeue(vq, NULL)) != NULL)
2187		vtscsi_handle_event(sc, event);
2188
2189	if (virtqueue_enable_intr(vq) != 0) {
2190		virtqueue_disable_intr(vq);
2191		VTSCSI_UNLOCK(sc);
2192		goto again;
2193	}
2194
2195	VTSCSI_UNLOCK(sc);
2196}
2197
2198static void
2199vtscsi_request_vq_intr(void *xsc)
2200{
2201	struct vtscsi_softc *sc;
2202	struct virtqueue *vq;
2203
2204	sc = xsc;
2205	vq = sc->vtscsi_request_vq;
2206
2207again:
2208	VTSCSI_LOCK(sc);
2209
2210	vtscsi_complete_vq(sc, sc->vtscsi_request_vq);
2211
2212	if (virtqueue_enable_intr(vq) != 0) {
2213		virtqueue_disable_intr(vq);
2214		VTSCSI_UNLOCK(sc);
2215		goto again;
2216	}
2217
2218	VTSCSI_UNLOCK(sc);
2219}
2220
2221static void
2222vtscsi_disable_vqs_intr(struct vtscsi_softc *sc)
2223{
2224
2225	virtqueue_disable_intr(sc->vtscsi_control_vq);
2226	virtqueue_disable_intr(sc->vtscsi_event_vq);
2227	virtqueue_disable_intr(sc->vtscsi_request_vq);
2228}
2229
2230static void
2231vtscsi_enable_vqs_intr(struct vtscsi_softc *sc)
2232{
2233
2234	virtqueue_enable_intr(sc->vtscsi_control_vq);
2235	virtqueue_enable_intr(sc->vtscsi_event_vq);
2236	virtqueue_enable_intr(sc->vtscsi_request_vq);
2237}
2238
2239static void
2240vtscsi_get_tunables(struct vtscsi_softc *sc)
2241{
2242	char tmpstr[64];
2243
2244	TUNABLE_INT_FETCH("hw.vtscsi.debug_level", &sc->vtscsi_debug);
2245
2246	snprintf(tmpstr, sizeof(tmpstr), "dev.vtscsi.%d.debug_level",
2247	    device_get_unit(sc->vtscsi_dev));
2248	TUNABLE_INT_FETCH(tmpstr, &sc->vtscsi_debug);
2249}
2250
2251static void
2252vtscsi_add_sysctl(struct vtscsi_softc *sc)
2253{
2254	device_t dev;
2255	struct vtscsi_statistics *stats;
2256        struct sysctl_ctx_list *ctx;
2257	struct sysctl_oid *tree;
2258	struct sysctl_oid_list *child;
2259
2260	dev = sc->vtscsi_dev;
2261	stats = &sc->vtscsi_stats;
2262	ctx = device_get_sysctl_ctx(dev);
2263	tree = device_get_sysctl_tree(dev);
2264	child = SYSCTL_CHILDREN(tree);
2265
2266	SYSCTL_ADD_INT(ctx, child, OID_AUTO, "debug_level",
2267	    CTLFLAG_RW, &sc->vtscsi_debug, 0,
2268	    "Debug level");
2269
2270	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "scsi_cmd_timeouts",
2271	    CTLFLAG_RD, &stats->scsi_cmd_timeouts,
2272	    "SCSI command timeouts");
2273	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dequeue_no_requests",
2274	    CTLFLAG_RD, &stats->dequeue_no_requests,
2275	    "No available requests to dequeue");
2276}
2277
2278static void
2279vtscsi_printf_req(struct vtscsi_request *req, const char *func,
2280    const char *fmt, ...)
2281{
2282	struct vtscsi_softc *sc;
2283	union ccb *ccb;
2284	struct sbuf sb;
2285	va_list ap;
2286	char str[192];
2287	char path_str[64];
2288
2289	if (req == NULL)
2290		return;
2291
2292	sc = req->vsr_softc;
2293	ccb = req->vsr_ccb;
2294
2295	va_start(ap, fmt);
2296	sbuf_new(&sb, str, sizeof(str), 0);
2297
2298	if (ccb == NULL) {
2299		sbuf_printf(&sb, "(noperiph:%s%d:%u): ",
2300		    cam_sim_name(sc->vtscsi_sim), cam_sim_unit(sc->vtscsi_sim),
2301		    cam_sim_bus(sc->vtscsi_sim));
2302	} else {
2303		xpt_path_string(ccb->ccb_h.path, path_str, sizeof(path_str));
2304		sbuf_cat(&sb, path_str);
2305		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
2306			scsi_command_string(&ccb->csio, &sb);
2307			sbuf_printf(&sb, "length %d ", ccb->csio.dxfer_len);
2308		}
2309	}
2310
2311	sbuf_vprintf(&sb, fmt, ap);
2312	va_end(ap);
2313
2314	sbuf_finish(&sb);
2315	printf("%s: %s: %s", device_get_nameunit(sc->vtscsi_dev), func,
2316	    sbuf_data(&sb));
2317}
2318