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