1 /* $NetBSD: usscanner.c,v 1.42 2016/12/04 10:12:35 skrll Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) and LLoyd Parkes. 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This driver is partly based on information taken from the Linux driver 34 * by John Fremlin, Oliver Neukum, and Jeremy Hall. 35 */ 36 /* 37 * Protocol: 38 * Send raw SCSI command on the bulk-out pipe. 39 * If output command then 40 * send further data on the bulk-out pipe 41 * else if input command then 42 * read data on the bulk-in pipe 43 * else 44 * don't do anything. 45 * Read status byte on the interrupt pipe (which doesn't seem to be 46 * an interrupt pipe at all). This operation sometimes times out. 47 */ 48 49 #include <sys/cdefs.h> 50 __KERNEL_RCSID(0, "$NetBSD: usscanner.c,v 1.42 2016/12/04 10:12:35 skrll Exp $"); 51 52 #ifdef _KERNEL_OPT 53 #include "opt_usb.h" 54 #endif 55 56 #include "scsibus.h" 57 #include <sys/param.h> 58 #include <sys/systm.h> 59 #include <sys/kernel.h> 60 #include <sys/lwp.h> 61 #include <sys/device.h> 62 #include <sys/conf.h> 63 #include <sys/buf.h> 64 65 #include <dev/usb/usb.h> 66 #include <dev/usb/usbdi.h> 67 #include <dev/usb/usbdi_util.h> 68 69 #include <dev/usb/usbdevs.h> 70 71 #include <sys/scsiio.h> 72 #include <dev/scsipi/scsi_spc.h> 73 #include <dev/scsipi/scsi_all.h> 74 #include <dev/scsipi/scsipi_all.h> 75 #include <dev/scsipi/scsiconf.h> 76 #include <dev/scsipi/atapiconf.h> 77 78 #ifdef USSCANNER_DEBUG 79 #define DPRINTF(x) if (usscannerdebug) printf x 80 #define DPRINTFN(n,x) if (usscannerdebug>(n)) printf x 81 int usscannerdebug = 0; 82 #else 83 #define DPRINTF(x) 84 #define DPRINTFN(n,x) 85 #endif 86 87 88 #define USSCANNER_CONFIG_NO 1 89 #define USSCANNER_IFACE_IDX 0 90 91 #define USSCANNER_SCSIID_HOST 0x00 92 #define USSCANNER_SCSIID_DEVICE 0x01 93 94 #define USSCANNER_MAX_TRANSFER_SIZE MAXPHYS 95 96 #define USSCANNER_TIMEOUT 2000 97 98 struct usscanner_softc { 99 device_t sc_dev; 100 struct usbd_device *sc_udev; 101 struct usbd_interface *sc_iface; 102 103 int sc_in_addr; 104 struct usbd_pipe *sc_in_pipe; 105 106 int sc_intr_addr; 107 struct usbd_pipe *sc_intr_pipe; 108 struct usbd_xfer *sc_intr_xfer; 109 u_char sc_status; 110 111 int sc_out_addr; 112 struct usbd_pipe *sc_out_pipe; 113 114 struct usbd_xfer *sc_cmd_xfer; 115 void *sc_cmd_buffer; 116 struct usbd_xfer *sc_datain_xfer; 117 void *sc_datain_buffer; 118 struct usbd_xfer *sc_dataout_xfer; 119 void *sc_dataout_buffer; 120 121 int sc_state; 122 #define UAS_IDLE 0 123 #define UAS_CMD 1 124 #define UAS_DATA 2 125 #define UAS_SENSECMD 3 126 #define UAS_SENSEDATA 4 127 #define UAS_STATUS 5 128 129 struct scsipi_xfer *sc_xs; 130 131 device_t sc_child; /* child device, for detach */ 132 133 struct scsipi_adapter sc_adapter; 134 struct scsipi_channel sc_channel; 135 136 int sc_refcnt; 137 char sc_dying; 138 }; 139 140 141 Static void usscanner_cleanup(struct usscanner_softc *); 142 Static void usscanner_scsipi_request(struct scsipi_channel *, 143 scsipi_adapter_req_t, void *); 144 Static void usscanner_scsipi_minphys(struct buf *); 145 Static void usscanner_done(struct usscanner_softc *); 146 Static void usscanner_sense(struct usscanner_softc *); 147 typedef void callback(struct usbd_xfer *, void *, usbd_status); 148 Static callback usscanner_intr_cb; 149 Static callback usscanner_cmd_cb; 150 Static callback usscanner_data_cb; 151 Static callback usscanner_sensecmd_cb; 152 Static callback usscanner_sensedata_cb; 153 154 int usscanner_match(device_t, cfdata_t, void *); 155 void usscanner_attach(device_t, device_t, void *); 156 void usscanner_childdet(device_t, device_t); 157 int usscanner_detach(device_t, int); 158 int usscanner_activate(device_t, enum devact); 159 extern struct cfdriver usscanner_cd; 160 CFATTACH_DECL2_NEW(usscanner, sizeof(struct usscanner_softc), 161 usscanner_match, usscanner_attach, usscanner_detach, usscanner_activate, 162 NULL, usscanner_childdet); 163 164 int 165 usscanner_match(device_t parent, cfdata_t match, void *aux) 166 { 167 struct usb_attach_arg *uaa = aux; 168 169 DPRINTFN(50,("usscanner_match\n")); 170 171 if (uaa->uaa_vendor == USB_VENDOR_HP && 172 uaa->uaa_product == USB_PRODUCT_HP_5300C) 173 return UMATCH_VENDOR_PRODUCT; 174 else 175 return UMATCH_NONE; 176 } 177 178 void 179 usscanner_attach(device_t parent, device_t self, void *aux) 180 { 181 struct usscanner_softc *sc = device_private(self); 182 struct usb_attach_arg *uaa = aux; 183 struct usbd_device * dev = uaa->uaa_device; 184 struct usbd_interface * iface; 185 char *devinfop; 186 usbd_status err; 187 usb_endpoint_descriptor_t *ed; 188 uint8_t epcount; 189 int i; 190 int error; 191 192 DPRINTFN(10,("usscanner_attach: sc=%p\n", sc)); 193 194 sc->sc_dev = self; 195 196 aprint_naive("\n"); 197 aprint_normal("\n"); 198 199 devinfop = usbd_devinfo_alloc(dev, 0); 200 aprint_normal_dev(self, "%s\n", devinfop); 201 usbd_devinfo_free(devinfop); 202 203 err = usbd_set_config_no(dev, USSCANNER_CONFIG_NO, 1); 204 if (err) { 205 aprint_error_dev(self, "failed to set configuration, err=%s\n", 206 usbd_errstr(err)); 207 return; 208 } 209 210 err = usbd_device2interface_handle(dev, USSCANNER_IFACE_IDX, &iface); 211 if (err) { 212 aprint_error_dev(self, "getting interface handle failed\n"); 213 return; 214 } 215 216 sc->sc_udev = dev; 217 sc->sc_iface = iface; 218 219 epcount = 0; 220 (void)usbd_endpoint_count(iface, &epcount); 221 222 sc->sc_in_addr = -1; 223 sc->sc_intr_addr = -1; 224 sc->sc_out_addr = -1; 225 for (i = 0; i < epcount; i++) { 226 ed = usbd_interface2endpoint_descriptor(iface, i); 227 if (ed == NULL) { 228 aprint_error_dev(self, "couldn't get ep %d\n", i); 229 return; 230 } 231 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 232 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 233 sc->sc_in_addr = ed->bEndpointAddress; 234 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 235 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 236 sc->sc_intr_addr = ed->bEndpointAddress; 237 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 238 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 239 sc->sc_out_addr = ed->bEndpointAddress; 240 } 241 } 242 if (sc->sc_in_addr == -1 || sc->sc_intr_addr == -1 || 243 sc->sc_out_addr == -1) { 244 aprint_error_dev(self, "missing endpoint\n"); 245 return; 246 } 247 248 err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 249 USBD_EXCLUSIVE_USE, &sc->sc_in_pipe); 250 if (err) { 251 aprint_error_dev(self, "open in pipe failed, err=%d\n", err); 252 return; 253 } 254 255 /* The interrupt endpoint must be opened as a normal pipe. */ 256 err = usbd_open_pipe(sc->sc_iface, sc->sc_intr_addr, 257 USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe); 258 259 if (err) { 260 aprint_error_dev(self, "open intr pipe failed, err=%d\n", err); 261 usscanner_cleanup(sc); 262 return; 263 } 264 err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr, 265 USBD_EXCLUSIVE_USE, &sc->sc_out_pipe); 266 if (err) { 267 aprint_error_dev(self, "open out pipe failed, err=%d\n", err); 268 usscanner_cleanup(sc); 269 return; 270 } 271 272 /* XXX too big */ 273 error = usbd_create_xfer(sc->sc_out_pipe, USSCANNER_MAX_TRANSFER_SIZE, 274 0, 0, &sc->sc_cmd_xfer); 275 if (error) { 276 aprint_error_dev(self, "alloc cmd xfer failed, error=%d\n", 277 error); 278 usscanner_cleanup(sc); 279 return; 280 } 281 282 sc->sc_cmd_buffer = usbd_get_buffer(sc->sc_cmd_xfer); 283 284 error = usbd_create_xfer(sc->sc_intr_pipe, 1, USBD_SHORT_XFER_OK, 285 0, &sc->sc_intr_xfer); 286 if (error) { 287 aprint_error_dev(self, "alloc intr xfer failed, error=%d\n", 288 error); 289 usscanner_cleanup(sc); 290 return; 291 } 292 293 error = usbd_create_xfer(sc->sc_in_pipe, USSCANNER_MAX_TRANSFER_SIZE, 294 USBD_SHORT_XFER_OK, 0, &sc->sc_datain_xfer); 295 if (error) { 296 aprint_error_dev(self, "alloc data xfer failed, error=%d\n", 297 error); 298 usscanner_cleanup(sc); 299 return; 300 } 301 sc->sc_datain_buffer = usbd_get_buffer(sc->sc_datain_xfer); 302 303 error = usbd_create_xfer(sc->sc_out_pipe, USSCANNER_MAX_TRANSFER_SIZE, 304 USBD_SHORT_XFER_OK, 0, &sc->sc_dataout_xfer); 305 if (error) { 306 aprint_error_dev(self, "alloc data xfer failed, err=%d\n", err); 307 usscanner_cleanup(sc); 308 return; 309 } 310 sc->sc_dataout_buffer = usbd_get_buffer(sc->sc_dataout_xfer); 311 312 /* 313 * Fill in the adapter. 314 */ 315 sc->sc_adapter.adapt_request = usscanner_scsipi_request; 316 sc->sc_adapter.adapt_dev = sc->sc_dev; 317 sc->sc_adapter.adapt_nchannels = 1; 318 sc->sc_adapter.adapt_openings = 1; 319 sc->sc_adapter.adapt_max_periph = 1; 320 sc->sc_adapter.adapt_minphys = usscanner_scsipi_minphys; 321 322 #if NSCSIBUS > 0 323 /* 324 * fill in the scsipi_channel. 325 */ 326 sc->sc_channel.chan_adapter = &sc->sc_adapter; 327 sc->sc_channel.chan_bustype = &scsi_bustype; 328 sc->sc_channel.chan_channel = 0; 329 sc->sc_channel.chan_ntargets = USSCANNER_SCSIID_DEVICE + 1; 330 sc->sc_channel.chan_nluns = 1; 331 sc->sc_channel.chan_id = USSCANNER_SCSIID_HOST; 332 333 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 334 335 sc->sc_child = config_found(sc->sc_dev, &sc->sc_channel, scsiprint); 336 337 DPRINTFN(10, ("usscanner_attach: %p\n", sc->sc_udev)); 338 339 return; 340 341 #else 342 /* No SCSI bus, just ignore it */ 343 usscanner_cleanup(sc); 344 345 aprint_error_dev(self, 346 "no scsibus configured, see usscanner(4) for details\n"); 347 348 return; 349 350 #endif 351 } 352 353 void 354 usscanner_childdet(device_t self, device_t child) 355 { 356 struct usscanner_softc *sc = device_private(self); 357 358 KASSERT(sc->sc_child == NULL); 359 sc->sc_child = NULL; 360 } 361 362 int 363 usscanner_detach(device_t self, int flags) 364 { 365 struct usscanner_softc *sc = device_private(self); 366 int rv, s; 367 368 DPRINTF(("usscanner_detach: sc=%p flags=%d\n", sc, flags)); 369 370 sc->sc_dying = 1; 371 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 372 if (sc->sc_in_pipe != NULL) 373 usbd_abort_pipe(sc->sc_in_pipe); 374 if (sc->sc_intr_pipe != NULL) 375 usbd_abort_pipe(sc->sc_intr_pipe); 376 if (sc->sc_out_pipe != NULL) 377 usbd_abort_pipe(sc->sc_out_pipe); 378 379 s = splusb(); 380 if (--sc->sc_refcnt >= 0) { 381 /* Wait for processes to go away. */ 382 usb_detach_waitold(sc->sc_dev); 383 } 384 splx(s); 385 386 if (sc->sc_child != NULL) 387 rv = config_detach(sc->sc_child, flags); 388 else 389 rv = 0; 390 391 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 392 393 return rv; 394 } 395 396 Static void 397 usscanner_cleanup(struct usscanner_softc *sc) 398 { 399 if (sc->sc_cmd_xfer != NULL) { 400 usbd_destroy_xfer(sc->sc_cmd_xfer); 401 sc->sc_cmd_xfer = NULL; 402 } 403 if (sc->sc_datain_xfer != NULL) { 404 usbd_destroy_xfer(sc->sc_datain_xfer); 405 sc->sc_datain_xfer = NULL; 406 } 407 if (sc->sc_dataout_xfer != NULL) { 408 usbd_destroy_xfer(sc->sc_dataout_xfer); 409 sc->sc_dataout_xfer = NULL; 410 } 411 if (sc->sc_in_pipe != NULL) { 412 usbd_close_pipe(sc->sc_in_pipe); 413 sc->sc_in_pipe = NULL; 414 } 415 if (sc->sc_intr_pipe != NULL) { 416 usbd_close_pipe(sc->sc_intr_pipe); 417 sc->sc_intr_pipe = NULL; 418 } 419 if (sc->sc_out_pipe != NULL) { 420 usbd_close_pipe(sc->sc_out_pipe); 421 sc->sc_out_pipe = NULL; 422 } 423 } 424 425 int 426 usscanner_activate(device_t self, enum devact act) 427 { 428 struct usscanner_softc *sc = device_private(self); 429 430 switch (act) { 431 case DVACT_DEACTIVATE: 432 sc->sc_dying = 1; 433 return 0; 434 default: 435 return EOPNOTSUPP; 436 } 437 } 438 439 Static void 440 usscanner_scsipi_minphys(struct buf *bp) 441 { 442 if (bp->b_bcount > USSCANNER_MAX_TRANSFER_SIZE) 443 bp->b_bcount = USSCANNER_MAX_TRANSFER_SIZE; 444 minphys(bp); 445 } 446 447 Static void 448 usscanner_sense(struct usscanner_softc *sc) 449 { 450 struct scsipi_xfer *xs = sc->sc_xs; 451 struct scsipi_periph *periph = xs->xs_periph; 452 struct scsi_request_sense sense_cmd; 453 usbd_status err; 454 455 /* fetch sense data */ 456 memset(&sense_cmd, 0, sizeof(sense_cmd)); 457 sense_cmd.opcode = SCSI_REQUEST_SENSE; 458 sense_cmd.byte2 = periph->periph_lun << SCSI_CMD_LUN_SHIFT; 459 sense_cmd.length = sizeof(xs->sense); 460 461 sc->sc_state = UAS_SENSECMD; 462 memcpy(sc->sc_cmd_buffer, &sense_cmd, sizeof(sense_cmd)); 463 464 usbd_setup_xfer(sc->sc_cmd_xfer, sc, sc->sc_cmd_buffer, 465 sizeof(sense_cmd), 0, USSCANNER_TIMEOUT, 466 usscanner_sensecmd_cb); 467 err = usbd_transfer(sc->sc_cmd_xfer); 468 if (err == USBD_IN_PROGRESS) 469 return; 470 471 xs->error = XS_DRIVER_STUFFUP; 472 usscanner_done(sc); 473 } 474 475 Static void 476 usscanner_intr_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 477 { 478 struct usscanner_softc *sc = priv; 479 int s; 480 481 DPRINTFN(10, ("usscanner_data_cb status=%d\n", status)); 482 483 #ifdef USSCANNER_DEBUG 484 if (sc->sc_state != UAS_STATUS) { 485 printf("%s: !UAS_STATUS\n", device_xname(sc->sc_dev)); 486 } 487 if (sc->sc_status != 0) { 488 printf("%s: status byte=0x%02x\n", device_xname(sc->sc_dev), 489 sc->sc_status); 490 } 491 #endif 492 /* XXX what should we do on non-0 status */ 493 494 sc->sc_state = UAS_IDLE; 495 496 s = splbio(); 497 KERNEL_LOCK(1, curlwp); 498 scsipi_done(sc->sc_xs); 499 KERNEL_UNLOCK_ONE(curlwp); 500 splx(s); 501 } 502 503 Static void 504 usscanner_data_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 505 { 506 struct usscanner_softc *sc = priv; 507 struct scsipi_xfer *xs = sc->sc_xs; 508 uint32_t len; 509 510 DPRINTFN(10, ("usscanner_data_cb status=%d\n", status)); 511 512 #ifdef USSCANNER_DEBUG 513 if (sc->sc_state != UAS_DATA) { 514 printf("%s: !UAS_DATA\n", device_xname(sc->sc_dev)); 515 } 516 #endif 517 518 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 519 520 xs->resid = xs->datalen - len; 521 522 switch (status) { 523 case USBD_NORMAL_COMPLETION: 524 xs->error = XS_NOERROR; 525 break; 526 case USBD_TIMEOUT: 527 xs->error = XS_TIMEOUT; 528 break; 529 case USBD_CANCELLED: 530 if (xs->error == XS_SENSE) { 531 usscanner_sense(sc); 532 return; 533 } 534 break; 535 default: 536 xs->error = XS_DRIVER_STUFFUP; /* XXX ? */ 537 break; 538 } 539 usscanner_done(sc); 540 } 541 542 Static void 543 usscanner_sensedata_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 544 { 545 struct usscanner_softc *sc = priv; 546 struct scsipi_xfer *xs = sc->sc_xs; 547 uint32_t len; 548 549 DPRINTFN(10, ("usscanner_sensedata_cb status=%d\n", status)); 550 551 #ifdef USSCANNER_DEBUG 552 if (sc->sc_state != UAS_SENSEDATA) { 553 printf("%s: !UAS_SENSEDATA\n", device_xname(sc->sc_dev)); 554 } 555 #endif 556 557 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 558 559 switch (status) { 560 case USBD_NORMAL_COMPLETION: 561 memcpy(&xs->sense, sc->sc_datain_buffer, len); 562 if (len < sizeof(xs->sense)) 563 xs->error = XS_SHORTSENSE; 564 break; 565 case USBD_TIMEOUT: 566 xs->error = XS_TIMEOUT; 567 break; 568 case USBD_CANCELLED: 569 xs->error = XS_RESET; 570 break; 571 default: 572 xs->error = XS_DRIVER_STUFFUP; /* XXX ? */ 573 break; 574 } 575 usscanner_done(sc); 576 } 577 578 Static void 579 usscanner_done(struct usscanner_softc *sc) 580 { 581 struct scsipi_xfer *xs = sc->sc_xs; 582 usbd_status err; 583 584 DPRINTFN(10,("usscanner_done: error=%d\n", sc->sc_xs->error)); 585 586 sc->sc_state = UAS_STATUS; 587 usbd_setup_xfer(sc->sc_intr_xfer, sc, &sc->sc_status, 1, 588 USBD_SHORT_XFER_OK, USSCANNER_TIMEOUT, usscanner_intr_cb); 589 err = usbd_transfer(sc->sc_intr_xfer); 590 if (err == USBD_IN_PROGRESS) 591 return; 592 xs->error = XS_DRIVER_STUFFUP; 593 } 594 595 Static void 596 usscanner_sensecmd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 597 { 598 struct usscanner_softc *sc = priv; 599 struct scsipi_xfer *xs = sc->sc_xs; 600 usbd_status err; 601 602 DPRINTFN(10, ("usscanner_sensecmd_cb status=%d\n", status)); 603 604 #ifdef USSCANNER_DEBUG 605 if (usscannerdebug > 15) 606 xs->xs_periph->periph_flags |= 1; /* XXX 1 */ 607 608 if (sc->sc_state != UAS_SENSECMD) { 609 aprint_error_dev(sc->sc_dev, "!UAS_SENSECMD\n"); 610 xs->error = XS_DRIVER_STUFFUP; 611 goto done; 612 } 613 #endif 614 615 switch (status) { 616 case USBD_NORMAL_COMPLETION: 617 break; 618 case USBD_TIMEOUT: 619 xs->error = XS_TIMEOUT; 620 goto done; 621 default: 622 xs->error = XS_DRIVER_STUFFUP; /* XXX ? */ 623 goto done; 624 } 625 626 sc->sc_state = UAS_SENSEDATA; 627 usbd_setup_xfer(sc->sc_datain_xfer, sc, sc->sc_datain_buffer, 628 sizeof(xs->sense), USBD_SHORT_XFER_OK, 629 USSCANNER_TIMEOUT, usscanner_sensedata_cb); 630 err = usbd_transfer(sc->sc_datain_xfer); 631 if (err == USBD_IN_PROGRESS) 632 return; 633 xs->error = XS_DRIVER_STUFFUP; 634 done: 635 usscanner_done(sc); 636 } 637 638 Static void 639 usscanner_cmd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 640 { 641 struct usscanner_softc *sc = priv; 642 struct scsipi_xfer *xs = sc->sc_xs; 643 struct usbd_xfer *dxfer; 644 usbd_status err; 645 646 DPRINTFN(10, ("usscanner_cmd_cb status=%d\n", status)); 647 648 #ifdef USSCANNER_DEBUG 649 if (usscannerdebug > 15) 650 xs->xs_periph->periph_flags |= 1; /* XXX 1 */ 651 652 if (sc->sc_state != UAS_CMD) { 653 aprint_error_dev(sc->sc_dev, "!UAS_CMD\n"); 654 xs->error = XS_DRIVER_STUFFUP; 655 goto done; 656 } 657 #endif 658 659 switch (status) { 660 case USBD_NORMAL_COMPLETION: 661 break; 662 case USBD_TIMEOUT: 663 xs->error = XS_TIMEOUT; 664 goto done; 665 case USBD_CANCELLED: 666 goto done; 667 default: 668 xs->error = XS_DRIVER_STUFFUP; /* XXX ? */ 669 goto done; 670 } 671 672 if (xs->datalen == 0) { 673 DPRINTFN(4, ("usscanner_cmd_cb: no data phase\n")); 674 xs->error = XS_NOERROR; 675 goto done; 676 } 677 678 if (xs->xs_control & XS_CTL_DATA_IN) { 679 DPRINTFN(4, ("usscanner_cmd_cb: data in len=%d\n", 680 xs->datalen)); 681 dxfer = sc->sc_datain_xfer; 682 } else { 683 DPRINTFN(4, ("usscanner_cmd_cb: data out len=%d\n", 684 xs->datalen)); 685 dxfer = sc->sc_dataout_xfer; 686 } 687 sc->sc_state = UAS_DATA; 688 usbd_setup_xfer(dxfer, sc, xs->data, xs->datalen, 689 USBD_SHORT_XFER_OK, xs->timeout, usscanner_data_cb); 690 err = usbd_transfer(dxfer); 691 if (err == USBD_IN_PROGRESS) 692 return; 693 xs->error = XS_DRIVER_STUFFUP; 694 695 done: 696 usscanner_done(sc); 697 } 698 699 Static void 700 usscanner_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 701 void *arg) 702 { 703 struct scsipi_xfer *xs; 704 struct usscanner_softc *sc = 705 device_private(chan->chan_adapter->adapt_dev); 706 usbd_status err; 707 708 switch (req) { 709 case ADAPTER_REQ_RUN_XFER: 710 xs = arg; 711 712 DPRINTFN(8, ("%s: usscanner_scsipi_request: %d:%d " 713 "xs=%p cmd=0x%02x datalen=%d (quirks=0x%x, poll=%d)\n", 714 device_xname(sc->sc_dev), 715 xs->xs_periph->periph_target, xs->xs_periph->periph_lun, 716 xs, xs->cmd->opcode, xs->datalen, 717 xs->xs_periph->periph_quirks, 718 xs->xs_control & XS_CTL_POLL)); 719 720 if (sc->sc_dying) { 721 xs->error = XS_DRIVER_STUFFUP; 722 goto done; 723 } 724 725 #ifdef USSCANNER_DEBUG 726 if (xs->xs_periph->periph_target != USSCANNER_SCSIID_DEVICE) { 727 DPRINTF(("%s: wrong SCSI ID %d\n", 728 device_xname(sc->sc_dev), 729 xs->xs_periph->periph_target)); 730 xs->error = XS_DRIVER_STUFFUP; 731 goto done; 732 } 733 if (sc->sc_state != UAS_IDLE) { 734 printf("%s: !UAS_IDLE\n", device_xname(sc->sc_dev)); 735 xs->error = XS_DRIVER_STUFFUP; 736 goto done; 737 } 738 #endif 739 740 if (xs->datalen > USSCANNER_MAX_TRANSFER_SIZE) { 741 aprint_normal_dev(sc->sc_dev, 742 "usscanner_scsipi_request: large datalen, %d\n", 743 xs->datalen); 744 xs->error = XS_DRIVER_STUFFUP; 745 goto done; 746 } 747 748 DPRINTFN(4, ("%s: usscanner_scsipi_request: async cmdlen=%d" 749 " datalen=%d\n", device_xname(sc->sc_dev), xs->cmdlen, 750 xs->datalen)); 751 sc->sc_state = UAS_CMD; 752 sc->sc_xs = xs; 753 memcpy(sc->sc_cmd_buffer, xs->cmd, xs->cmdlen); 754 usbd_setup_xfer(sc->sc_cmd_xfer, sc, sc->sc_cmd_buffer, 755 xs->cmdlen, 0, USSCANNER_TIMEOUT, usscanner_cmd_cb); 756 err = usbd_transfer(sc->sc_cmd_xfer); 757 if (err != USBD_IN_PROGRESS) { 758 xs->error = XS_DRIVER_STUFFUP; 759 goto done; 760 } 761 762 return; 763 764 765 done: 766 sc->sc_state = UAS_IDLE; 767 KERNEL_LOCK(1, curlwp); 768 scsipi_done(xs); 769 KERNEL_UNLOCK_ONE(curlwp); 770 return; 771 772 case ADAPTER_REQ_GROW_RESOURCES: 773 /* XXX Not supported. */ 774 return; 775 case ADAPTER_REQ_SET_XFER_MODE: 776 /* XXX Not supported. */ 777 return; 778 } 779 780 } 781