LCOV - code coverage report
Current view: top level - dev/usb - umass.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 600 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: umass.c,v 1.74 2017/01/09 14:44:28 mpi Exp $ */
       2             : /*      $NetBSD: umass.c,v 1.116 2004/06/30 05:53:46 mycroft Exp $      */
       3             : 
       4             : /*
       5             :  * Copyright (c) 2003 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Charles M. Hannum.
      10             :  *
      11             :  * Redistribution and use in source and binary forms, with or without
      12             :  * modification, are permitted provided that the following conditions
      13             :  * are met:
      14             :  * 1. Redistributions of source code must retain the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer.
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in the
      18             :  *    documentation and/or other materials provided with the distribution.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      21             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      22             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      23             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      24             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : /*-
      34             :  * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
      35             :  *                    Nick Hibma <n_hibma@freebsd.org>
      36             :  * All rights reserved.
      37             :  *
      38             :  * Redistribution and use in source and binary forms, with or without
      39             :  * modification, are permitted provided that the following conditions
      40             :  * are met:
      41             :  * 1. Redistributions of source code must retain the above copyright
      42             :  *    notice, this list of conditions and the following disclaimer.
      43             :  * 2. Redistributions in binary form must reproduce the above copyright
      44             :  *    notice, this list of conditions and the following disclaimer in the
      45             :  *    documentation and/or other materials provided with the distribution.
      46             :  *
      47             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      48             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      49             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      50             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      51             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      52             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      53             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      54             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      55             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      56             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      57             :  * SUCH DAMAGE.
      58             :  *
      59             :  *     $FreeBSD: src/sys/dev/usb/umass.c,v 1.13 2000/03/26 01:39:12 n_hibma Exp $
      60             :  */
      61             : 
      62             : /*
      63             :  * Universal Serial Bus Mass Storage Class specs:
      64             :  * http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf
      65             :  * http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
      66             :  * http://www.usb.org/developers/devclass_docs/usb_msc_cbi_1.1.pdf
      67             :  * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
      68             :  */
      69             : 
      70             : /*
      71             :  * Ported to NetBSD by Lennart Augustsson <augustss@NetBSD.org>.
      72             :  * Parts of the code written by Jason R. Thorpe <thorpej@shagadelic.org>.
      73             :  */
      74             : 
      75             : /*
      76             :  * The driver handles 3 Wire Protocols
      77             :  * - Command/Bulk/Interrupt (CBI)
      78             :  * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI)
      79             :  * - Mass Storage Bulk-Only (BBB)
      80             :  *   (BBB refers Bulk/Bulk/Bulk for Command/Data/Status phases)
      81             :  *
      82             :  * Over these wire protocols it handles the following command protocols
      83             :  * - SCSI
      84             :  * - 8070 (ATA/ATAPI for rewritable removable media)
      85             :  * - UFI (USB Floppy Interface)
      86             :  *
      87             :  * 8070i is a transformed version of the SCSI command set. UFI is a transformed
      88             :  * version of the 8070i command set.  The sc->transform method is used to
      89             :  * convert the commands into the appropriate format (if at all necessary).
      90             :  * For example, ATAPI requires all commands to be 12 bytes in length amongst
      91             :  * other things.
      92             :  *
      93             :  * The source code below is marked and can be split into a number of pieces
      94             :  * (in this order):
      95             :  *
      96             :  * - probe/attach/detach
      97             :  * - generic transfer routines
      98             :  * - BBB
      99             :  * - CBI
     100             :  * - CBI_I (in addition to functions from CBI)
     101             :  * - CAM (Common Access Method)
     102             :  * - SCSI
     103             :  * - UFI
     104             :  * - 8070i
     105             :  *
     106             :  * The protocols are implemented using a state machine, for the transfers as
     107             :  * well as for the resets. The state machine is contained in umass_*_state.
     108             :  * The state machine is started through either umass_*_transfer or
     109             :  * umass_*_reset.
     110             :  *
     111             :  * The reason for doing this is a) CAM performs a lot better this way and b) it
     112             :  * avoids using tsleep from interrupt context (for example after a failed
     113             :  * transfer).
     114             :  */
     115             : 
     116             : /*
     117             :  * The SCSI related part of this driver has been derived from the
     118             :  * dev/ppbus/vpo.c driver, by Nicolas Souchu (nsouch@freebsd.org).
     119             :  *
     120             :  * The CAM layer uses so called actions which are messages sent to the host
     121             :  * adapter for completion. The actions come in through umass_cam_action. The
     122             :  * appropriate block of routines is called depending on the transport protocol
     123             :  * in use. When the transfer has finished, these routines call
     124             :  * umass_cam_cb again to complete the CAM command.
     125             :  */
     126             : 
     127             : #include <sys/param.h>
     128             : #include <sys/systm.h>
     129             : #include <sys/kernel.h>
     130             : #include <sys/conf.h>
     131             : #include <sys/buf.h>
     132             : #include <sys/device.h>
     133             : #include <sys/timeout.h>
     134             : #undef KASSERT
     135             : #define KASSERT(cond, msg)
     136             : #include <machine/bus.h>
     137             : 
     138             : #include <scsi/scsi_all.h>
     139             : 
     140             : #include <dev/usb/usb.h>
     141             : #include <dev/usb/usbdi.h>
     142             : #include <dev/usb/usbdi_util.h>
     143             : #include <dev/usb/usbdivar.h>
     144             : 
     145             : #include <dev/usb/umassvar.h>
     146             : #include <dev/usb/umass_quirks.h>
     147             : #include <dev/usb/umass_scsi.h>
     148             : 
     149             : 
     150             : #ifdef UMASS_DEBUG
     151             : int umassdebug = 0;
     152             : 
     153             : char *states[TSTATE_STATES+1] = {
     154             :         /* should be kept in sync with the list at transfer_state */
     155             :         "Idle",
     156             :         "BBB CBW",
     157             :         "BBB Data",
     158             :         "BBB Data bulk-in/-out clear stall",
     159             :         "BBB CSW, 1st attempt",
     160             :         "BBB CSW bulk-in clear stall",
     161             :         "BBB CSW, 2nd attempt",
     162             :         "BBB Reset",
     163             :         "BBB bulk-in clear stall",
     164             :         "BBB bulk-out clear stall",
     165             :         "CBI Command",
     166             :         "CBI Data",
     167             :         "CBI Status",
     168             :         "CBI Data bulk-in/-out clear stall",
     169             :         "CBI Status intr-in clear stall",
     170             :         "CBI Reset",
     171             :         "CBI bulk-in clear stall",
     172             :         "CBI bulk-out clear stall",
     173             :         NULL
     174             : };
     175             : #endif
     176             : 
     177             : /* USB device probe/attach/detach functions */
     178             : int umass_match(struct device *, void *, void *); 
     179             : void umass_attach(struct device *, struct device *, void *); 
     180             : int umass_detach(struct device *, int); 
     181             : 
     182             : struct cfdriver umass_cd = { 
     183             :         NULL, "umass", DV_DULL 
     184             : }; 
     185             : 
     186             : const struct cfattach umass_ca = {
     187             :         sizeof(struct umass_softc), umass_match, umass_attach, umass_detach
     188             : };
     189             : 
     190             : void umass_disco(struct umass_softc *sc);
     191             : 
     192             : /* generic transfer functions */
     193             : usbd_status umass_polled_transfer(struct umass_softc *sc,
     194             :                                 struct usbd_xfer *xfer);
     195             : usbd_status umass_setup_transfer(struct umass_softc *sc,
     196             :                                 struct usbd_pipe *pipe,
     197             :                                 void *buffer, int buflen, int flags,
     198             :                                 struct usbd_xfer *xfer);
     199             : usbd_status umass_setup_ctrl_transfer(struct umass_softc *sc,
     200             :                                 usb_device_request_t *req,
     201             :                                 void *buffer, int buflen, int flags,
     202             :                                 struct usbd_xfer *xfer);
     203             : void umass_clear_endpoint_stall(struct umass_softc *sc, int endpt,
     204             :                                 struct usbd_xfer *xfer);
     205             : void umass_adjust_transfer(struct umass_softc *);
     206             : #if 0
     207             : void umass_reset(struct umass_softc *sc,        transfer_cb_f cb, void *priv);
     208             : #endif
     209             : 
     210             : /* Bulk-Only related functions */
     211             : void umass_bbb_transfer(struct umass_softc *, int, void *, int, void *,
     212             :                                int, int, u_int, umass_callback, void *);
     213             : void umass_bbb_reset(struct umass_softc *, int);
     214             : void umass_bbb_state(struct usbd_xfer *, void *, usbd_status);
     215             : 
     216             : u_int8_t umass_bbb_get_max_lun(struct umass_softc *);
     217             : 
     218             : /* CBI related functions */
     219             : void umass_cbi_transfer(struct umass_softc *, int, void *, int, void *,
     220             :                                int, int, u_int, umass_callback, void *);
     221             : void umass_cbi_reset(struct umass_softc *, int);
     222             : void umass_cbi_state(struct usbd_xfer *, void *, usbd_status);
     223             : 
     224             : int umass_cbi_adsc(struct umass_softc *, char *, int, struct usbd_xfer *);
     225             : 
     226             : const struct umass_wire_methods umass_bbb_methods = {
     227             :         umass_bbb_transfer,
     228             :         umass_bbb_reset,
     229             :         umass_bbb_state
     230             : };
     231             : 
     232             : const struct umass_wire_methods umass_cbi_methods = {
     233             :         umass_cbi_transfer,
     234             :         umass_cbi_reset,
     235             :         umass_cbi_state
     236             : };
     237             : 
     238             : #ifdef UMASS_DEBUG
     239             : /* General debugging functions */
     240             : void umass_bbb_dump_cbw(struct umass_softc *sc,
     241             :                                 struct umass_bbb_cbw *cbw);
     242             : void umass_bbb_dump_csw(struct umass_softc *sc,
     243             :                                 struct umass_bbb_csw *csw);
     244             : void umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer,
     245             :                                 int buflen, int printlen);
     246             : #endif
     247             : 
     248             : 
     249             : /*
     250             :  * USB device probe/attach/detach
     251             :  */
     252             : 
     253             : int
     254           0 : umass_match(struct device *parent, void *match, void *aux)
     255             : {
     256           0 :         struct usb_attach_arg *uaa = aux;
     257             :         const struct umass_quirk *quirk;
     258             :         usb_interface_descriptor_t *id;
     259             : 
     260           0 :         if (uaa->iface == NULL)
     261           0 :                 return (UMATCH_NONE);
     262             : 
     263           0 :         quirk = umass_lookup(uaa->vendor, uaa->product);
     264           0 :         if (quirk != NULL)
     265           0 :                 return (quirk->uq_match);
     266             : 
     267           0 :         id = usbd_get_interface_descriptor(uaa->iface);
     268           0 :         if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
     269           0 :                 return (UMATCH_NONE);
     270             : 
     271           0 :         switch (id->bInterfaceSubClass) {
     272             :         case UISUBCLASS_RBC:
     273             :         case UISUBCLASS_SFF8020I:
     274             :         case UISUBCLASS_QIC157:
     275             :         case UISUBCLASS_UFI:
     276             :         case UISUBCLASS_SFF8070I:
     277             :         case UISUBCLASS_SCSI:
     278             :                 break;
     279             :         default:
     280           0 :                 return (UMATCH_IFACECLASS);
     281             :         }
     282             : 
     283           0 :         switch (id->bInterfaceProtocol) {
     284             :         case UIPROTO_MASS_CBI_I:
     285             :         case UIPROTO_MASS_CBI:
     286             :         case UIPROTO_MASS_BBB_OLD:
     287             :         case UIPROTO_MASS_BBB:
     288             :                 break;
     289             :         default:
     290           0 :                 return (UMATCH_IFACECLASS_IFACESUBCLASS);
     291             :         }
     292             : 
     293           0 :         return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
     294           0 : }
     295             : 
     296             : void
     297           0 : umass_attach(struct device *parent, struct device *self, void *aux)
     298             : {
     299           0 :         struct umass_softc *sc = (struct umass_softc *)self;
     300           0 :         struct usb_attach_arg *uaa = aux;
     301             :         const struct umass_quirk *quirk;
     302             :         usb_interface_descriptor_t *id;
     303             :         usb_endpoint_descriptor_t *ed;
     304             :         const char *sWire, *sCommand;
     305             :         usbd_status err;
     306             :         int i, bno, error;
     307             : 
     308           0 :         sc->sc_udev = uaa->device;
     309           0 :         sc->sc_iface = uaa->iface;
     310           0 :         sc->sc_ifaceno = uaa->ifaceno;
     311             : 
     312           0 :         quirk = umass_lookup(uaa->vendor, uaa->product);
     313           0 :         if (quirk != NULL) {
     314           0 :                 sc->sc_wire = quirk->uq_wire;
     315           0 :                 sc->sc_cmd = quirk->uq_cmd;
     316           0 :                 sc->sc_quirks = quirk->uq_flags;
     317           0 :                 sc->sc_busquirks = quirk->uq_busquirks;
     318             : 
     319           0 :                 if (quirk->uq_fixup != NULL)
     320           0 :                         (*quirk->uq_fixup)(sc);
     321             :         } else {
     322           0 :                 sc->sc_wire = UMASS_WPROTO_UNSPEC;
     323           0 :                 sc->sc_cmd = UMASS_CPROTO_UNSPEC;
     324           0 :                 sc->sc_quirks = 0;
     325           0 :                 sc->sc_busquirks = 0;
     326             :         }
     327             : 
     328           0 :         id = usbd_get_interface_descriptor(sc->sc_iface);
     329           0 :         if (id == NULL)
     330           0 :                 return;
     331             : 
     332           0 :         if (sc->sc_wire == UMASS_WPROTO_UNSPEC) {
     333           0 :                 switch (id->bInterfaceProtocol) {
     334             :                 case UIPROTO_MASS_CBI:
     335           0 :                         sc->sc_wire = UMASS_WPROTO_CBI;
     336           0 :                         break;
     337             :                 case UIPROTO_MASS_CBI_I:
     338           0 :                         sc->sc_wire = UMASS_WPROTO_CBI_I;
     339           0 :                         break;
     340             :                 case UIPROTO_MASS_BBB:
     341             :                 case UIPROTO_MASS_BBB_OLD:
     342           0 :                         sc->sc_wire = UMASS_WPROTO_BBB;
     343           0 :                         break;
     344             :                 default:
     345             :                         DPRINTF(UDMASS_GEN,
     346             :                                 ("%s: Unsupported wire protocol %u\n",
     347             :                                 sc->sc_dev.dv_xname,
     348             :                                 id->bInterfaceProtocol));
     349           0 :                         return;
     350             :                 }
     351             :         }
     352             : 
     353           0 :         if (sc->sc_cmd == UMASS_CPROTO_UNSPEC) {
     354           0 :                 switch (id->bInterfaceSubClass) {
     355             :                 case UISUBCLASS_SCSI:
     356           0 :                         sc->sc_cmd = UMASS_CPROTO_SCSI;
     357           0 :                         break;
     358             :                 case UISUBCLASS_UFI:
     359           0 :                         sc->sc_cmd = UMASS_CPROTO_UFI;
     360           0 :                         break;
     361             :                 case UISUBCLASS_SFF8020I:
     362             :                 case UISUBCLASS_SFF8070I:
     363             :                 case UISUBCLASS_QIC157:
     364           0 :                         sc->sc_cmd = UMASS_CPROTO_ATAPI;
     365           0 :                         break;
     366             :                 case UISUBCLASS_RBC:
     367           0 :                         sc->sc_cmd = UMASS_CPROTO_RBC;
     368           0 :                         break;
     369             :                 default:
     370             :                         DPRINTF(UDMASS_GEN,
     371             :                                 ("%s: Unsupported command protocol %u\n",
     372             :                                 sc->sc_dev.dv_xname,
     373             :                                 id->bInterfaceSubClass));
     374           0 :                         return;
     375             :                 }
     376             :         }
     377             : 
     378           0 :         switch (sc->sc_wire) {
     379             :         case UMASS_WPROTO_CBI:
     380             :                 sWire = "CBI";
     381           0 :                 break;
     382             :         case UMASS_WPROTO_CBI_I:
     383             :                 sWire = "CBI with CCI";
     384           0 :                 break;
     385             :         case UMASS_WPROTO_BBB:
     386             :                 sWire = "Bulk-Only";
     387           0 :                 break;
     388             :         default:
     389             :                 sWire = "unknown";
     390           0 :                 break;
     391             :         }
     392             : 
     393           0 :         switch (sc->sc_cmd) {
     394             :         case UMASS_CPROTO_RBC:
     395             :                 sCommand = "RBC";
     396           0 :                 break;
     397             :         case UMASS_CPROTO_SCSI:
     398             :                 sCommand = "SCSI";
     399           0 :                 break;
     400             :         case UMASS_CPROTO_UFI:
     401             :                 sCommand = "UFI";
     402           0 :                 break;
     403             :         case UMASS_CPROTO_ATAPI:
     404             :                 sCommand = "ATAPI";
     405           0 :                 break;
     406             :         case UMASS_CPROTO_ISD_ATA:
     407             :                 sCommand = "ISD-ATA";
     408           0 :                 break;
     409             :         default:
     410             :                 sCommand = "unknown";
     411           0 :                 break;
     412             :         }
     413             : 
     414           0 :         printf("%s: using %s over %s\n", sc->sc_dev.dv_xname, sCommand,
     415             :                sWire);
     416             : 
     417           0 :         if (quirk != NULL && quirk->uq_init != NULL) {
     418           0 :                 err = (*quirk->uq_init)(sc);
     419           0 :                 if (err) {
     420           0 :                         umass_disco(sc);
     421           0 :                         return;
     422             :                 }
     423             :         }
     424             : 
     425             :         /*
     426             :          * In addition to the Control endpoint the following endpoints
     427             :          * are required:
     428             :          * a) bulk-in endpoint.
     429             :          * b) bulk-out endpoint.
     430             :          * and for Control/Bulk/Interrupt with CCI (CBI_I)
     431             :          * c) intr-in
     432             :          *
     433             :          * The endpoint addresses are not fixed, so we have to read them
     434             :          * from the device descriptors of the current interface.
     435             :          */
     436           0 :         for (i = 0 ; i < id->bNumEndpoints ; i++) {
     437           0 :                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
     438           0 :                 if (ed == NULL) {
     439           0 :                         printf("%s: could not read endpoint descriptor\n",
     440             :                                sc->sc_dev.dv_xname);
     441           0 :                         return;
     442             :                 }
     443           0 :                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
     444           0 :                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
     445           0 :                         sc->sc_epaddr[UMASS_BULKIN] = ed->bEndpointAddress;
     446           0 :                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
     447           0 :                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
     448           0 :                         sc->sc_epaddr[UMASS_BULKOUT] = ed->bEndpointAddress;
     449           0 :                 } else if (sc->sc_wire == UMASS_WPROTO_CBI_I
     450           0 :                     && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
     451           0 :                     && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
     452           0 :                         sc->sc_epaddr[UMASS_INTRIN] = ed->bEndpointAddress;
     453             : #ifdef UMASS_DEBUG
     454             :                         if (UGETW(ed->wMaxPacketSize) > 2) {
     455             :                                 DPRINTF(UDMASS_CBI, ("%s: intr size is %d\n",
     456             :                                         sc->sc_dev.dv_xname,
     457             :                                         UGETW(ed->wMaxPacketSize)));
     458             :                         }
     459             : #endif
     460           0 :                 }
     461             :         }
     462             : 
     463             :         /* check whether we found all the endpoints we need */
     464           0 :         if (!sc->sc_epaddr[UMASS_BULKIN] || !sc->sc_epaddr[UMASS_BULKOUT] ||
     465           0 :             (sc->sc_wire == UMASS_WPROTO_CBI_I &&
     466           0 :              !sc->sc_epaddr[UMASS_INTRIN])) {
     467             :                 DPRINTF(UDMASS_USB, ("%s: endpoint not found %u/%u/%u\n",
     468             :                         sc->sc_dev.dv_xname, sc->sc_epaddr[UMASS_BULKIN],
     469             :                         sc->sc_epaddr[UMASS_BULKOUT],
     470             :                         sc->sc_epaddr[UMASS_INTRIN]));
     471           0 :                 return;
     472             :         }
     473             : 
     474             :         /*
     475             :          * Get the maximum LUN supported by the device.
     476             :          */
     477           0 :         if (sc->sc_wire == UMASS_WPROTO_BBB) {
     478           0 :                 sc->maxlun = umass_bbb_get_max_lun(sc);
     479           0 :         } else {
     480           0 :                 sc->maxlun = 0;
     481             :         }
     482             : 
     483             :         /* Open the bulk-in and -out pipe */
     484             :         DPRINTF(UDMASS_USB, ("%s: opening iface %p epaddr %d for BULKOUT\n",
     485             :             sc->sc_dev.dv_xname, sc->sc_iface,
     486             :             sc->sc_epaddr[UMASS_BULKOUT]));
     487           0 :         err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_BULKOUT],
     488             :                                 USBD_EXCLUSIVE_USE,
     489           0 :                                 &sc->sc_pipe[UMASS_BULKOUT]);
     490           0 :         if (err) {
     491             :                 DPRINTF(UDMASS_USB, ("%s: cannot open %u-out pipe (bulk)\n",
     492             :                         sc->sc_dev.dv_xname, sc->sc_epaddr[UMASS_BULKOUT]));
     493           0 :                 umass_disco(sc);
     494           0 :                 return;
     495             :         }
     496             :         DPRINTF(UDMASS_USB, ("%s: opening iface %p epaddr %d for BULKIN\n",
     497             :             sc->sc_dev.dv_xname, sc->sc_iface,
     498             :             sc->sc_epaddr[UMASS_BULKIN]));
     499           0 :         err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_BULKIN],
     500           0 :                                 USBD_EXCLUSIVE_USE, &sc->sc_pipe[UMASS_BULKIN]);
     501           0 :         if (err) {
     502             :                 DPRINTF(UDMASS_USB, ("%s: could not open %u-in pipe (bulk)\n",
     503             :                         sc->sc_dev.dv_xname, sc->sc_epaddr[UMASS_BULKIN]));
     504           0 :                 umass_disco(sc);
     505           0 :                 return;
     506             :         }
     507             :         /*
     508             :          * Open the intr-in pipe if the protocol is CBI with CCI.
     509             :          * Note: early versions of the Zip drive do have an interrupt pipe, but
     510             :          * this pipe is unused
     511             :          *
     512             :          * We do not open the interrupt pipe as an interrupt pipe, but as a
     513             :          * normal bulk endpoint. We send an IN transfer down the wire at the
     514             :          * appropriate time, because we know exactly when to expect data on
     515             :          * that endpoint. This saves bandwidth, but more important, makes the
     516             :          * code for handling the data on that endpoint simpler. No data
     517             :          * arriving concurrently.
     518             :          */
     519           0 :         if (sc->sc_wire == UMASS_WPROTO_CBI_I) {
     520             :                 DPRINTF(UDMASS_USB, ("%s: opening iface %p epaddr %d for INTRIN\n",
     521             :                     sc->sc_dev.dv_xname, sc->sc_iface,
     522             :                     sc->sc_epaddr[UMASS_INTRIN]));
     523           0 :                 err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_INTRIN],
     524           0 :                                 USBD_EXCLUSIVE_USE, &sc->sc_pipe[UMASS_INTRIN]);
     525           0 :                 if (err) {
     526             :                         DPRINTF(UDMASS_USB, ("%s: couldn't open %u-in (intr)\n",
     527             :                                 sc->sc_dev.dv_xname,
     528             :                                 sc->sc_epaddr[UMASS_INTRIN]));
     529           0 :                         umass_disco(sc);
     530           0 :                         return;
     531             :                 }
     532             :         }
     533             : 
     534             :         /* initialisation of generic part */
     535           0 :         sc->transfer_state = TSTATE_IDLE;
     536             : 
     537             :         /* request a sufficient number of xfer handles */
     538           0 :         for (i = 0; i < XFER_NR; i++) {
     539           0 :                 sc->transfer_xfer[i] = usbd_alloc_xfer(uaa->device);
     540           0 :                 if (sc->transfer_xfer[i] == NULL) {
     541             :                         DPRINTF(UDMASS_USB, ("%s: Out of memory\n",
     542             :                                 sc->sc_dev.dv_xname));
     543           0 :                         umass_disco(sc);
     544           0 :                         return;
     545             :                 }
     546             :         }
     547             :         /* Allocate buffer for data transfer (it's huge). */
     548           0 :         switch (sc->sc_wire) {
     549             :         case UMASS_WPROTO_BBB:
     550             :                 bno = XFER_BBB_DATA;
     551           0 :                 goto dalloc;
     552             :         case UMASS_WPROTO_CBI:
     553             :                 bno = XFER_CBI_DATA;
     554           0 :                 goto dalloc;
     555             :         case UMASS_WPROTO_CBI_I:
     556           0 :                 bno = XFER_CBI_DATA;
     557             :         dalloc:
     558           0 :                 sc->data_buffer = usbd_alloc_buffer(sc->transfer_xfer[bno],
     559             :                                                     UMASS_MAX_TRANSFER_SIZE);
     560           0 :                 if (sc->data_buffer == NULL) {
     561           0 :                         umass_disco(sc);
     562           0 :                         return;
     563             :                 }
     564             :                 break;
     565             :         default:
     566             :                 break;
     567             :         }
     568             : 
     569             :         /* Initialise the wire protocol specific methods */
     570           0 :         switch (sc->sc_wire) {
     571             :         case UMASS_WPROTO_BBB:
     572           0 :                 sc->sc_methods = &umass_bbb_methods;
     573           0 :                 break;
     574             :         case UMASS_WPROTO_CBI:
     575             :         case UMASS_WPROTO_CBI_I:
     576           0 :                 sc->sc_methods = &umass_cbi_methods;
     577           0 :                 break;
     578             :         default:
     579           0 :                 umass_disco(sc);
     580           0 :                 return;
     581             :         }
     582             : 
     583             :         error = 0;
     584           0 :         switch (sc->sc_cmd) {
     585             :         case UMASS_CPROTO_RBC:
     586             :         case UMASS_CPROTO_SCSI:
     587             :         case UMASS_CPROTO_UFI:
     588             :         case UMASS_CPROTO_ATAPI:
     589           0 :                 error = umass_scsi_attach(sc);
     590           0 :                 break;
     591             : 
     592             :         case UMASS_CPROTO_ISD_ATA:
     593           0 :                 printf("%s: isdata not configured\n", sc->sc_dev.dv_xname);
     594           0 :                 break;
     595             : 
     596             :         default:
     597           0 :                 printf("%s: command protocol=0x%x not supported\n",
     598             :                        sc->sc_dev.dv_xname, sc->sc_cmd);
     599           0 :                 umass_disco(sc);
     600           0 :                 return;
     601             :         }
     602           0 :         if (error) {
     603           0 :                 printf("%s: bus attach failed\n", sc->sc_dev.dv_xname);
     604           0 :                 umass_disco(sc);
     605           0 :                 return;
     606             :         }
     607             : 
     608             :         DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", sc->sc_dev.dv_xname));
     609           0 : }
     610             : 
     611             : int
     612           0 : umass_detach(struct device *self, int flags)
     613             : {
     614           0 :         struct umass_softc *sc = (struct umass_softc *)self;
     615             :         int rv = 0, i, s;
     616             : 
     617             :         DPRINTF(UDMASS_USB, ("%s: detached\n", sc->sc_dev.dv_xname));
     618             : 
     619             :         /* Abort the pipes to wake up any waiting processes. */
     620           0 :         for (i = 0 ; i < UMASS_NEP ; i++) {
     621           0 :                 if (sc->sc_pipe[i] != NULL)
     622           0 :                         usbd_abort_pipe(sc->sc_pipe[i]);
     623             :         }
     624             : 
     625             :         /* Do we really need reference counting?  Perhaps in ioctl() */
     626           0 :         s = splusb();
     627           0 :         if (--sc->sc_refcnt >= 0) {
     628             : #ifdef DIAGNOSTIC
     629           0 :                 printf("%s: waiting for refcnt\n", sc->sc_dev.dv_xname);
     630             : #endif
     631             :                 /* Wait for processes to go away. */
     632           0 :                 usb_detach_wait(&sc->sc_dev);
     633           0 :         }
     634             : 
     635             :         /* Free the buffers via callback. */
     636           0 :         if (sc->transfer_state != TSTATE_IDLE && sc->transfer_priv) {
     637           0 :                 sc->transfer_state = TSTATE_IDLE;
     638           0 :                 sc->transfer_cb(sc, sc->transfer_priv,
     639           0 :                                 sc->transfer_datalen,
     640             :                                 STATUS_WIRE_FAILED);
     641           0 :                 sc->transfer_priv = NULL;
     642           0 :         }
     643           0 :         splx(s);
     644             : 
     645           0 :         rv = umass_scsi_detach(sc, flags);
     646           0 :         if (rv != 0)
     647           0 :                 return (rv);
     648             : 
     649           0 :         umass_disco(sc);
     650             : 
     651           0 :         return (rv);
     652           0 : }
     653             : 
     654             : void
     655           0 : umass_disco(struct umass_softc *sc)
     656             : {
     657             :         int i;
     658             : 
     659             :         DPRINTF(UDMASS_GEN, ("umass_disco\n"));
     660             : 
     661             :         /* Remove all the pipes. */
     662           0 :         for (i = 0 ; i < UMASS_NEP ; i++) {
     663           0 :                 if (sc->sc_pipe[i] != NULL) {
     664           0 :                         usbd_close_pipe(sc->sc_pipe[i]);
     665           0 :                         sc->sc_pipe[i] = NULL;
     666           0 :                 }
     667             :         }
     668             : 
     669             :         /* Make sure there is no stuck control transfer left. */
     670           0 :         usbd_abort_pipe(sc->sc_udev->default_pipe);
     671             : 
     672             :         /* Free the xfers. */
     673           0 :         for (i = 0; i < XFER_NR; i++) {
     674           0 :                 if (sc->transfer_xfer[i] != NULL) {
     675           0 :                         usbd_free_xfer(sc->transfer_xfer[i]);
     676           0 :                         sc->transfer_xfer[i] = NULL;
     677           0 :                 }
     678             :         }
     679           0 : }
     680             : 
     681             : /*
     682             :  * Generic functions to handle transfers
     683             :  */
     684             : 
     685             : usbd_status
     686           0 : umass_polled_transfer(struct umass_softc *sc, struct usbd_xfer *xfer)
     687             : {
     688             :         usbd_status err;
     689             : 
     690           0 :         if (usbd_is_dying(sc->sc_udev))
     691           0 :                 return (USBD_IOERROR);
     692             : 
     693             :         /*
     694             :          * If a polled transfer is already in progress, preserve the new
     695             :          * struct usbd_xfer and run it after the running one completes.
     696             :          * This converts the recursive calls into the umass_*_state callbacks
     697             :          * into iteration, preventing us from running out of stack under
     698             :          * error conditions.
     699             :          */
     700           0 :         if (sc->polling_depth) {
     701           0 :                 if (sc->next_polled_xfer)
     702           0 :                         panic("%s: got polled xfer %p, but %p already "
     703           0 :                             "pending\n", sc->sc_dev.dv_xname, xfer,
     704             :                             sc->next_polled_xfer);
     705             : 
     706             :                 DPRINTF(UDMASS_XFER, ("%s: saving polled xfer %p\n",
     707             :                     sc->sc_dev.dv_xname, xfer));
     708           0 :                 sc->next_polled_xfer = xfer;
     709             : 
     710           0 :                 return (USBD_IN_PROGRESS);
     711             :         }
     712             : 
     713           0 :         sc->polling_depth++;
     714             : 
     715             : start_next_xfer:
     716             :         DPRINTF(UDMASS_XFER, ("%s: start polled xfer %p\n",
     717             :             sc->sc_dev.dv_xname, xfer));
     718           0 :         err = usbd_transfer(xfer);
     719           0 :         if (err && err != USBD_IN_PROGRESS && sc->next_polled_xfer == NULL) {
     720             :                 DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n",
     721             :                     sc->sc_dev.dv_xname, usbd_errstr(err)));
     722           0 :                 sc->polling_depth--;
     723           0 :                 return (err);
     724             :         }
     725             : 
     726             :         if (err && err != USBD_IN_PROGRESS) {
     727             :                 DPRINTF(UDMASS_XFER, ("umass_polled_xfer %p has error %s\n",
     728             :                     xfer, usbd_errstr(err)));
     729             :         }
     730             : 
     731           0 :         if (sc->next_polled_xfer != NULL) {
     732             :                 DPRINTF(UDMASS_XFER, ("umass_polled_xfer running next "
     733             :                     "transaction %p\n", sc->next_polled_xfer));
     734             :                 xfer = sc->next_polled_xfer;
     735           0 :                 sc->next_polled_xfer = NULL;
     736           0 :                 goto start_next_xfer;
     737             :         }
     738             : 
     739           0 :         sc->polling_depth--;
     740             : 
     741           0 :         return (USBD_NORMAL_COMPLETION);
     742           0 : }
     743             : 
     744             : usbd_status
     745           0 : umass_setup_transfer(struct umass_softc *sc, struct usbd_pipe *pipe,
     746             :                         void *buffer, int buflen, int flags,
     747             :                         struct usbd_xfer *xfer)
     748             : {
     749             :         usbd_status err;
     750             : 
     751           0 :         if (usbd_is_dying(sc->sc_udev))
     752           0 :                 return (USBD_IOERROR);
     753             : 
     754             :         /* Initialise a USB transfer and then schedule it */
     755             : 
     756           0 :         usbd_setup_xfer(xfer, pipe, (void *)sc, buffer, buflen,
     757           0 :             flags | sc->sc_xfer_flags, sc->timeout, sc->sc_methods->wire_state);
     758             : 
     759           0 :         if (sc->sc_udev->bus->use_polling) {
     760             :                 DPRINTF(UDMASS_XFER,("%s: start polled xfer buffer=%p "
     761             :                     "buflen=%d flags=0x%x timeout=%d\n", sc->sc_dev.dv_xname,
     762             :                     buffer, buflen, flags | sc->sc_xfer_flags, sc->timeout));
     763           0 :                 err = umass_polled_transfer(sc, xfer);
     764           0 :         } else {
     765           0 :                 err = usbd_transfer(xfer);
     766             :                 DPRINTF(UDMASS_XFER,("%s: start xfer buffer=%p buflen=%d "
     767             :                     "flags=0x%x timeout=%d\n", sc->sc_dev.dv_xname,
     768             :                     buffer, buflen, flags | sc->sc_xfer_flags, sc->timeout));
     769             :         }
     770           0 :         if (err && err != USBD_IN_PROGRESS) {
     771             :                 DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n",
     772             :                         sc->sc_dev.dv_xname, usbd_errstr(err)));
     773           0 :                 return (err);
     774             :         }
     775             : 
     776           0 :         return (USBD_NORMAL_COMPLETION);
     777           0 : }
     778             : 
     779             : 
     780             : usbd_status
     781           0 : umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req,
     782             :          void *buffer, int buflen, int flags, struct usbd_xfer *xfer)
     783             : {
     784             :         usbd_status err;
     785             : 
     786           0 :         if (usbd_is_dying(sc->sc_udev))
     787           0 :                 return (USBD_IOERROR);
     788             : 
     789             :         /* Initialise a USB control transfer and then schedule it */
     790             : 
     791           0 :         usbd_setup_default_xfer(xfer, sc->sc_udev, (void *) sc,
     792           0 :             USBD_DEFAULT_TIMEOUT, req, buffer, buflen, flags,
     793           0 :             sc->sc_methods->wire_state);
     794             : 
     795           0 :         if (sc->sc_udev->bus->use_polling) {
     796             :                 DPRINTF(UDMASS_XFER,("%s: start polled ctrl xfer buffer=%p "
     797             :                     "buflen=%d flags=0x%x\n", sc->sc_dev.dv_xname, buffer,
     798             :                     buflen, flags));
     799           0 :                 err = umass_polled_transfer(sc, xfer);
     800           0 :         } else {
     801             :                 DPRINTF(UDMASS_XFER,("%s: start ctrl xfer buffer=%p buflen=%d "
     802             :                     "flags=0x%x\n", sc->sc_dev.dv_xname, buffer, buflen,
     803             :                     flags));
     804           0 :                 err = usbd_transfer(xfer);
     805             :         }
     806           0 :         if (err && err != USBD_IN_PROGRESS) {
     807             :                 DPRINTF(UDMASS_BBB, ("%s: failed to setup ctrl transfer, %s\n",
     808             :                          sc->sc_dev.dv_xname, usbd_errstr(err)));
     809             : 
     810             :                 /* do not reset, as this would make us loop */
     811           0 :                 return (err);
     812             :         }
     813             : 
     814           0 :         return (USBD_NORMAL_COMPLETION);
     815           0 : }
     816             : 
     817             : void
     818           0 : umass_adjust_transfer(struct umass_softc *sc)
     819             : {
     820           0 :         switch (sc->sc_cmd) {
     821             :         case UMASS_CPROTO_UFI:
     822           0 :                 sc->cbw.bCDBLength = UFI_COMMAND_LENGTH; 
     823             :                 /* Adjust the length field in certain scsi commands. */
     824           0 :                 switch (sc->cbw.CBWCDB[0]) {
     825             :                 case INQUIRY:
     826           0 :                         if (sc->transfer_datalen > 36) {
     827           0 :                                 sc->transfer_datalen = 36;
     828           0 :                                 sc->cbw.CBWCDB[4] = 36;
     829           0 :                         }
     830             :                         break;
     831             :                 case MODE_SENSE_BIG:
     832           0 :                         if (sc->transfer_datalen > 8) {
     833           0 :                                 sc->transfer_datalen = 8;
     834           0 :                                 sc->cbw.CBWCDB[7] = 0;
     835           0 :                                 sc->cbw.CBWCDB[8] = 8;
     836           0 :                         }
     837             :                         break;
     838             :                 case REQUEST_SENSE:
     839           0 :                         if (sc->transfer_datalen > 18) {
     840           0 :                                 sc->transfer_datalen = 18;
     841           0 :                                 sc->cbw.CBWCDB[4] = 18;
     842           0 :                         }
     843             :                         break;
     844             :                 }
     845             :                 break;
     846             :         case UMASS_CPROTO_ATAPI:
     847           0 :                 sc->cbw.bCDBLength = UFI_COMMAND_LENGTH; 
     848           0 :                 break;
     849             :         }
     850           0 : }
     851             : 
     852             : void
     853           0 : umass_clear_endpoint_stall(struct umass_softc *sc, int endpt,
     854             :     struct usbd_xfer *xfer)
     855             : {
     856           0 :         if (usbd_is_dying(sc->sc_udev))
     857             :                 return;
     858             : 
     859             :         DPRINTF(UDMASS_BBB, ("%s: Clear endpoint 0x%02x stall\n",
     860             :                 sc->sc_dev.dv_xname, sc->sc_epaddr[endpt]));
     861             : 
     862           0 :         usbd_clear_endpoint_toggle(sc->sc_pipe[endpt]);
     863             : 
     864           0 :         sc->sc_req.bmRequestType = UT_WRITE_ENDPOINT;
     865           0 :         sc->sc_req.bRequest = UR_CLEAR_FEATURE;
     866           0 :         USETW(sc->sc_req.wValue, UF_ENDPOINT_HALT);
     867           0 :         USETW(sc->sc_req.wIndex, sc->sc_epaddr[endpt]);
     868           0 :         USETW(sc->sc_req.wLength, 0);
     869           0 :         umass_setup_ctrl_transfer(sc, &sc->sc_req, NULL, 0, 0, xfer);
     870           0 : }
     871             : 
     872             : #if 0
     873             : void
     874             : umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv)
     875             : {
     876             :         sc->transfer_cb = cb;
     877             :         sc->transfer_priv = priv;
     878             : 
     879             :         /* The reset is a forced reset, so no error (yet) */
     880             :         sc->reset(sc, STATUS_CMD_OK);
     881             : }
     882             : #endif
     883             : 
     884             : /*
     885             :  * Bulk protocol specific functions
     886             :  */
     887             : 
     888             : void
     889           0 : umass_bbb_reset(struct umass_softc *sc, int status)
     890             : {
     891             :         KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
     892             :                 ("sc->sc_wire == 0x%02x wrong for umass_bbb_reset\n",
     893             :                 sc->sc_wire));
     894             : 
     895           0 :         if (usbd_is_dying(sc->sc_udev))
     896             :                 return;
     897             : 
     898             :         /*
     899             :          * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
     900             :          *
     901             :          * For Reset Recovery the host shall issue in the following order:
     902             :          * a) a Bulk-Only Mass Storage Reset
     903             :          * b) a Clear Feature HALT to the Bulk-In endpoint
     904             :          * c) a Clear Feature HALT to the Bulk-Out endpoint
     905             :          *
     906             :          * This is done in 3 steps, states:
     907             :          * TSTATE_BBB_RESET1
     908             :          * TSTATE_BBB_RESET2
     909             :          * TSTATE_BBB_RESET3
     910             :          *
     911             :          * If the reset doesn't succeed, the device should be port reset.
     912             :          */
     913             : 
     914             :         DPRINTF(UDMASS_BBB, ("%s: Bulk Reset\n",
     915             :                 sc->sc_dev.dv_xname));
     916             : 
     917           0 :         sc->transfer_state = TSTATE_BBB_RESET1;
     918           0 :         sc->transfer_status = status;
     919             : 
     920             :         /* reset is a class specific interface write */
     921           0 :         sc->sc_req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
     922           0 :         sc->sc_req.bRequest = UR_BBB_RESET;
     923           0 :         USETW(sc->sc_req.wValue, 0);
     924           0 :         USETW(sc->sc_req.wIndex, sc->sc_ifaceno);
     925           0 :         USETW(sc->sc_req.wLength, 0);
     926           0 :         umass_setup_ctrl_transfer(sc, &sc->sc_req, NULL, 0, 0,
     927           0 :                                   sc->transfer_xfer[XFER_BBB_RESET1]);
     928           0 : }
     929             : 
     930             : void
     931           0 : umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
     932             :                    void *data, int datalen, int dir, u_int timeout,
     933             :                    umass_callback cb, void *priv)
     934             : {
     935             :         static int dCBWtag = 42;        /* unique for CBW of transfer */
     936             :         usbd_status err;
     937             : 
     938             :         DPRINTF(UDMASS_BBB,("%s: umass_bbb_transfer cmd=0x%02x\n",
     939             :                 sc->sc_dev.dv_xname, *(u_char *)cmd));
     940             : 
     941             :         KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
     942             :                 ("sc->sc_wire == 0x%02x wrong for umass_bbb_transfer\n",
     943             :                 sc->sc_wire));
     944             : 
     945           0 :         if (usbd_is_dying(sc->sc_udev)) {
     946           0 :                 sc->polled_xfer_status = USBD_IOERROR;
     947           0 :                 return;
     948             :         }
     949             : 
     950             :         /* Be a little generous. */
     951           0 :         sc->timeout = timeout + USBD_DEFAULT_TIMEOUT;
     952             : 
     953             :         /*
     954             :          * Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
     955             :          * a data phase of datalen bytes from/to the device and finally a
     956             :          * csw read phase.
     957             :          * If the data direction was inbound a maximum of datalen bytes
     958             :          * is stored in the buffer pointed to by data.
     959             :          *
     960             :          * umass_bbb_transfer initialises the transfer and lets the state
     961             :          * machine in umass_bbb_state handle the completion. It uses the
     962             :          * following states:
     963             :          * TSTATE_BBB_COMMAND
     964             :          *   -> TSTATE_BBB_DATA
     965             :          *   -> TSTATE_BBB_STATUS
     966             :          *   -> TSTATE_BBB_STATUS2
     967             :          *   -> TSTATE_BBB_IDLE
     968             :          *
     969             :          * An error in any of those states will invoke
     970             :          * umass_bbb_reset.
     971             :          */
     972             : 
     973             :         /* check the given arguments */
     974             :         KASSERT(datalen == 0 || data != NULL,
     975             :                 ("%s: datalen > 0, but no buffer",sc->sc_dev.dv_xname));
     976             :         KASSERT(cmdlen <= CBWCDBLENGTH,
     977             :                 ("%s: cmdlen exceeds CDB length in CBW (%d > %d)",
     978             :                         sc->sc_dev.dv_xname, cmdlen, CBWCDBLENGTH));
     979             :         KASSERT(dir == DIR_NONE || datalen > 0,
     980             :                 ("%s: datalen == 0 while direction is not NONE\n",
     981             :                         sc->sc_dev.dv_xname));
     982             :         KASSERT(datalen == 0 || dir != DIR_NONE,
     983             :                 ("%s: direction is NONE while datalen is not zero\n",
     984             :                         sc->sc_dev.dv_xname));
     985             :         KASSERT(sizeof(struct umass_bbb_cbw) == UMASS_BBB_CBW_SIZE,
     986             :                 ("%s: CBW struct does not have the right size (%d vs. %d)\n",
     987             :                         sc->sc_dev.dv_xname,
     988             :                         sizeof(struct umass_bbb_cbw), UMASS_BBB_CBW_SIZE));
     989             :         KASSERT(sizeof(struct umass_bbb_csw) == UMASS_BBB_CSW_SIZE,
     990             :                 ("%s: CSW struct does not have the right size (%d vs. %d)\n",
     991             :                         sc->sc_dev.dv_xname,
     992             :                         sizeof(struct umass_bbb_csw), UMASS_BBB_CSW_SIZE));
     993             : 
     994             :         /*
     995             :          * Determine the direction of the data transfer and the length.
     996             :          *
     997             :          * dCBWDataTransferLength (datalen) :
     998             :          *   This field indicates the number of bytes of data that the host
     999             :          *   intends to transfer on the IN or OUT Bulk endpoint(as indicated by
    1000             :          *   the Direction bit) during the execution of this command. If this
    1001             :          *   field is set to 0, the device will expect that no data will be
    1002             :          *   transferred IN or OUT during this command, regardless of the value
    1003             :          *   of the Direction bit defined in dCBWFlags.
    1004             :          *
    1005             :          * dCBWFlags (dir) :
    1006             :          *   The bits of the Flags field are defined as follows:
    1007             :          *     Bits 0-6  reserved
    1008             :          *     Bit  7    Direction - this bit shall be ignored if the
    1009             :          *                           dCBWDataTransferLength field is zero.
    1010             :          *               0 = data Out from host to device
    1011             :          *               1 = data In from device to host
    1012             :          */
    1013             : 
    1014             :         /* Fill in the Command Block Wrapper */
    1015           0 :         USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
    1016           0 :         USETDW(sc->cbw.dCBWTag, dCBWtag);
    1017           0 :         dCBWtag++;      /* cannot be done in macro (it will be done 4 times) */
    1018           0 :         USETDW(sc->cbw.dCBWDataTransferLength, datalen);
    1019             :         /* DIR_NONE is treated as DIR_OUT (0x00) */
    1020           0 :         sc->cbw.bCBWFlags = (dir == DIR_IN? CBWFLAGS_IN:CBWFLAGS_OUT);
    1021           0 :         sc->cbw.bCBWLUN = lun;
    1022           0 :         sc->cbw.bCDBLength = cmdlen;
    1023           0 :         bzero(sc->cbw.CBWCDB, sizeof(sc->cbw.CBWCDB));
    1024           0 :         memcpy(sc->cbw.CBWCDB, cmd, cmdlen);
    1025             : 
    1026             :         DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
    1027             : 
    1028             :         /* store the details for the data transfer phase */
    1029           0 :         sc->transfer_dir = dir;
    1030           0 :         sc->transfer_data = data;
    1031           0 :         sc->transfer_datalen = datalen;
    1032           0 :         sc->transfer_actlen = 0;
    1033           0 :         sc->transfer_cb = cb;
    1034           0 :         sc->transfer_priv = priv;
    1035           0 :         sc->transfer_status = STATUS_CMD_OK;
    1036             : 
    1037             :         /* move from idle to the command state */
    1038           0 :         sc->transfer_state = TSTATE_BBB_COMMAND;
    1039             : 
    1040             :         /* Send the CBW from host to device via bulk-out endpoint. */
    1041           0 :         umass_adjust_transfer(sc);
    1042           0 :         if ((err = umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
    1043           0 :                         &sc->cbw, UMASS_BBB_CBW_SIZE, 0,
    1044           0 :                         sc->transfer_xfer[XFER_BBB_CBW])))
    1045           0 :                 umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1046             : 
    1047           0 :         if (sc->sc_udev->bus->use_polling)
    1048           0 :                 sc->polled_xfer_status = err;
    1049           0 : }
    1050             : 
    1051             : void
    1052           0 : umass_bbb_state(struct usbd_xfer *xfer, void *priv, usbd_status err)
    1053             : {
    1054           0 :         struct umass_softc *sc = (struct umass_softc *) priv;
    1055             :         struct usbd_xfer *next_xfer;
    1056             : 
    1057             :         KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
    1058             :                 ("sc->sc_wire == 0x%02x wrong for umass_bbb_state\n",
    1059             :                 sc->sc_wire));
    1060             : 
    1061           0 :         if (usbd_is_dying(sc->sc_udev))
    1062           0 :                 return;
    1063             : 
    1064             :         /*
    1065             :          * State handling for BBB transfers.
    1066             :          *
    1067             :          * The subroutine is rather long. It steps through the states given in
    1068             :          * Annex A of the Bulk-Only specification.
    1069             :          * Each state first does the error handling of the previous transfer
    1070             :          * and then prepares the next transfer.
    1071             :          * Each transfer is done asynchronously so after the request/transfer
    1072             :          * has been submitted you will find a 'return;'.
    1073             :          */
    1074             : 
    1075             :         DPRINTF(UDMASS_BBB, ("%s: Handling BBB state %d (%s), xfer=%p, %s\n",
    1076             :                 sc->sc_dev.dv_xname, sc->transfer_state,
    1077             :                 states[sc->transfer_state], xfer, usbd_errstr(err)));
    1078             : 
    1079           0 :         switch (sc->transfer_state) {
    1080             : 
    1081             :         /***** Bulk Transfer *****/
    1082             :         case TSTATE_BBB_COMMAND:
    1083             :                 /* Command transport phase, error handling */
    1084           0 :                 if (err) {
    1085             :                         DPRINTF(UDMASS_BBB, ("%s: failed to send CBW\n",
    1086             :                                 sc->sc_dev.dv_xname));
    1087             :                         /* If the device detects that the CBW is invalid, then
    1088             :                          * the device may STALL both bulk endpoints and require
    1089             :                          * a Bulk-Reset
    1090             :                          */
    1091           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1092           0 :                         return;
    1093             :                 }
    1094             : 
    1095             :                 /* Data transport phase, setup transfer */
    1096           0 :                 sc->transfer_state = TSTATE_BBB_DATA;
    1097           0 :                 if (sc->transfer_dir == DIR_IN) {
    1098           0 :                         if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
    1099           0 :                                         sc->data_buffer, sc->transfer_datalen,
    1100             :                                         USBD_SHORT_XFER_OK | USBD_NO_COPY,
    1101           0 :                                         sc->transfer_xfer[XFER_BBB_DATA]))
    1102           0 :                                 umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1103             : 
    1104           0 :                         return;
    1105           0 :                 } else if (sc->transfer_dir == DIR_OUT) {
    1106           0 :                         memcpy(sc->data_buffer, sc->transfer_data,
    1107             :                                sc->transfer_datalen);
    1108           0 :                         if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
    1109           0 :                                         sc->data_buffer, sc->transfer_datalen,
    1110             :                                         USBD_NO_COPY,/* fixed length transfer */
    1111           0 :                                         sc->transfer_xfer[XFER_BBB_DATA]))
    1112           0 :                                 umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1113             : 
    1114           0 :                         return;
    1115             :                 } else {
    1116             :                         DPRINTF(UDMASS_BBB, ("%s: no data phase\n",
    1117             :                                 sc->sc_dev.dv_xname));
    1118             :                 }
    1119             : 
    1120             :                 /* FALLTHROUGH if no data phase, err == 0 */
    1121             :         case TSTATE_BBB_DATA:
    1122             :                 /* Command transport phase error handling (ignored if no data
    1123             :                  * phase (fallthrough from previous state)) */
    1124           0 :                 if (sc->transfer_dir != DIR_NONE) {
    1125             :                         /* retrieve the length of the transfer that was done */
    1126           0 :                         usbd_get_xfer_status(xfer, NULL, NULL,
    1127           0 :                              &sc->transfer_actlen, NULL);
    1128             :                         DPRINTF(UDMASS_BBB, ("%s: BBB_DATA actlen=%d\n",
    1129             :                                 sc->sc_dev.dv_xname, sc->transfer_actlen));
    1130             : 
    1131           0 :                         if (err) {
    1132             :                                 DPRINTF(UDMASS_BBB, ("%s: Data-%s %d failed, "
    1133             :                                         "%s\n", sc->sc_dev.dv_xname,
    1134             :                                         (sc->transfer_dir == DIR_IN?"in":"out"),
    1135             :                                         sc->transfer_datalen,usbd_errstr(err)));
    1136             : 
    1137           0 :                                 if (err == USBD_STALLED) {
    1138           0 :                                         sc->transfer_state = TSTATE_BBB_DCLEAR;
    1139           0 :                                         umass_clear_endpoint_stall(sc,
    1140           0 :                                           (sc->transfer_dir == DIR_IN?
    1141             :                                             UMASS_BULKIN:UMASS_BULKOUT),
    1142           0 :                                           sc->transfer_xfer[XFER_BBB_DCLEAR]);
    1143           0 :                                 } else {
    1144             :                                         /* Unless the error is a pipe stall the
    1145             :                                          * error is fatal.
    1146             :                                          */
    1147           0 :                                         umass_bbb_reset(sc,STATUS_WIRE_FAILED);
    1148             :                                 }
    1149           0 :                                 return;
    1150             :                         }
    1151             :                 }
    1152             : 
    1153             :                 /* FALLTHROUGH, err == 0 (no data phase or successful) */
    1154             :         case TSTATE_BBB_DCLEAR: /* stall clear after data phase */
    1155           0 :                 if (sc->transfer_dir == DIR_IN)
    1156           0 :                         memcpy(sc->transfer_data, sc->data_buffer,
    1157             :                                sc->transfer_actlen);
    1158             : 
    1159             :                 DIF(UDMASS_BBB, if (sc->transfer_dir == DIR_IN)
    1160             :                                         umass_dump_buffer(sc, sc->transfer_data,
    1161             :                                                 sc->transfer_datalen, 48));
    1162             : 
    1163             :                 /* FALLTHROUGH, err == 0 (no data phase or successful) */
    1164             :         case TSTATE_BBB_SCLEAR: /* stall clear after status phase */
    1165             :                 /* Reading of CSW after bulk stall condition in data phase
    1166             :                  * (TSTATE_BBB_DATA2) or bulk-in stall condition after
    1167             :                  * reading CSW (TSTATE_BBB_SCLEAR).
    1168             :                  * In the case of no data phase or successful data phase,
    1169             :                  * err == 0 and the following if block is passed.
    1170             :                  */
    1171           0 :                 if (err) {      /* should not occur */
    1172             :                         DPRINTF(UDMASS_BBB, ("%s: BBB bulk-%s stall clear"
    1173             :                             " failed, %s\n", sc->sc_dev.dv_xname,
    1174             :                             (sc->transfer_dir == DIR_IN? "in":"out"),
    1175             :                             usbd_errstr(err)));
    1176           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1177           0 :                         return;
    1178             :                 }
    1179             : 
    1180             :                 /* Status transport phase, setup transfer */
    1181           0 :                 if (sc->transfer_state == TSTATE_BBB_COMMAND ||
    1182           0 :                     sc->transfer_state == TSTATE_BBB_DATA ||
    1183           0 :                     sc->transfer_state == TSTATE_BBB_DCLEAR) {
    1184             :                         /* After no data phase, successful data phase and
    1185             :                          * after clearing bulk-in/-out stall condition
    1186             :                          */
    1187           0 :                         sc->transfer_state = TSTATE_BBB_STATUS1;
    1188           0 :                         next_xfer = sc->transfer_xfer[XFER_BBB_CSW1];
    1189           0 :                 } else {
    1190             :                         /* After first attempt of fetching CSW */
    1191           0 :                         sc->transfer_state = TSTATE_BBB_STATUS2;
    1192           0 :                         next_xfer = sc->transfer_xfer[XFER_BBB_CSW2];
    1193             :                 }
    1194             : 
    1195             :                 /* Read the Command Status Wrapper via bulk-in endpoint. */
    1196           0 :                 if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
    1197           0 :                         &sc->csw, UMASS_BBB_CSW_SIZE, 0, next_xfer)) {
    1198           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1199           0 :                         return;
    1200             :                 }
    1201             : 
    1202           0 :                 return;
    1203             :         case TSTATE_BBB_STATUS1:        /* first attempt */
    1204             :         case TSTATE_BBB_STATUS2:        /* second attempt */
    1205             :                 /* Status transfer, error handling */
    1206           0 :                 if (err) {
    1207             :                         DPRINTF(UDMASS_BBB, ("%s: Failed to read CSW, %s%s\n",
    1208             :                                 sc->sc_dev.dv_xname, usbd_errstr(err),
    1209             :                                 (sc->transfer_state == TSTATE_BBB_STATUS1?
    1210             :                                         ", retrying":"")));
    1211             : 
    1212             :                         /* If this was the first attempt at fetching the CSW
    1213             :                          * retry it, otherwise fail.
    1214             :                          */
    1215           0 :                         if (sc->transfer_state == TSTATE_BBB_STATUS1) {
    1216           0 :                                 sc->transfer_state = TSTATE_BBB_SCLEAR;
    1217           0 :                                 umass_clear_endpoint_stall(sc, UMASS_BULKIN,
    1218           0 :                                     sc->transfer_xfer[XFER_BBB_SCLEAR]);
    1219           0 :                                 return;
    1220             :                         } else {
    1221           0 :                                 umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1222           0 :                                 return;
    1223             :                         }
    1224             :                 }
    1225             : 
    1226             :                 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
    1227             : 
    1228             :                 /* Translate weird command-status signatures. */
    1229           0 :                 if ((sc->sc_quirks & UMASS_QUIRK_WRONG_CSWSIG) &&
    1230           0 :                     UGETDW(sc->csw.dCSWSignature) == CSWSIGNATURE_OLYMPUS_C1)
    1231           0 :                         USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
    1232             : 
    1233             :                 /* Translate invalid command-status tags */
    1234           0 :                 if (sc->sc_quirks & UMASS_QUIRK_WRONG_CSWTAG)
    1235           0 :                         USETDW(sc->csw.dCSWTag, UGETDW(sc->cbw.dCBWTag));
    1236             : 
    1237             :                 /* Check CSW and handle any error */
    1238           0 :                 if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
    1239             :                         /* Invalid CSW: Wrong signature or wrong tag might
    1240             :                          * indicate that the device is confused -> reset it.
    1241             :                          */
    1242           0 :                         printf("%s: Invalid CSW: sig 0x%08x should be 0x%08x\n",
    1243           0 :                                 sc->sc_dev.dv_xname,
    1244             :                                 UGETDW(sc->csw.dCSWSignature),
    1245             :                                 CSWSIGNATURE);
    1246             : 
    1247           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1248           0 :                         return;
    1249           0 :                 } else if (UGETDW(sc->csw.dCSWTag)
    1250           0 :                                 != UGETDW(sc->cbw.dCBWTag)) {
    1251           0 :                         printf("%s: Invalid CSW: tag %d should be %d\n",
    1252           0 :                                 sc->sc_dev.dv_xname,
    1253             :                                 UGETDW(sc->csw.dCSWTag),
    1254             :                                 UGETDW(sc->cbw.dCBWTag));
    1255             : 
    1256           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1257           0 :                         return;
    1258             : 
    1259             :                 /* CSW is valid here */
    1260           0 :                 } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
    1261           0 :                         printf("%s: Invalid CSW: status %d > %d\n",
    1262           0 :                                 sc->sc_dev.dv_xname,
    1263             :                                 sc->csw.bCSWStatus,
    1264             :                                 CSWSTATUS_PHASE);
    1265             : 
    1266           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1267           0 :                         return;
    1268           0 :                 } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
    1269           0 :                         printf("%s: Phase Error, residue = %d\n",
    1270           0 :                                 sc->sc_dev.dv_xname,
    1271           0 :                                 UGETDW(sc->csw.dCSWDataResidue));
    1272             : 
    1273           0 :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1274           0 :                         return;
    1275             : 
    1276           0 :                 } else if (sc->transfer_actlen > sc->transfer_datalen) {
    1277             :                         /* Buffer overrun! Don't let this go by unnoticed */
    1278           0 :                         panic("%s: transferred %d bytes instead of %d bytes",
    1279           0 :                                 sc->sc_dev.dv_xname,
    1280             :                                 sc->transfer_actlen, sc->transfer_datalen);
    1281             : #if 0
    1282             :                 } else if (sc->transfer_datalen - sc->transfer_actlen
    1283             :                            != UGETDW(sc->csw.dCSWDataResidue)) {
    1284             :                         DPRINTF(UDMASS_BBB, ("%s: actlen=%d != residue=%d\n",
    1285             :                                 sc->sc_dev.dv_xname,
    1286             :                                 sc->transfer_datalen - sc->transfer_actlen,
    1287             :                                 UGETDW(sc->csw.dCSWDataResidue)));
    1288             : 
    1289             :                         umass_bbb_reset(sc, STATUS_WIRE_FAILED);
    1290             :                         return;
    1291             : #endif
    1292           0 :                 } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
    1293             :                         DPRINTF(UDMASS_BBB, ("%s: Command Failed, res = %d\n",
    1294             :                                 sc->sc_dev.dv_xname,
    1295             :                                 UGETDW(sc->csw.dCSWDataResidue)));
    1296             : 
    1297             :                         /* SCSI command failed but transfer was successful */
    1298             :                         sc->transfer_state = TSTATE_IDLE;
    1299           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1300             :                                         UGETDW(sc->csw.dCSWDataResidue),
    1301             :                                         STATUS_CMD_FAILED);
    1302             : 
    1303           0 :                         return;
    1304             : 
    1305             :                 } else {        /* success */
    1306             :                         sc->transfer_state = TSTATE_IDLE;
    1307           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1308             :                                         UGETDW(sc->csw.dCSWDataResidue),
    1309             :                                         STATUS_CMD_OK);
    1310             : 
    1311           0 :                         return;
    1312             :                 }
    1313             : 
    1314             :         /***** Bulk Reset *****/
    1315             :         case TSTATE_BBB_RESET1:
    1316             :                 if (err)
    1317             :                         DPRINTF(UDMASS_BBB, ("%s: BBB reset failed, %s\n",
    1318             :                                 sc->sc_dev.dv_xname, usbd_errstr(err)));
    1319             : 
    1320           0 :                 sc->transfer_state = TSTATE_BBB_RESET2;
    1321           0 :                 umass_clear_endpoint_stall(sc, UMASS_BULKIN,
    1322           0 :                         sc->transfer_xfer[XFER_BBB_RESET2]);
    1323             : 
    1324           0 :                 return;
    1325             :         case TSTATE_BBB_RESET2:
    1326             :                 if (err)        /* should not occur */
    1327             :                         DPRINTF(UDMASS_BBB, ("%s: BBB bulk-in clear stall"
    1328             :                                 " failed, %s\n", sc->sc_dev.dv_xname,
    1329             :                                 usbd_errstr(err)));
    1330             :                         /* no error recovery, otherwise we end up in a loop */
    1331             : 
    1332           0 :                 sc->transfer_state = TSTATE_BBB_RESET3;
    1333           0 :                 umass_clear_endpoint_stall(sc, UMASS_BULKOUT,
    1334           0 :                         sc->transfer_xfer[XFER_BBB_RESET3]);
    1335             : 
    1336           0 :                 return;
    1337             :         case TSTATE_BBB_RESET3:
    1338             :                 if (err)        /* should not occur */
    1339             :                         DPRINTF(UDMASS_BBB,("%s: BBB bulk-out clear stall"
    1340             :                                 " failed, %s\n", sc->sc_dev.dv_xname,
    1341             :                                 usbd_errstr(err)));
    1342             :                         /* no error recovery, otherwise we end up in a loop */
    1343             : 
    1344           0 :                 sc->transfer_state = TSTATE_IDLE;
    1345           0 :                 if (sc->transfer_priv) {
    1346           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1347           0 :                                         sc->transfer_datalen,
    1348           0 :                                         sc->transfer_status);
    1349           0 :                 }
    1350             : 
    1351           0 :                 return;
    1352             : 
    1353             :         /***** Default *****/
    1354             :         default:
    1355           0 :                 panic("%s: Unknown state %d",
    1356           0 :                       sc->sc_dev.dv_xname, sc->transfer_state);
    1357             :         }
    1358           0 : }
    1359             : 
    1360             : /*
    1361             :  * Command/Bulk/Interrupt (CBI) specific functions
    1362             :  */
    1363             : 
    1364             : int
    1365           0 : umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen,
    1366             :     struct usbd_xfer *xfer)
    1367             : {
    1368             :         KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
    1369             :                 ("sc->sc_wire == 0x%02x wrong for umass_cbi_adsc\n",
    1370             :                 sc->sc_wire));
    1371             : 
    1372           0 :         sc->sc_req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
    1373           0 :         sc->sc_req.bRequest = UR_CBI_ADSC;
    1374           0 :         USETW(sc->sc_req.wValue, 0);
    1375           0 :         USETW(sc->sc_req.wIndex, sc->sc_ifaceno);
    1376           0 :         USETW(sc->sc_req.wLength, buflen);
    1377           0 :         return umass_setup_ctrl_transfer(sc, &sc->sc_req, buffer,
    1378             :                                          buflen, 0, xfer);
    1379             : }
    1380             : 
    1381             : 
    1382             : void
    1383           0 : umass_cbi_reset(struct umass_softc *sc, int status)
    1384             : {
    1385             :         int i;
    1386             : #       define SEND_DIAGNOSTIC_CMDLEN   12
    1387             : 
    1388             :         KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
    1389             :                 ("sc->sc_wire == 0x%02x wrong for umass_cbi_reset\n",
    1390             :                 sc->sc_wire));
    1391             : 
    1392           0 :         if (usbd_is_dying(sc->sc_udev))
    1393           0 :                 return;
    1394             : 
    1395             :         /*
    1396             :          * Command Block Reset Protocol
    1397             :          *
    1398             :          * First send a reset request to the device. Then clear
    1399             :          * any possibly stalled bulk endpoints.
    1400             : 
    1401             :          * This is done in 3 steps, states:
    1402             :          * TSTATE_CBI_RESET1
    1403             :          * TSTATE_CBI_RESET2
    1404             :          * TSTATE_CBI_RESET3
    1405             :          *
    1406             :          * If the reset doesn't succeed, the device should be port reset.
    1407             :          */
    1408             : 
    1409             :         DPRINTF(UDMASS_CBI, ("%s: CBI Reset\n",
    1410             :                 sc->sc_dev.dv_xname));
    1411             : 
    1412             :         KASSERT(sizeof(sc->cbl) >= SEND_DIAGNOSTIC_CMDLEN,
    1413             :                 ("%s: CBL struct is too small (%d < %d)\n",
    1414             :                         sc->sc_dev.dv_xname,
    1415             :                         sizeof(sc->cbl), SEND_DIAGNOSTIC_CMDLEN));
    1416             : 
    1417           0 :         sc->transfer_state = TSTATE_CBI_RESET1;
    1418           0 :         sc->transfer_status = status;
    1419             : 
    1420             :         /* The 0x1d code is the SEND DIAGNOSTIC command. To distinguish between
    1421             :          * the two the last 10 bytes of the cbl is filled with 0xff (section
    1422             :          * 2.2 of the CBI spec).
    1423             :          */
    1424           0 :         sc->cbl[0] = 0x1d;   /* Command Block Reset */
    1425           0 :         sc->cbl[1] = 0x04;
    1426           0 :         for (i = 2; i < SEND_DIAGNOSTIC_CMDLEN; i++)
    1427           0 :                 sc->cbl[i] = 0xff;
    1428             : 
    1429           0 :         umass_cbi_adsc(sc, sc->cbl, SEND_DIAGNOSTIC_CMDLEN,
    1430           0 :                        sc->transfer_xfer[XFER_CBI_RESET1]);
    1431             :         /* XXX if the command fails we should reset the port on the bub */
    1432           0 : }
    1433             : 
    1434             : void
    1435           0 : umass_cbi_transfer(struct umass_softc *sc, int lun,
    1436             :                    void *cmd, int cmdlen, void *data, int datalen, int dir,
    1437             :                    u_int timeout, umass_callback cb, void *priv)
    1438             : {
    1439             :         usbd_status err;
    1440             : 
    1441             :         DPRINTF(UDMASS_CBI,("%s: umass_cbi_transfer cmd=0x%02x, len=%d\n",
    1442             :                 sc->sc_dev.dv_xname, *(u_char *)cmd, datalen));
    1443             : 
    1444             :         KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
    1445             :                 ("sc->sc_wire == 0x%02x wrong for umass_cbi_transfer\n",
    1446             :                 sc->sc_wire));
    1447             : 
    1448           0 :         if (usbd_is_dying(sc->sc_udev)) {
    1449           0 :                 sc->polled_xfer_status = USBD_IOERROR;
    1450           0 :                 return;
    1451             :         }
    1452             : 
    1453             :         /* Be a little generous. */
    1454           0 :         sc->timeout = timeout + USBD_DEFAULT_TIMEOUT;
    1455             : 
    1456             :         /*
    1457             :          * Do a CBI transfer with cmdlen bytes from cmd, possibly
    1458             :          * a data phase of datalen bytes from/to the device and finally a
    1459             :          * csw read phase.
    1460             :          * If the data direction was inbound a maximum of datalen bytes
    1461             :          * is stored in the buffer pointed to by data.
    1462             :          *
    1463             :          * umass_cbi_transfer initialises the transfer and lets the state
    1464             :          * machine in umass_cbi_state handle the completion. It uses the
    1465             :          * following states:
    1466             :          * TSTATE_CBI_COMMAND
    1467             :          *   -> XXX fill in
    1468             :          *
    1469             :          * An error in any of those states will invoke
    1470             :          * umass_cbi_reset.
    1471             :          */
    1472             : 
    1473             :         /* check the given arguments */
    1474             :         KASSERT(datalen == 0 || data != NULL,
    1475             :                 ("%s: datalen > 0, but no buffer",sc->sc_dev.dv_xname));
    1476             :         KASSERT(datalen == 0 || dir != DIR_NONE,
    1477             :                 ("%s: direction is NONE while datalen is not zero\n",
    1478             :                         sc->sc_dev.dv_xname));
    1479             : 
    1480             :         /* store the details for the data transfer phase */
    1481           0 :         sc->transfer_dir = dir;
    1482           0 :         sc->transfer_data = data;
    1483           0 :         sc->transfer_datalen = datalen;
    1484           0 :         sc->transfer_actlen = 0;
    1485           0 :         sc->transfer_cb = cb;
    1486           0 :         sc->transfer_priv = priv;
    1487           0 :         sc->transfer_status = STATUS_CMD_OK;
    1488             : 
    1489             :         /* move from idle to the command state */
    1490           0 :         sc->transfer_state = TSTATE_CBI_COMMAND;
    1491             : 
    1492             :         /* Send the Command Block from host to device via control endpoint. */
    1493           0 :         sc->cbw.bCDBLength = cmdlen;
    1494           0 :         bzero(sc->cbw.CBWCDB, sizeof(sc->cbw.CBWCDB));
    1495           0 :         memcpy(sc->cbw.CBWCDB, cmd, cmdlen);
    1496           0 :         umass_adjust_transfer(sc);
    1497           0 :         if ((err = umass_cbi_adsc(sc, (void *)sc->cbw.CBWCDB, sc->cbw.bCDBLength,
    1498           0 :             sc->transfer_xfer[XFER_CBI_CB])))
    1499           0 :                 umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1500             : 
    1501           0 :         if (sc->sc_udev->bus->use_polling)
    1502           0 :                 sc->polled_xfer_status = err;
    1503           0 : }
    1504             : 
    1505             : void
    1506           0 : umass_cbi_state(struct usbd_xfer *xfer, void *priv,  usbd_status err)
    1507             : {
    1508           0 :         struct umass_softc *sc = (struct umass_softc *) priv;
    1509             : 
    1510             :         KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
    1511             :                 ("sc->sc_wire == 0x%02x wrong for umass_cbi_state\n",
    1512             :                 sc->sc_wire));
    1513             : 
    1514           0 :         if (usbd_is_dying(sc->sc_udev))
    1515           0 :                 return;
    1516             : 
    1517             :         /*
    1518             :          * State handling for CBI transfers.
    1519             :          */
    1520             : 
    1521             :         DPRINTF(UDMASS_CBI, ("%s: Handling CBI state %d (%s), xfer=%p, %s\n",
    1522             :                 sc->sc_dev.dv_xname, sc->transfer_state,
    1523             :                 states[sc->transfer_state], xfer, usbd_errstr(err)));
    1524             : 
    1525           0 :         switch (sc->transfer_state) {
    1526             : 
    1527             :         /***** CBI Transfer *****/
    1528             :         case TSTATE_CBI_COMMAND:
    1529           0 :                 if (err == USBD_STALLED) {
    1530             :                         DPRINTF(UDMASS_CBI, ("%s: Command Transport failed\n",
    1531             :                                 sc->sc_dev.dv_xname));
    1532             :                         /* Status transport by control pipe (section 2.3.2.1).
    1533             :                          * The command contained in the command block failed.
    1534             :                          *
    1535             :                          * The control pipe has already been unstalled by the
    1536             :                          * USB stack.
    1537             :                          * Section 2.4.3.1.1 states that the bulk in endpoints
    1538             :                          * should not stalled at this point.
    1539             :                          */
    1540             : 
    1541           0 :                         sc->transfer_state = TSTATE_IDLE;
    1542           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1543           0 :                                         sc->transfer_datalen,
    1544             :                                         STATUS_CMD_FAILED);
    1545             : 
    1546           0 :                         return;
    1547           0 :                 } else if (err) {
    1548             :                         DPRINTF(UDMASS_CBI, ("%s: failed to send ADSC\n",
    1549             :                                 sc->sc_dev.dv_xname));
    1550           0 :                         umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1551           0 :                         return;
    1552             :                 }
    1553             : 
    1554             :                 /* Data transport phase, setup transfer */
    1555           0 :                 sc->transfer_state = TSTATE_CBI_DATA;
    1556           0 :                 if (sc->transfer_dir == DIR_IN) {
    1557           0 :                         if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
    1558           0 :                                         sc->data_buffer, sc->transfer_datalen,
    1559             :                                         USBD_SHORT_XFER_OK | USBD_NO_COPY,
    1560           0 :                                         sc->transfer_xfer[XFER_CBI_DATA]))
    1561           0 :                                 umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1562             : 
    1563           0 :                         return;
    1564           0 :                 } else if (sc->transfer_dir == DIR_OUT) {
    1565           0 :                         memcpy(sc->data_buffer, sc->transfer_data,
    1566             :                                sc->transfer_datalen);
    1567           0 :                         if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
    1568           0 :                                         sc->data_buffer, sc->transfer_datalen,
    1569             :                                         USBD_NO_COPY,/* fixed length transfer */
    1570           0 :                                         sc->transfer_xfer[XFER_CBI_DATA]))
    1571           0 :                                 umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1572             : 
    1573           0 :                         return;
    1574             :                 } else {
    1575             :                         DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
    1576             :                                 sc->sc_dev.dv_xname));
    1577             :                 }
    1578             : 
    1579             :                 /* FALLTHROUGH if no data phase, err == 0 */
    1580             :         case TSTATE_CBI_DATA:
    1581             :                 /* Command transport phase error handling (ignored if no data
    1582             :                  * phase (fallthrough from previous state)) */
    1583           0 :                 if (sc->transfer_dir != DIR_NONE) {
    1584             :                         /* retrieve the length of the transfer that was done */
    1585           0 :                         usbd_get_xfer_status(xfer, NULL, NULL,
    1586           0 :                             &sc->transfer_actlen, NULL);
    1587             :                         DPRINTF(UDMASS_CBI, ("%s: CBI_DATA actlen=%d\n",
    1588             :                                 sc->sc_dev.dv_xname, sc->transfer_actlen));
    1589             : 
    1590           0 :                         if (err) {
    1591             :                                 DPRINTF(UDMASS_CBI, ("%s: Data-%s %d failed, "
    1592             :                                         "%s\n", sc->sc_dev.dv_xname,
    1593             :                                         (sc->transfer_dir == DIR_IN?"in":"out"),
    1594             :                                         sc->transfer_datalen,usbd_errstr(err)));
    1595             : 
    1596           0 :                                 if (err == USBD_STALLED) {
    1597           0 :                                         sc->transfer_state = TSTATE_CBI_DCLEAR;
    1598           0 :                                         umass_clear_endpoint_stall(sc,
    1599           0 :                                           (sc->transfer_dir == DIR_IN?
    1600             :                                             UMASS_BULKIN:UMASS_BULKOUT),
    1601           0 :                                         sc->transfer_xfer[XFER_CBI_DCLEAR]);
    1602           0 :                                 } else {
    1603             :                                         /* Unless the error is a pipe stall the
    1604             :                                          * error is fatal.
    1605             :                                          */
    1606           0 :                                         umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1607             :                                 }
    1608           0 :                                 return;
    1609             :                         }
    1610             :                 }
    1611             : 
    1612           0 :                 if (sc->transfer_dir == DIR_IN)
    1613           0 :                         memcpy(sc->transfer_data, sc->data_buffer,
    1614             :                                sc->transfer_actlen);
    1615             : 
    1616             :                 DIF(UDMASS_CBI, if (sc->transfer_dir == DIR_IN)
    1617             :                                         umass_dump_buffer(sc, sc->transfer_data,
    1618             :                                                 sc->transfer_actlen, 48));
    1619             : 
    1620             :                 /* Status phase */
    1621           0 :                 if (sc->sc_wire == UMASS_WPROTO_CBI_I) {
    1622           0 :                         sc->transfer_state = TSTATE_CBI_STATUS;
    1623           0 :                         memset(&sc->sbl, 0, sizeof(sc->sbl));
    1624           0 :                         if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_INTRIN],
    1625             :                                     &sc->sbl, sizeof(sc->sbl),
    1626             :                                     0,  /* fixed length transfer */
    1627           0 :                                     sc->transfer_xfer[XFER_CBI_STATUS]))
    1628           0 :                                 umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1629             :                 } else {
    1630             :                         /* No command completion interrupt. Request
    1631             :                          * sense to get status of command.
    1632             :                          */
    1633           0 :                         sc->transfer_state = TSTATE_IDLE;
    1634           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1635           0 :                                 sc->transfer_datalen - sc->transfer_actlen,
    1636             :                                 STATUS_CMD_UNKNOWN);
    1637             :                 }
    1638           0 :                 return;
    1639             : 
    1640             :         case TSTATE_CBI_STATUS:
    1641           0 :                 if (err) {
    1642             :                         DPRINTF(UDMASS_CBI, ("%s: Status Transport failed\n",
    1643             :                                 sc->sc_dev.dv_xname));
    1644             :                         /* Status transport by interrupt pipe (section 2.3.2.2).
    1645             :                          */
    1646             : 
    1647           0 :                         if (err == USBD_STALLED) {
    1648           0 :                                 sc->transfer_state = TSTATE_CBI_SCLEAR;
    1649           0 :                                 umass_clear_endpoint_stall(sc, UMASS_INTRIN,
    1650           0 :                                         sc->transfer_xfer[XFER_CBI_SCLEAR]);
    1651           0 :                         } else {
    1652           0 :                                 umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1653             :                         }
    1654           0 :                         return;
    1655             :                 }
    1656             : 
    1657             :                 /* Dissect the information in the buffer */
    1658             : 
    1659             :                 {
    1660           0 :                         u_int32_t actlen;
    1661           0 :                         usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
    1662             :                         DPRINTF(UDMASS_CBI, ("%s: CBI_STATUS actlen=%d\n",
    1663             :                             sc->sc_dev.dv_xname, actlen));
    1664           0 :                         if (actlen != 2)
    1665           0 :                                 break;
    1666           0 :                 }
    1667             : 
    1668           0 :                 if (sc->sc_cmd == UMASS_CPROTO_UFI) {
    1669             :                         int status;
    1670             : 
    1671             :                         /* Section 3.4.3.1.3 specifies that the UFI command
    1672             :                          * protocol returns an ASC and ASCQ in the interrupt
    1673             :                          * data block.
    1674             :                          */
    1675             : 
    1676             :                         DPRINTF(UDMASS_CBI, ("%s: UFI CCI, ASC = 0x%02x, "
    1677             :                                 "ASCQ = 0x%02x\n",
    1678             :                                 sc->sc_dev.dv_xname,
    1679             :                                 sc->sbl.ufi.asc, sc->sbl.ufi.ascq));
    1680             : 
    1681           0 :                         if ((sc->sbl.ufi.asc == 0 && sc->sbl.ufi.ascq == 0) ||
    1682           0 :                             sc->sc_sense)
    1683           0 :                                 status = STATUS_CMD_OK;
    1684             :                         else
    1685             :                                 status = STATUS_CMD_FAILED;
    1686             : 
    1687             :                         /* No autosense, command successful */
    1688           0 :                         sc->transfer_state = TSTATE_IDLE;
    1689           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1690           0 :                             sc->transfer_datalen - sc->transfer_actlen, status);
    1691           0 :                 } else {
    1692             :                         /* Command Interrupt Data Block */
    1693             : 
    1694             :                         DPRINTF(UDMASS_CBI, ("%s: type=0x%02x, value=0x%02x\n",
    1695             :                                 sc->sc_dev.dv_xname,
    1696             :                                 sc->sbl.common.type, sc->sbl.common.value));
    1697             : 
    1698           0 :                         if (sc->sbl.common.type == IDB_TYPE_CCI) {
    1699             :                                 int status;
    1700           0 :                                 switch (sc->sbl.common.value &
    1701             :                                     IDB_VALUE_STATUS_MASK) {
    1702             :                                 case IDB_VALUE_PASS:
    1703             :                                         status = STATUS_CMD_OK;
    1704           0 :                                         break;
    1705             :                                 case IDB_VALUE_FAIL:
    1706             :                                 case IDB_VALUE_PERSISTENT:
    1707             :                                         status = STATUS_CMD_FAILED;
    1708           0 :                                         break;
    1709             :                                 case IDB_VALUE_PHASE:
    1710             :                                 default:
    1711             :                                         status = STATUS_WIRE_FAILED;
    1712           0 :                                         break;
    1713             :                                 }
    1714             : 
    1715           0 :                                 sc->transfer_state = TSTATE_IDLE;
    1716           0 :                                 sc->transfer_cb(sc, sc->transfer_priv,
    1717           0 :                                     sc->transfer_datalen - sc->transfer_actlen,
    1718             :                                     status);
    1719           0 :                         }
    1720             :                 }
    1721           0 :                 return;
    1722             : 
    1723             :         case TSTATE_CBI_DCLEAR:
    1724           0 :                 if (err) {      /* should not occur */
    1725           0 :                         printf("%s: CBI bulk-in/out stall clear failed, %s\n",
    1726           0 :                                sc->sc_dev.dv_xname, usbd_errstr(err));
    1727           0 :                         umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1728           0 :                 } else {
    1729           0 :                         sc->transfer_state = TSTATE_IDLE;
    1730           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1731           0 :                             sc->transfer_datalen, STATUS_CMD_FAILED);
    1732             :                 }
    1733           0 :                 return;
    1734             : 
    1735             :         case TSTATE_CBI_SCLEAR:
    1736           0 :                 if (err) {      /* should not occur */
    1737           0 :                         printf("%s: CBI intr-in stall clear failed, %s\n",
    1738           0 :                                sc->sc_dev.dv_xname, usbd_errstr(err));
    1739           0 :                         umass_cbi_reset(sc, STATUS_WIRE_FAILED);
    1740           0 :                 } else {
    1741           0 :                         sc->transfer_state = TSTATE_IDLE;
    1742           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1743           0 :                             sc->transfer_datalen, STATUS_CMD_FAILED);
    1744             :                 }
    1745           0 :                 return;
    1746             : 
    1747             :         /***** CBI Reset *****/
    1748             :         case TSTATE_CBI_RESET1:
    1749           0 :                 if (err)
    1750           0 :                         printf("%s: CBI reset failed, %s\n",
    1751           0 :                                 sc->sc_dev.dv_xname, usbd_errstr(err));
    1752             : 
    1753           0 :                 sc->transfer_state = TSTATE_CBI_RESET2;
    1754           0 :                 umass_clear_endpoint_stall(sc, UMASS_BULKIN,
    1755           0 :                         sc->transfer_xfer[XFER_CBI_RESET2]);
    1756             : 
    1757           0 :                 return;
    1758             :         case TSTATE_CBI_RESET2:
    1759           0 :                 if (err)        /* should not occur */
    1760           0 :                         printf("%s: CBI bulk-in stall clear failed, %s\n",
    1761           0 :                                sc->sc_dev.dv_xname, usbd_errstr(err));
    1762             :                         /* no error recovery, otherwise we end up in a loop */
    1763             : 
    1764           0 :                 sc->transfer_state = TSTATE_CBI_RESET3;
    1765           0 :                 umass_clear_endpoint_stall(sc, UMASS_BULKOUT,
    1766           0 :                         sc->transfer_xfer[XFER_CBI_RESET3]);
    1767             : 
    1768           0 :                 return;
    1769             :         case TSTATE_CBI_RESET3:
    1770           0 :                 if (err)        /* should not occur */
    1771           0 :                         printf("%s: CBI bulk-out stall clear failed, %s\n",
    1772           0 :                                sc->sc_dev.dv_xname, usbd_errstr(err));
    1773             :                         /* no error recovery, otherwise we end up in a loop */
    1774             : 
    1775           0 :                 sc->transfer_state = TSTATE_IDLE;
    1776           0 :                 if (sc->transfer_priv) {
    1777           0 :                         sc->transfer_cb(sc, sc->transfer_priv,
    1778           0 :                                         sc->transfer_datalen,
    1779           0 :                                         sc->transfer_status);
    1780           0 :                 }
    1781             : 
    1782           0 :                 return;
    1783             : 
    1784             : 
    1785             :         /***** Default *****/
    1786             :         default:
    1787           0 :                 panic("%s: Unknown state %d",
    1788           0 :                       sc->sc_dev.dv_xname, sc->transfer_state);
    1789             :         }
    1790           0 : }
    1791             : 
    1792             : u_int8_t
    1793           0 : umass_bbb_get_max_lun(struct umass_softc *sc)
    1794             : {
    1795           0 :         usb_device_request_t req;
    1796             :         usbd_status err;
    1797             :         u_int8_t maxlun = 0;
    1798           0 :         u_int8_t buf = 0;
    1799             : 
    1800             :         DPRINTF(UDMASS_BBB, ("%s: Get Max Lun\n", sc->sc_dev.dv_xname));
    1801             : 
    1802             :         /* The Get Max Lun command is a class-specific request. */
    1803           0 :         req.bmRequestType = UT_READ_CLASS_INTERFACE;
    1804           0 :         req.bRequest = UR_BBB_GET_MAX_LUN;
    1805           0 :         USETW(req.wValue, 0);
    1806           0 :         USETW(req.wIndex, sc->sc_ifaceno);
    1807           0 :         USETW(req.wLength, 1);
    1808             : 
    1809           0 :         err = usbd_do_request_flags(sc->sc_udev, &req, &buf,
    1810             :             USBD_SHORT_XFER_OK, 0, USBD_DEFAULT_TIMEOUT);
    1811             : 
    1812           0 :         switch (err) {
    1813             :         case USBD_NORMAL_COMPLETION:
    1814           0 :                 maxlun = buf;
    1815           0 :                 break;
    1816             : 
    1817             :         default:
    1818             :                 /* XXX Should we port_reset the device? */
    1819             :                 DPRINTF(UDMASS_BBB, ("%s: Get Max Lun not supported (%s)\n",
    1820             :                     sc->sc_dev.dv_xname, usbd_errstr(err)));
    1821             :                 break;
    1822             :         }
    1823             : 
    1824             :         DPRINTF(UDMASS_BBB, ("%s: Max Lun %d\n", sc->sc_dev.dv_xname, maxlun));
    1825           0 :         return (maxlun);
    1826           0 : }
    1827             : 
    1828             : #ifdef UMASS_DEBUG
    1829             : void
    1830             : umass_bbb_dump_cbw(struct umass_softc *sc, struct umass_bbb_cbw *cbw)
    1831             : {
    1832             :         int clen = cbw->bCDBLength;
    1833             :         int dlen = UGETDW(cbw->dCBWDataTransferLength);
    1834             :         u_int8_t *c = cbw->CBWCDB;
    1835             :         int tag = UGETDW(cbw->dCBWTag);
    1836             :         int flags = cbw->bCBWFlags;
    1837             : 
    1838             :         DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmdlen=%d "
    1839             :                 "(0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%s), "
    1840             :                 "data = %d bytes, dir = %s\n",
    1841             :                 sc->sc_dev.dv_xname, tag, clen,
    1842             :                 c[0], c[1], c[2], c[3], c[4], c[5],
    1843             :                 c[6], c[7], c[8], c[9],
    1844             :                 (clen > 10? "...":""),
    1845             :                 dlen, (flags == CBWFLAGS_IN? "in":
    1846             :                        (flags == CBWFLAGS_OUT? "out":"<invalid>"))));
    1847             : }
    1848             : 
    1849             : void
    1850             : umass_bbb_dump_csw(struct umass_softc *sc, struct umass_bbb_csw *csw)
    1851             : {
    1852             :         int sig = UGETDW(csw->dCSWSignature);
    1853             :         int tag = UGETDW(csw->dCSWTag);
    1854             :         int res = UGETDW(csw->dCSWDataResidue);
    1855             :         int status = csw->bCSWStatus;
    1856             : 
    1857             :         DPRINTF(UDMASS_BBB, ("%s: CSW %d: sig = 0x%08x (%s), tag = %d, "
    1858             :                 "res = %d, status = 0x%02x (%s)\n", sc->sc_dev.dv_xname,
    1859             :                 tag, sig, (sig == CSWSIGNATURE?  "valid":"invalid"),
    1860             :                 tag, res,
    1861             :                 status, (status == CSWSTATUS_GOOD? "good":
    1862             :                          (status == CSWSTATUS_FAILED? "failed":
    1863             :                           (status == CSWSTATUS_PHASE? "phase":"<invalid>")))));
    1864             : }
    1865             : 
    1866             : void
    1867             : umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen,
    1868             :                   int printlen)
    1869             : {
    1870             :         int i, j;
    1871             :         char s1[40];
    1872             :         char s2[40];
    1873             :         char s3[5];
    1874             : 
    1875             :         s1[0] = '\0';
    1876             :         s3[0] = '\0';
    1877             : 
    1878             :         snprintf(s2, sizeof s2, " buffer=%p, buflen=%d", buffer, buflen);
    1879             :         for (i = 0; i < buflen && i < printlen; i++) {
    1880             :                 j = i % 16;
    1881             :                 if (j == 0 && i != 0) {
    1882             :                         DPRINTF(UDMASS_GEN, ("%s: 0x %s%s\n",
    1883             :                                 sc->sc_dev.dv_xname, s1, s2));
    1884             :                         s2[0] = '\0';
    1885             :                 }
    1886             :                 snprintf(&s1[j*2], sizeof s1 - j*2, "%02x", buffer[i] & 0xff);
    1887             :         }
    1888             :         if (buflen > printlen)
    1889             :                 snprintf(s3, sizeof s3, " ...");
    1890             :         DPRINTF(UDMASS_GEN, ("%s: 0x %s%s%s\n",
    1891             :                 sc->sc_dev.dv_xname, s1, s2, s3));
    1892             : }
    1893             : #endif

Generated by: LCOV version 1.13