xref: /freebsd/sys/dev/usb/storage/cfumass.c (revision eac7052fdebb90caf2f653e06187bdbca837b9c7)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2016 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * This software was developed by Edward Tomasz Napierala under sponsorship
8  * from the FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32 /*
33  * USB Mass Storage Class Bulk-Only (BBB) Transport target.
34  *
35  * http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
36  *
37  * This code implements the USB Mass Storage frontend driver for the CAM
38  * Target Layer (ctl(4)) subsystem.
39  */
40 
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43 
44 #include <sys/param.h>
45 #include <sys/bus.h>
46 #include <sys/kernel.h>
47 #include <sys/lock.h>
48 #include <sys/module.h>
49 #include <sys/mutex.h>
50 #include <sys/refcount.h>
51 #include <sys/stdint.h>
52 #include <sys/sysctl.h>
53 #include <sys/systm.h>
54 
55 #include <dev/usb/usb.h>
56 #include <dev/usb/usbdi.h>
57 #include "usbdevs.h"
58 #include "usb_if.h"
59 
60 #include <cam/scsi/scsi_all.h>
61 #include <cam/scsi/scsi_da.h>
62 #include <cam/ctl/ctl_io.h>
63 #include <cam/ctl/ctl.h>
64 #include <cam/ctl/ctl_backend.h>
65 #include <cam/ctl/ctl_error.h>
66 #include <cam/ctl/ctl_frontend.h>
67 #include <cam/ctl/ctl_debug.h>
68 #include <cam/ctl/ctl_ha.h>
69 #include <cam/ctl/ctl_ioctl.h>
70 #include <cam/ctl/ctl_private.h>
71 
72 SYSCTL_NODE(_hw_usb, OID_AUTO, cfumass, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
73     "CAM Target Layer USB Mass Storage Frontend");
74 static int debug = 1;
75 SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, debug, CTLFLAG_RWTUN,
76     &debug, 1, "Enable debug messages");
77 static int max_lun = 0;
78 SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, max_lun, CTLFLAG_RWTUN,
79     &max_lun, 1, "Maximum advertised LUN number");
80 static int ignore_stop = 1;
81 SYSCTL_INT(_hw_usb_cfumass, OID_AUTO, ignore_stop, CTLFLAG_RWTUN,
82     &ignore_stop, 1, "Ignore START STOP UNIT with START and LOEJ bits cleared");
83 
84 /*
85  * The driver uses a single, global CTL port.  It could create its ports
86  * in cfumass_attach() instead, but that would make it impossible to specify
87  * "port cfumass0" in ctl.conf(5), as the port generally wouldn't exist
88  * at the time ctld(8) gets run.
89  */
90 struct ctl_port	cfumass_port;
91 bool		cfumass_port_online;
92 volatile u_int	cfumass_refcount;
93 
94 #ifndef CFUMASS_BULK_SIZE
95 #define	CFUMASS_BULK_SIZE	(1U << 17)	/* bytes */
96 #endif
97 
98 /*
99  * USB transfer definitions.
100  */
101 #define	CFUMASS_T_COMMAND	0
102 #define	CFUMASS_T_DATA_OUT	1
103 #define	CFUMASS_T_DATA_IN	2
104 #define	CFUMASS_T_STATUS	3
105 #define	CFUMASS_T_MAX		4
106 
107 /*
108  * USB interface specific control requests.
109  */
110 #define	UR_RESET	0xff	/* Bulk-Only Mass Storage Reset */
111 #define	UR_GET_MAX_LUN	0xfe	/* Get Max LUN */
112 
113 /*
114  * Command Block Wrapper.
115  */
116 struct cfumass_cbw_t {
117 	uDWord	dCBWSignature;
118 #define	CBWSIGNATURE		0x43425355 /* "USBC" */
119 	uDWord	dCBWTag;
120 	uDWord	dCBWDataTransferLength;
121 	uByte	bCBWFlags;
122 #define	CBWFLAGS_OUT		0x00
123 #define	CBWFLAGS_IN		0x80
124 	uByte	bCBWLUN;
125 	uByte	bCDBLength;
126 #define	CBWCBLENGTH		16
127 	uByte	CBWCB[CBWCBLENGTH];
128 } __packed;
129 
130 #define	CFUMASS_CBW_SIZE	31
131 CTASSERT(sizeof(struct cfumass_cbw_t) == CFUMASS_CBW_SIZE);
132 
133 /*
134  * Command Status Wrapper.
135  */
136 struct cfumass_csw_t {
137 	uDWord	dCSWSignature;
138 #define	CSWSIGNATURE		0x53425355 /* "USBS" */
139 	uDWord	dCSWTag;
140 	uDWord	dCSWDataResidue;
141 	uByte	bCSWStatus;
142 #define	CSWSTATUS_GOOD		0x0
143 #define	CSWSTATUS_FAILED	0x1
144 #define	CSWSTATUS_PHASE		0x2
145 } __packed;
146 
147 #define	CFUMASS_CSW_SIZE	13
148 CTASSERT(sizeof(struct cfumass_csw_t) == CFUMASS_CSW_SIZE);
149 
150 struct cfumass_softc {
151 	device_t		sc_dev;
152 	struct usb_device	*sc_udev;
153 	struct usb_xfer		*sc_xfer[CFUMASS_T_MAX];
154 
155 	struct cfumass_cbw_t *sc_cbw;
156 	struct cfumass_csw_t *sc_csw;
157 
158 	struct mtx	sc_mtx;
159 	int		sc_online;
160 	int		sc_ctl_initid;
161 
162 	/*
163 	 * This is used to communicate between CTL callbacks
164 	 * and USB callbacks; basically, it holds the state
165 	 * for the current command ("the" command, since there
166 	 * is no queueing in USB Mass Storage).
167 	 */
168 	bool		sc_current_stalled;
169 
170 	/*
171 	 * The following are set upon receiving a SCSI command.
172 	 */
173 	int		sc_current_tag;
174 	int		sc_current_transfer_length;
175 	int		sc_current_flags;
176 
177 	/*
178 	 * The following are set in ctl_datamove().
179 	 */
180 	int		sc_current_residue;
181 	union ctl_io	*sc_ctl_io;
182 
183 	/*
184 	 * The following is set in cfumass_done().
185 	 */
186 	int		sc_current_status;
187 
188 	/*
189 	 * Number of requests queued to CTL.
190 	 */
191 	volatile u_int	sc_queued;
192 };
193 
194 /*
195  * USB interface.
196  */
197 static device_probe_t		cfumass_probe;
198 static device_attach_t		cfumass_attach;
199 static device_detach_t		cfumass_detach;
200 static device_suspend_t		cfumass_suspend;
201 static device_resume_t		cfumass_resume;
202 static usb_handle_request_t	cfumass_handle_request;
203 
204 static usb_callback_t		cfumass_t_command_callback;
205 static usb_callback_t		cfumass_t_data_callback;
206 static usb_callback_t		cfumass_t_status_callback;
207 
208 static device_method_t cfumass_methods[] = {
209 	/* USB interface. */
210 	DEVMETHOD(usb_handle_request, cfumass_handle_request),
211 
212 	/* Device interface. */
213 	DEVMETHOD(device_probe, cfumass_probe),
214 	DEVMETHOD(device_attach, cfumass_attach),
215 	DEVMETHOD(device_detach, cfumass_detach),
216 	DEVMETHOD(device_suspend, cfumass_suspend),
217 	DEVMETHOD(device_resume, cfumass_resume),
218 
219 	DEVMETHOD_END
220 };
221 
222 static driver_t cfumass_driver = {
223 	.name = "cfumass",
224 	.methods = cfumass_methods,
225 	.size = sizeof(struct cfumass_softc),
226 };
227 
228 static devclass_t cfumass_devclass;
229 
230 DRIVER_MODULE(cfumass, uhub, cfumass_driver, cfumass_devclass, NULL, 0);
231 MODULE_VERSION(cfumass, 0);
232 MODULE_DEPEND(cfumass, usb, 1, 1, 1);
233 MODULE_DEPEND(cfumass, usb_template, 1, 1, 1);
234 
235 static struct usb_config cfumass_config[CFUMASS_T_MAX] = {
236 	[CFUMASS_T_COMMAND] = {
237 		.type = UE_BULK,
238 		.endpoint = UE_ADDR_ANY,
239 		.direction = UE_DIR_OUT,
240 		.bufsize = sizeof(struct cfumass_cbw_t),
241 		.callback = &cfumass_t_command_callback,
242 		.usb_mode = USB_MODE_DEVICE,
243 	},
244 
245 	[CFUMASS_T_DATA_OUT] = {
246 		.type = UE_BULK,
247 		.endpoint = UE_ADDR_ANY,
248 		.direction = UE_DIR_OUT,
249 		.bufsize = CFUMASS_BULK_SIZE,
250 		.flags = {.proxy_buffer = 1, .short_xfer_ok = 1,
251 		    .ext_buffer = 1},
252 		.callback = &cfumass_t_data_callback,
253 		.usb_mode = USB_MODE_DEVICE,
254 	},
255 
256 	[CFUMASS_T_DATA_IN] = {
257 		.type = UE_BULK,
258 		.endpoint = UE_ADDR_ANY,
259 		.direction = UE_DIR_IN,
260 		.bufsize = CFUMASS_BULK_SIZE,
261 		.flags = {.proxy_buffer = 1, .short_xfer_ok = 1,
262 		    .ext_buffer = 1},
263 		.callback = &cfumass_t_data_callback,
264 		.usb_mode = USB_MODE_DEVICE,
265 	},
266 
267 	[CFUMASS_T_STATUS] = {
268 		.type = UE_BULK,
269 		.endpoint = UE_ADDR_ANY,
270 		.direction = UE_DIR_IN,
271 		.bufsize = sizeof(struct cfumass_csw_t),
272 		.flags = {.short_xfer_ok = 1},
273 		.callback = &cfumass_t_status_callback,
274 		.usb_mode = USB_MODE_DEVICE,
275 	},
276 };
277 
278 /*
279  * CTL frontend interface.
280  */
281 static int	cfumass_init(void);
282 static int	cfumass_shutdown(void);
283 static void	cfumass_online(void *arg);
284 static void	cfumass_offline(void *arg);
285 static void	cfumass_datamove(union ctl_io *io);
286 static void	cfumass_done(union ctl_io *io);
287 
288 static struct ctl_frontend cfumass_frontend = {
289 	.name = "umass",
290 	.init = cfumass_init,
291 	.shutdown = cfumass_shutdown,
292 };
293 CTL_FRONTEND_DECLARE(ctlcfumass, cfumass_frontend);
294 
295 #define	CFUMASS_DEBUG(S, X, ...)					\
296 	do {								\
297 		if (debug > 1) {					\
298 			device_printf(S->sc_dev, "%s: " X "\n",		\
299 			    __func__, ## __VA_ARGS__);			\
300 		}							\
301 	} while (0)
302 
303 #define	CFUMASS_WARN(S, X, ...)						\
304 	do {								\
305 		if (debug > 0) {					\
306 			device_printf(S->sc_dev, "WARNING: %s: " X "\n",\
307 			    __func__, ## __VA_ARGS__);			\
308 		}							\
309 	} while (0)
310 
311 #define CFUMASS_LOCK(X)		mtx_lock(&X->sc_mtx)
312 #define CFUMASS_UNLOCK(X)	mtx_unlock(&X->sc_mtx)
313 
314 static void	cfumass_transfer_start(struct cfumass_softc *sc,
315 		    uint8_t xfer_index);
316 static void	cfumass_terminate(struct cfumass_softc *sc);
317 
318 static int
319 cfumass_probe(device_t dev)
320 {
321 	struct usb_attach_arg *uaa;
322 	struct usb_interface_descriptor *id;
323 
324 	uaa = device_get_ivars(dev);
325 
326 	if (uaa->usb_mode != USB_MODE_DEVICE)
327 		return (ENXIO);
328 
329 	/*
330 	 * Check for a compliant device.
331 	 */
332 	id = usbd_get_interface_descriptor(uaa->iface);
333 	if ((id == NULL) ||
334 	    (id->bInterfaceClass != UICLASS_MASS) ||
335 	    (id->bInterfaceSubClass != UISUBCLASS_SCSI) ||
336 	    (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) {
337 		return (ENXIO);
338 	}
339 
340 	return (BUS_PROBE_GENERIC);
341 }
342 
343 static int
344 cfumass_attach(device_t dev)
345 {
346 	struct cfumass_softc *sc;
347 	struct usb_attach_arg *uaa;
348 	int error;
349 
350 	sc = device_get_softc(dev);
351 	uaa = device_get_ivars(dev);
352 
353 	sc->sc_dev = dev;
354 	sc->sc_udev = uaa->device;
355 
356 	CFUMASS_DEBUG(sc, "go");
357 
358 	usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE);
359 	device_set_usb_desc(dev);
360 
361 	mtx_init(&sc->sc_mtx, "cfumass", NULL, MTX_DEF);
362 	refcount_acquire(&cfumass_refcount);
363 
364 	error = usbd_transfer_setup(uaa->device,
365 	    &uaa->info.bIfaceIndex, sc->sc_xfer, cfumass_config,
366 	    CFUMASS_T_MAX, sc, &sc->sc_mtx);
367 	if (error != 0) {
368 		CFUMASS_WARN(sc, "usbd_transfer_setup() failed: %s",
369 		    usbd_errstr(error));
370 		refcount_release(&cfumass_refcount);
371 		return (ENXIO);
372 	}
373 
374 	sc->sc_cbw =
375 	    usbd_xfer_get_frame_buffer(sc->sc_xfer[CFUMASS_T_COMMAND], 0);
376 	sc->sc_csw =
377 	    usbd_xfer_get_frame_buffer(sc->sc_xfer[CFUMASS_T_STATUS], 0);
378 
379 	sc->sc_ctl_initid = ctl_add_initiator(&cfumass_port, -1, 0, NULL);
380 	if (sc->sc_ctl_initid < 0) {
381 		CFUMASS_WARN(sc, "ctl_add_initiator() failed with error %d",
382 		    sc->sc_ctl_initid);
383 		usbd_transfer_unsetup(sc->sc_xfer, CFUMASS_T_MAX);
384 		refcount_release(&cfumass_refcount);
385 		return (ENXIO);
386 	}
387 
388 	refcount_init(&sc->sc_queued, 0);
389 
390 	CFUMASS_LOCK(sc);
391 	cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
392 	CFUMASS_UNLOCK(sc);
393 
394 	return (0);
395 }
396 
397 static int
398 cfumass_detach(device_t dev)
399 {
400 	struct cfumass_softc *sc;
401 	int error;
402 
403 	sc = device_get_softc(dev);
404 
405 	CFUMASS_DEBUG(sc, "go");
406 
407 	CFUMASS_LOCK(sc);
408 	cfumass_terminate(sc);
409 	CFUMASS_UNLOCK(sc);
410 	usbd_transfer_unsetup(sc->sc_xfer, CFUMASS_T_MAX);
411 
412 	if (sc->sc_ctl_initid != -1) {
413 		error = ctl_remove_initiator(&cfumass_port, sc->sc_ctl_initid);
414 		if (error != 0) {
415 			CFUMASS_WARN(sc, "ctl_remove_initiator() failed "
416 			    "with error %d", error);
417 		}
418 		sc->sc_ctl_initid = -1;
419 	}
420 
421 	mtx_destroy(&sc->sc_mtx);
422 	refcount_release(&cfumass_refcount);
423 
424 	return (0);
425 }
426 
427 static int
428 cfumass_suspend(device_t dev)
429 {
430 	struct cfumass_softc *sc;
431 
432 	sc = device_get_softc(dev);
433 	CFUMASS_DEBUG(sc, "go");
434 
435 	return (0);
436 }
437 
438 static int
439 cfumass_resume(device_t dev)
440 {
441 	struct cfumass_softc *sc;
442 
443 	sc = device_get_softc(dev);
444 	CFUMASS_DEBUG(sc, "go");
445 
446 	return (0);
447 }
448 
449 static void
450 cfumass_transfer_start(struct cfumass_softc *sc, uint8_t xfer_index)
451 {
452 
453 	usbd_transfer_start(sc->sc_xfer[xfer_index]);
454 }
455 
456 static void
457 cfumass_transfer_stop_and_drain(struct cfumass_softc *sc, uint8_t xfer_index)
458 {
459 
460 	usbd_transfer_stop(sc->sc_xfer[xfer_index]);
461 	CFUMASS_UNLOCK(sc);
462 	usbd_transfer_drain(sc->sc_xfer[xfer_index]);
463 	CFUMASS_LOCK(sc);
464 }
465 
466 static void
467 cfumass_terminate(struct cfumass_softc *sc)
468 {
469 	int last;
470 
471 	for (;;) {
472 		cfumass_transfer_stop_and_drain(sc, CFUMASS_T_COMMAND);
473 		cfumass_transfer_stop_and_drain(sc, CFUMASS_T_DATA_IN);
474 		cfumass_transfer_stop_and_drain(sc, CFUMASS_T_DATA_OUT);
475 
476 		if (sc->sc_ctl_io != NULL) {
477 			CFUMASS_DEBUG(sc, "terminating CTL transfer");
478 			ctl_set_data_phase_error(&sc->sc_ctl_io->scsiio);
479 			sc->sc_ctl_io->scsiio.be_move_done(sc->sc_ctl_io);
480 			sc->sc_ctl_io = NULL;
481 		}
482 
483 		cfumass_transfer_stop_and_drain(sc, CFUMASS_T_STATUS);
484 
485 		refcount_acquire(&sc->sc_queued);
486 		last = refcount_release(&sc->sc_queued);
487 		if (last != 0)
488 			break;
489 
490 		CFUMASS_DEBUG(sc, "%d CTL tasks pending", sc->sc_queued);
491 		msleep(__DEVOLATILE(void *, &sc->sc_queued), &sc->sc_mtx,
492 		    0, "cfumass_reset", hz / 100);
493 	}
494 }
495 
496 static int
497 cfumass_handle_request(device_t dev,
498     const void *preq, void **pptr, uint16_t *plen,
499     uint16_t offset, uint8_t *pstate)
500 {
501 	static uint8_t max_lun_tmp;
502 	struct cfumass_softc *sc;
503 	const struct usb_device_request *req;
504 	uint8_t is_complete;
505 
506 	sc = device_get_softc(dev);
507 	req = preq;
508 	is_complete = *pstate;
509 
510 	CFUMASS_DEBUG(sc, "go");
511 
512 	if (is_complete)
513 		return (ENXIO);
514 
515 	if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) &&
516 	    (req->bRequest == UR_RESET)) {
517 		CFUMASS_WARN(sc, "received Bulk-Only Mass Storage Reset");
518 		*plen = 0;
519 
520 		CFUMASS_LOCK(sc);
521 		cfumass_terminate(sc);
522 		cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
523 		CFUMASS_UNLOCK(sc);
524 
525 		CFUMASS_DEBUG(sc, "Bulk-Only Mass Storage Reset done");
526 		return (0);
527 	}
528 
529 	if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
530 	    (req->bRequest == UR_GET_MAX_LUN)) {
531 		CFUMASS_DEBUG(sc, "received Get Max LUN");
532 		if (offset == 0) {
533 			*plen = 1;
534 			/*
535 			 * The protocol doesn't support LUN numbers higher
536 			 * than 15.  Also, some initiators (namely Windows XP
537 			 * SP3 Version 2002) can't properly query the number
538 			 * of LUNs, resulting in inaccessible "fake" ones - thus
539 			 * the default limit of one LUN.
540 			 */
541 			if (max_lun < 0 || max_lun > 15) {
542 				CFUMASS_WARN(sc,
543 				    "invalid hw.usb.cfumass.max_lun, must be "
544 				    "between 0 and 15; defaulting to 0");
545 				max_lun_tmp = 0;
546 			} else {
547 				max_lun_tmp = max_lun;
548 			}
549 			*pptr = &max_lun_tmp;
550 		} else {
551 			*plen = 0;
552 		}
553 		return (0);
554 	}
555 
556 	return (ENXIO);
557 }
558 
559 static int
560 cfumass_quirk(struct cfumass_softc *sc, unsigned char *cdb, int cdb_len)
561 {
562 	struct scsi_start_stop_unit *sssu;
563 
564 	switch (cdb[0]) {
565 	case START_STOP_UNIT:
566 		/*
567 		 * Some initiators - eg OSX, Darwin Kernel Version 15.6.0,
568 		 * root:xnu-3248.60.11~2/RELEASE_X86_64 - attempt to stop
569 		 * the unit on eject, but fail to start it when it's plugged
570 		 * back.  Just ignore the command.
571 		 */
572 
573 		if (cdb_len < sizeof(*sssu)) {
574 			CFUMASS_DEBUG(sc, "received START STOP UNIT with "
575 			    "bCDBLength %d, should be %zd",
576 			    cdb_len, sizeof(*sssu));
577 			break;
578 		}
579 
580 		sssu = (struct scsi_start_stop_unit *)cdb;
581 		if ((sssu->how & SSS_PC_MASK) != 0)
582 			break;
583 
584 		if ((sssu->how & SSS_START) != 0)
585 			break;
586 
587 		if ((sssu->how & SSS_LOEJ) != 0)
588 			break;
589 
590 		if (ignore_stop == 0) {
591 			break;
592 		} else if (ignore_stop == 1) {
593 			CFUMASS_WARN(sc, "ignoring START STOP UNIT request");
594 		} else {
595 			CFUMASS_DEBUG(sc, "ignoring START STOP UNIT request");
596 		}
597 
598 		sc->sc_current_status = 0;
599 		cfumass_transfer_start(sc, CFUMASS_T_STATUS);
600 
601 		return (1);
602 	default:
603 		break;
604 	}
605 
606 	return (0);
607 }
608 
609 static void
610 cfumass_t_command_callback(struct usb_xfer *xfer, usb_error_t usb_error)
611 {
612 	struct cfumass_softc *sc;
613 	uint32_t signature;
614 	union ctl_io *io;
615 	int error = 0;
616 
617 	sc = usbd_xfer_softc(xfer);
618 
619 	KASSERT(sc->sc_ctl_io == NULL,
620 	    ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
621 
622 	switch (USB_GET_STATE(xfer)) {
623 	case USB_ST_TRANSFERRED:
624 		CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
625 
626 		signature = UGETDW(sc->sc_cbw->dCBWSignature);
627 		if (signature != CBWSIGNATURE) {
628 			CFUMASS_WARN(sc, "wrong dCBWSignature 0x%08x, "
629 			    "should be 0x%08x", signature, CBWSIGNATURE);
630 			break;
631 		}
632 
633 		if (sc->sc_cbw->bCDBLength <= 0 ||
634 		    sc->sc_cbw->bCDBLength > sizeof(sc->sc_cbw->CBWCB)) {
635 			CFUMASS_WARN(sc, "invalid bCDBLength %d, should be <= %zd",
636 			    sc->sc_cbw->bCDBLength, sizeof(sc->sc_cbw->CBWCB));
637 			break;
638 		}
639 
640 		sc->sc_current_stalled = false;
641 		sc->sc_current_status = 0;
642 		sc->sc_current_tag = UGETDW(sc->sc_cbw->dCBWTag);
643 		sc->sc_current_transfer_length =
644 		    UGETDW(sc->sc_cbw->dCBWDataTransferLength);
645 		sc->sc_current_flags = sc->sc_cbw->bCBWFlags;
646 
647 		/*
648 		 * Make sure to report proper residue if the datamove wasn't
649 		 * required, or wasn't called due to SCSI error.
650 		 */
651 		sc->sc_current_residue = sc->sc_current_transfer_length;
652 
653 		if (cfumass_quirk(sc,
654 		    sc->sc_cbw->CBWCB, sc->sc_cbw->bCDBLength) != 0)
655 			break;
656 
657 		if (!cfumass_port_online) {
658 			CFUMASS_DEBUG(sc, "cfumass port is offline; stalling");
659 			usbd_xfer_set_stall(xfer);
660 			break;
661 		}
662 
663 		/*
664 		 * Those CTL functions cannot be called with mutex held.
665 		 */
666 		CFUMASS_UNLOCK(sc);
667 		io = ctl_alloc_io(cfumass_port.ctl_pool_ref);
668 		ctl_zero_io(io);
669 		io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = sc;
670 		io->io_hdr.io_type = CTL_IO_SCSI;
671 		io->io_hdr.nexus.initid = sc->sc_ctl_initid;
672 		io->io_hdr.nexus.targ_port = cfumass_port.targ_port;
673 		io->io_hdr.nexus.targ_lun = ctl_decode_lun(sc->sc_cbw->bCBWLUN);
674 		io->scsiio.tag_num = UGETDW(sc->sc_cbw->dCBWTag);
675 		io->scsiio.tag_type = CTL_TAG_UNTAGGED;
676 		io->scsiio.cdb_len = sc->sc_cbw->bCDBLength;
677 		memcpy(io->scsiio.cdb, sc->sc_cbw->CBWCB, sc->sc_cbw->bCDBLength);
678 		refcount_acquire(&sc->sc_queued);
679 		error = ctl_queue(io);
680 		if (error != CTL_RETVAL_COMPLETE) {
681 			CFUMASS_WARN(sc,
682 			    "ctl_queue() failed; error %d; stalling", error);
683 			ctl_free_io(io);
684 			refcount_release(&sc->sc_queued);
685 			CFUMASS_LOCK(sc);
686 			usbd_xfer_set_stall(xfer);
687 			break;
688 		}
689 
690 		CFUMASS_LOCK(sc);
691 		break;
692 
693 	case USB_ST_SETUP:
694 tr_setup:
695 		CFUMASS_DEBUG(sc, "USB_ST_SETUP");
696 
697 		usbd_xfer_set_frame_len(xfer, 0, sizeof(*sc->sc_cbw));
698 		usbd_transfer_submit(xfer);
699 		break;
700 
701 	default:
702 		if (usb_error == USB_ERR_CANCELLED) {
703 			CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
704 			break;
705 		}
706 
707 		CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s", usbd_errstr(usb_error));
708 
709 		goto tr_setup;
710 	}
711 }
712 
713 static void
714 cfumass_t_data_callback(struct usb_xfer *xfer, usb_error_t usb_error)
715 {
716 	struct cfumass_softc *sc = usbd_xfer_softc(xfer);
717 	union ctl_io *io = sc->sc_ctl_io;
718 	uint32_t max_bulk;
719 	struct ctl_sg_entry sg_entry, *sglist;
720 	int actlen, sumlen, sg_count;
721 
722 	switch (USB_GET_STATE(xfer)) {
723 	case USB_ST_TRANSFERRED:
724 		CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
725 
726 		usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
727 		sc->sc_current_residue -= actlen;
728 		io->scsiio.ext_data_filled += actlen;
729 		io->scsiio.kern_data_resid -= actlen;
730 		if (actlen < sumlen ||
731 		    sc->sc_current_residue == 0 ||
732 		    io->scsiio.kern_data_resid == 0) {
733 			sc->sc_ctl_io = NULL;
734 			io->scsiio.be_move_done(io);
735 			break;
736 		}
737 		/* FALLTHROUGH */
738 
739 	case USB_ST_SETUP:
740 tr_setup:
741 		CFUMASS_DEBUG(sc, "USB_ST_SETUP");
742 
743 		if (io->scsiio.kern_sg_entries > 0) {
744 			sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
745 			sg_count = io->scsiio.kern_sg_entries;
746 		} else {
747 			sglist = &sg_entry;
748 			sglist->addr = io->scsiio.kern_data_ptr;
749 			sglist->len = io->scsiio.kern_data_len;
750 			sg_count = 1;
751 		}
752 
753 		sumlen = io->scsiio.ext_data_filled -
754 		    io->scsiio.kern_rel_offset;
755 		while (sumlen >= sglist->len && sg_count > 0) {
756 			sumlen -= sglist->len;
757 			sglist++;
758 			sg_count--;
759 		}
760 		KASSERT(sg_count > 0, ("Run out of S/G list entries"));
761 
762 		max_bulk = usbd_xfer_max_len(xfer);
763 		actlen = min(sglist->len - sumlen, max_bulk);
764 		actlen = min(actlen, sc->sc_current_transfer_length -
765 		    io->scsiio.ext_data_filled);
766 		CFUMASS_DEBUG(sc, "requested %d, done %d, max_bulk %d, "
767 		    "segment %zd => transfer %d",
768 		    sc->sc_current_transfer_length, io->scsiio.ext_data_filled,
769 		    max_bulk, sglist->len - sumlen, actlen);
770 
771 		usbd_xfer_set_frame_data(xfer, 0,
772 		    (uint8_t *)sglist->addr + sumlen, actlen);
773 		usbd_transfer_submit(xfer);
774 		break;
775 
776 	default:
777 		if (usb_error == USB_ERR_CANCELLED) {
778 			CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
779 			break;
780 		}
781 		CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s", usbd_errstr(usb_error));
782 		goto tr_setup;
783 	}
784 }
785 
786 static void
787 cfumass_t_status_callback(struct usb_xfer *xfer, usb_error_t usb_error)
788 {
789 	struct cfumass_softc *sc;
790 
791 	sc = usbd_xfer_softc(xfer);
792 
793 	KASSERT(sc->sc_ctl_io == NULL,
794 	    ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
795 
796 	switch (USB_GET_STATE(xfer)) {
797 	case USB_ST_TRANSFERRED:
798 		CFUMASS_DEBUG(sc, "USB_ST_TRANSFERRED");
799 
800 		cfumass_transfer_start(sc, CFUMASS_T_COMMAND);
801 		break;
802 
803 	case USB_ST_SETUP:
804 tr_setup:
805 		CFUMASS_DEBUG(sc, "USB_ST_SETUP");
806 
807 		if (sc->sc_current_residue > 0 && !sc->sc_current_stalled) {
808 			CFUMASS_DEBUG(sc, "non-zero residue, stalling");
809 			usbd_xfer_set_stall(xfer);
810 			sc->sc_current_stalled = true;
811 		}
812 
813 		USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE);
814 		USETDW(sc->sc_csw->dCSWTag, sc->sc_current_tag);
815 		USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_current_residue);
816 		sc->sc_csw->bCSWStatus = sc->sc_current_status;
817 
818 		usbd_xfer_set_frame_len(xfer, 0, sizeof(*sc->sc_csw));
819 		usbd_transfer_submit(xfer);
820 		break;
821 
822 	default:
823 		if (usb_error == USB_ERR_CANCELLED) {
824 			CFUMASS_DEBUG(sc, "USB_ERR_CANCELLED");
825 			break;
826 		}
827 
828 		CFUMASS_DEBUG(sc, "USB_ST_ERROR: %s",
829 		    usbd_errstr(usb_error));
830 
831 		goto tr_setup;
832 	}
833 }
834 
835 static void
836 cfumass_online(void *arg __unused)
837 {
838 
839 	cfumass_port_online = true;
840 }
841 
842 static void
843 cfumass_offline(void *arg __unused)
844 {
845 
846 	cfumass_port_online = false;
847 }
848 
849 static void
850 cfumass_datamove(union ctl_io *io)
851 {
852 	struct cfumass_softc *sc;
853 
854 	sc = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
855 
856 	CFUMASS_DEBUG(sc, "go");
857 
858 	CFUMASS_LOCK(sc);
859 
860 	KASSERT(sc->sc_ctl_io == NULL,
861 	    ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
862 	sc->sc_ctl_io = io;
863 
864 	if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
865 		/*
866 		 * Verify that CTL wants us to send the data in the direction
867 		 * expected by the initiator.
868 		 */
869 		if (sc->sc_current_flags != CBWFLAGS_IN) {
870 			CFUMASS_WARN(sc, "wrong bCBWFlags 0x%x, should be 0x%x",
871 			    sc->sc_current_flags, CBWFLAGS_IN);
872 			goto fail;
873 		}
874 
875 		cfumass_transfer_start(sc, CFUMASS_T_DATA_IN);
876 	} else {
877 		if (sc->sc_current_flags != CBWFLAGS_OUT) {
878 			CFUMASS_WARN(sc, "wrong bCBWFlags 0x%x, should be 0x%x",
879 			    sc->sc_current_flags, CBWFLAGS_OUT);
880 			goto fail;
881 		}
882 
883 		cfumass_transfer_start(sc, CFUMASS_T_DATA_OUT);
884 	}
885 
886 	CFUMASS_UNLOCK(sc);
887 	return;
888 
889 fail:
890 	ctl_set_data_phase_error(&io->scsiio);
891 	io->scsiio.be_move_done(io);
892 	sc->sc_ctl_io = NULL;
893 }
894 
895 static void
896 cfumass_done(union ctl_io *io)
897 {
898 	struct cfumass_softc *sc;
899 
900 	sc = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
901 
902 	CFUMASS_DEBUG(sc, "go");
903 
904 	KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE),
905 	    ("invalid CTL status %#x", io->io_hdr.status));
906 	KASSERT(sc->sc_ctl_io == NULL,
907 	    ("sc_ctl_io is %p, should be NULL", sc->sc_ctl_io));
908 
909 	if (io->io_hdr.io_type == CTL_IO_TASK &&
910 	    io->taskio.task_action == CTL_TASK_I_T_NEXUS_RESET) {
911 		/*
912 		 * Implicit task termination has just completed; nothing to do.
913 		 */
914 		ctl_free_io(io);
915 		return;
916 	}
917 
918 	/*
919 	 * Do not return status for aborted commands.
920 	 * There are exceptions, but none supported by CTL yet.
921 	 */
922 	if (((io->io_hdr.flags & CTL_FLAG_ABORT) &&
923 	     (io->io_hdr.flags & CTL_FLAG_ABORT_STATUS) == 0) ||
924 	    (io->io_hdr.flags & CTL_FLAG_STATUS_SENT)) {
925 		ctl_free_io(io);
926 		return;
927 	}
928 
929 	if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SUCCESS)
930 		sc->sc_current_status = 0;
931 	else
932 		sc->sc_current_status = 1;
933 
934 	/* XXX: How should we report BUSY, RESERVATION CONFLICT, etc? */
935 	if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR &&
936 	    io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
937 		ctl_queue_sense(io);
938 	else
939 		ctl_free_io(io);
940 
941 	CFUMASS_LOCK(sc);
942 	cfumass_transfer_start(sc, CFUMASS_T_STATUS);
943 	CFUMASS_UNLOCK(sc);
944 
945 	refcount_release(&sc->sc_queued);
946 }
947 
948 int
949 cfumass_init(void)
950 {
951 	int error;
952 
953 	cfumass_port.frontend = &cfumass_frontend;
954 	cfumass_port.port_type = CTL_PORT_UMASS;
955 	cfumass_port.num_requested_ctl_io = 1;
956 	cfumass_port.port_name = "cfumass";
957 	cfumass_port.physical_port = 0;
958 	cfumass_port.virtual_port = 0;
959 	cfumass_port.port_online = cfumass_online;
960 	cfumass_port.port_offline = cfumass_offline;
961 	cfumass_port.onoff_arg = NULL;
962 	cfumass_port.fe_datamove = cfumass_datamove;
963 	cfumass_port.fe_done = cfumass_done;
964 	cfumass_port.targ_port = -1;
965 
966 	error = ctl_port_register(&cfumass_port);
967 	if (error != 0) {
968 		printf("%s: ctl_port_register() failed "
969 		    "with error %d", __func__, error);
970 	}
971 
972 	cfumass_port_online = true;
973 	refcount_init(&cfumass_refcount, 0);
974 
975 	return (error);
976 }
977 
978 int
979 cfumass_shutdown(void)
980 {
981 	int error;
982 
983 	if (cfumass_refcount > 0) {
984 		if (debug > 1) {
985 			printf("%s: still have %u attachments; "
986 			    "returning EBUSY\n", __func__, cfumass_refcount);
987 		}
988 		return (EBUSY);
989 	}
990 
991 	error = ctl_port_deregister(&cfumass_port);
992 	if (error != 0) {
993 		printf("%s: ctl_port_deregister() failed "
994 		    "with error %d\n", __func__, error);
995 	}
996 
997 	return (error);
998 }
999