xref: /netbsd-src/sys/arch/usermode/dev/vatapi.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /* $NetBSD: vatapi.c,v 1.4 2021/08/07 16:19:07 thorpej Exp $ */
2efbd3dcdSreinoud 
3efbd3dcdSreinoud /*-
4efbd3dcdSreinoud  * Copyright (c) 2018 Reinoud Zandijk <reinoud@NetBSD.org>
5efbd3dcdSreinoud  * All rights reserved.
6efbd3dcdSreinoud  *
7efbd3dcdSreinoud  * Redistribution and use in source and binary forms, with or without
8efbd3dcdSreinoud  * modification, are permitted provided that the following conditions
9efbd3dcdSreinoud  * are met:
10efbd3dcdSreinoud  * 1. Redistributions of source code must retain the above copyright
11efbd3dcdSreinoud  *    notice, this list of conditions and the following disclaimer.
12efbd3dcdSreinoud  * 2. Redistributions in binary form must reproduce the above copyright
13efbd3dcdSreinoud  *    notice, this list of conditions and the following disclaimer in the
14efbd3dcdSreinoud  *    documentation and/or other materials provided with the distribution.
15efbd3dcdSreinoud  *
16efbd3dcdSreinoud  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17efbd3dcdSreinoud  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18efbd3dcdSreinoud  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19efbd3dcdSreinoud  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20efbd3dcdSreinoud  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21efbd3dcdSreinoud  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22efbd3dcdSreinoud  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23efbd3dcdSreinoud  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24efbd3dcdSreinoud  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25efbd3dcdSreinoud  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26efbd3dcdSreinoud  * POSSIBILITY OF SUCH DAMAGE.
27efbd3dcdSreinoud  */
28efbd3dcdSreinoud 
29efbd3dcdSreinoud #include <sys/cdefs.h>
30*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: vatapi.c,v 1.4 2021/08/07 16:19:07 thorpej Exp $");
31efbd3dcdSreinoud 
32efbd3dcdSreinoud #include <sys/param.h>
33efbd3dcdSreinoud #include <sys/proc.h>
34efbd3dcdSreinoud #include <sys/systm.h>
35efbd3dcdSreinoud #include <sys/device.h>
36efbd3dcdSreinoud #include <sys/buf.h>
37efbd3dcdSreinoud #include <sys/disk.h>
38efbd3dcdSreinoud #include <sys/kmem.h>
39efbd3dcdSreinoud #include <sys/malloc.h>
40efbd3dcdSreinoud #include <sys/scsiio.h>
41efbd3dcdSreinoud 
42efbd3dcdSreinoud #include <machine/mainbus.h>
43efbd3dcdSreinoud #include <machine/thunk.h>
44efbd3dcdSreinoud #include <machine/intr.h>
45efbd3dcdSreinoud 
46efbd3dcdSreinoud #include <dev/scsipi/scsi_all.h>	/* for SCSI status */
47efbd3dcdSreinoud #include <dev/scsipi/scsipi_all.h>
48efbd3dcdSreinoud #include <dev/scsipi/scsipiconf.h>
49efbd3dcdSreinoud #include <dev/scsipi/atapiconf.h>
50efbd3dcdSreinoud 
517e24c785Sreinoud #include "opt_scsi.h"
527e24c785Sreinoud 
53efbd3dcdSreinoud /* parameter? */
54efbd3dcdSreinoud #define VDEV_ATAPI_DRIVE	0
55efbd3dcdSreinoud #define MAX_SIZE		((1<<16))
56efbd3dcdSreinoud 
57efbd3dcdSreinoud /* forwards */
58efbd3dcdSreinoud struct vatapi_softc;
59efbd3dcdSreinoud 
60efbd3dcdSreinoud static int	vatapi_match(device_t, cfdata_t, void *);
61efbd3dcdSreinoud static void	vatapi_attach(device_t, device_t, void *);
62efbd3dcdSreinoud static void	vatapi_callback(device_t self);
63efbd3dcdSreinoud 
64efbd3dcdSreinoud static void	vatapi_minphys(struct buf *bp);
65efbd3dcdSreinoud static void	vatapi_kill_pending(struct scsipi_periph *periph);
66efbd3dcdSreinoud static void	vatapi_scsipi_request(struct scsipi_channel *chan,
67efbd3dcdSreinoud 	scsipi_adapter_req_t req, void *arg);
68efbd3dcdSreinoud static void	vatapi_probe_device(struct atapibus_softc *, int);
69efbd3dcdSreinoud 
70efbd3dcdSreinoud static void	vatapi_complete(void *arg);
71efbd3dcdSreinoud 
72efbd3dcdSreinoud /* for debugging */
737e24c785Sreinoud #ifdef SCSIVERBOSE
74efbd3dcdSreinoud void	scsipi_print_sense_data_real(struct scsi_sense_data *sense, int verbosity);
757e24c785Sreinoud #endif
76efbd3dcdSreinoud 
77efbd3dcdSreinoud 
78efbd3dcdSreinoud /* Note its one vdev, one adapter, one channel for now */
79efbd3dcdSreinoud struct vatapi_softc {
80efbd3dcdSreinoud 	device_t	sc_dev;
81efbd3dcdSreinoud 	device_t	sc_pdev;
82efbd3dcdSreinoud 
83efbd3dcdSreinoud 	int		sc_flags;
84efbd3dcdSreinoud #define VATAPI_FLAG_POLLING	1
85efbd3dcdSreinoud #define VATAPI_FLAG_INTR	2
86efbd3dcdSreinoud 	/* backing `device' with its active command */
87efbd3dcdSreinoud 	int		sc_fd;
88efbd3dcdSreinoud 	void		*sc_ih;
89efbd3dcdSreinoud 	struct scsipi_xfer *sc_xs;
90efbd3dcdSreinoud 
91efbd3dcdSreinoud 	/* atapibus */
92efbd3dcdSreinoud 	device_t	sc_vatapibus;
93efbd3dcdSreinoud 	struct atapi_adapter    sc_atapi_adapter;
94efbd3dcdSreinoud #define sc_adapter sc_atapi_adapter._generic
95efbd3dcdSreinoud 	struct scsipi_channel sc_channel;
96efbd3dcdSreinoud };
97efbd3dcdSreinoud 
98efbd3dcdSreinoud CFATTACH_DECL_NEW(vatapi_thunkbus, sizeof(struct vatapi_softc),
99efbd3dcdSreinoud     vatapi_match, vatapi_attach, NULL, NULL);
100efbd3dcdSreinoud 
101efbd3dcdSreinoud 
102efbd3dcdSreinoud static const struct scsipi_bustype vatapi_bustype = {
103efbd3dcdSreinoud 	SCSIPI_BUSTYPE_ATAPI,
104efbd3dcdSreinoud 	atapi_scsipi_cmd,
105efbd3dcdSreinoud 	atapi_interpret_sense,
106efbd3dcdSreinoud 	atapi_print_addr,
107efbd3dcdSreinoud 	vatapi_kill_pending,
108efbd3dcdSreinoud 	NULL
109efbd3dcdSreinoud };
110efbd3dcdSreinoud 
111efbd3dcdSreinoud int
vatapi_match(device_t parent,cfdata_t match,void * opaque)112efbd3dcdSreinoud vatapi_match(device_t parent, cfdata_t match, void *opaque)
113efbd3dcdSreinoud {
114efbd3dcdSreinoud 	struct thunkbus_attach_args *taa = opaque;
115efbd3dcdSreinoud 
116efbd3dcdSreinoud 	if (taa->taa_type != THUNKBUS_TYPE_VATAPI)
117efbd3dcdSreinoud 		return 0;
118efbd3dcdSreinoud 
119efbd3dcdSreinoud 	return 1;
120efbd3dcdSreinoud }
121efbd3dcdSreinoud 
122efbd3dcdSreinoud static void
vatapi_attach(device_t parent,device_t self,void * opaque)123efbd3dcdSreinoud vatapi_attach(device_t parent, device_t self, void *opaque)
124efbd3dcdSreinoud {
125efbd3dcdSreinoud 	struct vatapi_softc *sc = device_private(self);
126efbd3dcdSreinoud 	struct thunkbus_attach_args *taa = opaque;
127efbd3dcdSreinoud 
128efbd3dcdSreinoud 	sc->sc_dev = self;
129efbd3dcdSreinoud 	sc->sc_pdev = parent;
130efbd3dcdSreinoud 
131efbd3dcdSreinoud 	/* open device */
132efbd3dcdSreinoud 	sc->sc_fd = thunk_open(taa->u.vdev.path, O_RDWR, 0);
133efbd3dcdSreinoud 	if (sc->sc_fd < 0) {
134efbd3dcdSreinoud 		aprint_error(": error %d opening path\n", thunk_geterrno());
135efbd3dcdSreinoud 		return;
136efbd3dcdSreinoud 	}
137efbd3dcdSreinoud 
138efbd3dcdSreinoud 	aprint_naive("\n");
139efbd3dcdSreinoud 	aprint_normal("\n");
140efbd3dcdSreinoud 
141efbd3dcdSreinoud 	sc->sc_ih = softint_establish(SOFTINT_BIO,
142efbd3dcdSreinoud 		vatapi_complete, sc);
143efbd3dcdSreinoud 
144efbd3dcdSreinoud 	/* rest of the configuration is deferred */
145efbd3dcdSreinoud 	config_interrupts(self, vatapi_callback);
146efbd3dcdSreinoud }
147efbd3dcdSreinoud 
148efbd3dcdSreinoud static void
vatapi_callback(device_t self)149efbd3dcdSreinoud vatapi_callback(device_t self)
150efbd3dcdSreinoud {
151efbd3dcdSreinoud 	struct vatapi_softc *sc = device_private(self);
152efbd3dcdSreinoud 	struct scsipi_adapter *adapt = &sc->sc_adapter;
153efbd3dcdSreinoud 	struct scsipi_channel *chan  = &sc->sc_channel;
154efbd3dcdSreinoud 
155efbd3dcdSreinoud 	/* set up the scsipi adapter and channel */
156efbd3dcdSreinoud 	memset(adapt, 0, sizeof(*adapt));
157efbd3dcdSreinoud 	adapt->adapt_dev = sc->sc_dev;
158efbd3dcdSreinoud 	adapt->adapt_nchannels = 1;
159efbd3dcdSreinoud 	adapt->adapt_request   = vatapi_scsipi_request;
160efbd3dcdSreinoud 	adapt->adapt_minphys   = vatapi_minphys;
161efbd3dcdSreinoud 	adapt->adapt_flags     = 0; //SCSIPI_ADAPT_POLL_ONLY;
162efbd3dcdSreinoud 	sc->sc_atapi_adapter.atapi_probe_device = vatapi_probe_device;
163efbd3dcdSreinoud 
164efbd3dcdSreinoud 	memset(chan,  0, sizeof(*chan));
165efbd3dcdSreinoud 	chan->chan_adapter    = adapt;
166efbd3dcdSreinoud 	chan->chan_bustype    = &vatapi_bustype;
167efbd3dcdSreinoud 	chan->chan_channel    = 0;	/* location */
168efbd3dcdSreinoud 	chan->chan_flags      = SCSIPI_CHAN_OPENINGS;
169efbd3dcdSreinoud 	chan->chan_openings   = 1;
170efbd3dcdSreinoud 	chan->chan_max_periph = 1;
171efbd3dcdSreinoud 	chan->chan_ntargets   = 1;
172efbd3dcdSreinoud 	chan->chan_nluns      = 1;
173efbd3dcdSreinoud 
174efbd3dcdSreinoud 	/* set polling */
175efbd3dcdSreinoud 	//sc->sc_flags = VATAPI_FLAG_POLLING;
176efbd3dcdSreinoud 
177efbd3dcdSreinoud 	/* we `discovered' an atapi adapter */
1782685996bSthorpej 	sc->sc_vatapibus =
179*c7fb772bSthorpej 	    config_found(sc->sc_dev, chan, atapiprint, CFARGS_NONE);
180efbd3dcdSreinoud }
181efbd3dcdSreinoud 
182efbd3dcdSreinoud 
183efbd3dcdSreinoud /* XXX why is it be called minphys, when it enforces maxphys? */
184efbd3dcdSreinoud static void
vatapi_minphys(struct buf * bp)185efbd3dcdSreinoud vatapi_minphys(struct buf *bp)
186efbd3dcdSreinoud {
187efbd3dcdSreinoud 	if (bp->b_bcount > MAX_SIZE)
188efbd3dcdSreinoud 		bp->b_bcount = MAX_SIZE;
189efbd3dcdSreinoud 	minphys(bp);
190efbd3dcdSreinoud }
191efbd3dcdSreinoud 
192efbd3dcdSreinoud /*
193efbd3dcdSreinoud  * ATAPI device probing
194efbd3dcdSreinoud  */
195efbd3dcdSreinoud static void
vatapi_probe_device(struct atapibus_softc * atapi,int target)196efbd3dcdSreinoud vatapi_probe_device(struct atapibus_softc *atapi, int target)
197efbd3dcdSreinoud {
198efbd3dcdSreinoud 	struct scsipi_channel *chan = atapi->sc_channel;
199efbd3dcdSreinoud 	struct scsipi_periph *periph;
200efbd3dcdSreinoud 	struct scsipibus_attach_args sa;
201efbd3dcdSreinoud 	char vendor[33], product[65], revision[17];
202efbd3dcdSreinoud 	struct scsipi_inquiry_data inqbuf;
203efbd3dcdSreinoud 
204efbd3dcdSreinoud 	if (target != VDEV_ATAPI_DRIVE)	/* only probe drive 0 */
205efbd3dcdSreinoud 		return;
206efbd3dcdSreinoud 
207efbd3dcdSreinoud 	/* skip if already attached */
208efbd3dcdSreinoud 	if (scsipi_lookup_periph(chan, target, 0) != NULL)
209efbd3dcdSreinoud 		return;
210efbd3dcdSreinoud 
211efbd3dcdSreinoud 	/* allocate and set up periph structure */
212efbd3dcdSreinoud 	periph = scsipi_alloc_periph(M_NOWAIT);
213efbd3dcdSreinoud 	if (periph == NULL) {
214efbd3dcdSreinoud 		aprint_error_dev(atapi->sc_dev,
215efbd3dcdSreinoud 		    "can't allocate link for drive %d\n", target);
216efbd3dcdSreinoud 		return;
217efbd3dcdSreinoud 	}
218efbd3dcdSreinoud 	periph->periph_channel = chan;
219efbd3dcdSreinoud 	periph->periph_switch = &atapi_probe_periphsw;
220efbd3dcdSreinoud 	periph->periph_target = target;
221efbd3dcdSreinoud 	periph->periph_quirks = chan->chan_defquirks;
222efbd3dcdSreinoud 
223efbd3dcdSreinoud 	/* inquiry */
224efbd3dcdSreinoud 	aprint_verbose("%s: inquiry devices\n", __func__);
225efbd3dcdSreinoud 	memset(&inqbuf, 0, sizeof(inqbuf));
226efbd3dcdSreinoud 	if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY) != 0) {
227efbd3dcdSreinoud 		aprint_error_dev(atapi->sc_dev, ": scsipi_inquire failed\n");
228efbd3dcdSreinoud 		free(periph, M_DEVBUF);
229efbd3dcdSreinoud 		return;
230efbd3dcdSreinoud 	}
231efbd3dcdSreinoud 
232efbd3dcdSreinoud #define scsipi_strvis(a, al, b, bl) strlcpy(a, b, al)
233efbd3dcdSreinoud 	scsipi_strvis(vendor, 33, inqbuf.vendor, 8);
234efbd3dcdSreinoud 	scsipi_strvis(product, 65, inqbuf.product, 16);
235efbd3dcdSreinoud 	scsipi_strvis(revision, 17, inqbuf.revision, 4);
236efbd3dcdSreinoud #undef scsipi_strvis
237efbd3dcdSreinoud 
238efbd3dcdSreinoud 	sa.sa_periph = periph;
239efbd3dcdSreinoud 	sa.sa_inqbuf.type = inqbuf.device;
240efbd3dcdSreinoud 	sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
241efbd3dcdSreinoud 	    T_REMOV : T_FIXED;
242efbd3dcdSreinoud 	if (sa.sa_inqbuf.removable)
243efbd3dcdSreinoud 		periph->periph_flags |= PERIPH_REMOVABLE;
244efbd3dcdSreinoud 	sa.sa_inqbuf.vendor = vendor;
245efbd3dcdSreinoud 	sa.sa_inqbuf.product = product;
246efbd3dcdSreinoud 	sa.sa_inqbuf.revision = revision;
247efbd3dcdSreinoud 	sa.sa_inqptr = NULL;
248efbd3dcdSreinoud 
249efbd3dcdSreinoud 	/* ATAPI demands only READ10 and higher IIRC */
250efbd3dcdSreinoud 	periph->periph_quirks |= PQUIRK_ONLYBIG;
251efbd3dcdSreinoud 
252efbd3dcdSreinoud 	aprint_verbose(": probedev on vendor '%s' product '%s' revision '%s'\n",
253efbd3dcdSreinoud 		vendor, product, revision);
254efbd3dcdSreinoud 
255efbd3dcdSreinoud 	atapi_probe_device(atapi, target, periph, &sa);
256efbd3dcdSreinoud 	/* atapi_probe_device() frees the periph when there is no device.*/
257efbd3dcdSreinoud }
258efbd3dcdSreinoud 
259efbd3dcdSreinoud /*
260efbd3dcdSreinoud  * Issue a request for a periph.
261efbd3dcdSreinoud  */
262efbd3dcdSreinoud static void
vatapi_scsipi_request(struct scsipi_channel * chan,scsipi_adapter_req_t req,void * arg)263efbd3dcdSreinoud vatapi_scsipi_request(struct scsipi_channel *chan,
264efbd3dcdSreinoud 	scsipi_adapter_req_t req, void *arg)
265efbd3dcdSreinoud {
266efbd3dcdSreinoud 	device_t sc_dev = chan->chan_adapter->adapt_dev;
267efbd3dcdSreinoud 	struct vatapi_softc *sc = device_private(sc_dev);
268efbd3dcdSreinoud  	struct scsipi_xfer *xs = arg;
269efbd3dcdSreinoud 
270efbd3dcdSreinoud 	switch (req) {
271efbd3dcdSreinoud  	case ADAPTER_REQ_GROW_RESOURCES:
272efbd3dcdSreinoud  	case ADAPTER_REQ_SET_XFER_MODE:
273efbd3dcdSreinoud 		return;
274efbd3dcdSreinoud 	case ADAPTER_REQ_RUN_XFER :
275efbd3dcdSreinoud 		KASSERT(sc->sc_xs == NULL);
276efbd3dcdSreinoud 
277efbd3dcdSreinoud 		/* queue the command */
278efbd3dcdSreinoud 		KASSERT(sc->sc_xs == NULL);
279efbd3dcdSreinoud 		sc->sc_xs = xs;
280efbd3dcdSreinoud 		softint_schedule(sc->sc_ih);
281efbd3dcdSreinoud 	}
282efbd3dcdSreinoud }
283efbd3dcdSreinoud 
284efbd3dcdSreinoud 
285efbd3dcdSreinoud static void
vatapi_report_problem(scsireq_t * kreq)2867e24c785Sreinoud vatapi_report_problem(scsireq_t *kreq)
2877e24c785Sreinoud {
2887e24c785Sreinoud #ifdef SCSIVERBOSE
2897e24c785Sreinoud 	printf("vatapi cmd failed: ");
2907e24c785Sreinoud 	for (int i = 0; i < kreq->cmdlen; i++) {
2917e24c785Sreinoud 		printf("%02x ", kreq->cmd[i]);
2927e24c785Sreinoud 	}
2937e24c785Sreinoud 	printf("\n");
2947e24c785Sreinoud 	scsipi_print_sense_data_real(
2957e24c785Sreinoud 		(struct scsi_sense_data *) kreq->sense, 1);
2967e24c785Sreinoud #endif
2977e24c785Sreinoud }
2987e24c785Sreinoud 
2997e24c785Sreinoud 
3007e24c785Sreinoud static void
vatapi_complete(void * arg)301efbd3dcdSreinoud vatapi_complete(void *arg)
302efbd3dcdSreinoud {
303efbd3dcdSreinoud 	struct vatapi_softc *sc = arg;
304efbd3dcdSreinoud  	struct scsipi_xfer *xs = sc->sc_xs;
305efbd3dcdSreinoud 	scsireq_t kreq;
306efbd3dcdSreinoud 
307efbd3dcdSreinoud 	memset(&kreq, 0, sizeof(kreq));
308efbd3dcdSreinoud 	memcpy(kreq.cmd, xs->cmd, xs->cmdlen);
309efbd3dcdSreinoud 	kreq.cmdlen = xs->cmdlen;
310efbd3dcdSreinoud 	kreq.databuf = xs->data;		/* in virt? */
311efbd3dcdSreinoud 	kreq.datalen = xs->datalen;
312efbd3dcdSreinoud 	kreq.timeout = xs->timeout;
313efbd3dcdSreinoud 
314efbd3dcdSreinoud 	kreq.flags = (xs->xs_control & XS_CTL_DATA_IN) ?
315efbd3dcdSreinoud 		SCCMD_READ : SCCMD_WRITE;
316efbd3dcdSreinoud 
317efbd3dcdSreinoud 	kreq.senselen = sizeof(struct scsi_sense_data);
318efbd3dcdSreinoud 
319efbd3dcdSreinoud 	xs->error = XS_SHORTSENSE;
320efbd3dcdSreinoud 	/* this is silly, but better make sure */
321efbd3dcdSreinoud 	thunk_assert_presence((vaddr_t) kreq.databuf,
322efbd3dcdSreinoud 		(size_t) kreq.datalen);
323efbd3dcdSreinoud 
324efbd3dcdSreinoud 	if (thunk_ioctl(sc->sc_fd, SCIOCCOMMAND, &kreq) != -1) {
325efbd3dcdSreinoud 		switch (kreq.retsts) {
326efbd3dcdSreinoud 		case SCCMD_OK :
327efbd3dcdSreinoud 			xs->resid = 0;
328efbd3dcdSreinoud 			xs->error = 0;
329efbd3dcdSreinoud 			break;
330efbd3dcdSreinoud 		case SCCMD_TIMEOUT :
331efbd3dcdSreinoud 			break;
332efbd3dcdSreinoud 		case SCCMD_BUSY :
333efbd3dcdSreinoud 			break;
334efbd3dcdSreinoud 		case SCCMD_SENSE :
335efbd3dcdSreinoud 			xs->error = XS_SHORTSENSE;	/* ATAPI */
336efbd3dcdSreinoud 			memcpy(&xs->sense.scsi_sense, kreq.sense,
337efbd3dcdSreinoud 				sizeof(struct scsi_sense_data));
3387e24c785Sreinoud 			vatapi_report_problem(&kreq);
339efbd3dcdSreinoud 			break;
340efbd3dcdSreinoud 		default:
341efbd3dcdSreinoud 			thunk_printf("unhandled/unknown retstst %d\n", kreq.retsts);
342efbd3dcdSreinoud 			break;
343efbd3dcdSreinoud 		}
344efbd3dcdSreinoud 	} else {
345efbd3dcdSreinoud 		printf("thunk_ioctl == -1, errno %d\n", thunk_geterrno());
346efbd3dcdSreinoud 	}
347efbd3dcdSreinoud 	sc->sc_xs = NULL;
348efbd3dcdSreinoud 	scsipi_done(xs);
349efbd3dcdSreinoud }
350efbd3dcdSreinoud 
351efbd3dcdSreinoud 
352efbd3dcdSreinoud /*
353efbd3dcdSreinoud  * Kill off all pending xfers for a periph.
354efbd3dcdSreinoud  *
355efbd3dcdSreinoud  * Must be called at splbio().
356efbd3dcdSreinoud  */
357efbd3dcdSreinoud static void
vatapi_kill_pending(struct scsipi_periph * periph)358efbd3dcdSreinoud vatapi_kill_pending(struct scsipi_periph *periph)
359efbd3dcdSreinoud {
360efbd3dcdSreinoud 	/* do we need to do anything ? (yet?) */
361efbd3dcdSreinoud 	printf("%s: target %d\n", __func__, periph->periph_target);
362efbd3dcdSreinoud }
363efbd3dcdSreinoud 
364