1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 
  27 /*
  28  * scsa2usb bridge nexus driver:
  29  *
  30  * This driver supports the following wire transports:
  31  * a. Bulk Only transport (see usb_ms_bulkonly.c)
  32  * b. CB transport (see usb_ms_cbi.c)
  33  * c. CBI transport with interrupt status completion (see usb_ms_cbi.c)
  34  *
  35  * It handles the following command sets:
  36  * a. SCSI
  37  * b. ATAPI command set (subset of SCSI command set)
  38  * c. UFI command set (
  39  *      http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf)
  40  *
  41  * For details on USB Mass Storage Class overview:
  42  *      http://www.usb.org/developers/devclass_docs/usbmassover_11.pdf
  43  */
  44 #if defined(lint) && !defined(DEBUG)
  45 #define DEBUG   1
  46 #endif
  47 
  48 #include <sys/usb/usba/usbai_version.h>
  49 #include <sys/scsi/scsi.h>
  50 #include <sys/cdio.h>
  51 #include <sys/sunndi.h>
  52 #include <sys/esunddi.h>
  53 #include <sys/callb.h>
  54 #include <sys/kobj.h>
  55 #include <sys/kobj_lex.h>
  56 #include <sys/strsubr.h>
  57 #include <sys/strsun.h>
  58 #include <sys/sysmacros.h>
  59 
  60 #include <sys/usb/usba.h>
  61 #include <sys/usb/clients/ugen/usb_ugen.h>
  62 #include <sys/usb/usba/usba_ugen.h>
  63 
  64 #include <sys/usb/usba/usba_private.h>
  65 #include <sys/usb/usba/usba_ugend.h>
  66 #include <sys/usb/clients/mass_storage/usb_bulkonly.h>
  67 #include <sys/usb/scsa2usb/scsa2usb.h>
  68 
  69 /*
  70  * Function Prototypes
  71  */
  72 static int      scsa2usb_attach(dev_info_t *, ddi_attach_cmd_t);
  73 static int      scsa2usb_info(dev_info_t *, ddi_info_cmd_t, void *,
  74                                                 void **);
  75 static int      scsa2usb_detach(dev_info_t *, ddi_detach_cmd_t);
  76 static int      scsa2usb_cleanup(dev_info_t *, scsa2usb_state_t *);
  77 static void     scsa2usb_validate_attrs(scsa2usb_state_t *);
  78 static void     scsa2usb_create_luns(scsa2usb_state_t *);
  79 static int      scsa2usb_is_usb(dev_info_t *);
  80 static void     scsa2usb_fake_inquiry(scsa2usb_state_t *,
  81                     struct scsi_inquiry *);
  82 static void     scsa2usb_do_inquiry(scsa2usb_state_t *,
  83                                                 uint_t, uint_t);
  84 static int      scsa2usb_do_tur(scsa2usb_state_t *, struct scsi_address *);
  85 
  86 /* override property handling */
  87 static void     scsa2usb_override(scsa2usb_state_t *);
  88 static int      scsa2usb_parse_input_str(char *, scsa2usb_ov_t *,
  89                     scsa2usb_state_t *);
  90 static void     scsa2usb_override_error(char *, scsa2usb_state_t *);
  91 static char     *scsa2usb_strtok_r(char *, char *, char **);
  92 
  93 
  94 /* PANIC callback handling */
  95 static void     scsa2usb_panic_callb_init(scsa2usb_state_t *);
  96 static void     scsa2usb_panic_callb_fini(scsa2usb_state_t *);
  97 static boolean_t scsa2usb_panic_callb(void *, int);
  98 
  99 /* SCSA support */
 100 static int      scsa2usb_scsi_tgt_probe(struct scsi_device *, int (*)(void));
 101 static int      scsa2usb_scsi_tgt_init(dev_info_t *, dev_info_t *,
 102                     scsi_hba_tran_t *, struct scsi_device *);
 103 static void     scsa2usb_scsi_tgt_free(dev_info_t *, dev_info_t *,
 104                     scsi_hba_tran_t *, struct scsi_device *);
 105 static struct   scsi_pkt *scsa2usb_scsi_init_pkt(struct scsi_address *,
 106                     struct scsi_pkt *, struct buf *, int, int,
 107                     int, int, int (*)(), caddr_t);
 108 static void     scsa2usb_scsi_destroy_pkt(struct scsi_address *,
 109                     struct scsi_pkt *);
 110 static int      scsa2usb_scsi_start(struct scsi_address *, struct scsi_pkt *);
 111 static int      scsa2usb_scsi_abort(struct scsi_address *, struct scsi_pkt *);
 112 static int      scsa2usb_scsi_reset(struct scsi_address *, int);
 113 static int      scsa2usb_scsi_getcap(struct scsi_address *, char *, int);
 114 static int      scsa2usb_scsi_setcap(struct scsi_address *, char *, int, int);
 115 static int      scsa2usb_scsi_bus_config(dev_info_t *, uint_t,
 116                     ddi_bus_config_op_t, void *, dev_info_t **);
 117 static int      scsa2usb_scsi_bus_unconfig(dev_info_t *, uint_t,
 118                     ddi_bus_config_op_t, void *);
 119 
 120 /* functions for command and transport support */
 121 static void     scsa2usb_prepare_pkt(scsa2usb_state_t *, struct scsi_pkt *);
 122 static int      scsa2usb_cmd_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
 123 static int      scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *,
 124                     scsa2usb_cmd_t *, uchar_t);
 125 static int      scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *, uchar_t,
 126                     scsa2usb_cmd_t *);
 127 static int      scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *,
 128                     scsa2usb_cmd_t *, struct scsi_pkt *);
 129 static int      scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *,
 130                     scsa2usb_cmd_t *, struct scsi_pkt *);
 131 
 132 /* waitQ handling */
 133 static void     scsa2usb_work_thread(void *);
 134 static void     scsa2usb_transport_request(scsa2usb_state_t *, uint_t);
 135 static void     scsa2usb_flush_waitQ(scsa2usb_state_t *, uint_t, uchar_t);
 136 static int      scsa2usb_all_waitQs_empty(scsa2usb_state_t *);
 137 
 138 /* auto request sense handling */
 139 static int      scsa2usb_create_arq_pkt(scsa2usb_state_t *,
 140                     struct scsi_address *);
 141 static void     scsa2usb_delete_arq_pkt(scsa2usb_state_t *);
 142 static void     scsa2usb_complete_arq_pkt(scsa2usb_state_t *, struct scsi_pkt *,
 143                     scsa2usb_cmd_t *, struct buf *);
 144 
 145 /* utility functions for any transport */
 146 static int      scsa2usb_open_usb_pipes(scsa2usb_state_t *);
 147 void            scsa2usb_close_usb_pipes(scsa2usb_state_t *);
 148 
 149 static void     scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *, int);
 150 static void     scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *, int);
 151 static void     scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *, int, int);
 152 static void     scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *, int, int);
 153 static int      scsa2usb_read_cd_blk_size(uchar_t);
 154 int             scsa2usb_rw_transport(scsa2usb_state_t *, struct scsi_pkt *);
 155 void            scsa2usb_setup_next_xfer(scsa2usb_state_t *, scsa2usb_cmd_t *);
 156 
 157 static mblk_t   *scsa2usb_bp_to_mblk(scsa2usb_state_t *);
 158 int             scsa2usb_handle_data_start(scsa2usb_state_t *,
 159                     scsa2usb_cmd_t *, usb_bulk_req_t *);
 160 void            scsa2usb_handle_data_done(scsa2usb_state_t *,
 161                     scsa2usb_cmd_t *cmd, usb_bulk_req_t *);
 162 
 163 usb_bulk_req_t *scsa2usb_init_bulk_req(scsa2usb_state_t *,
 164                             size_t, uint_t, usb_req_attrs_t, usb_flags_t);
 165 int             scsa2usb_bulk_timeout(int);
 166 int             scsa2usb_clear_ept_stall(scsa2usb_state_t *, uint_t,
 167                     usb_pipe_handle_t, char *);
 168 static void     scsa2usb_pkt_completion(scsa2usb_state_t *, struct scsi_pkt *);
 169 
 170 /* event handling */
 171 static int      scsa2usb_reconnect_event_cb(dev_info_t *);
 172 static int      scsa2usb_disconnect_event_cb(dev_info_t *);
 173 static int      scsa2usb_cpr_suspend(dev_info_t *);
 174 static void     scsa2usb_cpr_resume(dev_info_t *);
 175 static void     scsa2usb_restore_device_state(dev_info_t *, scsa2usb_state_t *);
 176 
 177 /* PM handling */
 178 static void     scsa2usb_create_pm_components(dev_info_t *, scsa2usb_state_t *);
 179 static void     scsa2usb_raise_power(scsa2usb_state_t *);
 180 static int      scsa2usb_pwrlvl0(scsa2usb_state_t *);
 181 static int      scsa2usb_pwrlvl1(scsa2usb_state_t *);
 182 static int      scsa2usb_pwrlvl2(scsa2usb_state_t *);
 183 static int      scsa2usb_pwrlvl3(scsa2usb_state_t *);
 184 static int      scsa2usb_power(dev_info_t *, int comp, int level);
 185 static void     scsa2usb_pm_busy_component(scsa2usb_state_t *);
 186 static void     scsa2usb_pm_idle_component(scsa2usb_state_t *);
 187 
 188 /* external functions for Bulk only (BO) support */
 189 extern int      scsa2usb_bulk_only_transport(scsa2usb_state_t *,
 190                     scsa2usb_cmd_t *);
 191 extern int      scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *);
 192 
 193 /* external functions for CB/CBI support */
 194 extern int      scsa2usb_cbi_transport(scsa2usb_state_t *, scsa2usb_cmd_t *);
 195 extern void     scsa2usb_cbi_stop_intr_polling(scsa2usb_state_t *);
 196 
 197 
 198 /* cmd decoding */
 199 static char *scsa2usb_cmds[] = {
 200         "\000tur",
 201         "\001rezero",
 202         "\003rqsense",
 203         "\004format",
 204         "\014cartprot",
 205         "\022inquiry",
 206         "\026tranlba",
 207         "\030fmtverify",
 208         "\032modesense",
 209         "\033start",
 210         "\035snddiag",
 211         "\036doorlock",
 212         "\043formatcap",
 213         "\045readcap",
 214         "\050read10",
 215         "\052write10",
 216         "\053seek10",
 217         "\056writeverify",
 218         "\057verify",
 219         "\065synchcache",
 220         "\076readlong",
 221         "\077writelong",
 222         "\102readsubchan",
 223         "\103readtoc",
 224         "\104readhdr",
 225         "\105playaudio10",
 226         "\107playaudio_msf",
 227         "\110playaudio_ti",
 228         "\111playtrk_r10",
 229         "\112geteventnotify",
 230         "\113pause_resume",
 231         "\116stop/play_scan",
 232         "\121readdiscinfo",
 233         "\122readtrkinfo",
 234         "\123reservedtrk",
 235         "\124sendopcinfo",
 236         "\125modeselect",
 237         "\132modesense",
 238         "\133closetrksession",
 239         "\135sendcuesheet",
 240         "\136prin",
 241         "\137prout",
 242         "\241blankcd",
 243         "\245playaudio12",
 244         "\250read12",
 245         "\251playtrk12",
 246         "\252write12",
 247         "\254getperf",
 248         "\271readcdmsf",
 249         "\273setcdspeed",
 250         "\275mechanism_sts",
 251         "\276readcd",
 252         NULL
 253 };
 254 
 255 
 256 /*
 257  * Mass-Storage devices masquerade as "sd" disks.
 258  *
 259  * These devices may not support all SCSI CDBs in their
 260  * entirety due to their hardware implementation limitations.
 261  *
 262  * As such, following is a list of some of the black-listed
 263  * devices w/ the attributes that they do not support.
 264  * (See scsa2usb.h for description on each attribute)
 265  */
 266 #define X       ((uint16_t)(-1))
 267 
 268 static struct blacklist {
 269         uint16_t        idVendor;       /* vendor ID                    */
 270         uint16_t        idProduct;      /* product ID                   */
 271         uint16_t        bcdDevice;      /* device release number in bcd */
 272         uint16_t        attributes;     /* attributes to blacklist      */
 273 } scsa2usb_blacklist[] = {
 274         /* Iomega Zip100 drive (prototype) with flaky bridge */
 275         {MS_IOMEGA_VID, MS_IOMEGA_PID1_ZIP100, 0,
 276             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
 277 
 278         /* Iomega Zip100 drive (newer model) with flaky bridge */
 279         {MS_IOMEGA_VID, MS_IOMEGA_PID2_ZIP100, 0,
 280             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
 281 
 282         /* Iomega Zip100 drive (newer model) with flaky bridge */
 283         {MS_IOMEGA_VID, MS_IOMEGA_PID3_ZIP100, 0,
 284             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_PM},
 285 
 286         /* Iomega Zip250 drive */
 287         {MS_IOMEGA_VID, MS_IOMEGA_PID_ZIP250, 0, SCSA2USB_ATTRS_GET_LUN},
 288 
 289         /* Iomega Clik! drive */
 290         {MS_IOMEGA_VID, MS_IOMEGA_PID_CLIK, 0,
 291             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
 292 
 293         /* Kingston DataTraveler Stick / PNY Attache Stick */
 294         {MS_TOSHIBA_VID, MS_TOSHIBA_PID0, 0,
 295             SCSA2USB_ATTRS_GET_LUN},
 296 
 297         /* PNY Floppy drive */
 298         {MS_PNY_VID, MS_PNY_PID0, 0,
 299             SCSA2USB_ATTRS_GET_LUN},
 300 
 301         /* SMSC floppy Device - and its clones */
 302         {MS_SMSC_VID, X, 0, SCSA2USB_ATTRS_START_STOP},
 303 
 304         /* Hagiwara SmartMedia Device */
 305         {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID1, 0,
 306             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
 307 
 308         /* Hagiwara CompactFlash Device */
 309         {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID2, 0,
 310             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
 311 
 312         /* Hagiwara SmartMedia/CompactFlash Combo Device */
 313         {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID3, 0,
 314             SCSA2USB_ATTRS_START_STOP},
 315 
 316         /* Hagiwara new SM Device */
 317         {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID4, 0,
 318             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
 319 
 320         /* Hagiwara new CF Device */
 321         {MS_HAGIWARA_SYS_COM_VID, MS_HAGIWARA_SYSCOM_PID5, 0,
 322             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_START_STOP},
 323 
 324         /* Mitsumi CD-RW Device(s) */
 325         {MS_MITSUMI_VID, X, X, SCSA2USB_ATTRS_BIG_TIMEOUT |
 326             SCSA2USB_ATTRS_GET_CONF | SCSA2USB_ATTRS_GET_PERF},
 327 
 328         /* Neodio Technologies Corporation SM/CF/MS/SD Combo Device */
 329         {MS_NEODIO_VID, MS_NEODIO_DEVICE_3050, 0,
 330             SCSA2USB_ATTRS_MODE_SENSE },
 331 
 332         /* dumb flash devices */
 333         {MS_SONY_FLASH_VID, MS_SONY_FLASH_PID, 0,
 334             SCSA2USB_ATTRS_REDUCED_CMD},
 335 
 336         {MS_TREK_FLASH_VID, MS_TREK_FLASH_PID, 0,
 337             SCSA2USB_ATTRS_REDUCED_CMD},
 338 
 339         {MS_PENN_FLASH_VID, MS_PENN_FLASH_PID, 0,
 340             SCSA2USB_ATTRS_REDUCED_CMD},
 341 
 342         /* SimpleTech UCF-100 CF Device */
 343         {MS_SIMPLETECH_VID, MS_SIMPLETECH_PID1, 0,
 344             SCSA2USB_ATTRS_REDUCED_CMD},
 345 
 346         {MS_ADDONICS_CARD_READER_VID, MS_ADDONICS_CARD_READER_PID,
 347             0, SCSA2USB_ATTRS_REDUCED_CMD},
 348 
 349         /* Acomdata 80GB USB/1394 Hard Disk */
 350         {MS_ACOMDATA_VID, MS_ACOMDATA_PID1, 0,
 351             SCSA2USB_ATTRS_USE_CSW_RESIDUE},
 352 
 353         /* OTi6828 Flash Disk */
 354         {MS_OTI_VID, MS_OTI_DEVICE_6828, 0,
 355             SCSA2USB_ATTRS_USE_CSW_RESIDUE},
 356 
 357         /* AMI Virtual Floppy */
 358         {MS_AMI_VID, MS_AMI_VIRTUAL_FLOPPY, 0,
 359             SCSA2USB_ATTRS_NO_MEDIA_CHECK},
 360 
 361         /* ScanLogic USB Storage Device */
 362         {MS_SCANLOGIC_VID, MS_SCANLOGIC_PID1, 0,
 363             SCSA2USB_ATTRS_NO_CAP_ADJUST},
 364 
 365         /* Super Top USB 2.0 IDE Device */
 366         {MS_SUPERTOP_VID, MS_SUPERTOP_DEVICE_6600, 0,
 367             SCSA2USB_ATTRS_USE_CSW_RESIDUE},
 368 
 369         /* Aigo Miniking Device NEHFSP14 */
 370         {MS_AIGO_VID, MS_AIGO_DEVICE_6981, 0,
 371             SCSA2USB_ATTRS_USE_CSW_RESIDUE},
 372 
 373         /* Alcor Micro Corp 6387 flash disk */
 374         {MS_ALCOR_VID, MS_ALCOR_PID0, 0,
 375             SCSA2USB_ATTRS_GET_LUN | SCSA2USB_ATTRS_USE_CSW_RESIDUE},
 376 
 377         /* Western Digital External HDD */
 378         {MS_WD_VID, MS_WD_PID, 0,
 379             SCSA2USB_ATTRS_INQUIRY_EVPD}
 380 };
 381 
 382 
 383 #define N_SCSA2USB_BLACKLIST (sizeof (scsa2usb_blacklist))/ \
 384                                 sizeof (struct blacklist)
 385 
 386 /*
 387  * Attribute values can be overridden by values
 388  * contained in the scsa2usb.conf file.
 389  * These arrays define possible user input values.
 390  */
 391 
 392 struct scsa2usb_subclass_protocol_override {
 393         char    *name;
 394         int     value;
 395 };
 396 
 397 static struct scsa2usb_subclass_protocol_override scsa2usb_protocol[] =  {
 398         {"CB", SCSA2USB_CB_PROTOCOL},
 399         {"CBI", SCSA2USB_CBI_PROTOCOL},
 400         {"BO", SCSA2USB_BULK_ONLY_PROTOCOL}
 401 };
 402 
 403 static struct scsa2usb_subclass_protocol_override scsa2usb_subclass[] = {
 404         {"SCSI", SCSA2USB_SCSI_CMDSET},
 405         {"ATAPI", SCSA2USB_ATAPI_CMDSET},
 406         {"UFI", SCSA2USB_UFI_CMDSET}
 407 };
 408 
 409 
 410 #define N_SCSA2USB_SUBC_OVERRIDE (sizeof (scsa2usb_subclass))/ \
 411                         sizeof (struct scsa2usb_subclass_protocol_override)
 412 
 413 #define N_SCSA2USB_PROT_OVERRIDE (sizeof (scsa2usb_protocol))/ \
 414                         sizeof (struct scsa2usb_subclass_protocol_override)
 415 
 416 /* global variables */
 417 static void *scsa2usb_statep;                           /* for soft state */
 418 static boolean_t scsa2usb_sync_message = B_TRUE;        /* for syncing */
 419 
 420 /* for debug messages */
 421 uint_t  scsa2usb_errmask        = (uint_t)DPRINT_MASK_ALL;
 422 uint_t  scsa2usb_errlevel       = USB_LOG_L4;
 423 uint_t  scsa2usb_instance_debug = (uint_t)-1;
 424 uint_t  scsa2usb_scsi_bus_config_debug = 0;
 425 uint_t  scsa2usb_long_timeout   = 50 * SCSA2USB_BULK_PIPE_TIMEOUT;
 426 
 427 
 428 /*
 429  * Some devices have problems with big bulk transfers,
 430  * transfers >= 128kbytes hang the device.  This tunable allows to
 431  * limit the maximum bulk transfers rate.
 432  */
 433 uint_t  scsa2usb_max_bulk_xfer_size = SCSA2USB_MAX_BULK_XFER_SIZE;
 434 
 435 
 436 #ifdef  SCSA2USB_BULK_ONLY_TEST
 437 /*
 438  * Test BO 13 cases. (See USB Mass Storage Class - Bulk Only Transport).
 439  * We are not covering test cases 1, 6, and 12 as these are the "good"
 440  * test cases and are tested as part of the normal drive access operations.
 441  *
 442  * NOTE: This is for testing only. It will be replaced by a uscsi test.
 443  * Some are listed here while; other test cases are moved to usb_bulkonly.c
 444  */
 445 static int scsa2usb_test_case_5 = 0;
 446 int scsa2usb_test_case_8 = 0;
 447 int scsa2usb_test_case_10 = 0;
 448 static int scsa2usb_test_case_11 = 0;
 449 
 450 static void     scsa2usb_test_mblk(scsa2usb_state_t *, boolean_t);
 451 #endif  /* SCSA2USB_BULK_ONLY_TEST */
 452 
 453 static int      scsa2usb_ugen_open(dev_t *, int, int, cred_t *);
 454 static int      scsa2usb_ugen_close(dev_t, int, int, cred_t *);
 455 static int      scsa2usb_ugen_read(dev_t, struct uio *, cred_t *);
 456 static int      scsa2usb_ugen_write(dev_t, struct uio *, cred_t *);
 457 static int      scsa2usb_ugen_poll(dev_t, short, int,  short *,
 458                                                 struct pollhead **);
 459 
 460 /* scsa2usb cb_ops */
 461 static struct cb_ops scsa2usb_cbops = {
 462         scsa2usb_ugen_open,     /* open  */
 463         scsa2usb_ugen_close,    /* close */
 464         nodev,                  /* strategy */
 465         nodev,                  /* print */
 466         nodev,                  /* dump */
 467         scsa2usb_ugen_read,     /* read */
 468         scsa2usb_ugen_write,    /* write */
 469         nodev,                  /* ioctl */
 470         nodev,                  /* devmap */
 471         nodev,                  /* mmap */
 472         nodev,                  /* segmap */
 473         scsa2usb_ugen_poll,     /* poll */
 474         ddi_prop_op,            /* prop_op */
 475         NULL,                   /* stream */
 476         D_MP,                   /* cb_flag */
 477         CB_REV,                 /* rev */
 478         nodev,                  /* int (*cb_aread)() */
 479         nodev                   /* int (*cb_awrite)() */
 480 };
 481 
 482 /* modloading support */
 483 static struct dev_ops scsa2usb_ops = {
 484         DEVO_REV,               /* devo_rev, */
 485         0,                      /* refcnt  */
 486         scsa2usb_info,          /* info */
 487         nulldev,                /* identify */
 488         nulldev,                /* probe */
 489         scsa2usb_attach,        /* attach */
 490         scsa2usb_detach,        /* detach */
 491         nodev,                  /* reset */
 492         &scsa2usb_cbops,    /* driver operations */
 493         NULL,                   /* bus operations */
 494         scsa2usb_power,         /* power */
 495         ddi_quiesce_not_needed,         /* quiesce */
 496 };
 497 
 498 static struct modldrv modldrv = {
 499         &mod_driverops,                     /* Module type. This one is a driver */
 500         "SCSA to USB Driver",   /* Name of the module. */
 501         &scsa2usb_ops,                      /* driver ops */
 502 };
 503 
 504 static struct modlinkage modlinkage = {
 505         MODREV_1, { (void *)&modldrv, NULL }
 506 };
 507 
 508 /* event support */
 509 static usb_event_t scsa2usb_events = {
 510         scsa2usb_disconnect_event_cb,
 511         scsa2usb_reconnect_event_cb,
 512         NULL, NULL
 513 };
 514 
 515 int
 516 _init(void)
 517 {
 518         int rval;
 519 
 520         if (((rval = ddi_soft_state_init(&scsa2usb_statep,
 521             sizeof (scsa2usb_state_t), SCSA2USB_INITIAL_ALLOC)) != 0)) {
 522 
 523                 return (rval);
 524         }
 525 
 526         if ((rval = scsi_hba_init(&modlinkage)) != 0) {
 527                 ddi_soft_state_fini(&scsa2usb_statep);
 528 
 529                 return (rval);
 530         }
 531 
 532         if ((rval = mod_install(&modlinkage)) != 0) {
 533                 scsi_hba_fini(&modlinkage);
 534                 ddi_soft_state_fini(&scsa2usb_statep);
 535 
 536                 return (rval);
 537         }
 538 
 539         return (rval);
 540 }
 541 
 542 
 543 int
 544 _fini(void)
 545 {
 546         int     rval;
 547 
 548         if ((rval = mod_remove(&modlinkage)) == 0) {
 549                 scsi_hba_fini(&modlinkage);
 550                 ddi_soft_state_fini(&scsa2usb_statep);
 551         }
 552 
 553         return (rval);
 554 }
 555 
 556 
 557 int
 558 _info(struct modinfo *modinfop)
 559 {
 560         return (mod_info(&modlinkage, modinfop));
 561 }
 562 
 563 
 564 /*
 565  * scsa2usb_info :
 566  *      Get minor number, soft state structure etc.
 567  */
 568 /*ARGSUSED*/
 569 static int
 570 scsa2usb_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
 571     void *arg, void **result)
 572 {
 573         scsa2usb_state_t *scsa2usbp = NULL;
 574         int error = DDI_FAILURE;
 575         int instance = SCSA2USB_MINOR_TO_INSTANCE(getminor((dev_t)arg));
 576 
 577         switch (infocmd) {
 578         case DDI_INFO_DEVT2DEVINFO:
 579                 if (((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
 580                     instance)) != NULL) &&
 581                     scsa2usbp->scsa2usb_dip) {
 582                         *result = scsa2usbp->scsa2usb_dip;
 583                         error = DDI_SUCCESS;
 584                 } else {
 585                         *result = NULL;
 586                 }
 587                 break;
 588         case DDI_INFO_DEVT2INSTANCE:
 589                 *result = (void *)(uintptr_t)instance;
 590                 error = DDI_SUCCESS;
 591                 break;
 592         default:
 593                 break;
 594         }
 595 
 596         return (error);
 597 }
 598 
 599 
 600 /*
 601  * scsa2usb_attach:
 602  *      Attach driver
 603  *      Allocate a "scsi_hba_tran" - call scsi_hba_tran_alloc()
 604  *      Invoke scsi_hba_attach_setup
 605  *      Get the serialno of the device
 606  *      Open bulk pipes
 607  *      Create disk child(ren)
 608  *      Register events
 609  *      Create and register panic callback
 610  *
 611  * NOTE: Replaced CBW_DIR_OUT with USB_EP_DIR_OUT and CBW_DIR_IN with
 612  * USB_EP_DIR_IN as they are the same #defines.
 613  */
 614 static int
 615 scsa2usb_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 616 {
 617         int                     instance = ddi_get_instance(dip);
 618         int                     interface;
 619         uint_t                  lun;
 620         boolean_t               ept_check = B_TRUE;
 621         scsi_hba_tran_t         *tran;          /* scsi transport */
 622         scsa2usb_state_t        *scsa2usbp;
 623         usb_log_handle_t        log_handle;
 624         usb_ep_data_t           *ep_data;
 625         usb_client_dev_data_t   *dev_data;
 626         usb_alt_if_data_t       *altif_data;
 627         usb_ugen_info_t         usb_ugen_info;
 628 
 629         USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL,
 630             "scsa2usb_attach: dip = 0x%p", (void *)dip);
 631 
 632         switch (cmd) {
 633         case DDI_ATTACH:
 634                 break;
 635         case DDI_RESUME:
 636                 scsa2usb_cpr_resume(dip);
 637 
 638                 return (DDI_SUCCESS);
 639         default:
 640                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
 641                     "scsa2usb_attach: failed");
 642 
 643                 return (DDI_FAILURE);
 644         }
 645 
 646         /* Allocate softc information */
 647         if (ddi_soft_state_zalloc(scsa2usb_statep, instance) != DDI_SUCCESS) {
 648                 ddi_prop_remove_all(dip);
 649 
 650                 return (DDI_FAILURE);
 651         }
 652 
 653         /* get soft state space and initialize */
 654         if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
 655             instance)) == NULL) {
 656                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, NULL,
 657                     "scsa2usb%d: bad soft state", instance);
 658                 ddi_prop_remove_all(dip);
 659 
 660                 return (DDI_FAILURE);
 661         }
 662 
 663         scsa2usbp->scsa2usb_dip      = dip;
 664         scsa2usbp->scsa2usb_instance = instance;
 665 
 666         /* allocate a log handle for debug/error messages */
 667         scsa2usbp->scsa2usb_log_handle = log_handle =
 668             usb_alloc_log_hdl(dip, "s2u",
 669             &scsa2usb_errlevel,
 670             &scsa2usb_errmask, &scsa2usb_instance_debug,
 671             0);
 672 
 673         /* attach to USBA */
 674         if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) {
 675                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 676                     "usb_client_attach failed");
 677 
 678                 goto fail;
 679         }
 680         if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) !=
 681             USB_SUCCESS) {
 682                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 683                     "usb_get_dev_data failed");
 684 
 685                 goto fail;
 686         }
 687 
 688         /* initialize the mutex with the right cookie */
 689         mutex_init(&scsa2usbp->scsa2usb_mutex, NULL, MUTEX_DRIVER,
 690             dev_data->dev_iblock_cookie);
 691         cv_init(&scsa2usbp->scsa2usb_transport_busy_cv, NULL, CV_DRIVER, NULL);
 692 
 693         for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
 694                 usba_init_list(&scsa2usbp->scsa2usb_waitQ[lun], NULL,
 695                     dev_data->dev_iblock_cookie);
 696         }
 697         mutex_enter(&scsa2usbp->scsa2usb_mutex);
 698         scsa2usbp->scsa2usb_dip      = dip;
 699         scsa2usbp->scsa2usb_instance = instance;
 700         scsa2usbp->scsa2usb_attrs    = SCSA2USB_ALL_ATTRS;
 701         scsa2usbp->scsa2usb_dev_data = dev_data;
 702 
 703 
 704         /* save the default pipe handle */
 705         scsa2usbp->scsa2usb_default_pipe = dev_data->dev_default_ph;
 706 
 707         /* basic inits are done */
 708         scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_LOCKS_INIT;
 709 
 710         USB_DPRINTF_L4(DPRINT_MASK_SCSA, log_handle,
 711             "curr_cfg=%ld, curr_if=%d",
 712             (long)(dev_data->dev_curr_cfg - &dev_data->dev_cfg[0]),
 713             dev_data->dev_curr_if);
 714 
 715         interface = dev_data->dev_curr_if;
 716         scsa2usbp->scsa2usb_intfc_num = dev_data->dev_curr_if;
 717 
 718         /* now find out relevant descriptors for alternate 0 */
 719         altif_data = &dev_data->dev_curr_cfg->cfg_if[interface].if_alt[0];
 720 
 721         if (altif_data->altif_n_ep == 0) {
 722                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 723                     "invalid alt 0 for interface %d", interface);
 724                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 725 
 726                 goto fail;
 727         }
 728 
 729         /* All CB/CBI, BO devices should have this value set */
 730         if (altif_data->altif_descr.bInterfaceClass !=
 731             USB_CLASS_MASS_STORAGE) {
 732                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 733                     "invalid interface class (0x%x)",
 734                     altif_data->altif_descr.bInterfaceClass);
 735         }
 736         scsa2usbp->scsa2usb_intfc_descr = altif_data->altif_descr;
 737 
 738         /* figure out the endpoints and copy the descr */
 739         if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
 740             USB_EP_ATTR_BULK, USB_EP_DIR_OUT)) != NULL) {
 741                 scsa2usbp->scsa2usb_bulkout_ept = ep_data->ep_descr;
 742         }
 743         if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
 744             USB_EP_ATTR_BULK, USB_EP_DIR_IN)) != NULL) {
 745                 scsa2usbp->scsa2usb_bulkin_ept = ep_data->ep_descr;
 746         }
 747         if ((ep_data = usb_lookup_ep_data(dip, dev_data, interface, 0, 0,
 748             USB_EP_ATTR_INTR, USB_EP_DIR_IN)) != NULL) {
 749                 scsa2usbp->scsa2usb_intr_ept = ep_data->ep_descr;
 750         }
 751 
 752         /*
 753          * check here for protocol and subclass supported by this driver
 754          *
 755          * first check if conf file has override values
 756          * Note: override values are not used if supplied values are legal
 757          */
 758         scsa2usb_override(scsa2usbp);
 759 
 760         USB_DPRINTF_L3(DPRINT_MASK_SCSA, log_handle,
 761             "protocol=0x%x override=0x%x subclass=0x%x override=0x%x",
 762             scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol,
 763             scsa2usbp->scsa2usb_protocol_override,
 764             scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass,
 765             scsa2usbp->scsa2usb_subclass_override);
 766 
 767         switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol) {
 768         case USB_PROTO_MS_CBI:
 769                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CB_PROTOCOL;
 770                 break;
 771         case USB_PROTO_MS_CBI_WC:
 772                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_CBI_PROTOCOL;
 773                 break;
 774         case USB_PROTO_MS_ISD_1999_SILICN:
 775         case USB_PROTO_MS_BULK_ONLY:
 776                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_BULK_ONLY_PROTOCOL;
 777                 break;
 778         default:
 779                 if (scsa2usbp->scsa2usb_protocol_override) {
 780                         scsa2usbp->scsa2usb_cmd_protocol |=
 781                             scsa2usbp->scsa2usb_protocol_override;
 782                         USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 783                             "overriding protocol %x",
 784                             scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
 785                         break;
 786                 }
 787 
 788                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 789                     "unsupported protocol = %x",
 790                     scsa2usbp->scsa2usb_intfc_descr.bInterfaceProtocol);
 791                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 792 
 793                 goto fail;
 794         }
 795 
 796         switch (scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass) {
 797         case USB_SUBCLS_MS_SCSI:                /* transparent SCSI */
 798                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_SCSI_CMDSET;
 799                 break;
 800         case USB_SUBCLS_MS_SFF8020I:
 801         case USB_SUBCLS_MS_SFF8070I:
 802                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_ATAPI_CMDSET;
 803                 break;
 804         case USB_SUBCLS_MS_UFI:         /* UFI */
 805                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
 806                 break;
 807         default:
 808                 if (scsa2usbp->scsa2usb_subclass_override) {
 809                         scsa2usbp->scsa2usb_cmd_protocol |=
 810                             scsa2usbp->scsa2usb_subclass_override;
 811                         USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 812                             "overriding subclass %x",
 813                             scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
 814                         break;
 815                 }
 816 
 817                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 818                     "unsupported subclass = %x",
 819                     scsa2usbp->scsa2usb_intfc_descr.bInterfaceSubClass);
 820                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 821 
 822                 goto fail;
 823         }
 824 
 825         /* check that we have the right set of endpoint descriptors */
 826         if (SCSA2USB_IS_BULK_ONLY(scsa2usbp) || SCSA2USB_IS_CB(scsa2usbp)) {
 827                 if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
 828                     (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0)) {
 829                         ept_check = B_FALSE;
 830                 }
 831         } else if (SCSA2USB_IS_CBI(scsa2usbp)) {
 832                 if ((scsa2usbp->scsa2usb_bulkout_ept.bLength == 0) ||
 833                     (scsa2usbp->scsa2usb_bulkin_ept.bLength == 0) ||
 834                     (scsa2usbp->scsa2usb_intr_ept.bLength == 0)) {
 835                         ept_check = B_FALSE;
 836                 }
 837         }
 838 
 839         if (ept_check == B_FALSE) {
 840                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 841                     "scsa2usb%d doesn't support minimum required endpoints",
 842                     instance);
 843                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 844 
 845                 goto fail;
 846         }
 847 
 848         /*
 849          * Validate the black-listed attributes
 850          */
 851         scsa2usb_validate_attrs(scsa2usbp);
 852 
 853         /* Print the serial number from the registration data */
 854         if (scsa2usbp->scsa2usb_dev_data->dev_serial) {
 855                 USB_DPRINTF_L4(DPRINT_MASK_SCSA,
 856                     scsa2usbp->scsa2usb_log_handle, "Serial Number = %s",
 857                     scsa2usbp->scsa2usb_dev_data->dev_serial);
 858         }
 859 
 860         /*
 861          * Allocate a SCSA transport structure
 862          */
 863         tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
 864         scsa2usbp->scsa2usb_tran = tran;
 865 
 866         /*
 867          * initialize transport structure
 868          */
 869         tran->tran_hba_private               = scsa2usbp;
 870         tran->tran_tgt_private               = NULL;
 871         tran->tran_tgt_init          = scsa2usb_scsi_tgt_init;
 872         tran->tran_tgt_probe         = scsa2usb_scsi_tgt_probe;
 873         tran->tran_tgt_free          = scsa2usb_scsi_tgt_free;
 874         tran->tran_start             = scsa2usb_scsi_start;
 875         tran->tran_abort             = scsa2usb_scsi_abort;
 876         tran->tran_reset             = scsa2usb_scsi_reset;
 877         tran->tran_getcap            = scsa2usb_scsi_getcap;
 878         tran->tran_setcap            = scsa2usb_scsi_setcap;
 879         tran->tran_init_pkt          = scsa2usb_scsi_init_pkt;
 880         tran->tran_destroy_pkt               = scsa2usb_scsi_destroy_pkt;
 881         tran->tran_dmafree           = NULL;
 882         tran->tran_sync_pkt          = NULL;
 883         tran->tran_reset_notify              = NULL;
 884         tran->tran_get_bus_addr              = NULL;
 885         tran->tran_get_name          = NULL;
 886         tran->tran_quiesce           = NULL;
 887         tran->tran_unquiesce         = NULL;
 888         tran->tran_bus_reset         = NULL;
 889         tran->tran_add_eventcall     = NULL;
 890         tran->tran_get_eventcookie   = NULL;
 891         tran->tran_post_event                = NULL;
 892         tran->tran_remove_eventcall  = NULL;
 893         tran->tran_bus_config                = scsa2usb_scsi_bus_config;
 894         tran->tran_bus_unconfig              = scsa2usb_scsi_bus_unconfig;
 895 
 896         /*
 897          * register with SCSA as an HBA
 898          * Note that the dma attributes are from parent nexus
 899          */
 900         if (scsi_hba_attach_setup(dip, usba_get_hc_dma_attr(dip), tran, 0)) {
 901                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 902                     "scsi_hba_attach_setup failed");
 903                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 904 
 905                 goto fail;
 906         }
 907 
 908         scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_HBA_ATTACH_SETUP;
 909 
 910         /* create minor node */
 911         if (ddi_create_minor_node(dip, "scsa2usb", S_IFCHR,
 912             instance << SCSA2USB_MINOR_INSTANCE_SHIFT,
 913             DDI_NT_SCSI_NEXUS, 0) != DDI_SUCCESS) {
 914                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
 915                     "scsi_attach: ddi_create_minor_node failed");
 916                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 917 
 918                 goto fail;
 919         }
 920 
 921         /* open pipes and set scsa2usb_flags */
 922         if (scsa2usb_open_usb_pipes(scsa2usbp) == USB_FAILURE) {
 923                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 924                     "error opening pipes");
 925                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
 926 
 927                 goto fail;
 928         }
 929 
 930         /* set default block size. updated after read cap cmd */
 931         for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
 932                 scsa2usbp->scsa2usb_lbasize[lun] = DEV_BSIZE;
 933         }
 934 
 935         mutex_exit(&scsa2usbp->scsa2usb_mutex);
 936 
 937         /* initialize PANIC callback */
 938         scsa2usb_panic_callb_init(scsa2usbp);
 939 
 940         /* finally we are all done 'initializing' the device */
 941         mutex_enter(&scsa2usbp->scsa2usb_mutex);
 942         scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
 943 
 944         /* enable PM, mutex needs to be held across this */
 945         scsa2usb_create_pm_components(dip, scsa2usbp);
 946         mutex_exit(&scsa2usbp->scsa2usb_mutex);
 947 
 948         /* register for connect/disconnect events */
 949         if (usb_register_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events,
 950             0) != USB_SUCCESS) {
 951                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, log_handle,
 952                     "error cb registering");
 953                 goto fail;
 954         }
 955 
 956         /* free the dev_data tree, we no longer need it */
 957         usb_free_descr_tree(dip, dev_data);
 958 
 959         scsa2usb_pm_idle_component(scsa2usbp);
 960 
 961         /* log the conf file override string if there is one */
 962         if (scsa2usbp->scsa2usb_override_str) {
 963                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
 964                     "scsa2usb.conf override: %s",
 965                     scsa2usbp->scsa2usb_override_str);
 966         }
 967 
 968         if (usb_owns_device(dip)) {
 969                 /* get a ugen handle */
 970                 bzero(&usb_ugen_info, sizeof (usb_ugen_info));
 971                 usb_ugen_info.usb_ugen_flags = 0;
 972                 usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
 973                     (dev_t)SCSA2USB_MINOR_UGEN_BITS_MASK;
 974                 usb_ugen_info.usb_ugen_minor_node_instance_mask =
 975                     (dev_t)~SCSA2USB_MINOR_UGEN_BITS_MASK;
 976                 scsa2usbp->scsa2usb_ugen_hdl =
 977                     usb_ugen_get_hdl(dip, &usb_ugen_info);
 978 
 979                 if (usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl, cmd) !=
 980                     USB_SUCCESS) {
 981                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
 982                             scsa2usbp->scsa2usb_log_handle,
 983                             "usb_ugen_attach failed");
 984 
 985                         usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
 986                         scsa2usbp->scsa2usb_ugen_hdl = NULL;
 987                 }
 988         }
 989 
 990         /* report device */
 991         ddi_report_dev(dip);
 992 
 993         return (DDI_SUCCESS);
 994 
 995 fail:
 996         if (scsa2usbp) {
 997                 (void) scsa2usb_cleanup(dip, scsa2usbp);
 998         }
 999 
1000         return (DDI_FAILURE);
1001 }
1002 
1003 
1004 /*
1005  * scsa2usb_detach:
1006  *      detach or suspend driver instance
1007  */
1008 static int
1009 scsa2usb_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1010 {
1011         scsi_hba_tran_t *tran;
1012         scsa2usb_state_t *scsa2usbp;
1013         int rval;
1014 
1015         tran = ddi_get_driver_private(dip);
1016         ASSERT(tran != NULL);
1017 
1018         scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
1019         ASSERT(scsa2usbp);
1020 
1021         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1022             "scsa2usb_detach: dip = 0x%p, cmd = %d", (void *)dip, cmd);
1023 
1024         switch (cmd) {
1025         case DDI_DETACH:
1026 
1027                 if (scsa2usb_cleanup(dip, scsa2usbp) != USB_SUCCESS) {
1028 
1029                         return (DDI_FAILURE);
1030                 }
1031 
1032                 return (DDI_SUCCESS);
1033         case DDI_SUSPEND:
1034                 rval = scsa2usb_cpr_suspend(dip);
1035 
1036                 return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
1037         default:
1038 
1039                 return (DDI_FAILURE);
1040         }
1041 }
1042 
1043 /*
1044  * ugen support
1045  */
1046 /*
1047  * scsa2usb_ugen_open()
1048  * (all ugen opens and pipe opens are by definition exclusive so it is OK
1049  * to count opens)
1050  */
1051 static int
1052 scsa2usb_ugen_open(dev_t *devp, int flag, int sflag, cred_t *cr)
1053 {
1054         scsa2usb_state_t *scsa2usbp;
1055         int             rval;
1056 
1057         if ((scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1058             SCSA2USB_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) {
1059                 /* deferred detach */
1060 
1061                 return (ENXIO);
1062         }
1063 
1064         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1065             "scsa2usb_ugen_open: dev_t=0x%lx", *devp);
1066 
1067         mutex_enter(&scsa2usbp->scsa2usb_mutex);
1068 
1069         /* if this is the first ugen open, check on transport busy */
1070         if (scsa2usbp->scsa2usb_busy_proc != curproc) {
1071                 while (scsa2usbp->scsa2usb_transport_busy ||
1072                     (scsa2usb_all_waitQs_empty(scsa2usbp) !=
1073                     USB_SUCCESS)) {
1074                         rval = cv_wait_sig(
1075                             &scsa2usbp->scsa2usb_transport_busy_cv,
1076                             &scsa2usbp->scsa2usb_mutex);
1077                         if (rval == 0) {
1078                                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1079 
1080                                 return (EINTR);
1081                         }
1082                 }
1083                 scsa2usbp->scsa2usb_transport_busy++;
1084                 scsa2usbp->scsa2usb_busy_proc = curproc;
1085         }
1086 
1087         scsa2usbp->scsa2usb_ugen_open_count++;
1088 
1089         scsa2usb_raise_power(scsa2usbp);
1090 
1091         scsa2usb_close_usb_pipes(scsa2usbp);
1092 
1093         mutex_exit(&scsa2usbp->scsa2usb_mutex);
1094 
1095         rval = usb_ugen_open(scsa2usbp->scsa2usb_ugen_hdl, devp, flag,
1096             sflag, cr);
1097         if (!rval) {
1098                 /*
1099                  * if usb_ugen_open() succeeded, we'll change the minor number
1100                  * so that we can keep track of every open()/close() issued by
1101                  * the userland processes. We need to pick a minor number that
1102                  * is not used by the ugen framework
1103                  */
1104 
1105                 usb_ugen_hdl_impl_t     *usb_ugen_hdl_impl;
1106                 ugen_state_t            *ugenp;
1107                 int                     ugen_minor, clone;
1108 
1109                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1110 
1111                 usb_ugen_hdl_impl =
1112                     (usb_ugen_hdl_impl_t *)scsa2usbp->scsa2usb_ugen_hdl;
1113                 ugenp =  usb_ugen_hdl_impl->hdl_ugenp;
1114 
1115                 /* 'clone' is bigger than any ugen minor in use */
1116                 for (clone = ugenp->ug_minor_node_table_index + 1;
1117                     clone < SCSA2USB_MAX_CLONE; clone++) {
1118                         if (!scsa2usbp->scsa2usb_clones[clone])
1119                                 break;
1120                 }
1121 
1122                 if (clone >= SCSA2USB_MAX_CLONE) {
1123                         cmn_err(CE_WARN, "scsa2usb_ugen_open: too many clones");
1124                         rval = EBUSY;
1125                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
1126                         goto open_done;
1127                 }
1128 
1129                 ugen_minor = getminor(*devp) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1130                 *devp = makedevice(getmajor(*devp),
1131                     (scsa2usbp->scsa2usb_instance
1132                     << SCSA2USB_MINOR_INSTANCE_SHIFT)
1133                     + clone);
1134 
1135                 /* save the ugen minor */
1136                 scsa2usbp->scsa2usb_clones[clone] = (uint8_t)ugen_minor;
1137                 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1138                     "scsa2usb_ugen_open: new dev=%lx, old minor=%x",
1139                     *devp, ugen_minor);
1140 
1141                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1142         }
1143 
1144 open_done:
1145 
1146         if (rval) {
1147                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1148 
1149                 /* reopen the pipes */
1150                 if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1151                         scsa2usbp->scsa2usb_transport_busy--;
1152                         scsa2usbp->scsa2usb_busy_proc = NULL;
1153                         cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1154                 }
1155                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1156 
1157                 scsa2usb_pm_idle_component(scsa2usbp);
1158         }
1159 
1160         return (rval);
1161 }
1162 
1163 
1164 /*
1165  * scsa2usb_ugen_close()
1166  */
1167 static int
1168 scsa2usb_ugen_close(dev_t dev, int flag, int otype, cred_t *cr)
1169 {
1170         int rval;
1171         int     ugen_minor, clone;
1172 
1173         scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1174             SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1175 
1176         if (scsa2usbp == NULL) {
1177 
1178                 return (ENXIO);
1179         }
1180 
1181         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1182             "scsa2usb_ugen_close: dev_t=0x%lx", dev);
1183 
1184         clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1185         ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1186         dev = makedevice(getmajor(dev),
1187             (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1188             + ugen_minor);
1189         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1190             "scsa2usb_ugen_close: old dev=%lx", dev);
1191         rval = usb_ugen_close(scsa2usbp->scsa2usb_ugen_hdl, dev, flag,
1192             otype, cr);
1193 
1194         if (rval == 0) {
1195                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1196 
1197                 scsa2usbp->scsa2usb_clones[clone] = 0;
1198                 /* reopen the pipes */
1199                 if (--scsa2usbp->scsa2usb_ugen_open_count == 0) {
1200                         scsa2usbp->scsa2usb_transport_busy--;
1201                         scsa2usbp->scsa2usb_busy_proc = NULL;
1202                         cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
1203                 }
1204                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1205 
1206                 scsa2usb_pm_idle_component(scsa2usbp);
1207         }
1208 
1209         return (rval);
1210 }
1211 
1212 
1213 /*
1214  * scsa2usb_ugen_read/write()
1215  */
1216 /*ARGSUSED*/
1217 static int
1218 scsa2usb_ugen_read(dev_t dev, struct uio *uiop, cred_t *credp)
1219 {
1220         int clone, ugen_minor;
1221         scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1222             SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1223 
1224         if (scsa2usbp == NULL) {
1225 
1226                 return (ENXIO);
1227         }
1228 
1229         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1230             "scsa2usb_ugen_read: dev_t=0x%lx", dev);
1231 
1232         clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1233         ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1234         dev = makedevice(getmajor(dev),
1235             (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1236             + ugen_minor);
1237 
1238         return (usb_ugen_read(scsa2usbp->scsa2usb_ugen_hdl, dev,
1239             uiop, credp));
1240 }
1241 
1242 
1243 /*ARGSUSED*/
1244 static int
1245 scsa2usb_ugen_write(dev_t dev, struct uio *uiop, cred_t *credp)
1246 {
1247         int clone, ugen_minor;
1248         scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1249             SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1250 
1251         if (scsa2usbp == NULL) {
1252 
1253                 return (ENXIO);
1254         }
1255 
1256         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1257             "scsa2usb_ugen_write: dev_t=0x%lx", dev);
1258 
1259         clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1260         ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1261         dev = makedevice(getmajor(dev),
1262             (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1263             + ugen_minor);
1264 
1265         return (usb_ugen_write(scsa2usbp->scsa2usb_ugen_hdl,
1266             dev, uiop, credp));
1267 }
1268 
1269 
1270 /*
1271  * scsa2usb_ugen_poll
1272  */
1273 static int
1274 scsa2usb_ugen_poll(dev_t dev, short events,
1275     int anyyet,  short *reventsp, struct pollhead **phpp)
1276 {
1277         int clone, ugen_minor;
1278         scsa2usb_state_t *scsa2usbp = ddi_get_soft_state(scsa2usb_statep,
1279             SCSA2USB_MINOR_TO_INSTANCE(getminor(dev)));
1280 
1281         if (scsa2usbp == NULL) {
1282 
1283                 return (ENXIO);
1284         }
1285 
1286         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1287             "scsa2usb_ugen_poll: dev_t=0x%lx", dev);
1288 
1289         clone = getminor(dev) & SCSA2USB_MINOR_UGEN_BITS_MASK;
1290         ugen_minor = scsa2usbp->scsa2usb_clones[clone];
1291         dev = makedevice(getmajor(dev),
1292             (scsa2usbp->scsa2usb_instance << SCSA2USB_MINOR_INSTANCE_SHIFT)
1293             + ugen_minor);
1294 
1295         return (usb_ugen_poll(scsa2usbp->scsa2usb_ugen_hdl, dev, events,
1296             anyyet, reventsp, phpp));
1297 }
1298 
1299 
1300 /*
1301  * scsa2usb_cleanup:
1302  *      cleanup whatever attach has setup
1303  */
1304 static int
1305 scsa2usb_cleanup(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
1306 {
1307         int             rval, i;
1308         scsa2usb_power_t *pm;
1309         uint_t          lun;
1310 
1311         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1312             "scsa2usb_cleanup:");
1313 
1314         /* wait till the work thread is done */
1315         mutex_enter(&scsa2usbp->scsa2usb_mutex);
1316         for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
1317                 if (scsa2usbp->scsa2usb_work_thread_id == NULL) {
1318 
1319                         break;
1320                 }
1321                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1322                 delay(drv_usectohz(1000000));
1323                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1324         }
1325         mutex_exit(&scsa2usbp->scsa2usb_mutex);
1326 
1327         if (i >= SCSA2USB_DRAIN_TIMEOUT) {
1328 
1329                 return (USB_FAILURE);
1330         }
1331 
1332         /*
1333          * Disable the event callbacks first, after this point, event
1334          * callbacks will never get called. Note we shouldn't hold
1335          * mutex while unregistering events because there may be a
1336          * competing event callback thread. Event callbacks are done
1337          * with ndi mutex held and this can cause a potential deadlock.
1338          */
1339         usb_unregister_event_cbs(scsa2usbp->scsa2usb_dip, &scsa2usb_events);
1340 
1341         if (scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_LOCKS_INIT) {
1342                 /*
1343                  * if a waitQ exists, get rid of it before destroying it
1344                  */
1345                 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
1346                         scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_TRAN_ERR);
1347                         usba_destroy_list(&scsa2usbp->scsa2usb_waitQ[lun]);
1348                 }
1349 
1350                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1351                 if (scsa2usbp->scsa2usb_flags &
1352                     SCSA2USB_FLAGS_HBA_ATTACH_SETUP) {
1353                         (void) scsi_hba_detach(dip);
1354                         scsi_hba_tran_free(scsa2usbp->scsa2usb_tran);
1355                 }
1356 
1357                 if (scsa2usbp->scsa2usb_flags &
1358                     SCSA2USB_FLAGS_PIPES_OPENED) {
1359                         scsa2usb_close_usb_pipes(scsa2usbp);
1360                 }
1361 
1362                 /* Lower the power */
1363                 pm = scsa2usbp->scsa2usb_pm;
1364 
1365                 if (pm && (scsa2usbp->scsa2usb_dev_state !=
1366                     USB_DEV_DISCONNECTED)) {
1367                         if (pm->scsa2usb_wakeup_enabled) {
1368                                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1369                                 (void) pm_raise_power(dip, 0,
1370                                     USB_DEV_OS_FULL_PWR);
1371 
1372                                 if ((rval = usb_handle_remote_wakeup(dip,
1373                                     USB_REMOTE_WAKEUP_DISABLE)) !=
1374                                     USB_SUCCESS) {
1375                                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1376                                             scsa2usbp->scsa2usb_log_handle,
1377                                             "disable remote wakeup failed "
1378                                             "(%d)", rval);
1379                                 }
1380                         } else {
1381                                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1382                         }
1383 
1384                         (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
1385 
1386                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
1387                 }
1388 
1389                 if (pm) {
1390                         kmem_free(pm, sizeof (scsa2usb_power_t));
1391                 }
1392 
1393                 if (scsa2usbp->scsa2usb_override_str) {
1394                         kmem_free(scsa2usbp->scsa2usb_override_str,
1395                             strlen(scsa2usbp->scsa2usb_override_str) + 1);
1396                         scsa2usbp->scsa2usb_override_str = NULL;
1397                 }
1398 
1399                 /* remove the minor nodes */
1400                 ddi_remove_minor_node(dip, NULL);
1401 
1402                 /* Cancel the registered panic callback */
1403                 scsa2usb_panic_callb_fini(scsa2usbp);
1404 
1405                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1406 
1407                 mutex_destroy(&scsa2usbp->scsa2usb_mutex);
1408                 cv_destroy(&scsa2usbp->scsa2usb_transport_busy_cv);
1409         }
1410 
1411         usb_client_detach(scsa2usbp->scsa2usb_dip,
1412             scsa2usbp->scsa2usb_dev_data);
1413 
1414         if (scsa2usbp->scsa2usb_ugen_hdl) {
1415                 (void) usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
1416                     DDI_DETACH);
1417                 usb_ugen_release_hdl(scsa2usbp->scsa2usb_ugen_hdl);
1418         }
1419 
1420         usb_free_log_hdl(scsa2usbp->scsa2usb_log_handle);
1421 
1422         ddi_prop_remove_all(dip);
1423 
1424         ddi_soft_state_free(scsa2usb_statep, ddi_get_instance(dip));
1425 
1426         return (USB_SUCCESS);
1427 }
1428 
1429 
1430 /*
1431  * scsa2usb_override:
1432  *      some devices may be attached even though their subclass or
1433  *      protocol info is not according to spec.
1434  *      these can be determined by the 'subclass-protocol-override'
1435  *      property set in the conf file.
1436  */
1437 static void
1438 scsa2usb_override(scsa2usb_state_t *scsa2usbp)
1439 {
1440         scsa2usb_ov_t ov;
1441         char    **override_str = NULL;
1442         char    *override_str_cpy;
1443         uint_t  override_str_len, override_str_cpy_len;
1444         uint_t  i;
1445         usb_dev_descr_t *descr = scsa2usbp->scsa2usb_dev_data->dev_descr;
1446 
1447         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
1448 
1449         scsa2usbp->scsa2usb_subclass_override =
1450             scsa2usbp->scsa2usb_protocol_override = 0;
1451 
1452         if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, scsa2usbp->scsa2usb_dip,
1453             DDI_PROP_DONTPASS, "attribute-override-list",
1454             &override_str, &override_str_len) != DDI_PROP_SUCCESS) {
1455 
1456                 return;
1457         }
1458 
1459         /* parse each string in the subclass-protocol-override property */
1460         for (i = 0; i < override_str_len; i++) {
1461 
1462                 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1463                     "override_str[%d] = %s", i, override_str[i]);
1464 
1465                 /*
1466                  * save a copy of the override string for possible
1467                  * inclusion in soft state later
1468                  */
1469                 override_str_cpy_len = strlen(override_str[i]) + 1;
1470                 override_str_cpy = kmem_zalloc(override_str_cpy_len, KM_SLEEP);
1471                 (void) strcpy(override_str_cpy, override_str[i]);
1472 
1473                 bzero(&ov, sizeof (scsa2usb_ov_t));
1474 
1475                 if (scsa2usb_parse_input_str(override_str[i], &ov,
1476                     scsa2usbp) == USB_FAILURE) {
1477                         kmem_free(override_str_cpy, override_str_cpy_len);
1478                         continue;
1479                 }
1480 
1481                 /*
1482                  * see if subclass/protocol needs to be overridden for device
1483                  * or if device should not be power managed
1484                  * if there'a a match, save the override string in soft state
1485                  */
1486                 if (((descr->idVendor == (uint16_t)ov.vid) || (ov.vid == 0)) &&
1487                     ((descr->idProduct == (uint16_t)ov.pid) || (ov.pid == 0)) &&
1488                     ((descr->bcdDevice == (uint16_t)ov.rev) || (ov.rev == 0))) {
1489                         scsa2usbp->scsa2usb_subclass_override = ov.subclass;
1490                         scsa2usbp->scsa2usb_protocol_override = ov.protocol;
1491 
1492                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1493                             scsa2usbp->scsa2usb_log_handle,
1494                             "vid=0x%x pid=0x%x rev=0x%x subclass=0x%x "
1495                             "protocol=0x%x "
1496                             "pmoff=%d fake_removable=%d modesense=%d "
1497                             "reduced-cmd-support=%d",
1498                             ov.vid, ov.pid, ov.rev, ov.subclass, ov.protocol,
1499                             ov.pmoff, ov.fake_removable, ov.no_modesense,
1500                             ov.reduced_cmd_support);
1501 
1502                         if (ov.pmoff) {
1503                                 scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_PM;
1504                         }
1505                         if (ov.fake_removable) {
1506                                 scsa2usbp->scsa2usb_attrs &=
1507                                     ~SCSA2USB_ATTRS_RMB;
1508                         }
1509                         if (ov.no_modesense) {
1510                                 scsa2usbp->scsa2usb_attrs &=
1511                                     ~SCSA2USB_ATTRS_MODE_SENSE;
1512                         }
1513                         if (ov.reduced_cmd_support) {
1514                                 scsa2usbp->scsa2usb_attrs &=
1515                                     ~SCSA2USB_ATTRS_REDUCED_CMD;
1516                         }
1517                         scsa2usbp->scsa2usb_override_str = override_str_cpy;
1518                         break;
1519                 } else {
1520                         kmem_free(override_str_cpy, override_str_cpy_len);
1521                 }
1522         }
1523 
1524         ddi_prop_free(override_str);
1525 }
1526 
1527 
1528 /*
1529  * scsa2usb_parse_input_str:
1530  *      parse one conf file subclass-protocol-override string
1531  *      return vendor id, product id, revision, subclass, protocol
1532  *      function return is success or failure
1533  */
1534 static int
1535 scsa2usb_parse_input_str(char *str, scsa2usb_ov_t *ovp,
1536     scsa2usb_state_t *scsa2usbp)
1537 {
1538         char            *input_field, *input_value;
1539         char            *lasts;
1540         uint_t          i;
1541         u_longlong_t    value;
1542 
1543         /* parse all the input pairs in the string */
1544         for (input_field = scsa2usb_strtok_r(str, "=", &lasts);
1545             input_field != NULL;
1546             input_field = scsa2usb_strtok_r(lasts, "=", &lasts)) {
1547 
1548                 if ((input_value = scsa2usb_strtok_r(lasts, " ", &lasts)) ==
1549                     NULL) {
1550                         scsa2usb_override_error("format", scsa2usbp);
1551 
1552                         return (USB_FAILURE);
1553                 }
1554                 /* if input value is a 'don't care', skip to the next pair */
1555                 if (strcmp(input_value, "*") == 0) {
1556                         continue;
1557                 }
1558                 if (strcasecmp(input_field, "vid") == 0) {
1559                         if (kobj_getvalue(input_value, &value) == -1) {
1560                                 scsa2usb_override_error("vendor id", scsa2usbp);
1561 
1562                                 return (USB_FAILURE);
1563                         }
1564                         ovp->vid = (int)value;
1565                 } else if (strcasecmp(input_field, "pid") == 0) {
1566                         if (kobj_getvalue(input_value, &value) == -1) {
1567                                 scsa2usb_override_error("product id",
1568                                     scsa2usbp);
1569 
1570                                 return (USB_FAILURE);
1571                         }
1572                         ovp->pid = (int)value;
1573                 } else if (strcasecmp(input_field, "rev") == 0) {
1574                         if (kobj_getvalue(input_value, &value) == -1) {
1575                                 scsa2usb_override_error("revision id",
1576                                     scsa2usbp);
1577 
1578                                 return (USB_FAILURE);
1579                         }
1580                         ovp->rev = (int)value;
1581                 } else if (strcasecmp(input_field, "subclass") == 0) {
1582                         for (i = 0; i < N_SCSA2USB_SUBC_OVERRIDE; i++) {
1583                                 if (strcasecmp(input_value,
1584                                     scsa2usb_subclass[i].name) == 0) {
1585                                         ovp->subclass =
1586                                             scsa2usb_subclass[i].value;
1587                                         break;
1588                                 }
1589                         }
1590                         if (ovp->subclass == 0) {
1591                                 scsa2usb_override_error("subclass", scsa2usbp);
1592 
1593                                 return (USB_FAILURE);
1594                         }
1595                 } else if (strcasecmp(input_field, "protocol") == 0) {
1596                         for (i = 0; i < N_SCSA2USB_PROT_OVERRIDE; i++) {
1597                                 if (strcasecmp(input_value,
1598                                     scsa2usb_protocol[i].name) == 0) {
1599                                         ovp->protocol =
1600                                             scsa2usb_protocol[i].value;
1601                                         break;
1602                                 }
1603                         }
1604                         if (ovp->protocol == 0) {
1605                                 scsa2usb_override_error("protocol", scsa2usbp);
1606 
1607                                 return (USB_FAILURE);
1608                         }
1609                 } else if (strcasecmp(input_field, "pm") == 0) {
1610                         if (strcasecmp(input_value, "off") == 0) {
1611                                 ovp->pmoff = 1;
1612                                 break;
1613                         } else {
1614                                 scsa2usb_override_error("pm", scsa2usbp);
1615 
1616                                 return (USB_FAILURE);
1617                         }
1618                 } else if (strcasecmp(input_field, "removable") == 0) {
1619                         if (strcasecmp(input_value, "true") == 0) {
1620                                 ovp->fake_removable = 1;
1621                                 break;
1622                         } else {
1623                                 scsa2usb_override_error("removable", scsa2usbp);
1624 
1625                                 return (USB_FAILURE);
1626                         }
1627                 } else if (strcasecmp(input_field, "modesense") == 0) {
1628                         if (strcasecmp(input_value, "false") == 0) {
1629                                 ovp->no_modesense = 1;
1630                                 break;
1631                         } else {
1632                                 scsa2usb_override_error("modesense",
1633                                     scsa2usbp);
1634 
1635                                 return (USB_FAILURE);
1636                         }
1637                 } else if (strcasecmp(input_field,
1638                     "reduced-cmd-support") == 0) {
1639                         if (strcasecmp(input_value, "true") == 0) {
1640                                 ovp->reduced_cmd_support = 1;
1641                                 break;
1642                         } else {
1643                                 scsa2usb_override_error(
1644                                     "reduced-cmd-support", scsa2usbp);
1645 
1646                                 return (USB_FAILURE);
1647                         }
1648                 } else {
1649                         scsa2usb_override_error(input_field, scsa2usbp);
1650 
1651                         return (USB_FAILURE);
1652                 }
1653         }
1654 
1655         return (USB_SUCCESS);
1656 }
1657 
1658 
1659 /*
1660  * scsa2usb_override_error:
1661  *      print an error message if conf file string is bad format
1662  */
1663 static void
1664 scsa2usb_override_error(char *input_field, scsa2usb_state_t *scsa2usbp)
1665 {
1666         USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1667             "invalid %s in scsa2usb.conf file entry", input_field);
1668 }
1669 
1670 /*
1671  * scsa2usb_strtok_r:
1672  *      parse a list of tokens
1673  */
1674 static char *
1675 scsa2usb_strtok_r(char *p, char *sep, char **lasts)
1676 {
1677         char    *e;
1678         char    *tok = NULL;
1679 
1680         if (p == 0 || *p == 0) {
1681 
1682                 return (NULL);
1683         }
1684 
1685         e = p+strlen(p);
1686 
1687         do {
1688                 if (strchr(sep, *p) != NULL) {
1689                         if (tok != NULL) {
1690                                 *p = 0;
1691                                 *lasts = p+1;
1692 
1693                                 return (tok);
1694                         }
1695                 } else if (tok == NULL) {
1696                         tok = p;
1697                 }
1698         } while (++p < e);
1699 
1700         *lasts = NULL;
1701 
1702         return (tok);
1703 }
1704 
1705 
1706 /*
1707  * scsa2usb_validate_attrs:
1708  *      many devices have BO/CB/CBI protocol support issues.
1709  *      use vendor/product info to reset the
1710  *      individual erroneous attributes
1711  *
1712  * NOTE: we look at only device at a time (at attach time)
1713  */
1714 static void
1715 scsa2usb_validate_attrs(scsa2usb_state_t *scsa2usbp)
1716 {
1717         int i, mask;
1718         usb_dev_descr_t *desc = scsa2usbp->scsa2usb_dev_data->dev_descr;
1719 
1720         if (!SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1721                 scsa2usbp->scsa2usb_attrs &= ~SCSA2USB_ATTRS_GET_LUN;
1722         }
1723 
1724         /* determine if this device is on the blacklist */
1725         for (i = 0; i < N_SCSA2USB_BLACKLIST; i++) {
1726                 if ((scsa2usb_blacklist[i].idVendor == desc->idVendor) &&
1727                     ((scsa2usb_blacklist[i].idProduct == desc->idProduct) ||
1728                     (scsa2usb_blacklist[i].idProduct == X))) {
1729                         scsa2usbp->scsa2usb_attrs &=
1730                             ~(scsa2usb_blacklist[i].attributes);
1731                         break;
1732                 }
1733         }
1734 
1735         /*
1736          * Mitsumi's CD-RW drives subclass isn't UFI.
1737          * But they support UFI command-set (this code ensures that)
1738          * NOTE: This is a special case, and is being called out so.
1739          */
1740         if (desc->idVendor == MS_MITSUMI_VID) {
1741                 mask = scsa2usbp->scsa2usb_cmd_protocol & SCSA2USB_CMDSET_MASK;
1742                 if (mask) {
1743                         scsa2usbp->scsa2usb_cmd_protocol &= ~mask;
1744                 }
1745                 scsa2usbp->scsa2usb_cmd_protocol |= SCSA2USB_UFI_CMDSET;
1746         }
1747 
1748         if (scsa2usbp->scsa2usb_attrs != SCSA2USB_ALL_ATTRS) {
1749                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1750                     scsa2usbp->scsa2usb_log_handle,
1751                     "scsa2usb attributes modified: 0x%x",
1752                     scsa2usbp->scsa2usb_attrs);
1753         }
1754 }
1755 
1756 
1757 /*
1758  * scsa2usb_create_luns:
1759  *      check the number of luns but continue if the check fails,
1760  *      create child nodes for each lun
1761  */
1762 static void
1763 scsa2usb_create_luns(scsa2usb_state_t *scsa2usbp)
1764 {
1765         int             lun, rval;
1766         char            *compatible[MAX_COMPAT_NAMES];  /* compatible names */
1767         dev_info_t      *cdip;
1768         uchar_t         dtype;
1769         char            *node_name;
1770         char            *driver_name = NULL;
1771 
1772         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1773             "scsa2usb_create_luns:");
1774 
1775         mutex_enter(&scsa2usbp->scsa2usb_mutex);
1776 
1777         /* Set n_luns to 1 by default (for floppies and other devices) */
1778         scsa2usbp->scsa2usb_n_luns = 1;
1779 
1780         /*
1781          * Check if there are any device out there which don't
1782          * support the GET_MAX_LUN command. If so, don't issue
1783          * control request to them.
1784          */
1785         if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_LUN) == 0) {
1786                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1787                     "get_max_lun cmd not supported");
1788         } else {
1789                 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
1790                         scsa2usbp->scsa2usb_n_luns =
1791                             scsa2usb_bulk_only_get_max_lun(scsa2usbp);
1792                 }
1793         }
1794 
1795         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1796             "scsa2usb_create_luns: %d luns found", scsa2usbp->scsa2usb_n_luns);
1797 
1798         /*
1799          * create disk child for each lun
1800          */
1801         for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
1802                 ASSERT(scsa2usbp->scsa2usb_lun_dip[lun] == NULL);
1803 
1804                 /* do an inquiry to get the dtype of this lun */
1805                 scsa2usb_do_inquiry(scsa2usbp, 0, lun);
1806 
1807                 dtype = scsa2usbp->scsa2usb_lun_inquiry[lun].
1808                     inq_dtype & DTYPE_MASK;
1809 
1810                 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
1811                     "dtype[%d]=0x%x", lun, dtype);
1812 
1813                 driver_name = NULL;
1814 
1815                 switch (dtype) {
1816                 case DTYPE_DIRECT:
1817                 case DTYPE_RODIRECT:
1818                 case DTYPE_OPTICAL:
1819                         node_name = "disk";
1820                         driver_name = "sd";
1821 
1822                         break;
1823                 case DTYPE_SEQUENTIAL:
1824                         node_name = "tape";
1825                         driver_name = "st";
1826 
1827                         break;
1828                 case DTYPE_PRINTER:
1829                         node_name = "printer";
1830 
1831                         break;
1832                 case DTYPE_PROCESSOR:
1833                         node_name = "processor";
1834 
1835                         break;
1836                 case DTYPE_WORM:
1837                         node_name = "worm";
1838 
1839                         break;
1840                 case DTYPE_SCANNER:
1841                         node_name = "scanner";
1842 
1843                         break;
1844                 case DTYPE_CHANGER:
1845                         node_name = "changer";
1846 
1847                         break;
1848                 case DTYPE_COMM:
1849                         node_name = "comm";
1850 
1851                         break;
1852                 case DTYPE_ARRAY_CTRL:
1853                         node_name = "array_ctrl";
1854 
1855                         break;
1856                 case DTYPE_ESI:
1857                         node_name = "esi";
1858                         driver_name = "ses";
1859 
1860                         break;
1861                 default:
1862                         node_name = "generic";
1863 
1864                         break;
1865                 }
1866 
1867                 if (driver_name) {
1868                         compatible[0] = driver_name;
1869                 }
1870 
1871                 ndi_devi_alloc_sleep(scsa2usbp->scsa2usb_dip, node_name,
1872                     (pnode_t)DEVI_SID_NODEID, &cdip);
1873 
1874                 /* attach target & lun properties */
1875                 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", 0);
1876                 if (rval != DDI_PROP_SUCCESS) {
1877                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1878                             scsa2usbp->scsa2usb_log_handle,
1879                             "ndi_prop_update_int target failed %d", rval);
1880                         (void) ndi_devi_free(cdip);
1881                         continue;
1882                 }
1883 
1884                 rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip,
1885                     "hotpluggable");
1886                 if (rval != DDI_PROP_SUCCESS) {
1887                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1888                             scsa2usbp->scsa2usb_log_handle,
1889                             "ndi_prop_create_boolean hotpluggable failed %d",
1890                             rval);
1891                         ddi_prop_remove_all(cdip);
1892                         (void) ndi_devi_free(cdip);
1893                         continue;
1894                 }
1895                 /*
1896                  * Some devices don't support LOG SENSE, so tells
1897                  * sd driver not to send this command.
1898                  */
1899                 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
1900                     "pm-capable", 1);
1901                 if (rval != DDI_PROP_SUCCESS) {
1902                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1903                             scsa2usbp->scsa2usb_log_handle,
1904                             "ndi_prop_update_int pm-capable failed %d", rval);
1905                         ddi_prop_remove_all(cdip);
1906                         (void) ndi_devi_free(cdip);
1907                         continue;
1908                 }
1909 
1910                 rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", lun);
1911                 if (rval != DDI_PROP_SUCCESS) {
1912                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1913                             scsa2usbp->scsa2usb_log_handle,
1914                             "ndi_prop_update_int lun failed %d", rval);
1915                         ddi_prop_remove_all(cdip);
1916                         (void) ndi_devi_free(cdip);
1917                         continue;
1918                 }
1919 
1920                 if (driver_name) {
1921                         rval = ndi_prop_update_string_array(DDI_DEV_T_NONE,
1922                             cdip, "compatible", (char **)compatible,
1923                             MAX_COMPAT_NAMES);
1924                         if (rval != DDI_PROP_SUCCESS) {
1925                                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1926                                     scsa2usbp->scsa2usb_log_handle,
1927                                     "ndi_prop_update_string_array failed %d",
1928                                     rval);
1929                                 ddi_prop_remove_all(cdip);
1930                                 (void) ndi_devi_free(cdip);
1931                                 continue;
1932                         }
1933                 }
1934 
1935                 /*
1936                  * add property "usb" so we always verify that it is our child
1937                  */
1938                 rval = ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb");
1939                 if (rval != DDI_PROP_SUCCESS) {
1940                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
1941                             scsa2usbp->scsa2usb_log_handle,
1942                             "ndi_prop_create_boolean failed %d", rval);
1943                         ddi_prop_remove_all(cdip);
1944                         (void) ndi_devi_free(cdip);
1945                         continue;
1946                 }
1947 
1948                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
1949                 (void) ddi_initchild(scsa2usbp->scsa2usb_dip, cdip);
1950                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
1951 
1952                 usba_set_usba_device(cdip,
1953                     usba_get_usba_device(scsa2usbp->scsa2usb_dip));
1954         }
1955         mutex_exit(&scsa2usbp->scsa2usb_mutex);
1956 }
1957 
1958 
1959 /*
1960  * scsa2usb_is_usb:
1961  *      scsa2usb gets called for all possible sd children.
1962  *      we can only accept usb children
1963  */
1964 static int
1965 scsa2usb_is_usb(dev_info_t *dip)
1966 {
1967         if (dip) {
1968                 return (ddi_prop_exists(DDI_DEV_T_ANY, dip,
1969                     DDI_PROP_DONTPASS, "usb"));
1970         }
1971         return (0);
1972 }
1973 
1974 
1975 /*
1976  * Panic Stuff
1977  * scsa2usb_panic_callb_init:
1978  *      initialize PANIC callb and free allocated resources
1979  */
1980 static void
1981 scsa2usb_panic_callb_init(scsa2usb_state_t *scsa2usbp)
1982 {
1983         /*
1984          * In case the system panics, the sync command flushes
1985          * dirty FS pages or buffers. This would cause a hang
1986          * in USB.
1987          * The reason for the failure is that we enter
1988          * polled mode (interrupts disabled) and HCD gets stuck
1989          * trying to execute bulk requests
1990          * The panic_callback registered below provides a warning
1991          * that a panic has occurred and from that point onwards, we
1992          * complete each request successfully and immediately. This
1993          * will fake successful syncing so at least the rest of the
1994          * filesystems complete syncing.
1995          */
1996         scsa2usbp->scsa2usb_panic_info =
1997             kmem_zalloc(sizeof (scsa2usb_cpr_t), KM_SLEEP);
1998         mutex_init(&scsa2usbp->scsa2usb_panic_info->lockp,
1999             NULL, MUTEX_DRIVER,
2000             scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2001         scsa2usbp->scsa2usb_panic_info->statep = scsa2usbp;
2002         scsa2usbp->scsa2usb_panic_info->cpr.cc_lockp =
2003             &scsa2usbp->scsa2usb_panic_info->lockp;
2004         scsa2usbp->scsa2usb_panic_info->cpr.cc_id =
2005             callb_add(scsa2usb_panic_callb,
2006             (void *)scsa2usbp->scsa2usb_panic_info,
2007             CB_CL_PANIC, "scsa2usb");
2008 }
2009 
2010 
2011 /*
2012  * scsa2usb_panic_callb_fini:
2013  *      cancel out PANIC callb and free allocated resources
2014  */
2015 static void
2016 scsa2usb_panic_callb_fini(scsa2usb_state_t *scsa2usbp)
2017 {
2018         if (scsa2usbp->scsa2usb_panic_info) {
2019                 SCSA2USB_CANCEL_CB(scsa2usbp->scsa2usb_panic_info->cpr.cc_id);
2020                 mutex_destroy(&scsa2usbp->scsa2usb_panic_info->lockp);
2021                 scsa2usbp->scsa2usb_panic_info->statep = NULL;
2022                 kmem_free(scsa2usbp->scsa2usb_panic_info,
2023                     sizeof (scsa2usb_cpr_t));
2024                 scsa2usbp->scsa2usb_panic_info = NULL;
2025         }
2026 }
2027 
2028 
2029 /*
2030  * scsa2usb_panic_callb:
2031  *      This routine is called when there is a system panic.
2032  */
2033 /* ARGSUSED */
2034 static boolean_t
2035 scsa2usb_panic_callb(void *arg, int code)
2036 {
2037         scsa2usb_cpr_t *cpr_infop;
2038         scsa2usb_state_t *scsa2usbp;
2039         uint_t          lun;
2040 
2041         _NOTE(NO_COMPETING_THREADS_NOW);
2042         cpr_infop = (scsa2usb_cpr_t *)arg;
2043         scsa2usbp = (scsa2usb_state_t *)cpr_infop->statep;
2044 
2045         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2046             "scsa2usb_panic_callb: code=%d", code);
2047 
2048         /*
2049          * If we return error here, "sd" prints lots of error
2050          * messages and could retry the same pkt over and over again.
2051          * The sync recovery isn't "smooth" in that case. By faking
2052          * a success return, instead,  we force sync to complete.
2053          */
2054         if (scsa2usbp->scsa2usb_cur_pkt) {
2055                 /*
2056                  * Do not print the "no sync" warning here. it will then be
2057                  * displayed before we actually start syncing. Also we don't
2058                  * replace this code with a call to scsa2usb_pkt_completion().
2059                  * NOTE: mutexes are disabled during panic.
2060                  */
2061                 scsa2usbp->scsa2usb_cur_pkt->pkt_reason = CMD_CMPLT;
2062                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2063                 scsa2usb_pkt_completion(scsa2usbp, scsa2usbp->scsa2usb_cur_pkt);
2064                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2065         }
2066 
2067         /* get rid of waitQ */
2068         for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
2069                 scsa2usb_flush_waitQ(scsa2usbp, lun, CMD_CMPLT);
2070         }
2071 
2072 #ifndef lint
2073         _NOTE(COMPETING_THREADS_NOW);
2074 #endif
2075 
2076         return (B_TRUE);
2077 }
2078 
2079 /*
2080  * scsa2usb_cpr_suspend
2081  *      determine if the device's state can be changed to SUSPENDED
2082  *      close pipes if there is no activity
2083  */
2084 /* ARGSUSED */
2085 static int
2086 scsa2usb_cpr_suspend(dev_info_t *dip)
2087 {
2088         scsa2usb_state_t *scsa2usbp;
2089         int     prev_state;
2090         int     rval = USB_FAILURE;
2091 
2092         scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2093 
2094         ASSERT(scsa2usbp != NULL);
2095 
2096         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2097             "scsa2usb_cpr_suspend:");
2098 
2099         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2100         switch (scsa2usbp->scsa2usb_dev_state) {
2101         case USB_DEV_ONLINE:
2102         case USB_DEV_PWRED_DOWN:
2103         case USB_DEV_DISCONNECTED:
2104                 prev_state = scsa2usbp->scsa2usb_dev_state;
2105                 scsa2usbp->scsa2usb_dev_state = USB_DEV_SUSPENDED;
2106 
2107                 /*
2108                  * If the device is busy, we cannot suspend
2109                  */
2110                 if (SCSA2USB_BUSY(scsa2usbp)) {
2111                         USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2112                             scsa2usbp->scsa2usb_log_handle,
2113                             "scsa2usb_cpr_suspend: I/O active");
2114 
2115                         /* fall back to previous state */
2116                         scsa2usbp->scsa2usb_dev_state = prev_state;
2117                 } else {
2118                         rval = USB_SUCCESS;
2119                 }
2120 
2121                 break;
2122         case USB_DEV_SUSPENDED:
2123         default:
2124                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2125                     "scsa2usb_cpr_suspend: Illegal dev state: %d",
2126                     scsa2usbp->scsa2usb_dev_state);
2127 
2128                 break;
2129         }
2130         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2131 
2132         if ((rval == USB_SUCCESS) && scsa2usbp->scsa2usb_ugen_hdl) {
2133                 rval = usb_ugen_detach(scsa2usbp->scsa2usb_ugen_hdl,
2134                     DDI_SUSPEND);
2135         }
2136 
2137         return (rval);
2138 }
2139 
2140 
2141 /*
2142  * scsa2usb_cpr_resume:
2143  *      restore device's state
2144  */
2145 static void
2146 scsa2usb_cpr_resume(dev_info_t *dip)
2147 {
2148         scsa2usb_state_t *scsa2usbp =
2149             ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2150 
2151         ASSERT(scsa2usbp != NULL);
2152 
2153         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2154             "scsa2usb_cpr_resume: dip = 0x%p", (void *)dip);
2155 
2156         scsa2usb_restore_device_state(dip, scsa2usbp);
2157 
2158         if (scsa2usbp->scsa2usb_ugen_hdl) {
2159                 (void) usb_ugen_attach(scsa2usbp->scsa2usb_ugen_hdl,
2160                     DDI_RESUME);
2161         }
2162 }
2163 
2164 
2165 /*
2166  * scsa2usb_restore_device_state:
2167  *      - raise the device's power
2168  *      - reopen all the pipes
2169  */
2170 static void
2171 scsa2usb_restore_device_state(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
2172 {
2173         uint_t  prev_state;
2174 
2175         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2176             "scsa2usb_restore_device_state:");
2177 
2178         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2179         prev_state = scsa2usbp->scsa2usb_dev_state;
2180 
2181         scsa2usb_raise_power(scsa2usbp);
2182 
2183         ASSERT((prev_state == USB_DEV_DISCONNECTED) ||
2184             (prev_state == USB_DEV_SUSPENDED));
2185 
2186         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2187 
2188         /* Check for the same device */
2189         if (usb_check_same_device(dip, scsa2usbp->scsa2usb_log_handle,
2190             USB_LOG_L0, DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
2191 
2192                 /* change the flags to active */
2193                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2194                 scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
2195                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2196 
2197                 scsa2usb_pm_idle_component(scsa2usbp);
2198 
2199                 return;
2200         }
2201 
2202         /*
2203          * if the device had remote wakeup earlier,
2204          * enable it again
2205          */
2206         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2207         if (scsa2usbp->scsa2usb_pm &&
2208             scsa2usbp->scsa2usb_pm->scsa2usb_wakeup_enabled) {
2209                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2210                 (void) usb_handle_remote_wakeup(scsa2usbp->scsa2usb_dip,
2211                     USB_REMOTE_WAKEUP_ENABLE);
2212                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2213         }
2214 
2215         scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
2216         scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
2217         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2218 
2219         scsa2usb_pm_idle_component(scsa2usbp);
2220 }
2221 
2222 
2223 /*
2224  * SCSA entry points:
2225  *
2226  * scsa2usb_scsi_tgt_probe:
2227  * scsa functions are exported by means of the transport table
2228  * Issue a probe to get the inquiry data.
2229  */
2230 /* ARGSUSED */
2231 static int
2232 scsa2usb_scsi_tgt_probe(struct scsi_device *sd, int (*waitfunc)(void))
2233 {
2234         scsi_hba_tran_t *tran;
2235         scsa2usb_state_t *scsa2usbp;
2236         dev_info_t *dip = ddi_get_parent(sd->sd_dev);
2237         int     rval;
2238 
2239         ASSERT(dip);
2240 
2241         tran = ddi_get_driver_private(dip);
2242         ASSERT(tran != NULL);
2243         scsa2usbp = (scsa2usb_state_t *)tran->tran_hba_private;
2244         ASSERT(scsa2usbp);
2245 
2246         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2247             "scsa2usb_scsi_tgt_probe:");
2248 
2249         /* if device is disconnected (ie. pipes closed), fail immediately */
2250         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2251         if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2252                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2253 
2254                 return (SCSIPROBE_FAILURE);
2255         }
2256         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2257 
2258         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2259             "scsa2usb_scsi_tgt_probe: scsi_device = 0x%p", (void *)sd);
2260 
2261         if ((rval = scsi_hba_probe(sd, waitfunc)) == SCSIPROBE_EXISTS) {
2262                 /*
2263                  * respect the removable bit on all USB storage devices
2264                  * unless overridden by a scsa2usb.conf entry
2265                  */
2266                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2267                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_RMB)) {
2268                         _NOTE(SCHEME_PROTECTS_DATA("unshared", scsi_inquiry))
2269                         sd->sd_inq->inq_rmb = 1;
2270                 }
2271                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2272         }
2273 
2274         return (rval);
2275 }
2276 
2277 
2278 /*
2279  * scsa2usb_scsi_tgt_init:
2280  *      check whether we created this child ourselves
2281  */
2282 /* ARGSUSED */
2283 static int
2284 scsa2usb_scsi_tgt_init(dev_info_t *dip, dev_info_t *cdip,
2285     scsi_hba_tran_t *tran, struct scsi_device *sd)
2286 {
2287         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2288             tran->tran_hba_private;
2289         int lun;
2290         int t_len = sizeof (lun);
2291 
2292         if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2293             DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2294             &t_len) != DDI_PROP_SUCCESS) {
2295 
2296                 return (DDI_FAILURE);
2297         }
2298 
2299         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2300             "scsa2usb_scsi_tgt_init: %s, lun%d", ddi_driver_name(cdip), lun);
2301 
2302         /* is this a child we created? */
2303         if (scsa2usb_is_usb(cdip) == 0) {
2304 
2305                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2306                     "scsa2usb_scsi_tgt_init: new child %s%d",
2307                     ddi_driver_name(cdip), ddi_get_instance(cdip));
2308 
2309                 /*
2310                  * add property "usb" so we can always verify that it
2311                  * is our child
2312                  */
2313                 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, cdip, "usb") !=
2314                     DDI_PROP_SUCCESS) {
2315                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2316                             scsa2usbp->scsa2usb_log_handle,
2317                             "ndi_prop_create_boolean failed");
2318 
2319                         return (DDI_FAILURE);
2320                 }
2321 
2322                 usba_set_usba_device(cdip,
2323                     usba_get_usba_device(scsa2usbp->scsa2usb_dip));
2324 
2325                 /*
2326                  * we don't store this dip in scsa2usb_lun_dip, there
2327                  * might be multiple dips for the same device
2328                  */
2329 
2330                 return (DDI_SUCCESS);
2331         }
2332 
2333         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2334         if ((lun >= scsa2usbp->scsa2usb_n_luns) ||
2335             (scsa2usbp->scsa2usb_lun_dip[lun] != NULL)) {
2336                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2337 
2338                 return (DDI_FAILURE);
2339         }
2340 
2341         scsa2usbp->scsa2usb_lun_dip[lun] = cdip;
2342         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2343 
2344         return (DDI_SUCCESS);
2345 }
2346 
2347 
2348 /*
2349  * scsa2usb_scsi_tgt_free:
2350  */
2351 /* ARGSUSED */
2352 static void
2353 scsa2usb_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *cdip,
2354         scsi_hba_tran_t *tran, struct scsi_device *sd)
2355 {
2356         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)
2357             tran->tran_hba_private;
2358         int lun;
2359         int t_len = sizeof (lun);
2360 
2361         /* is this our child? */
2362         if (scsa2usb_is_usb(cdip) == 0) {
2363 
2364                 return;
2365         }
2366 
2367         if (ddi_prop_op(DDI_DEV_T_ANY, cdip, PROP_LEN_AND_VAL_BUF,
2368             DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP, "lun", (caddr_t)&lun,
2369             &t_len) != DDI_PROP_SUCCESS) {
2370 
2371                 return;
2372         }
2373 
2374         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2375             "scsa2usb_scsi_tgt_free: %s lun%d", ddi_driver_name(cdip), lun);
2376 
2377         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2378         if (lun < scsa2usbp->scsa2usb_n_luns) {
2379                 if (scsa2usbp->scsa2usb_lun_dip[lun] == cdip) {
2380                         scsa2usbp->scsa2usb_lun_dip[lun] = NULL;
2381                 }
2382         }
2383         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2384 }
2385 
2386 
2387 /*
2388  * bus enumeration entry points
2389  */
2390 static int
2391 scsa2usb_scsi_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2392     void *arg, dev_info_t **child)
2393 {
2394         int     circ;
2395         int     rval;
2396 
2397         scsa2usb_state_t *scsa2usbp =
2398             ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2399 
2400         ASSERT(scsa2usbp != NULL);
2401 
2402         USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2403             "scsa2usb_scsi_bus_config: op=%d", op);
2404 
2405         if (scsa2usb_scsi_bus_config_debug) {
2406                 flag |= NDI_DEVI_DEBUG;
2407         }
2408 
2409         ndi_devi_enter(dip, &circ);
2410         /* create children if necessary */
2411         if (DEVI(dip)->devi_child == NULL) {
2412                 scsa2usb_create_luns(scsa2usbp);
2413         }
2414 
2415         rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0);
2416 
2417         ndi_devi_exit(dip, circ);
2418 
2419         return (rval);
2420 }
2421 
2422 
2423 static int
2424 scsa2usb_scsi_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op,
2425     void *arg)
2426 {
2427         scsa2usb_state_t *scsa2usbp =
2428             ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
2429 
2430         int             circular_count;
2431         int             rval = NDI_SUCCESS;
2432         uint_t          save_flag = flag;
2433 
2434         ASSERT(scsa2usbp != NULL);
2435 
2436         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2437             "scsa2usb_scsi_bus_unconfig: op=%d", op);
2438 
2439         if (scsa2usb_scsi_bus_config_debug) {
2440                 flag |= NDI_DEVI_DEBUG;
2441         }
2442 
2443         /*
2444          * first offline and if offlining successful, then
2445          * remove children
2446          */
2447         if (op == BUS_UNCONFIG_ALL) {
2448                 flag &= ~(NDI_DEVI_REMOVE | NDI_UNCONFIG);
2449         }
2450 
2451         ndi_devi_enter(dip, &circular_count);
2452         rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2453 
2454         /*
2455          * If unconfig is successful and not part of modunload
2456          * daemon, attempt to remove children.
2457          */
2458         if (op == BUS_UNCONFIG_ALL && rval == NDI_SUCCESS &&
2459             (flag & NDI_AUTODETACH) == 0) {
2460                 flag |= NDI_DEVI_REMOVE;
2461                 rval = ndi_busop_bus_unconfig(dip, flag, op, arg);
2462         }
2463         ndi_devi_exit(dip, circular_count);
2464 
2465         if ((rval != NDI_SUCCESS) && (op == BUS_UNCONFIG_ALL) &&
2466             (save_flag & NDI_DEVI_REMOVE)) {
2467                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2468                 if (scsa2usbp->scsa2usb_warning_given != B_TRUE) {
2469                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2470                             scsa2usbp->scsa2usb_log_handle,
2471                             "Disconnected device was busy, "
2472                             "please reconnect.");
2473                         scsa2usbp->scsa2usb_warning_given = B_TRUE;
2474                 }
2475                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2476         }
2477 
2478         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2479             "scsa2usb_scsi_bus_unconfig: rval=%d", rval);
2480 
2481         return (rval);
2482 }
2483 
2484 
2485 /*
2486  * scsa2usb_scsi_init_pkt:
2487  *      Set up the scsi_pkt for transport. Also initialize
2488  *      scsa2usb_cmd struct for the transport.
2489  *      NOTE: We do not do any DMA setup here as USBA framework
2490  *      does that for us.
2491  */
2492 static struct scsi_pkt *
2493 scsa2usb_scsi_init_pkt(struct scsi_address *ap,
2494     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
2495     int tgtlen, int flags, int (*callback)(), caddr_t arg)
2496 {
2497         scsa2usb_cmd_t   *cmd;
2498         scsa2usb_state_t *scsa2usbp;
2499         struct scsi_pkt  *in_pkt = pkt;
2500 
2501         ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
2502 
2503         scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2504 
2505         /* Print sync message */
2506         if (ddi_in_panic()) {
2507                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2508                 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2509                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2510                 /* continue so caller will not hang or complain */
2511         }
2512 
2513         /* allocate a pkt, if none already allocated */
2514         if (pkt == NULL) {
2515                 if (statuslen < sizeof (struct scsi_arq_status)) {
2516                         statuslen = sizeof (struct scsi_arq_status);
2517                 }
2518 
2519                 pkt = scsi_hba_pkt_alloc(scsa2usbp->scsa2usb_dip, ap, cmdlen,
2520                     statuslen, tgtlen, sizeof (scsa2usb_cmd_t),
2521                     callback, arg);
2522                 if (pkt == NULL) {
2523 
2524                         return (NULL);
2525                 }
2526 
2527                 cmd = PKT2CMD(pkt);
2528                 cmd->cmd_pkt = pkt; /* back link to pkt */
2529                 cmd->cmd_scblen      = statuslen;
2530                 cmd->cmd_cdblen      = (uchar_t)cmdlen;
2531 
2532                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2533                 cmd->cmd_tag = scsa2usbp->scsa2usb_tag++;
2534                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2535 
2536                 cmd->cmd_bp  = bp;
2537                 /*
2538                  * The buffer size of cmd->cmd_scb is constrained
2539                  * to sizeof (struct scsi_arq_status), if the scblen
2540                  * is bigger than that, we use pkt->pkt_scbp directly.
2541                  */
2542                 if (cmd->cmd_scblen == sizeof (struct scsi_arq_status)) {
2543                         pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
2544                 }
2545 
2546                 usba_init_list(&cmd->cmd_waitQ, (usb_opaque_t)cmd,
2547                     scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
2548         } else {
2549                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2550                     "scsa2usb: pkt != NULL");
2551 
2552                 /* nothing to do */
2553         }
2554 
2555         if (bp && (bp->b_bcount != 0)) {
2556                 if ((bp_mapin_common(bp, (callback == SLEEP_FUNC) ?
2557                     VM_SLEEP : VM_NOSLEEP)) == NULL) {
2558                         if (pkt != in_pkt) {
2559                                 scsi_hba_pkt_free(ap, pkt);
2560                         }
2561 
2562                         return (NULL);
2563                 }
2564 
2565                 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
2566                     scsa2usbp->scsa2usb_log_handle,
2567                     "scsa2usb_scsi_init_pkt: mapped in 0x%p, addr=0x%p",
2568                     (void *)bp, (void *)bp->b_un.b_addr);
2569         }
2570 
2571         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2572             "scsa2usb_scsi_init_pkt: ap = 0x%p pkt: 0x%p\n\t"
2573             "bp = 0x%p cmdlen = %x stlen = 0x%x tlen = 0x%x flags = 0x%x",
2574             (void *)ap, (void *)pkt, (void *)bp, cmdlen, statuslen,
2575             tgtlen, flags);
2576 
2577         return (pkt);
2578 }
2579 
2580 
2581 /*
2582  * scsa2usb_scsi_destroy_pkt:
2583  *      We are done with the packet. Get rid of it.
2584  */
2585 static void
2586 scsa2usb_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2587 {
2588         scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
2589         scsa2usb_state_t *scsa2usbp = ADDR2SCSA2USB(ap);
2590 
2591         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2592             "scsa2usb_scsi_destroy_pkt: pkt=0x%p", (void *)pkt);
2593 
2594         usba_destroy_list(&cmd->cmd_waitQ);
2595         scsi_hba_pkt_free(ap, pkt);
2596 }
2597 
2598 
2599 /*
2600  * scsa2usb_scsi_start:
2601  *      For each command being issued, build up the CDB
2602  *      and call scsi_transport to issue the command. This
2603  *      function is based on the assumption that USB allows
2604  *      a subset of SCSI commands. Other SCSI commands we fail.
2605  */
2606 static int
2607 scsa2usb_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2608 {
2609         scsa2usb_cmd_t          *cmd;
2610         scsa2usb_state_t        *scsa2usbp = ADDR2SCSA2USB(ap);
2611         uint_t                  lun = ap->a_lun;
2612 
2613         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2614 
2615         cmd = PKT2CMD(pkt);
2616         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2617             "scsa2usb_scsi_start:\n\t"
2618             "bp: 0x%p ap: 0x%p pkt: 0x%p flag: 0x%x time: 0x%x\n\tcdb0: 0x%x "
2619             "dev_state: 0x%x pkt_state: 0x%x flags: 0x%x pipe_state: 0x%x",
2620             (void *)cmd->cmd_bp, (void *)ap, (void *)pkt, pkt->pkt_flags,
2621             pkt->pkt_time, pkt->pkt_cdbp[0], scsa2usbp->scsa2usb_dev_state,
2622             scsa2usbp->scsa2usb_pkt_state, scsa2usbp->scsa2usb_flags,
2623             scsa2usbp->scsa2usb_pipe_state);
2624 
2625         if (pkt->pkt_time == 0) {
2626                 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2627                     "pkt submitted with 0 timeout which may cause indefinite "
2628                     "hangs");
2629         }
2630 
2631         /*
2632          * if we are in panic, we are in polled mode, so we can just
2633          * accept the request, drop it and return
2634          * if we fail this request, the rest of the file systems do not
2635          * get synced
2636          */
2637         if (ddi_in_panic()) {
2638                 extern int do_polled_io;
2639 
2640                 ASSERT(do_polled_io);
2641                 scsa2usb_prepare_pkt(scsa2usbp, pkt);
2642                 SCSA2USB_PRINT_SYNC_MSG(scsa2usb_sync_message, scsa2usbp);
2643                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2644 
2645                 return (TRAN_ACCEPT);
2646         }
2647 
2648         /* we cannot do polling, this should not happen */
2649         if (pkt->pkt_flags & FLAG_NOINTR) {
2650                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2651                     "NOINTR packet: opcode = 0%x", pkt->pkt_cdbp[0]);
2652                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2653 
2654                 return (TRAN_BADPKT);
2655         }
2656 
2657         /* prepare packet */
2658         scsa2usb_prepare_pkt(scsa2usbp, pkt);
2659 
2660         /* just queue up the requests in the waitQ if below max */
2661         if (usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]) >
2662             SCSA2USB_MAX_REQ_PER_LUN) {
2663                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2664                     scsa2usbp->scsa2usb_log_handle,
2665                     "scsa2usb_scsi_start: limit (%d) exceeded",
2666                     SCSA2USB_MAX_REQ_PER_LUN);
2667                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2668 
2669                 return (TRAN_BUSY);
2670         }
2671 
2672         usba_add_to_list(&scsa2usbp->scsa2usb_waitQ[lun], &cmd->cmd_waitQ);
2673 
2674         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2675             "scsa2usb_work_thread_id=0x%p, count=%d, lun=%d",
2676             (void *)scsa2usbp->scsa2usb_work_thread_id,
2677             usba_list_entry_count(&scsa2usbp->scsa2usb_waitQ[lun]), lun);
2678 
2679         /* fire up a thread to start executing the protocol */
2680         if (scsa2usbp->scsa2usb_work_thread_id == 0) {
2681                 if ((usb_async_req(scsa2usbp->scsa2usb_dip,
2682                     scsa2usb_work_thread,
2683                     (void *)scsa2usbp, USB_FLAGS_SLEEP)) != USB_SUCCESS) {
2684                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2685                             scsa2usbp->scsa2usb_log_handle,
2686                             "no work thread started");
2687 
2688                         if (usba_rm_from_list(
2689                             &scsa2usbp->scsa2usb_waitQ[lun],
2690                             &cmd->cmd_waitQ) == USB_SUCCESS) {
2691                                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2692 
2693                                 return (TRAN_BUSY);
2694                         } else {
2695 
2696                                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2697 
2698                                 return (TRAN_ACCEPT);
2699                         }
2700                 }
2701                 scsa2usbp->scsa2usb_work_thread_id = (kthread_t *)1;
2702         }
2703 
2704         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2705 
2706         return (TRAN_ACCEPT);
2707 }
2708 
2709 
2710 /*
2711  * scsa2usb_scsi_abort:
2712  *      Issue SCSI abort command. This function is a NOP.
2713  */
2714 /* ARGSUSED */
2715 static int
2716 scsa2usb_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
2717 {
2718         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2719 
2720         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2721             "scsa2usb_scsi_abort: pkt = %p", (void *)pkt);
2722 
2723         /* if device is disconnected (ie. pipes closed), fail immediately */
2724         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2725         if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2726                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2727 
2728                 return (0);
2729         }
2730 
2731         /* flush waitQ if target and lun match */
2732         if ((ap->a_target == pkt->pkt_address.a_target) &&
2733             (ap->a_lun == pkt->pkt_address.a_lun)) {
2734                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2735                 scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_ABORTED);
2736                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
2737         }
2738         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2739 
2740         return (0);
2741 }
2742 
2743 
2744 /*
2745  * scsa2usb_scsi_reset:
2746  *      device reset may turn the device into a brick and bus reset
2747  *      is not applicable.
2748  *      just flush the waitQ
2749  *      We return success, always.
2750  */
2751 /* ARGSUSED */
2752 static int
2753 scsa2usb_scsi_reset(struct scsi_address *ap, int level)
2754 {
2755         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2756 
2757         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2758             "scsa2usb_scsi_reset: ap = 0x%p, level = %d", (void *)ap, level);
2759 
2760         /* flush waitQ */
2761         scsa2usb_flush_waitQ(scsa2usbp, ap->a_lun, CMD_RESET);
2762 
2763         return (1);
2764 }
2765 
2766 
2767 /*
2768  * scsa2usb_scsi_getcap:
2769  *      Get SCSI capabilities.
2770  */
2771 /* ARGSUSED */
2772 static int
2773 scsa2usb_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
2774 {
2775         int rval = -1;
2776         uint_t cidx;
2777         size_t dev_bsize_cap;
2778         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2779         ASSERT(scsa2usbp);
2780 
2781         if (cap == NULL) {
2782                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2783                     "scsa2usb_scsi_getcap: invalid arg, "
2784                     "cap = 0x%p whom = %d", (void *)cap, whom);
2785 
2786                 return (rval);
2787         }
2788 
2789         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2790             "scsa2usb_scsi_getcap: cap = %s", cap);
2791 
2792         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2793 
2794         /* if device is disconnected (ie. pipes closed), fail immediately */
2795         if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2796 
2797                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2798 
2799                 return (rval);
2800         }
2801 
2802         cidx =  scsi_hba_lookup_capstr(cap);
2803         switch (cidx) {
2804         case SCSI_CAP_GEOMETRY:
2805                 /* Just check and fail immediately if zero, rarely happens */
2806                 if (scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0) {
2807                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
2808                             scsa2usbp->scsa2usb_log_handle,
2809                             "scsa2usb_scsi_getcap failed:"
2810                             "scsa2usbp->scsa2usb_secsz[ap->a_lun] == 0");
2811                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2812 
2813                         return (rval);
2814                 }
2815 
2816                 dev_bsize_cap = scsa2usbp->scsa2usb_totalsec[ap->a_lun];
2817 
2818                 if (scsa2usbp->scsa2usb_secsz[ap->a_lun] > DEV_BSIZE) {
2819                         dev_bsize_cap *=
2820                             scsa2usbp->scsa2usb_secsz[ap->a_lun] / DEV_BSIZE;
2821                 } else if (scsa2usbp->scsa2usb_secsz[ap->a_lun] <
2822                     DEV_BSIZE) {
2823                         dev_bsize_cap /=
2824                             DEV_BSIZE / scsa2usbp->scsa2usb_secsz[ap->a_lun];
2825                 }
2826 
2827                 if (dev_bsize_cap < 65536 * 2 * 18) {                /* < ~1GB */
2828                         /* unlabeled floppy, 18k per cylinder */
2829                         rval = ((2 << 16) | 18);
2830                 } else if (dev_bsize_cap < 65536 * 64 * 32) {        /* < 64GB */
2831                         /* 1024k per cylinder */
2832                         rval = ((64 << 16) | 32);
2833                 } else if (dev_bsize_cap < 65536 * 255 * 63) {       /* < ~500GB */
2834                         /* ~8m per cylinder */
2835                         rval = ((255 << 16) | 63);
2836                 } else {                                        /* .. 8TB */
2837                         /* 64m per cylinder */
2838                         rval = ((512 << 16) | 256);
2839                 }
2840                 break;
2841 
2842         case SCSI_CAP_DMA_MAX:
2843                 rval = scsa2usbp->scsa2usb_max_bulk_xfer_size;
2844                 break;
2845         case SCSI_CAP_SCSI_VERSION:
2846                 rval = SCSI_VERSION_2;
2847                 break;
2848         case SCSI_CAP_INTERCONNECT_TYPE:
2849                 rval = INTERCONNECT_USB;
2850                 break;
2851         case SCSI_CAP_ARQ:
2852                 /* FALLTHRU */
2853         case SCSI_CAP_UNTAGGED_QING:
2854                 rval = 1;
2855                 break;
2856         default:
2857                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2858                     "scsa2usb_scsi_getcap: unsupported cap = %s", cap);
2859                 break;
2860         }
2861 
2862         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2863             "scsa2usb_scsi_getcap: cap = %s, returned = %d", cap, rval);
2864 
2865         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2866 
2867         return (rval);
2868 }
2869 
2870 
2871 /*
2872  * scsa2usb_scsi_setcap:
2873  *      Set SCSI capabilities.
2874  */
2875 /* ARGSUSED */
2876 static int
2877 scsa2usb_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
2878 {
2879         int rval = -1; /* default is cap undefined */
2880         uint_t cidx;
2881         scsa2usb_state_t *scsa2usbp = (scsa2usb_state_t *)ADDR2SCSA2USB(ap);
2882         ASSERT(scsa2usbp);
2883 
2884         if (cap == NULL || whom == 0) {
2885                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2886                     "scsa2usb_scsi_setcap: invalid arg");
2887 
2888                 return (rval);
2889         }
2890 
2891         mutex_enter(&scsa2usbp->scsa2usb_mutex);
2892         /* if device is disconnected (ie. pipes closed), fail immediately */
2893         if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
2894                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
2895 
2896                 return (rval);
2897         }
2898 
2899         cidx =  scsi_hba_lookup_capstr(cap);
2900         USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2901             "scsa2usb_scsi_setcap: ap = 0x%p value = 0x%x whom = 0x%x "
2902             "cidx = 0x%x", (void *)ap, value, whom, cidx);
2903 
2904         switch (cidx) {
2905         case SCSI_CAP_SECTOR_SIZE:
2906                 if (value) {
2907                         scsa2usbp->scsa2usb_secsz[ap->a_lun] = value;
2908                 }
2909                 break;
2910         case SCSI_CAP_TOTAL_SECTORS:
2911                 if (value) {
2912                         scsa2usbp->scsa2usb_totalsec[ap->a_lun] = value;
2913                 }
2914                 break;
2915         case SCSI_CAP_ARQ:
2916                 rval = 1;
2917                 break;
2918         case SCSI_CAP_DMA_MAX:
2919         case SCSI_CAP_SCSI_VERSION:
2920         case SCSI_CAP_INTERCONNECT_TYPE:
2921         case SCSI_CAP_UNTAGGED_QING:
2922                 /* supported but not settable */
2923                 rval = 0;
2924                 break;
2925         default:
2926                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2927                     "scsa2usb_scsi_setcap: unsupported cap = %s", cap);
2928                 break;
2929         }
2930 
2931         mutex_exit(&scsa2usbp->scsa2usb_mutex);
2932 
2933         return (rval);
2934 }
2935 
2936 
2937 /*
2938  * scsa2usb - cmd and transport stuff
2939  */
2940 /*
2941  * scsa2usb_prepare_pkt:
2942  *      initialize some fields of the pkt and cmd
2943  *      (the pkt may have been resubmitted/retried)
2944  */
2945 static void
2946 scsa2usb_prepare_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
2947 {
2948         scsa2usb_cmd_t  *cmd = PKT2CMD(pkt);
2949 
2950         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2951             "scsa2usb_prepare_pkt: pkt=0x%p cdb: 0x%x (%s)",
2952             (void *)pkt, pkt->pkt_cdbp[0],
2953             scsi_cname(pkt->pkt_cdbp[0], scsa2usb_cmds));
2954 
2955         pkt->pkt_reason = CMD_CMPLT; /* Set reason to pkt_complete */
2956         pkt->pkt_state = 0;          /* Reset next three fields */
2957         pkt->pkt_statistics = 0;
2958         pkt->pkt_resid = 0;
2959         bzero(pkt->pkt_scbp, cmd->cmd_scblen); /* Set status to good */
2960 
2961         if (cmd) {
2962                 cmd->cmd_timeout = pkt->pkt_time;
2963                 cmd->cmd_xfercount = 0;              /* Reset the fields */
2964                 cmd->cmd_total_xfercount = 0;
2965                 cmd->cmd_lba = 0;
2966                 cmd->cmd_done = 0;
2967                 cmd->cmd_dir = 0;
2968                 cmd->cmd_offset = 0;
2969                 cmd->cmd_actual_len = cmd->cmd_cdblen;
2970         }
2971 }
2972 
2973 
2974 /*
2975  * scsa2usb_force_invalid_request
2976  */
2977 static void
2978 scsa2usb_force_invalid_request(scsa2usb_state_t *scsa2usbp,
2979     scsa2usb_cmd_t *cmd)
2980 {
2981         struct scsi_arq_status  *arqp;
2982 
2983         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
2984             "scsa2usb_force_invalid_request: pkt = 0x%p", (void *)cmd->cmd_pkt);
2985 
2986         if (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) {
2987                 arqp = (struct scsi_arq_status *)cmd->cmd_pkt->pkt_scbp;
2988                 bzero(arqp, cmd->cmd_scblen);
2989 
2990                 arqp->sts_status.sts_chk = 1;
2991                 arqp->sts_rqpkt_reason = CMD_CMPLT;
2992                 arqp->sts_rqpkt_state = STATE_XFERRED_DATA |
2993                     STATE_GOT_BUS | STATE_GOT_STATUS;
2994                 arqp->sts_sensedata.es_valid = 1;
2995                 arqp->sts_sensedata.es_class = 7;
2996                 arqp->sts_sensedata.es_key = KEY_ILLEGAL_REQUEST;
2997 
2998                 cmd->cmd_pkt->pkt_state = STATE_ARQ_DONE |
2999                     STATE_GOT_BUS | STATE_GOT_BUS | STATE_GOT_BUS |
3000                     STATE_GOT_STATUS;
3001 #ifdef DEBUG
3002                 {
3003                         uchar_t *p = (uchar_t *)(&arqp->sts_sensedata);
3004                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3005                             scsa2usbp->scsa2usb_log_handle,
3006                             "cdb: %x rqsense: "
3007                             "%x %x %x %x %x %x %x %x %x %x "
3008                             "%x %x %x %x %x %x %x %x %x %x",
3009                             cmd->cmd_pkt->pkt_cdbp[0],
3010                             p[0], p[1], p[2], p[3], p[4],
3011                             p[5], p[6], p[7], p[8], p[9],
3012                             p[10], p[11], p[12], p[13], p[14],
3013                             p[15], p[16], p[17], p[18], p[19]);
3014                 }
3015 #endif
3016 
3017         }
3018 }
3019 
3020 
3021 /*
3022  * scsa2usb_cmd_transport:
3023  */
3024 static int
3025 scsa2usb_cmd_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3026 {
3027         int rval, transport;
3028         struct scsi_pkt *pkt;
3029 
3030         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3031             "scsa2usb_cmd_transport: pkt: 0x%p, cur_pkt = 0x%p",
3032             (void *)cmd->cmd_pkt, (void *)scsa2usbp->scsa2usb_cur_pkt);
3033 
3034         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3035         ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
3036 
3037         pkt = scsa2usbp->scsa2usb_cur_pkt = cmd->cmd_pkt;
3038 
3039         /* check black-listed attrs first */
3040         if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3041                 transport = scsa2usb_check_bulkonly_blacklist_attrs(scsa2usbp,
3042                     cmd, pkt->pkt_cdbp[0]);
3043         } else if (SCSA2USB_IS_CB(scsa2usbp) || SCSA2USB_IS_CBI(scsa2usbp)) {
3044                 transport =  scsa2usb_check_ufi_blacklist_attrs(scsa2usbp,
3045                     pkt->pkt_cdbp[0], cmd);
3046         }
3047 
3048         /* just accept the command or return error */
3049         if (transport == SCSA2USB_JUST_ACCEPT) {
3050                 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3051 
3052                 return (TRAN_ACCEPT);
3053         } else if (transport == SCSA2USB_REJECT) {
3054                 return (TRAN_FATAL_ERROR);
3055         }
3056 
3057         /* check command set next */
3058         if (SCSA2USB_IS_SCSI_CMDSET(scsa2usbp) ||
3059             SCSA2USB_IS_ATAPI_CMDSET(scsa2usbp)) {
3060                 transport =
3061                     scsa2usb_handle_scsi_cmd_sub_class(scsa2usbp, cmd, pkt);
3062         } else if (SCSA2USB_IS_UFI_CMDSET(scsa2usbp)) {
3063                 transport =
3064                     scsa2usb_handle_ufi_subclass_cmd(scsa2usbp, cmd, pkt);
3065         } else {
3066                 transport = SCSA2USB_REJECT;
3067         }
3068 
3069         switch (transport) {
3070         case SCSA2USB_TRANSPORT:
3071                 if (SCSA2USB_IS_BULK_ONLY(scsa2usbp)) {
3072                         rval = scsa2usb_bulk_only_transport(scsa2usbp, cmd);
3073                 } else if (SCSA2USB_IS_CB(scsa2usbp) ||
3074                     SCSA2USB_IS_CBI(scsa2usbp)) {
3075                         rval = scsa2usb_cbi_transport(scsa2usbp, cmd);
3076                 } else {
3077                         rval = TRAN_FATAL_ERROR;
3078                 }
3079                 break;
3080         case SCSA2USB_JUST_ACCEPT:
3081                 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
3082                 rval = TRAN_ACCEPT;
3083                 break;
3084         default:
3085                 rval = TRAN_FATAL_ERROR;
3086         }
3087 
3088         return (rval);
3089 }
3090 
3091 
3092 /*
3093  * scsa2usb_check_bulkonly_blacklist_attrs:
3094  *      validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3095  *      if blacklisted attrs match accept the request
3096  *      attributes checked are:-
3097  *              SCSA2USB_ATTRS_START_STOP
3098  */
3099 int
3100 scsa2usb_check_bulkonly_blacklist_attrs(scsa2usb_state_t *scsa2usbp,
3101     scsa2usb_cmd_t *cmd, uchar_t opcode)
3102 {
3103         struct scsi_inquiry *inq =
3104             &scsa2usbp->scsa2usb_lun_inquiry[cmd->cmd_pkt->pkt_address.a_lun];
3105 
3106         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3107             "scsa2usb_check_bulkonly_blacklist_attrs: opcode = %s",
3108             scsi_cname(opcode, scsa2usb_cmds));
3109 
3110         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3111 
3112         /*
3113          * decode and convert the packet
3114          * for most cmds, we can bcopy the cdb
3115          */
3116         switch (opcode) {
3117         case SCMD_DOORLOCK:
3118                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_DOORLOCK)) {
3119 
3120                         return (SCSA2USB_JUST_ACCEPT);
3121 
3122                 /*
3123                  * only lock the door for CD and DVD drives
3124                  */
3125                 } else if ((inq->inq_dtype == DTYPE_RODIRECT) ||
3126                     (inq->inq_dtype == DTYPE_OPTICAL)) {
3127 
3128                         if (inq->inq_rmb) {
3129 
3130                                 break;
3131                         }
3132                 }
3133 
3134                 return (SCSA2USB_JUST_ACCEPT);
3135 
3136         case SCMD_START_STOP:   /* SCMD_LOAD for sequential devices */
3137                 /*
3138                  * these devices don't have mechanics that spin the
3139                  * media up and down. So, it doesn't make much sense
3140                  * to issue this cmd.
3141                  *
3142                  * Furthermore, Hagiwara devices do not handle these
3143                  * cmds well. just accept this command as success.
3144                  */
3145                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3146 
3147                         return (SCSA2USB_JUST_ACCEPT);
3148 
3149                 } else if (inq->inq_dtype == DTYPE_SEQUENTIAL) {
3150                         /*
3151                          * In case of USB tape device, we need to send the
3152                          * command to the device to unload the media.
3153                          */
3154                         break;
3155 
3156                 } else if (cmd->cmd_pkt->pkt_cdbp[4] & LOEJECT) {
3157                         /*
3158                          * if the device is really a removable then
3159                          * pass it on to the device, else just accept
3160                          */
3161                         if (inq->inq_rmb) {
3162 
3163                                 break;
3164                         }
3165 
3166                         return (SCSA2USB_JUST_ACCEPT);
3167 
3168                 } else if (!scsa2usbp->scsa2usb_rcvd_not_ready) {
3169                         /*
3170                          * if we have not received a NOT READY condition,
3171                          * just accept since some device choke on this too.
3172                          * we do have to let EJECT get through though
3173                          */
3174                         return (SCSA2USB_JUST_ACCEPT);
3175                 }
3176 
3177                 break;
3178         case SCMD_INQUIRY:
3179                 /*
3180                  * Some devices do not handle the inquiry cmd well
3181                  * so build an inquiry and accept this command as
3182                  * success.
3183                  */
3184                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
3185                         uchar_t evpd = 0x01;
3186                         unsigned int bufsize;
3187                         int count;
3188 
3189                         if (cmd->cmd_pkt->pkt_cdbp[1] & evpd)
3190                                 return (SCSA2USB_REJECT);
3191 
3192                         scsa2usb_fake_inquiry(scsa2usbp, inq);
3193 
3194                         /* Copy no more than requested */
3195                         count = MIN(cmd->cmd_bp->b_bcount,
3196                             sizeof (struct scsi_inquiry));
3197                         bufsize = cmd->cmd_pkt->pkt_cdbp[4];
3198                         count = MIN(count, bufsize);
3199                         bcopy(inq, cmd->cmd_bp->b_un.b_addr, count);
3200 
3201                         cmd->cmd_pkt->pkt_resid = bufsize - count;
3202                         cmd->cmd_pkt->pkt_state |= STATE_XFERRED_DATA;
3203 
3204                         return (SCSA2USB_JUST_ACCEPT);
3205                 } else if (!(scsa2usbp->scsa2usb_attrs &
3206                     SCSA2USB_ATTRS_INQUIRY_EVPD)) {
3207                         /*
3208                          * Some devices do not handle the inquiry cmd with
3209                          * evpd bit set well, e.g. some devices return the
3210                          * same page 0x83 data which will cause the generated
3211                          * devid by sd is not unique, thus return CHECK
3212                          * CONDITION directly to sd.
3213                          */
3214                         uchar_t evpd = 0x01;
3215 
3216                         if (!(cmd->cmd_pkt->pkt_cdbp[1] & evpd))
3217                                 break;
3218 
3219                         if (cmd->cmd_bp) {
3220                                 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3221                                     b_bcount;
3222                         }
3223                         scsa2usb_force_invalid_request(scsa2usbp, cmd);
3224 
3225                         return (SCSA2USB_JUST_ACCEPT);
3226                 }
3227                 break;
3228         /*
3229          * Fake accepting the following  Opcodes
3230          * (as most drives don't support these)
3231          * These are needed by format command.
3232          */
3233         case SCMD_RESERVE:
3234         case SCMD_RELEASE:
3235         case SCMD_PERSISTENT_RESERVE_IN:
3236         case SCMD_PERSISTENT_RESERVE_OUT:
3237 
3238                 return (SCSA2USB_JUST_ACCEPT);
3239 
3240         case SCMD_MODE_SENSE:
3241         case SCMD_MODE_SELECT:
3242         case SCMD_MODE_SENSE_G1:
3243         case SCMD_MODE_SELECT_G1:
3244                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_MODE_SENSE)) {
3245                         if (cmd->cmd_bp) {
3246                                 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->
3247                                     b_bcount;
3248                         }
3249                         scsa2usb_force_invalid_request(scsa2usbp, cmd);
3250 
3251                         return (SCSA2USB_JUST_ACCEPT);
3252                 }
3253 
3254                 break;
3255         default:
3256 
3257                 break;
3258         }
3259 
3260         return (SCSA2USB_TRANSPORT);
3261 }
3262 
3263 
3264 /*
3265  * scsa2usb_handle_scsi_cmd_sub_class:
3266  *      prepare a scsi cmd
3267  *      returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT, SCSA2USB_JUST_ACCEPT
3268  */
3269 int
3270 scsa2usb_handle_scsi_cmd_sub_class(scsa2usb_state_t *scsa2usbp,
3271     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3272 {
3273         uchar_t evpd = 0x01;
3274         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3275             "scsa2usb_handle_scsi_cmd_sub_class: cmd = 0x%p pkt = 0x%p",
3276             (void *)cmd, (void *)pkt);
3277 
3278         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3279 
3280         bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3281         cmd->cmd_cdb[SCSA2USB_OPCODE] = pkt->pkt_cdbp[0];   /* Set the opcode */
3282         cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3283 
3284         /*
3285          * decode and convert the packet
3286          * for most cmds, we can bcopy the cdb
3287          */
3288         switch (pkt->pkt_cdbp[0]) {
3289         case SCMD_FORMAT:
3290                 /*
3291                  * SCMD_FORMAT used to limit cmd->cmd_xfercount
3292                  * to 4 bytes, but this hangs
3293                  * formatting dvd media using cdrecord (that is,
3294                  * a SCSI FORMAT UNIT command with a parameter list > 4 bytes)
3295                  * (bit 4 in cdb1 is the Fmtdata bit)
3296                  */
3297                 if ((pkt->pkt_cdbp[1] & 0x10) && cmd->cmd_bp) {
3298                         cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3299                 } else {
3300                         cmd->cmd_xfercount = 4;
3301                 }
3302                 cmd->cmd_dir = CBW_DIR_OUT;
3303                 cmd->cmd_actual_len = CDB_GROUP0;
3304                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3305                 break;
3306 
3307         case SCMD_INQUIRY:
3308                 cmd->cmd_dir = CBW_DIR_IN;
3309                 cmd->cmd_actual_len = CDB_GROUP0;
3310                 cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3311 
3312                 /*
3313                  * If vpd pages data is limited to maximum SCSA2USB_MAX_INQ_LEN,
3314                  * the page data may be truncated, which may cause some issues
3315                  * such as making the unique page 0x83 or 0x80 data from
3316                  * different devices become the same. So don't limit return
3317                  * length for vpd page inquiry cmd.
3318                  * Another, in order to maintain compatibility, the original
3319                  * length limitation for standard inquiry retains here. It
3320                  * can be removed in future if it is verified that enough
3321                  * devices can work well.
3322                  */
3323                 if (pkt->pkt_cdbp[1] & evpd) {
3324                         cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3325                             (cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3326                 } else {
3327                         cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3328                             min(SCSA2USB_MAX_INQ_LEN,
3329                             cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3330                 }
3331                 break;
3332 
3333         case SCMD_READ_CAPACITY:
3334                 cmd->cmd_dir = CBW_DIR_IN;
3335                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3336                 cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3337                 break;
3338 
3339         /*
3340          * SCMD_READ/SCMD_WRITE are converted to G1 cmds
3341          * (as ATAPI devices don't recognize G0 commands)
3342          *
3343          * SCMD_READ_LONG/SCMD_WRITE_LONG are handled in
3344          * scsa2usb_rw_transport() along with other commands.
3345          *
3346          * USB Host Controllers cannot handle large (read/write)
3347          * xfers. We split the large request to chunks of
3348          * smaller ones to meet the HCD limitations.
3349          */
3350         case SCMD_READ:
3351         case SCMD_WRITE:
3352         case SCMD_READ_G1:
3353         case SCMD_WRITE_G1:
3354         case SCMD_READ_G5:
3355         case SCMD_WRITE_G5:
3356         case SCMD_READ_LONG:
3357         case SCMD_WRITE_LONG:
3358         case SCMD_READ_CD:
3359                 switch (scsa2usbp->
3360                     scsa2usb_lun_inquiry[pkt->pkt_address.a_lun].
3361                     inq_dtype & DTYPE_MASK) {
3362                 case DTYPE_DIRECT:
3363                 case DTYPE_RODIRECT:
3364                 case DTYPE_OPTICAL:
3365                         return (scsa2usb_rw_transport(
3366                             scsa2usbp, pkt));
3367                 default:
3368                         bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3369                         if (cmd->cmd_bp) {
3370                                 cmd->cmd_dir =
3371                                     (cmd->cmd_bp->b_flags & B_READ) ?
3372                                     CBW_DIR_IN : CBW_DIR_OUT;
3373                                 cmd->cmd_xfercount =
3374                                     cmd->cmd_bp->b_bcount;
3375                         }
3376                         break;
3377                 }
3378                 break;
3379 
3380         case SCMD_REQUEST_SENSE:
3381                 cmd->cmd_dir = CBW_DIR_IN;
3382                 cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3383                 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3384                 cmd->cmd_actual_len = CDB_GROUP0;
3385                 break;
3386 
3387         case SCMD_DOORLOCK:
3388         case SCMD_START_STOP:
3389         case SCMD_TEST_UNIT_READY:
3390                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3391                 break;
3392 
3393         /*
3394          * Needed by zip protocol to reset the device
3395          */
3396         case SCMD_SDIAG:
3397         case SCMD_REZERO_UNIT:
3398                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3399                 cmd->cmd_actual_len = CDB_GROUP1;
3400                 break;
3401 
3402         case SCMD_WRITE_VERIFY:
3403                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3404                 cmd->cmd_dir = CBW_DIR_OUT;
3405                 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3406                 cmd->cmd_actual_len = CDB_GROUP1;
3407                 break;
3408 
3409         /*
3410          * Next command does not have a SCSI equivalent as
3411          * it is vendor specific.
3412          * It was listed in the vendor's ATAPI Zip specs.
3413          */
3414         case SCMD_READ_FORMAT_CAP:
3415                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3416                 cmd->cmd_dir = CBW_DIR_IN;
3417                 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3418                 cmd->cmd_actual_len = CDB_GROUP1;
3419                 break;
3420         case IOMEGA_CMD_CARTRIDGE_PROTECT:
3421                 cmd->cmd_dir = CBW_DIR_OUT;
3422                 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3423                 cmd->cmd_cdb[SCSA2USB_LBA_2] &= ~1;      /* Make it even */
3424                 cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3425                 cmd->cmd_actual_len = CDB_GROUP0;
3426                 cmd->cmd_xfercount = pkt->pkt_cdbp[4]; /* Length of password */
3427                 break;
3428 
3429         /*
3430          * Do not convert SCMD_MODE_SENSE/SELECT to G1 cmds because
3431          * the mode header is different as well. USB devices don't
3432          * support 0x03 & 0x04 mode pages, which are already obsoleted
3433          * by SPC-2 specification.
3434          */
3435         case SCMD_MODE_SENSE:
3436         case SCMD_MODE_SELECT:
3437                 if (((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3438                     == SD_MODE_SENSE_PAGE3_CODE) ||
3439                     ((pkt->pkt_cdbp[2] & SD_MODE_SENSE_PAGE_MASK)
3440                     == SD_MODE_SENSE_PAGE4_CODE)) {
3441                         if (cmd->cmd_bp) {
3442                                 cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3443                         }
3444                         scsa2usb_force_invalid_request(scsa2usbp, cmd);
3445                         return (SCSA2USB_JUST_ACCEPT);
3446                 }
3447                 /* FALLTHROUGH */
3448 
3449         default:
3450                 /*
3451                  * an unknown command may be a uscsi cmd which we
3452                  * should let go thru without mapping
3453                  */
3454                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3455                 if (cmd->cmd_bp) {
3456                         cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3457                             CBW_DIR_IN : CBW_DIR_OUT;
3458                         cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3459                 }
3460 
3461                 break;
3462         } /* end of switch */
3463 
3464         USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3465             "scsa2usb_handle_scsi_cmd_sub_class: opcode = 0x%x count = 0x%lx",
3466             pkt->pkt_cdbp[SCSA2USB_OPCODE], cmd->cmd_xfercount);
3467 
3468         cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3469 
3470         return (SCSA2USB_TRANSPORT);
3471 }
3472 
3473 
3474 /*
3475  * scsa2usb_do_tur is performed before READ CAPACITY command is issued.
3476  * It returns media status, 0 for media ready, -1 for media not ready
3477  * or other errors.
3478  */
3479 static int
3480 scsa2usb_do_tur(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
3481 {
3482         struct scsi_pkt         *pkt;
3483         scsa2usb_cmd_t          *turcmd;
3484         int                     rval = -1;
3485 
3486         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3487             "scsa2usb_do_tur:");
3488 
3489         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3490 
3491         mutex_exit(&scsa2usbp->scsa2usb_mutex);
3492         if ((pkt = scsi_init_pkt(ap, NULL, NULL, CDB_GROUP0, 1,
3493             PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL)) == NULL) {
3494                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
3495                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3496                     scsa2usbp->scsa2usb_log_handle,
3497                     "scsa2usb_do_tur: init pkt failed");
3498 
3499                 return (rval);
3500         }
3501 
3502         RQ_MAKECOM_G0(pkt, FLAG_HEAD | FLAG_NODISCON,
3503             (char)SCMD_TEST_UNIT_READY, 0, 0);
3504 
3505         pkt->pkt_comp = NULL;
3506         pkt->pkt_time = PKT_DEFAULT_TIMEOUT;
3507         turcmd = PKT2CMD(pkt);
3508 
3509         mutex_enter(&scsa2usbp->scsa2usb_mutex);
3510         scsa2usb_prepare_pkt(scsa2usbp, turcmd->cmd_pkt);
3511 
3512         if (scsa2usb_cmd_transport(scsa2usbp, turcmd) != TRAN_ACCEPT) {
3513                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3514                     scsa2usbp->scsa2usb_log_handle,
3515                     "scsa2usb_do_tur: cmd transport failed, "
3516                     "pkt_reason=0x%x", turcmd->cmd_pkt->pkt_reason);
3517         } else if (*(turcmd->cmd_pkt->pkt_scbp) != STATUS_GOOD) {
3518                 /*
3519                  * Theoretically, the sense data should be retrieved and
3520                  * sense key be checked when check condition happens. If
3521                  * the sense key is UNIT ATTENTION, TEST UNIT READY cmd
3522                  * needs to be sent again to clear the UNIT ATTENTION and
3523                  * another TUR to be sent to get the real media status.
3524                  * But the AMI virtual floppy device simply cannot recover
3525                  * from UNIT ATTENTION by re-sending a TUR cmd, so it
3526                  * doesn't make any difference whether to check sense key
3527                  * or not. Just ignore sense key checking here and assume
3528                  * the device is NOT READY.
3529                  */
3530                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
3531                     scsa2usbp->scsa2usb_log_handle,
3532                     "scsa2usb_do_tur: media not ready");
3533         } else {
3534                 rval = 0;
3535         }
3536 
3537         mutex_exit(&scsa2usbp->scsa2usb_mutex);
3538         scsi_destroy_pkt(pkt);
3539         mutex_enter(&scsa2usbp->scsa2usb_mutex);
3540 
3541         return (rval);
3542 }
3543 
3544 
3545 /*
3546  * scsa2usb_check_ufi_blacklist_attrs:
3547  *      validate "scsa2usb_blacklist_attrs" (see scsa2usb.h)
3548  *      if blacklisted attrs match accept the request
3549  *      attributes checked are:-
3550  *              SCSA2USB_ATTRS_GET_CONF
3551  *              SCSA2USB_ATTRS_GET_PERF
3552  *              SCSA2USB_ATTRS_GET_START_STOP
3553  */
3554 static int
3555 scsa2usb_check_ufi_blacklist_attrs(scsa2usb_state_t *scsa2usbp, uchar_t opcode,
3556     scsa2usb_cmd_t *cmd)
3557 {
3558         int     rval = SCSA2USB_TRANSPORT;
3559 
3560         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3561 
3562         switch (opcode) {
3563         case SCMD_PRIN:
3564         case SCMD_PROUT:
3565                 rval = SCSA2USB_JUST_ACCEPT;
3566                 break;
3567         case SCMD_MODE_SENSE:
3568         case SCMD_MODE_SELECT:
3569                 if (cmd->cmd_bp) {
3570                         cmd->cmd_pkt->pkt_resid = cmd->cmd_bp->b_bcount;
3571                 }
3572                 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3573                 rval = SCSA2USB_JUST_ACCEPT;
3574                 break;
3575         case SCMD_GET_CONFIGURATION:
3576                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_CONF)) {
3577                         rval = SCSA2USB_JUST_ACCEPT;
3578                 }
3579                 break;
3580         case SCMD_GET_PERFORMANCE:
3581                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_GET_PERF)) {
3582                         rval = SCSA2USB_JUST_ACCEPT;
3583                 }
3584                 break;
3585         case SCMD_START_STOP:
3586                 /*
3587                  * some CB/CBI devices don't have mechanics that spin the
3588                  * media up and down. So, it doesn't make much sense
3589                  * to issue this cmd to those devices.
3590                  */
3591                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_START_STOP)) {
3592                         rval = SCSA2USB_JUST_ACCEPT;
3593                 }
3594                 break;
3595         case SCMD_READ_CAPACITY:
3596                 /*
3597                  * Some devices don't support READ CAPACITY command
3598                  * when media is not ready. Need to check media status
3599                  * before issuing the cmd to such device.
3600                  */
3601                 if (!(scsa2usbp->scsa2usb_attrs &
3602                     SCSA2USB_ATTRS_NO_MEDIA_CHECK)) {
3603                         struct scsi_pkt *pkt = cmd->cmd_pkt;
3604 
3605                         ASSERT(scsa2usbp->scsa2usb_cur_pkt == pkt);
3606                         scsa2usbp->scsa2usb_cur_pkt = NULL;
3607 
3608                         if (scsa2usb_do_tur(scsa2usbp,
3609                             &pkt->pkt_address) != 0) {
3610                                 /* media not ready, force cmd invalid */
3611                                 if (cmd->cmd_bp) {
3612                                         cmd->cmd_pkt->pkt_resid =
3613                                             cmd->cmd_bp->b_bcount;
3614                                 }
3615                                 scsa2usb_force_invalid_request(scsa2usbp, cmd);
3616                                 rval = SCSA2USB_JUST_ACCEPT;
3617                         }
3618 
3619                         scsa2usbp->scsa2usb_cur_pkt = pkt;
3620                 }
3621                 break;
3622         default:
3623                 break;
3624         }
3625 
3626         return (rval);
3627 }
3628 
3629 
3630 /*
3631  * scsa2usb_handle_ufi_subclass_cmd:
3632  *      prepare a UFI cmd
3633  *      returns SCSA2USB_TRANSPORT, SCSA2USB_REJECT
3634  */
3635 int
3636 scsa2usb_handle_ufi_subclass_cmd(scsa2usb_state_t *scsa2usbp,
3637     scsa2usb_cmd_t *cmd, struct scsi_pkt *pkt)
3638 {
3639         uchar_t opcode =  pkt->pkt_cdbp[0];
3640 
3641         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3642             "scsa2usb_handle_ufi_subclass_cmd: cmd = 0x%p pkt = 0x%p",
3643             (void *)cmd, (void *)pkt);
3644 
3645         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3646 
3647         bzero(&cmd->cmd_cdb, SCSI_CDB_SIZE);
3648         cmd->cmd_cdb[SCSA2USB_OPCODE] = opcode;   /* Set the opcode */
3649         cmd->cmd_cdb[SCSA2USB_LUN] = pkt->pkt_cdbp[1];
3650 
3651         /*
3652          * decode and convert the packet if necessary
3653          * for most cmds, we can bcopy the cdb
3654          */
3655         switch (opcode) {
3656         case SCMD_FORMAT:
3657                 /* if parameter list is specified */
3658                 if (pkt->pkt_cdbp[1] & 0x10) {
3659                         cmd->cmd_xfercount =
3660                             (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3661                         cmd->cmd_dir = USB_EP_DIR_OUT;
3662                         cmd->cmd_actual_len = CDB_GROUP5;
3663                 }
3664                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3665                 break;
3666         case SCMD_INQUIRY:
3667                 cmd->cmd_dir = USB_EP_DIR_IN;
3668                 cmd->cmd_actual_len = CDB_GROUP0;
3669                 cmd->cmd_cdb[SCSA2USB_LBA_0] = pkt->pkt_cdbp[2];
3670                 cmd->cmd_cdb[SCSA2USB_LBA_2] = cmd->cmd_xfercount =
3671                     min(SCSA2USB_MAX_INQ_LEN,
3672                     cmd->cmd_bp ? cmd->cmd_bp->b_bcount : 0);
3673                 break;
3674         case SCMD_READ_CAPACITY:
3675                 cmd->cmd_dir = USB_EP_DIR_IN;
3676                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3677                 cmd->cmd_xfercount = sizeof (scsa2usb_read_cap_t);
3678                 break;
3679         case SCMD_REQUEST_SENSE:
3680                 cmd->cmd_dir = USB_EP_DIR_IN;
3681                 cmd->cmd_xfercount = pkt->pkt_cdbp[4];
3682                 cmd->cmd_cdb[SCSA2USB_LBA_2] = pkt->pkt_cdbp[4];
3683                 cmd->cmd_actual_len = CDB_GROUP0;
3684                 break;
3685 
3686         /*
3687          * do not convert SCMD_MODE_SENSE/SELECT because the
3688          * mode header is different as well
3689          */
3690 
3691         /*
3692          * see usb_bulkonly.c for comments on the next set of commands
3693          */
3694         case SCMD_READ:
3695         case SCMD_WRITE:
3696         case SCMD_READ_G1:
3697         case SCMD_WRITE_G1:
3698         case SCMD_READ_G5:
3699         case SCMD_WRITE_G5:
3700         case SCMD_READ_LONG:
3701         case SCMD_WRITE_LONG:
3702         case SCMD_READ_CD:
3703 
3704                 return (scsa2usb_rw_transport(scsa2usbp, pkt));
3705 
3706         case SCMD_TEST_UNIT_READY:
3707                 /*
3708                  * Some CB/CBI devices may not support TUR.
3709                  */
3710                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3711                 break;
3712         case SCMD_READ_FORMAT_CAP:
3713                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3714                 cmd->cmd_dir = USB_EP_DIR_IN;
3715                 cmd->cmd_actual_len = CDB_GROUP1;
3716                 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3717                 break;
3718         case SCMD_WRITE_VERIFY:
3719                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3720                 cmd->cmd_dir = USB_EP_DIR_OUT;
3721                 cmd->cmd_actual_len = CDB_GROUP1;
3722                 cmd->cmd_xfercount = (pkt->pkt_cdbp[7] << 8) | pkt->pkt_cdbp[8];
3723                 break;
3724         case SCMD_START_STOP:
3725                 /* A larger timeout is needed for 'flaky' CD-RW devices */
3726                 if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_BIG_TIMEOUT)) {
3727                         cmd->cmd_timeout = max(cmd->cmd_timeout,
3728                             20 * SCSA2USB_BULK_PIPE_TIMEOUT);
3729                 }
3730                 /* FALLTHRU */
3731         default:
3732                 /*
3733                  * all other commands don't need special mapping
3734                  */
3735                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3736                 if (cmd->cmd_bp) {
3737                         cmd->cmd_dir = (cmd->cmd_bp->b_flags & B_READ) ?
3738                             CBW_DIR_IN : CBW_DIR_OUT;
3739                         cmd->cmd_xfercount = cmd->cmd_bp->b_bcount;
3740                 }
3741                 break;
3742 
3743         } /* end of switch */
3744 
3745         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3746             "scsa2usb_handle_ufi_subclass_cmd: opcode = 0x%x count = 0x%lx",
3747             opcode, cmd->cmd_xfercount);
3748 
3749         cmd->cmd_total_xfercount = cmd->cmd_xfercount;
3750 
3751         return (SCSA2USB_TRANSPORT);
3752 }
3753 
3754 
3755 /*
3756  * scsa2usb_rw_transport:
3757  *      Handle splitting READ and WRITE requests to the
3758  *      device to a size that the host controller allows.
3759  *
3760  *      returns TRAN_* values and not USB_SUCCESS/FAILURE
3761  *
3762  * To support CD-R/CD-RW/DVD media, we need to support a
3763  * variety of block sizes for the different types of CD
3764  * data (audio, data, video, CD-XA, yellowbook, redbook etc.)
3765  *
3766  * Some of the block sizes used are:- 512, 1k, 2k, 2056, 2336
3767  * 2340, 2352, 2368, 2448, 2646, 2647 etc.
3768  *
3769  * NOTE: the driver could be entertaining a SCSI CDB that uses
3770  * any of the above listed block sizes at a given time, and a
3771  * totally different block size at any other given time for a
3772  * different CDB.
3773  *
3774  * We need to compute block size every time and figure out
3775  * matching LBA and LEN accordingly.
3776  *
3777  * Also UHCI has a limitation that it can only xfer 32k at a
3778  * given time. So, with "odd" sized blocks and a limitation of
3779  * how much we can xfer per shot, we need to compute xfer_count
3780  * as well each time.
3781  *
3782  * The same computation is also done in the function
3783  * scsa2usb_setup_next_xfer().  To save computing block_size in
3784  * this function, I am saving block_size in "cmd" now.
3785  */
3786 int
3787 scsa2usb_rw_transport(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
3788 {
3789         scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
3790         int lba, dir, opcode;
3791         struct buf *bp = cmd->cmd_bp;
3792         size_t len, xfer_count;
3793         size_t blk_size;        /* calculate the block size to be used */
3794         int sz;
3795 
3796         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3797             "scsa2usb_rw_transport:");
3798 
3799         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3800 
3801         opcode = pkt->pkt_cdbp[0];
3802         blk_size  = scsa2usbp->scsa2usb_lbasize[pkt->pkt_address.a_lun];
3803                                                 /* set to default */
3804 
3805         switch (opcode) {
3806         case SCMD_READ:
3807                 /*
3808                  * Note that READ/WRITE(6) are not supported by the drive.
3809                  * convert it into a 10 byte read/write.
3810                  */
3811                 lba = SCSA2USB_LBA_6BYTE(pkt);
3812                 len = SCSA2USB_LEN_6BYTE(pkt);
3813                 opcode = SCMD_READ_G1;  /* Overwrite it w/ byte 10 cmd val */
3814                 dir = USB_EP_DIR_IN;
3815                 break;
3816         case SCMD_WRITE:
3817                 lba = SCSA2USB_LBA_6BYTE(pkt);
3818                 len = SCSA2USB_LEN_6BYTE(pkt);
3819                 opcode = SCMD_WRITE_G1; /* Overwrite it w/ byte 10 cmd val */
3820                 dir = USB_EP_DIR_OUT;
3821                 break;
3822         case SCMD_READ_G1:
3823         case SCMD_READ_LONG:
3824                 lba = SCSA2USB_LBA_10BYTE(pkt);
3825                 len = SCSA2USB_LEN_10BYTE(pkt);
3826                 dir = USB_EP_DIR_IN;
3827                 break;
3828         case SCMD_WRITE_G1:
3829         case SCMD_WRITE_LONG:
3830                 lba = SCSA2USB_LBA_10BYTE(pkt);
3831                 len = SCSA2USB_LEN_10BYTE(pkt);
3832                 dir = USB_EP_DIR_OUT;
3833                 if (len) {
3834                         sz = SCSA2USB_CDRW_BLKSZ(bp ? bp->b_bcount : 0, len);
3835                         if (SCSA2USB_VALID_CDRW_BLKSZ(sz)) {
3836                                 blk_size = sz;  /* change it accordingly */
3837                         }
3838                 }
3839                 break;
3840         case SCMD_READ_CD:
3841                 lba = SCSA2USB_LBA_10BYTE(pkt);
3842                 len = SCSA2USB_LEN_READ_CD(pkt);
3843                 dir = USB_EP_DIR_IN;
3844 
3845                 /* Figure out the block size */
3846                 blk_size = scsa2usb_read_cd_blk_size(pkt->pkt_cdbp[1] >> 2);
3847                 break;
3848         case SCMD_READ_G5:
3849                 lba = SCSA2USB_LBA_12BYTE(pkt);
3850                 len = SCSA2USB_LEN_12BYTE(pkt);
3851                 dir = USB_EP_DIR_IN;
3852                 break;
3853         case SCMD_WRITE_G5:
3854                 lba = SCSA2USB_LBA_12BYTE(pkt);
3855                 len = SCSA2USB_LEN_12BYTE(pkt);
3856                 dir = USB_EP_DIR_OUT;
3857                 break;
3858         }
3859 
3860         cmd->cmd_total_xfercount = xfer_count = len * blk_size;
3861 
3862         /* reduce xfer count if necessary */
3863         if (blk_size &&
3864             (xfer_count > scsa2usbp->scsa2usb_max_bulk_xfer_size)) {
3865                 /*
3866                  * For CD-RW devices reduce the xfer count based
3867                  * on the block size used by these devices. The
3868                  * block size could change for READ_CD and WRITE
3869                  * opcodes.
3870                  *
3871                  * Also as UHCI allows a max xfer of 32k at a time;
3872                  * compute the xfer_count based on the new block_size.
3873                  *
3874                  * The len part of the cdb changes as a result of that.
3875                  */
3876                 if (SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3877                         xfer_count = ((scsa2usbp->scsa2usb_max_bulk_xfer_size/
3878                             blk_size) * blk_size);
3879                         len = xfer_count/blk_size;
3880                         xfer_count = blk_size * len;
3881                 } else {
3882                         xfer_count = scsa2usbp->scsa2usb_max_bulk_xfer_size;
3883                         len = xfer_count/blk_size;
3884                 }
3885         }
3886 
3887         cmd->cmd_xfercount = xfer_count;
3888         cmd->cmd_dir = (uchar_t)dir;
3889         cmd->cmd_blksize = (int)blk_size;
3890 
3891         /*
3892          * Having figure out the 'partial' xfer len based on he
3893          * block size; fill it in to the cmd->cmd_cdb
3894          */
3895         cmd->cmd_cdb[SCSA2USB_OPCODE] = (uchar_t)opcode;
3896         switch (opcode) {
3897         case SCMD_READ_CD:
3898                 bcopy(pkt->pkt_cdbp, &cmd->cmd_cdb, cmd->cmd_cdblen);
3899                 scsa2usb_fill_up_ReadCD_cdb_len(cmd, len, CDB_GROUP5);
3900                 break;
3901         case SCMD_WRITE_G5:
3902         case SCMD_READ_G5:
3903                 scsa2usb_fill_up_12byte_cdb_len(cmd, len, CDB_GROUP5);
3904                 break;
3905         default:
3906                 scsa2usb_fill_up_cdb_len(cmd, len);
3907                 cmd->cmd_actual_len = CDB_GROUP1;
3908                 break;
3909         }
3910 
3911         scsa2usb_fill_up_cdb_lba(cmd, lba);
3912 
3913         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3914             "bcount=0x%lx lba=0x%x len=0x%lx xfercount=0x%lx total=0x%lx",
3915             bp ? bp->b_bcount : 0, lba, len, cmd->cmd_xfercount,
3916             cmd->cmd_total_xfercount);
3917 
3918         /* Set the timeout value as per command request */
3919         if ((opcode == SCMD_WRITE_G1) && SCSA2USB_VALID_CDRW_BLKSZ(blk_size)) {
3920                 /*
3921                  * We increase the time as CD-RW writes have two things
3922                  * to do. After writing out the data to the media, a
3923                  * TOC needs to be filled up at the beginning of the media
3924                  * This is when the write gets "finalized".
3925                  * Hence the actual write could take longer than the
3926                  * value specified in cmd->cmd_timeout.
3927                  */
3928                 cmd->cmd_timeout *= 4;
3929 
3930                 USB_DPRINTF_L4(DPRINT_MASK_SCSA,
3931                     scsa2usbp->scsa2usb_log_handle,
3932                     "new timeout value = 0x%x", cmd->cmd_timeout);
3933         }
3934 
3935         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3936             "lba 0x%x len 0x%lx xfercount 0x%lx total 0x%lx",
3937             lba, len, cmd->cmd_xfercount, cmd->cmd_total_xfercount);
3938 
3939         return (SCSA2USB_TRANSPORT);
3940 }
3941 
3942 
3943 /*
3944  * scsa2usb_setup_next_xfer:
3945  *      For READs and WRITEs we split up the transfer in terms of
3946  *      HCD understood units. This function handles the split transfers.
3947  *
3948  * See comments in the previous function scsa2usb_rw_transport
3949  *
3950  * The lba computation was being done based on scsa2usb_max_bulk_xfer_size
3951  * earlier. With CD-RW devices, the xfer_count and the block_size may
3952  * no longer be a multiple of scsa2usb_max_bulk_xfer_size. So compute
3953  * xfer_count all over again. Adjust lba, based on the previous requests'
3954  * len. Find out the len and add it to cmd->cmd_lba to get the new lba
3955  */
3956 void
3957 scsa2usb_setup_next_xfer(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
3958 {
3959         int xfer_len = min(scsa2usbp->scsa2usb_max_bulk_xfer_size,
3960             cmd->cmd_total_xfercount);
3961         int cdb_len;
3962         size_t blk_size;
3963 
3964         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
3965 
3966         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
3967             "scsa2usb_setup_next_xfer: opcode = 0x%x lba = 0x%x "
3968             "total count = 0x%lx", cmd->cmd_cdb[SCSA2USB_OPCODE],
3969             cmd->cmd_lba, cmd->cmd_total_xfercount);
3970 
3971         ASSERT(cmd->cmd_total_xfercount > 0);
3972         cmd->cmd_xfercount = xfer_len;
3973         blk_size = scsa2usbp->scsa2usb_lbasize[
3974             cmd->cmd_pkt->pkt_address.a_lun];
3975 
3976         /*
3977          * For CD-RW devices reduce the xfer count based on the
3978          * block_size used by these devices. See changes below
3979          * where xfer_count is being adjusted.
3980          *
3981          * Also adjust len/lba based on the block_size and xfer_count.
3982          * NOTE: Always calculate lba first, as it based on previous
3983          * commands' values.
3984          */
3985         switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
3986         case SCMD_READ_CD:
3987                 /* calculate lba = current_lba + len_of_prev_cmd */
3988                 cmd->cmd_lba += (cmd->cmd_cdb[6] << 16) +
3989                     (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
3990                 cdb_len = xfer_len/cmd->cmd_blksize;
3991                 cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)cdb_len;
3992                 /* re-adjust xfer count */
3993                 cmd->cmd_xfercount = cdb_len * cmd->cmd_blksize;
3994                 break;
3995         case SCMD_WRITE_G5:
3996         case SCMD_READ_G5:
3997                 /* calculate lba = current_lba + len_of_prev_cmd */
3998                 cmd->cmd_lba += (cmd->cmd_cdb[6] << 24) +
3999                     (cmd->cmd_cdb[7] << 16) + (cmd->cmd_cdb[8] << 8) +
4000                     cmd->cmd_cdb[9];
4001                 if (blk_size) {
4002                         xfer_len /= blk_size;
4003                 }
4004                 scsa2usb_fill_up_12byte_cdb_len(cmd, xfer_len, CDB_GROUP5);
4005                 break;
4006         case SCMD_WRITE_G1:
4007         case SCMD_WRITE_LONG:
4008                 /* calculate lba = current_lba + len_of_prev_cmd */
4009                 cmd->cmd_lba += (cmd->cmd_cdb[7] << 8) + cmd->cmd_cdb[8];
4010                 if (SCSA2USB_VALID_CDRW_BLKSZ(cmd->cmd_blksize)) {
4011                         blk_size = cmd->cmd_blksize;
4012                 }
4013                 cdb_len = xfer_len/blk_size;
4014                 scsa2usb_fill_up_cdb_len(cmd, cdb_len);
4015                 /* re-adjust xfer count */
4016                 cmd->cmd_xfercount = cdb_len * blk_size;
4017                 break;
4018         default:
4019                 if (blk_size) {
4020                         xfer_len /= blk_size;
4021                 }
4022                 scsa2usb_fill_up_cdb_len(cmd, xfer_len);
4023                 cmd->cmd_lba += scsa2usbp->scsa2usb_max_bulk_xfer_size/blk_size;
4024         }
4025 
4026         /* fill in the lba */
4027         scsa2usb_fill_up_cdb_lba(cmd, cmd->cmd_lba);
4028 
4029         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4030             "scsa2usb_setup_next_xfer:\n\tlba = 0x%x xfer_len = 0x%x "
4031             "xfercount = 0x%lx total = 0x%lx", cmd->cmd_lba, xfer_len,
4032             cmd->cmd_xfercount, cmd->cmd_total_xfercount);
4033 }
4034 
4035 
4036 /*
4037  * take one request from the lun's waitQ and transport it
4038  */
4039 static void
4040 scsa2usb_transport_request(scsa2usb_state_t *scsa2usbp, uint_t lun)
4041 {
4042         int                     rval;
4043         struct scsi_pkt         *pkt;
4044         struct scsa2usb_cmd     *cmd, *arqcmd;
4045 
4046         if ((cmd = (scsa2usb_cmd_t *)
4047             usba_rm_first_pvt_from_list(
4048             &scsa2usbp->scsa2usb_waitQ[lun])) == NULL) {
4049 
4050                 return;
4051         }
4052         pkt = cmd->cmd_pkt;
4053 
4054         /*
4055          * if device has been disconnected, just complete it
4056          */
4057         if (scsa2usbp->scsa2usb_dev_state == USB_DEV_DISCONNECTED) {
4058                 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4059                     "device not accessible");
4060                 pkt->pkt_reason = CMD_DEV_GONE;
4061                 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4062                 scsa2usb_pkt_completion(scsa2usbp, pkt);
4063 
4064                 return;
4065         }
4066 
4067         USB_DPRINTF_L4(DPRINT_MASK_SCSA,
4068             scsa2usbp->scsa2usb_log_handle,
4069             "scsa2usb_transport_request: cmd=0x%p bp=0x%p addr=0x%p",
4070             (void *)cmd, (void *)cmd->cmd_bp,
4071             (void *)(cmd->cmd_bp ? cmd->cmd_bp->b_un.b_addr : NULL));
4072 
4073         rval = scsa2usb_cmd_transport(scsa2usbp, cmd);
4074 
4075         USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4076             scsa2usbp->scsa2usb_log_handle,
4077             "scsa2usb_transport_request: transport rval = %d",
4078             rval);
4079 
4080         if (scsa2usbp->scsa2usb_cur_pkt == NULL) {
4081 
4082                 return;
4083         }
4084 
4085         ASSERT(pkt == scsa2usbp->scsa2usb_cur_pkt);
4086 
4087         if (ddi_in_panic()) {
4088                 pkt->pkt_reason = CMD_CMPLT;
4089                 scsa2usb_pkt_completion(scsa2usbp, pkt);
4090 
4091                 return;
4092         }
4093 
4094         /*
4095          * start an auto-request sense iff
4096          * there was a check condition, we have enough
4097          * space in the status block, and we have not
4098          * faked an auto request sense
4099          */
4100         if ((*(pkt->pkt_scbp) == STATUS_CHECK) &&
4101             (cmd->cmd_scblen >= sizeof (struct scsi_arq_status)) &&
4102             ((pkt->pkt_state & STATE_ARQ_DONE) == 0) &&
4103             (scsa2usb_create_arq_pkt(scsa2usbp,
4104             &pkt->pkt_address) == USB_SUCCESS)) {
4105                 arqcmd = scsa2usbp->scsa2usb_arq_cmd;
4106 
4107                 /*
4108                  * copy the timeout from the
4109                  * original packet
4110                  * for lack of a better value
4111                  */
4112                 arqcmd->cmd_pkt->pkt_time = pkt->pkt_time;
4113                 scsa2usb_prepare_pkt(scsa2usbp,
4114                     arqcmd->cmd_pkt);
4115 
4116                 scsa2usbp->scsa2usb_cur_pkt = NULL;
4117                 if (scsa2usb_cmd_transport(
4118                     scsa2usbp, arqcmd) == TRAN_ACCEPT) {
4119 
4120                         /* finish w/ this packet */
4121                         scsa2usb_complete_arq_pkt(
4122                             scsa2usbp, arqcmd->cmd_pkt, cmd,
4123                             scsa2usbp->scsa2usb_arq_bp);
4124 
4125                         /*
4126                          * we have valid request sense
4127                          * data so clear the pkt_reason
4128                          */
4129                         pkt->pkt_reason = CMD_CMPLT;
4130                 }
4131                 scsa2usbp->scsa2usb_cur_pkt = pkt;
4132                 scsa2usb_delete_arq_pkt(scsa2usbp);
4133         }
4134 
4135         if ((rval != TRAN_ACCEPT) &&
4136             (pkt->pkt_reason == CMD_CMPLT)) {
4137                 pkt->pkt_reason = CMD_TRAN_ERR;
4138         }
4139 
4140         SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp);
4141         scsa2usb_pkt_completion(scsa2usbp, pkt);
4142 
4143         ASSERT(scsa2usbp->scsa2usb_cur_pkt == NULL);
4144 }
4145 
4146 
4147 /*
4148  * scsa2usb_work_thread:
4149  *      The taskq thread that kicks off the transport (BO and CB/CBI)
4150  */
4151 static void
4152 scsa2usb_work_thread(void *arg)
4153 {
4154         scsa2usb_state_t        *scsa2usbp = (scsa2usb_state_t *)arg;
4155         uint_t                  lun;
4156         uint_t                  count;
4157 
4158         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4159         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4160             "scsa2usb_work_thread start: thread_id=0x%p",
4161             (void *)scsa2usbp->scsa2usb_work_thread_id);
4162 
4163         ASSERT(scsa2usbp->scsa2usb_work_thread_id == (kthread_t *)1);
4164         scsa2usbp->scsa2usb_work_thread_id = curthread;
4165 
4166         /* exclude ugen accesses */
4167         while (scsa2usbp->scsa2usb_transport_busy) {
4168                 cv_wait(&scsa2usbp->scsa2usb_transport_busy_cv,
4169                     &scsa2usbp->scsa2usb_mutex);
4170         }
4171         ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4172         scsa2usbp->scsa2usb_transport_busy++;
4173         scsa2usbp->scsa2usb_busy_proc = curproc;
4174 
4175         scsa2usb_raise_power(scsa2usbp);
4176 
4177         /* reopen the pipes if necessary */
4178         (void) scsa2usb_open_usb_pipes(scsa2usbp);
4179 
4180         for (;;) {
4181                 ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4182                 for (lun = 0; lun < scsa2usbp->scsa2usb_n_luns; lun++) {
4183                         scsa2usb_transport_request(scsa2usbp, lun);
4184                 }
4185                 count = 0;
4186                 for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
4187                         count += usba_list_entry_count(
4188                             &scsa2usbp->scsa2usb_waitQ[lun]);
4189                 }
4190 
4191                 if (count == 0) {
4192 
4193                         break;
4194                 }
4195         }
4196 
4197         scsa2usbp->scsa2usb_work_thread_id = 0;
4198 
4199         ASSERT(scsa2usbp->scsa2usb_ugen_open_count == 0);
4200 
4201         scsa2usbp->scsa2usb_transport_busy--;
4202         scsa2usbp->scsa2usb_busy_proc = NULL;
4203         cv_signal(&scsa2usbp->scsa2usb_transport_busy_cv);
4204 
4205         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4206             "scsa2usb_work_thread: exit");
4207 
4208         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4209 
4210         scsa2usb_pm_idle_component(scsa2usbp);
4211 }
4212 
4213 
4214 /*
4215  * scsa2usb_flush_waitQ:
4216  *      empties the entire waitQ with errors asap.
4217  *
4218  * It is called from scsa2usb_scsi_reset and scsa2usb_panic_callb.
4219  * If the device is reset; we should empty the waitQ right away.
4220  * If the system has paniced; we should empty the waitQ right away.
4221  *
4222  * CPR suspend will only succeed if device is idle. No need to call
4223  * this function for CPR suspend case.
4224  */
4225 static void
4226 scsa2usb_flush_waitQ(scsa2usb_state_t *scsa2usbp, uint_t lun,
4227     uchar_t error)
4228 {
4229         struct scsi_pkt         *pkt;
4230         struct scsa2usb_cmd     *cmd;
4231         usba_list_entry_t       head;
4232 
4233         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4234 
4235         usba_move_list(&scsa2usbp->scsa2usb_waitQ[lun], &head,
4236             scsa2usbp->scsa2usb_dev_data->dev_iblock_cookie);
4237         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4238 
4239         while ((cmd = (scsa2usb_cmd_t *)usba_rm_first_pvt_from_list(&head)) !=
4240             NULL) {
4241                 pkt = cmd->cmd_pkt;
4242                 pkt->pkt_reason = error;     /* set error */
4243 
4244                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4245                 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_DO_COMP;
4246                 scsa2usb_pkt_completion(scsa2usbp, pkt);
4247                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4248         } /* end of while */
4249 }
4250 
4251 
4252 /*
4253  * scsa2usb_do_inquiry is performed before INIT CHILD and we have
4254  * to fake a few things normally done by SCSA
4255  */
4256 static void
4257 scsa2usb_do_inquiry(scsa2usb_state_t *scsa2usbp, uint_t target, uint_t lun)
4258 {
4259         struct buf      *bp;
4260         struct scsi_pkt *pkt;
4261         struct scsi_address ap;
4262         int             len = SCSA2USB_MAX_INQ_LEN;
4263 
4264         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4265             "scsa2usb_do_inquiry: %d bytes", len);
4266 
4267         /* is it inquiry-challenged? */
4268         if (!(scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_INQUIRY)) {
4269                 scsa2usb_fake_inquiry(scsa2usbp,
4270                     &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4271                 return;
4272         }
4273 
4274         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4275 
4276         bzero(&ap, sizeof (struct scsi_address));
4277         ap.a_hba_tran = scsa2usbp->scsa2usb_tran;
4278         ap.a_target = (ushort_t)target;
4279         ap.a_lun = (uchar_t)lun;
4280 
4281         /* limit inquiry to 36 bytes */
4282         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4283         if ((bp = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
4284             len, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4285                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4286                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4287                     scsa2usbp->scsa2usb_log_handle,
4288                     "scsa2usb_do_inquiry: failed");
4289 
4290                 return;
4291         }
4292 
4293         pkt = scsi_init_pkt(&ap, NULL, bp, CDB_GROUP0, 1,
4294             PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL);
4295 
4296         RQ_MAKECOM_G0(pkt, FLAG_NOINTR, (char)SCMD_INQUIRY, 0, (char)len);
4297 
4298         pkt->pkt_comp = NULL;
4299         pkt->pkt_time = 5;
4300         bzero(bp->b_un.b_addr, len);
4301 
4302         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4303             "scsa2usb_do_inquiry:INQUIRY");
4304 
4305         (void) scsi_transport(pkt);
4306 
4307         if (pkt->pkt_reason) {
4308                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4309                     scsa2usbp->scsa2usb_log_handle,
4310                     "INQUIRY failed, cannot determine device type, "
4311                     "pkt_reason=0x%x", pkt->pkt_reason);
4312 
4313                 /* not much hope for other cmds, reduce */
4314                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4315                 scsa2usbp->scsa2usb_attrs &=
4316                     ~SCSA2USB_ATTRS_REDUCED_CMD;
4317                 scsa2usb_fake_inquiry(scsa2usbp,
4318                     &scsa2usbp->scsa2usb_lun_inquiry[lun]);
4319                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4320         }
4321 
4322         scsi_destroy_pkt(pkt);
4323         scsi_free_consistent_buf(bp);
4324 
4325         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4326 }
4327 
4328 
4329 /*
4330  * scsa2usb_fake_inquiry:
4331  *    build an inquiry for a given device that doesnt like inquiry
4332  *    commands.
4333  */
4334 static void
4335 scsa2usb_fake_inquiry(scsa2usb_state_t *scsa2usbp, struct scsi_inquiry *inqp)
4336 {
4337         usb_client_dev_data_t *dev_data = scsa2usbp->scsa2usb_dev_data;
4338         int len;
4339 
4340         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4341             "scsa2usb_fake_inquiry:");
4342 
4343         bzero(inqp, sizeof (struct scsi_inquiry));
4344         for (len = 0; len < sizeof (inqp->inq_vid); len++) {
4345                 *(inqp->inq_vid + len) = ' ';
4346         }
4347 
4348         for (len = 0; len < sizeof (inqp->inq_pid); len++) {
4349                 *(inqp->inq_pid + len) = ' ';
4350         }
4351 
4352         inqp->inq_dtype = DTYPE_DIRECT;
4353         inqp->inq_rmb = 1;
4354         inqp->inq_ansi = 2;
4355         inqp->inq_rdf = RDF_SCSI2;
4356         inqp->inq_len = sizeof (struct scsi_inquiry)-4;
4357 
4358         /* Fill in the Vendor id/Product id strings */
4359         if (dev_data->dev_mfg) {
4360                 if ((len = strlen(dev_data->dev_mfg)) >
4361                     sizeof (inqp->inq_vid)) {
4362                         len = sizeof (inqp->inq_vid);
4363                 }
4364                 bcopy(dev_data->dev_mfg, inqp->inq_vid, len);
4365         }
4366 
4367         if (dev_data->dev_product) {
4368                 if ((len = strlen(dev_data->dev_product)) >
4369                     sizeof (inqp->inq_pid)) {
4370                         len = sizeof (inqp->inq_pid);
4371                 }
4372                 bcopy(dev_data->dev_product, inqp->inq_pid, len);
4373         }
4374 
4375         /* Set the Revision to the Device */
4376         inqp->inq_revision[0] = 0x30 +
4377             ((dev_data->dev_descr->bcdDevice>>12) & 0xF);
4378         inqp->inq_revision[1] = 0x30 +
4379             ((dev_data->dev_descr->bcdDevice>>8) & 0xF);
4380         inqp->inq_revision[2] = 0x30 +
4381             ((dev_data->dev_descr->bcdDevice>>4) & 0xF);
4382         inqp->inq_revision[3] = 0x30 +
4383             ((dev_data->dev_descr->bcdDevice) & 0xF);
4384 }
4385 
4386 
4387 /*
4388  * scsa2usb_create_arq_pkt:
4389  *      Create and ARQ packet to get request sense data
4390  */
4391 static int
4392 scsa2usb_create_arq_pkt(scsa2usb_state_t *scsa2usbp, struct scsi_address *ap)
4393 {
4394         struct buf *bp;
4395         scsa2usb_cmd_t *arq_cmd;
4396 
4397         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4398             "scsa2usb_create_arq_pkt: scsa2usbp: %p, ap: %p",
4399             (void *)scsa2usbp, (void *)ap);
4400 
4401         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4402 
4403         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4404         if ((bp = scsi_alloc_consistent_buf(ap, (struct buf *)NULL,
4405             SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL)) == NULL) {
4406                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4407 
4408                 return (USB_FAILURE);
4409         }
4410 
4411         arq_cmd = PKT2CMD(scsi_init_pkt(ap, NULL, bp, CDB_GROUP0, 1,
4412             PKT_PRIV_LEN, PKT_CONSISTENT, SLEEP_FUNC, NULL));
4413         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4414 
4415         RQ_MAKECOM_G0(arq_cmd->cmd_pkt,
4416             FLAG_SENSING | FLAG_HEAD | FLAG_NODISCON,
4417             (char)SCMD_REQUEST_SENSE, 0, (char)SENSE_LENGTH);
4418 
4419         arq_cmd->cmd_pkt->pkt_ha_private = arq_cmd;
4420         scsa2usbp->scsa2usb_arq_cmd = arq_cmd;
4421         scsa2usbp->scsa2usb_arq_bp = bp;
4422         arq_cmd->cmd_pkt->pkt_comp = NULL;
4423         bzero(bp->b_un.b_addr, SENSE_LENGTH);
4424 
4425         return (USB_SUCCESS);
4426 }
4427 
4428 
4429 /*
4430  * scsa2usb_delete_arq_pkt:
4431  *      Destroy the ARQ packet
4432  */
4433 static void
4434 scsa2usb_delete_arq_pkt(scsa2usb_state_t *scsa2usbp)
4435 {
4436         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4437             "scsa2usb_delete_arq_pkt: cmd: 0x%p",
4438             (void *)scsa2usbp->scsa2usb_arq_cmd);
4439 
4440         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4441 
4442         if (scsa2usbp->scsa2usb_arq_cmd != NULL) {
4443                 scsi_destroy_pkt(scsa2usbp->scsa2usb_arq_cmd->cmd_pkt);
4444                 scsi_free_consistent_buf(scsa2usbp->scsa2usb_arq_bp);
4445         }
4446         scsa2usbp->scsa2usb_arq_cmd = NULL;
4447         scsa2usbp->scsa2usb_arq_bp = NULL;
4448 }
4449 
4450 
4451 /*
4452  * scsa2usb_complete_arq_pkt:
4453  *      finish processing the arq packet
4454  */
4455 static void
4456 scsa2usb_complete_arq_pkt(scsa2usb_state_t *scsa2usbp,
4457     struct scsi_pkt *pkt, scsa2usb_cmd_t *ssp, struct buf *bp)
4458 {
4459         scsa2usb_cmd_t          *sp = pkt->pkt_ha_private;
4460         struct scsi_arq_status  *arqp;
4461 
4462         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4463 
4464         arqp = (struct scsi_arq_status *)(ssp->cmd_pkt->pkt_scbp);
4465         arqp->sts_rqpkt_status = *((struct scsi_status *)
4466             (sp->cmd_pkt->pkt_scbp));
4467         arqp->sts_rqpkt_reason = CMD_CMPLT;
4468         arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
4469         arqp->sts_rqpkt_statistics = arqp->sts_rqpkt_resid = 0;
4470 
4471         /* is this meaningful sense data */
4472         if (*(bp->b_un.b_addr) != 0) {
4473                 bcopy(bp->b_un.b_addr, &arqp->sts_sensedata, SENSE_LENGTH);
4474                 ssp->cmd_pkt->pkt_state |= STATE_ARQ_DONE;
4475         }
4476 
4477         /* we will not sense start cmd until we receive a NOT READY */
4478         if (arqp->sts_sensedata.es_key == KEY_NOT_READY) {
4479                 scsa2usbp->scsa2usb_rcvd_not_ready = B_TRUE;
4480         }
4481 }
4482 
4483 
4484 /*
4485  * Miscellaneous functions for any command/transport
4486  */
4487 /*
4488  * scsa2usb_open_usb_pipes:
4489  *      set up a pipe policy
4490  *      open usb bulk pipes (BO and CB/CBI)
4491  *      open usb interrupt pipe (CBI)
4492  */
4493 static int
4494 scsa2usb_open_usb_pipes(scsa2usb_state_t *scsa2usbp)
4495 {
4496         int                     rval;
4497         usb_pipe_policy_t       policy; /* bulk pipe policy */
4498         size_t                  sz;
4499 
4500         ASSERT(scsa2usbp);
4501         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4502 
4503         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4504             "scsa2usb_open_usb_pipes: dip = 0x%p flag = 0x%x",
4505             (void *)scsa2usbp->scsa2usb_dip, scsa2usbp->scsa2usb_flags);
4506 
4507         if (!(scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED)) {
4508 
4509                 /*
4510                  * one pipe policy for all bulk pipes
4511                  */
4512                 bzero(&policy, sizeof (usb_pipe_policy_t));
4513                 /* at least 2, for the normal and exceptional callbacks */
4514                 policy.pp_max_async_reqs = 1;
4515 
4516                 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4517                     "scsa2usb_open_usb_pipes: opening bulk pipes");
4518 
4519                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4520 
4521                 /* Open the USB bulk-in pipe */
4522                 if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4523                     &scsa2usbp->scsa2usb_bulkin_ept, &policy, USB_FLAGS_SLEEP,
4524                     &scsa2usbp->scsa2usb_bulkin_pipe)) != USB_SUCCESS) {
4525                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4526                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4527                             scsa2usbp->scsa2usb_log_handle,
4528                             "scsa2usb_open_usb_pipes: bulk/in pipe open "
4529                             " failed rval = %d", rval);
4530 
4531                         return (USB_FAILURE);
4532                 }
4533 
4534                 /* Open the bulk-out pipe  using the same policy */
4535                 if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4536                     &scsa2usbp->scsa2usb_bulkout_ept, &policy, USB_FLAGS_SLEEP,
4537                     &scsa2usbp->scsa2usb_bulkout_pipe)) != USB_SUCCESS) {
4538                         usb_pipe_close(scsa2usbp->scsa2usb_dip,
4539                             scsa2usbp->scsa2usb_bulkin_pipe,
4540                             USB_FLAGS_SLEEP, NULL, NULL);
4541 
4542                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4543                         scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4544 
4545                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4546                             scsa2usbp->scsa2usb_log_handle,
4547                             "scsa2usb_open_usb_pipes: bulk/out pipe open"
4548                             " failed rval = %d", rval);
4549 
4550                         return (USB_FAILURE);
4551                 }
4552 
4553                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4554 
4555                 /* open interrupt pipe for CBI protocol */
4556                 if (SCSA2USB_IS_CBI(scsa2usbp)) {
4557                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4558 
4559                         if ((rval = usb_pipe_open(scsa2usbp->scsa2usb_dip,
4560                             &scsa2usbp->scsa2usb_intr_ept, &policy,
4561                             USB_FLAGS_SLEEP, &scsa2usbp->scsa2usb_intr_pipe)) !=
4562                             USB_SUCCESS) {
4563                                 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4564                                     scsa2usbp->scsa2usb_bulkin_pipe,
4565                                     USB_FLAGS_SLEEP, NULL, NULL);
4566 
4567                                 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4568                                     scsa2usbp->scsa2usb_bulkout_pipe,
4569                                     USB_FLAGS_SLEEP, NULL, NULL);
4570 
4571                                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4572                                 scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4573                                 scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4574 
4575                                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
4576                                     scsa2usbp->scsa2usb_log_handle,
4577                                     "scsa2usb_open_usb_pipes: intr pipe open"
4578                                     " failed rval = %d", rval);
4579 
4580                                 return (USB_FAILURE);
4581                         }
4582 
4583                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4584                 }
4585 
4586                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4587 
4588                 /* get the max transfer size of the bulk pipe */
4589                 if (usb_pipe_get_max_bulk_transfer_size(scsa2usbp->scsa2usb_dip,
4590                     &sz) == USB_SUCCESS) {
4591                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4592                         scsa2usbp->scsa2usb_max_bulk_xfer_size = sz;
4593                 } else {
4594                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4595                         scsa2usbp->scsa2usb_max_bulk_xfer_size = DEV_BSIZE;
4596                 }
4597 
4598                 /* limit the xfer size */
4599                 scsa2usbp->scsa2usb_max_bulk_xfer_size = min(
4600                     scsa2usbp->scsa2usb_max_bulk_xfer_size,
4601                     scsa2usb_max_bulk_xfer_size);
4602 
4603                 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4604                     "scsa2usb_open_usb_pipes: max bulk transfer size = %lx",
4605                     scsa2usbp->scsa2usb_max_bulk_xfer_size);
4606 
4607                 /* Set the pipes opened flag */
4608                 scsa2usbp->scsa2usb_flags |= SCSA2USB_FLAGS_PIPES_OPENED;
4609 
4610                 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4611 
4612                 /* Set the state to NONE */
4613                 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
4614         }
4615 
4616         return (USB_SUCCESS);
4617 }
4618 
4619 
4620 /*
4621  * scsa2usb_close_usb_pipes:
4622  *      close all pipes synchronously
4623  */
4624 void
4625 scsa2usb_close_usb_pipes(scsa2usb_state_t *scsa2usbp)
4626 {
4627         usb_flags_t flags = USB_FLAGS_SLEEP;
4628 
4629         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4630             "scsa2usb_close_usb_pipes: scsa2usb_state = 0x%p",
4631             (void *)scsa2usbp);
4632 
4633         ASSERT(scsa2usbp);
4634         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4635 
4636         if ((scsa2usbp->scsa2usb_flags & SCSA2USB_FLAGS_PIPES_OPENED) == 0) {
4637 
4638                 return;
4639         }
4640 
4641         scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_CLOSING;
4642         /* to avoid races, reset the flag first */
4643         scsa2usbp->scsa2usb_flags &= ~SCSA2USB_FLAGS_PIPES_OPENED;
4644 
4645         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4646 
4647         usb_pipe_close(scsa2usbp->scsa2usb_dip,
4648             scsa2usbp->scsa2usb_bulkout_pipe, flags, NULL, NULL);
4649 
4650         usb_pipe_close(scsa2usbp->scsa2usb_dip,
4651             scsa2usbp->scsa2usb_bulkin_pipe, flags, NULL, NULL);
4652 
4653         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4654         if (SCSA2USB_IS_CBI(scsa2usbp)) {
4655                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4656                 usb_pipe_close(scsa2usbp->scsa2usb_dip,
4657                     scsa2usbp->scsa2usb_intr_pipe, flags, NULL, NULL);
4658                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4659         }
4660         scsa2usbp->scsa2usb_bulkout_pipe = NULL;
4661         scsa2usbp->scsa2usb_bulkin_pipe = NULL;
4662         scsa2usbp->scsa2usb_intr_pipe = NULL;
4663 
4664         scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_NORMAL;
4665 }
4666 
4667 
4668 /*
4669  * scsa2usb_fill_up_cdb_lba:
4670  *      fill up command CDBs' LBA part
4671  */
4672 static void
4673 scsa2usb_fill_up_cdb_lba(scsa2usb_cmd_t *cmd, int lba)
4674 {
4675         /* zero cdb1, lba bits so they won't get copied in the new cdb */
4676         cmd->cmd_cdb[SCSA2USB_LUN] &= 0xE0;
4677         cmd->cmd_cdb[SCSA2USB_LBA_0] = lba >> 24;
4678         cmd->cmd_cdb[SCSA2USB_LBA_1] = lba >> 16;
4679         cmd->cmd_cdb[SCSA2USB_LBA_2] = lba >> 8;
4680         cmd->cmd_cdb[SCSA2USB_LBA_3] = (uchar_t)lba;
4681         cmd->cmd_lba = lba;
4682 }
4683 
4684 
4685 /*
4686  * scsa2usb_fill_up_ReadCD_cdb_len:
4687  *      fill up READ_CD command CDBs' len part
4688  */
4689 static void
4690 scsa2usb_fill_up_ReadCD_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4691 {
4692         cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_0] = len >> 16;
4693         cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_1] = len >> 8;
4694         cmd->cmd_cdb[SCSA2USB_READ_CD_LEN_2] = (uchar_t)len;
4695         cmd->cmd_actual_len = (uchar_t)actual_len;
4696 }
4697 
4698 
4699 /*
4700  * scsa2usb_fill_up_12byte_cdb_len:
4701  *      fill up generic 12-byte command CDBs' len part
4702  */
4703 static void
4704 scsa2usb_fill_up_12byte_cdb_len(scsa2usb_cmd_t *cmd, int len, int actual_len)
4705 {
4706         cmd->cmd_cdb[6] = len >> 24;
4707         cmd->cmd_cdb[7] = len >> 16;
4708         cmd->cmd_cdb[8] = len >> 8;
4709         cmd->cmd_cdb[9] = (uchar_t)len;
4710         cmd->cmd_actual_len = (uchar_t)actual_len;
4711 }
4712 
4713 
4714 /*
4715  * scsa2usb_fill_up_cdb_len:
4716  *      fill up generic 10-byte command CDBs' len part
4717  */
4718 static void
4719 scsa2usb_fill_up_cdb_len(scsa2usb_cmd_t *cmd, int len)
4720 {
4721         cmd->cmd_cdb[SCSA2USB_LEN_0] = len >> 8;
4722         cmd->cmd_cdb[SCSA2USB_LEN_1] = (uchar_t)len;
4723 }
4724 
4725 
4726 /*
4727  * scsa2usb_read_cd_blk_size:
4728  *      For SCMD_READ_CD opcode (0xbe). Figure out the
4729  *      block size based on expected sector type field
4730  *      definition. See MMC SCSI Specs section 6.1.15
4731  *
4732  *      Based on the value of the "expected_sector_type"
4733  *      field, the block size could be different.
4734  */
4735 static int
4736 scsa2usb_read_cd_blk_size(uchar_t expected_sector_type)
4737 {
4738         int blk_size;
4739 
4740         switch (expected_sector_type) {
4741         case READ_CD_EST_CDDA:
4742                 blk_size = CDROM_BLK_2352;
4743                 break;
4744         case READ_CD_EST_MODE2:
4745                 blk_size = CDROM_BLK_2336;
4746                 break;
4747         case READ_CD_EST_MODE2FORM2:
4748                 blk_size = CDROM_BLK_2324;
4749                 break;
4750         case READ_CD_EST_MODE2FORM1:
4751         case READ_CD_EST_ALLTYPE:
4752         case READ_CD_EST_MODE1:
4753         default:
4754                 blk_size = CDROM_BLK_2048;
4755         }
4756 
4757         USB_DPRINTF_L4(DPRINT_MASK_SCSA, NULL, "scsa2usb_read_cd_blk_size: "
4758             "est = 0x%x blk_size = %d", expected_sector_type, blk_size);
4759 
4760         return (blk_size);
4761 }
4762 
4763 
4764 /*
4765  * scsa2usb_bp_to_mblk:
4766  *      Convert a bp to mblk_t. USBA framework understands mblk_t.
4767  */
4768 static mblk_t *
4769 scsa2usb_bp_to_mblk(scsa2usb_state_t *scsa2usbp)
4770 {
4771         size_t          size;
4772         mblk_t          *mp;
4773         struct buf      *bp;
4774         scsa2usb_cmd_t  *cmd = PKT2CMD(scsa2usbp->scsa2usb_cur_pkt);
4775 
4776         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4777             "scsa2usb_bp_to_mblk: ");
4778 
4779         ASSERT(scsa2usbp->scsa2usb_cur_pkt);
4780         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4781 
4782         bp = cmd->cmd_bp;
4783 
4784         if (bp && (bp->b_bcount > 0)) {
4785                 size = ((bp->b_bcount > cmd->cmd_xfercount) ?
4786                     cmd->cmd_xfercount : bp->b_bcount);
4787         } else {
4788 
4789                 return (NULL);
4790         }
4791 
4792         mp = esballoc_wait((uchar_t *)bp->b_un.b_addr + cmd->cmd_offset,
4793             size, BPRI_LO, &frnop);
4794 
4795         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4796             "scsa2usb_bp_to_mblk: "
4797             "mp=0x%p bp=0x%p pkt=0x%p off=0x%lx sz=%lu add=0x%p",
4798             (void *)mp, (void *)bp, (void *)scsa2usbp->scsa2usb_cur_pkt,
4799             cmd->cmd_offset, bp->b_bcount - cmd->cmd_offset,
4800             (void *)bp->b_un.b_addr);
4801 
4802         mp->b_wptr += size;
4803         cmd->cmd_offset += size;
4804 
4805         return (mp);
4806 }
4807 
4808 
4809 /*
4810  * scsa2usb_handle_data_start:
4811  *      Initiate the data xfer. It could be IN/OUT direction.
4812  *
4813  *      Data IN:
4814  *              Send out the bulk-xfer request
4815  *              if rval implies STALL
4816  *                      clear endpoint stall and reset bulk-in pipe
4817  *                      handle data read in so far; set cmd->cmd_done
4818  *                      also adjust data xfer length accordingly
4819  *              else other error
4820  *                      report back to transport
4821  *                      typically transport will call reset recovery
4822  *              else (no error)
4823  *                      return success
4824  *
4825  *      Data OUT:
4826  *              Send out the bulk-xfer request
4827  *              if rval implies STALL
4828  *                      clear endpoint stall and reset bulk-in pipe
4829  *                      adjust data xfer length
4830  *              else other error
4831  *                      report back to transport
4832  *                      typically transport will call reset recovery
4833  *              else (no error)
4834  *                      return success
4835  *
4836  *      NOTE: We call this function only if there is xfercount.
4837  */
4838 int
4839 scsa2usb_handle_data_start(scsa2usb_state_t *scsa2usbp,
4840     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
4841 {
4842         int             rval = USB_SUCCESS;
4843         uint_t          ept_addr;
4844         usb_flags_t     flags = USB_FLAGS_SLEEP;
4845 #ifdef  SCSA2USB_BULK_ONLY_TEST
4846         usb_req_attrs_t attrs = 0;
4847 #else
4848         usb_req_attrs_t attrs = USB_ATTRS_SHORT_XFER_OK;
4849 #endif
4850 
4851         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
4852             "scsa2usb_handle_data_start: BEGIN cmd = %p, req = %p",
4853             (void *)cmd, (void *)req);
4854 
4855         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
4856 
4857         switch (cmd->cmd_dir) {
4858         case USB_EP_DIR_IN:
4859 #ifdef  SCSA2USB_BULK_ONLY_TEST
4860                 /*
4861                  * This case occurs when the host expects to receive
4862                  * more data than the device actually transfers. Hi > Di
4863                  */
4864                 if (scsa2usb_test_case_5) {
4865                         usb_bulk_req_t *req2;
4866 
4867                         req->bulk_len = cmd->cmd_xfercount - 1;
4868                         req->bulk_attributes = 0;
4869                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4870                         SCSA2USB_FREE_MSG(req->bulk_data);
4871                         req->bulk_data = allocb_wait(req->bulk_len, BPRI_LO,
4872                             STR_NOSIG, NULL);
4873 
4874                         ASSERT(req->bulk_timeout);
4875                         rval = usb_pipe_bulk_xfer(
4876                             scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4877                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4878                         USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4879                             scsa2usbp->scsa2usb_log_handle, "rval = %x", rval);
4880 
4881                         req2 = scsa2usb_init_bulk_req(scsa2usbp,
4882                             cmd->cmd_xfercount + 2,
4883                             cmd->cmd_timeout, 0, flags);
4884                         req2->bulk_len = cmd->cmd_xfercount + 2;
4885                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4886 
4887                         ASSERT(req2->bulk_timeout);
4888                         rval = usb_pipe_bulk_xfer(
4889                             scsa2usbp->scsa2usb_bulkin_pipe, req2, flags);
4890                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4891 
4892                         USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4893                             scsa2usbp->scsa2usb_log_handle,
4894                             "TEST 5: Hi > Di: rval = 0x%x", rval);
4895                         scsa2usb_test_case_5 = 0;
4896                         usb_free_bulk_req(req2);
4897 
4898                         return (rval);
4899                 }
4900 
4901                 /*
4902                  * This happens when the host expects to send data to the
4903                  * device while the device intends to send data to the host.
4904                  */
4905                 if (scsa2usb_test_case_8 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) {
4906                         USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4907                             scsa2usbp->scsa2usb_log_handle,
4908                             "TEST 8: Hi <> Do: Step 2");
4909                         scsa2usb_test_mblk(scsa2usbp, B_TRUE);
4910                         scsa2usb_test_case_8 = 0;
4911 
4912                         return (rval);
4913                 }
4914 #endif  /* SCSA2USB_BULK_ONLY_TEST */
4915 
4916                 ept_addr = scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress;
4917                 req->bulk_len = cmd->cmd_xfercount;
4918                 req->bulk_attributes = attrs;
4919                 SCSA2USB_FREE_MSG(req->bulk_data);
4920                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4921 
4922                 req->bulk_data = esballoc_wait(
4923                     (uchar_t *)cmd->cmd_bp->b_un.b_addr +
4924                     cmd->cmd_offset,
4925                     req->bulk_len, BPRI_LO, &frnop);
4926 
4927                 ASSERT(req->bulk_timeout);
4928                 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe,
4929                     req, flags);
4930                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4931 
4932                 break;
4933 
4934         case USB_EP_DIR_OUT:
4935 #ifdef  SCSA2USB_BULK_ONLY_TEST
4936                 /*
4937                  * This happens when the host expects to receive data
4938                  * from the device while the device intends to receive
4939                  * data from the host.
4940                  */
4941                 if (scsa2usb_test_case_10 &&
4942                     (cmd->cmd_cdb[0] == SCMD_WRITE_G1)) {
4943                         req->bulk_len = CSW_LEN;
4944                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
4945 
4946                         ASSERT(req->bulk_timeout);
4947                         rval = usb_pipe_bulk_xfer(
4948                             scsa2usbp->scsa2usb_bulkin_pipe, req, flags);
4949                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
4950 
4951                         USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4952                             scsa2usbp->scsa2usb_log_handle,
4953                             "TEST 10: Ho <> Di: done rval = 0x%x",  rval);
4954                         scsa2usb_test_case_10 = 0;
4955 
4956                         return (rval);
4957                 }
4958 #endif  /* SCSA2USB_BULK_ONLY_TEST */
4959 
4960                 req->bulk_data = scsa2usb_bp_to_mblk(scsa2usbp);
4961                 if (req->bulk_data == NULL) {
4962 
4963                         return (USB_FAILURE);
4964                 }
4965 
4966 #ifdef  SCSA2USB_BULK_ONLY_TEST
4967                 if (scsa2usb_test_case_11) {
4968                         /*
4969                          * Host expects to send data to the device and
4970                          * device doesn't expect to receive any data
4971                          */
4972                         USB_DPRINTF_L1(DPRINT_MASK_SCSA,
4973                             scsa2usbp->scsa2usb_log_handle, "TEST 11: Ho > Do");
4974 
4975                         scsa2usb_test_mblk(scsa2usbp, B_FALSE);
4976                         scsa2usb_test_case_11 = 0;
4977                 }
4978 #endif  /* SCSA2USB_BULK_ONLY_TEST */
4979 
4980                 ept_addr = scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress;
4981                 req->bulk_len = MBLKL(req->bulk_data);
4982                 req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout);
4983                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
4984 
4985                 ASSERT(req->bulk_timeout);
4986                 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe,
4987                     req, flags);
4988                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
4989                 break;
4990         }
4991 
4992         USB_DPRINTF_L3(DPRINT_MASK_SCSA,
4993             scsa2usbp->scsa2usb_log_handle,
4994             "scsa2usb_handle_data_start: rval=%d cr=%d", rval,
4995             req->bulk_completion_reason);
4996 
4997         if (rval != USB_SUCCESS) {
4998                 /* Handle Errors now */
4999                 if (req->bulk_completion_reason == USB_CR_STALL) {
5000                         if (cmd->cmd_dir == USB_EP_DIR_IN) {
5001                                 (void) scsa2usb_clear_ept_stall(
5002                                     scsa2usbp, ept_addr,
5003                                     scsa2usbp-> scsa2usb_bulkin_pipe,
5004                                     "bulk-in");
5005                         } else {
5006                                 (void) scsa2usb_clear_ept_stall(
5007                                     scsa2usbp, ept_addr,
5008                                     scsa2usbp-> scsa2usb_bulkout_pipe,
5009                                     "bulk-out");
5010                         }
5011                 }
5012 
5013                 /* no more data to transfer after this */
5014                 cmd->cmd_done = 1;
5015         }
5016 
5017         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5018             "scsa2usb_handle_data_start: END %s data rval = %d",
5019             (cmd->cmd_dir == USB_EP_DIR_IN) ? "bulk-in" : "bulk-out", rval);
5020 
5021         return (rval);
5022 }
5023 
5024 
5025 /*
5026  * scsa2usb_handle_data_done:
5027  *      This function handles the completion of the data xfer.
5028  *      It also massages the inquiry data. This function may
5029  *      also be called after a stall.
5030  */
5031 void
5032 scsa2usb_handle_data_done(scsa2usb_state_t *scsa2usbp,
5033     scsa2usb_cmd_t *cmd, usb_bulk_req_t *req)
5034 {
5035         struct buf      *bp = cmd->cmd_bp;
5036         struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt;
5037         mblk_t          *data = req->bulk_data;
5038         int             len = data ? MBLKL(data) : 0;
5039         uint32_t        max_lba;
5040 
5041         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5042 
5043         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5044             "scsa2usb_handle_data_done:\n\tcmd = 0x%p data = 0x%p len = 0x%x",
5045             (void *)cmd, (void *)data, len);
5046 
5047         cmd->cmd_resid_xfercount = cmd->cmd_xfercount - len;
5048 
5049         if (len)  {
5050                 uchar_t *p;
5051                 uchar_t dtype;
5052                 scsa2usb_read_cap_t *cap;
5053                 struct scsi_inquiry *inq;
5054 
5055                 switch (cmd->cmd_cdb[SCSA2USB_OPCODE]) {
5056                 case SCMD_INQUIRY:
5057                         /*
5058                          * cache a copy of the inquiry data for our own use
5059                          * but ensure that we have at least up to
5060                          * inq_revision, inq_serial is not required.
5061                          * ignore inquiry data returned for inquiry commands
5062                          * with SCSI-3 EVPD, CmdDt bits set.
5063                          */
5064                         if (((cmd->cmd_cdb[SCSA2USB_LUN] & 0x1f) == 0) &&
5065                             (len >= SCSA2USB_MAX_INQ_LEN)) {
5066                                 inq = (struct scsi_inquiry *)data->b_rptr;
5067                                 dtype = inq->inq_dtype & DTYPE_MASK;
5068                                 /*
5069                                  * scsi framework sends zero byte write(10) cmd
5070                                  * to (Simplified) direct-access devices with
5071                                  * inquiry version > 2 for reservation changes.
5072                                  * But some USB devices don't support zero byte
5073                                  * write(10) even though they have inquiry
5074                                  * version > 2. Considering scsa2usb driver
5075                                  * doesn't support reservation and all the
5076                                  * reservation cmds are being faked, we fake
5077                                  * the inquiry version to 0 to make scsi
5078                                  * framework send test unit ready cmd which is
5079                                  * supported by all the usb devices.
5080                                  */
5081                                 if (((dtype == DTYPE_DIRECT) ||
5082                                     (dtype == DTYPE_RBC)) &&
5083                                     (inq->inq_ansi > 2)) {
5084                                         inq->inq_ansi = 0;
5085                                 }
5086 
5087                                 bzero(&scsa2usbp->scsa2usb_lun_inquiry
5088                                     [pkt->pkt_address.a_lun],
5089                                     sizeof (struct scsi_inquiry));
5090                                 bcopy(data->b_rptr,
5091                                     &scsa2usbp->scsa2usb_lun_inquiry
5092                                     [pkt->pkt_address.a_lun], len);
5093                         }
5094 
5095                         USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5096                             scsa2usbp->scsa2usb_log_handle,
5097                             "scsi inquiry type = 0x%x",
5098                             scsa2usbp->scsa2usb_lun_inquiry
5099                             [pkt->pkt_address.a_lun].inq_dtype);
5100 
5101                         cmd->cmd_done = 1;
5102                         goto handle_data;
5103 
5104                 case SCMD_READ_CAPACITY:
5105                         cap = (scsa2usb_read_cap_t *)data->b_rptr;
5106 
5107                         /* Figure out the logical block size */
5108                         if ((len >= sizeof (struct scsa2usb_read_cap)) &&
5109                             (req->bulk_completion_reason == USB_CR_OK)) {
5110                                 scsa2usbp->
5111                                     scsa2usb_lbasize[pkt->pkt_address.a_lun] =
5112                                     SCSA2USB_MK_32BIT(
5113                                     cap->scsa2usb_read_cap_blen3,
5114                                     cap->scsa2usb_read_cap_blen2,
5115                                     cap->scsa2usb_read_cap_blen1,
5116                                     cap->scsa2usb_read_cap_blen0);
5117 
5118                                 max_lba = SCSA2USB_MK_32BIT(
5119                                     cap->scsa2usb_read_cap_lba3,
5120                                     cap->scsa2usb_read_cap_lba2,
5121                                     cap->scsa2usb_read_cap_lba1,
5122                                     cap->scsa2usb_read_cap_lba0);
5123 
5124                                 /*
5125                                  * Some devices return total logical block
5126                                  * number instead of highest logical block
5127                                  * address. Adjust the value by minus 1.
5128                                  */
5129                                 if (max_lba > 0 && (scsa2usbp->scsa2usb_attrs &
5130                                     SCSA2USB_ATTRS_NO_CAP_ADJUST) == 0) {
5131                                         max_lba -= 1;
5132                                         cap->scsa2usb_read_cap_lba0 =
5133                                             (uchar_t)(max_lba & 0xFF);
5134                                         cap->scsa2usb_read_cap_lba1 =
5135                                             (uchar_t)(max_lba >> 8 & 0xFF);
5136                                         cap->scsa2usb_read_cap_lba2 =
5137                                             (uchar_t)(max_lba >> 16 & 0xFF);
5138                                         cap->scsa2usb_read_cap_lba3 =
5139                                             (uchar_t)(max_lba >> 24 & 0xFF);
5140                                 }
5141 
5142                                 USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5143                                     scsa2usbp->scsa2usb_log_handle,
5144                                     "bytes in each logical block=0x%lx,"
5145                                     "number of total logical blocks=0x%x",
5146                                     scsa2usbp->
5147                                     scsa2usb_lbasize[pkt->pkt_address.a_lun],
5148                                     max_lba + 1);
5149                         }
5150                         cmd->cmd_done = 1;
5151                         goto handle_data;
5152 
5153                 case SCMD_REQUEST_SENSE:
5154                         p = data->b_rptr;
5155                         USB_DPRINTF_L2(DPRINT_MASK_SCSA,
5156                             scsa2usbp->scsa2usb_log_handle,
5157                             "cdb: %x rqsense: "
5158                             "%x %x %x %x %x %x %x %x %x %x\n\t"
5159                             "%x %x %x %x %x %x %x %x %x %x",
5160                             cmd->cmd_cdb[0],
5161                             p[0], p[1], p[2], p[3], p[4],
5162                             p[5], p[6], p[7], p[8], p[9],
5163                             p[10], p[11], p[12], p[13], p[14],
5164                             p[15], p[16], p[17], p[18], p[19]);
5165 
5166                         scsa2usbp->scsa2usb_last_cmd.status = p[2];
5167                         cmd->cmd_done = 1;
5168                         /* FALLTHROUGH */
5169 
5170                 default:
5171 handle_data:
5172                         if (bp && len && (cmd->cmd_dir == USB_EP_DIR_IN)) {
5173                                 /*
5174                                  * we don't have to copy the data, the
5175                                  * data pointers for the mblk_t for
5176                                  * the bulk-in xfer points to the
5177                                  * struct buf * data.
5178                                  */
5179                                 cmd->cmd_offset += len;
5180                         }
5181 
5182                         USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5183                             scsa2usbp->scsa2usb_log_handle,
5184                             "len = 0x%x total = 0x%lx offset = 0x%lx",
5185                             len, cmd->cmd_total_xfercount, cmd->cmd_offset);
5186 
5187                         /*
5188                          * update total_xfercount now but it may be
5189                          * adjusted after receiving the residue
5190                          */
5191                         cmd->cmd_total_xfercount -= len;
5192 
5193                         if ((req->bulk_completion_reason != USB_CR_OK) ||
5194                             (cmd->cmd_resid_xfercount != 0) ||
5195                             (cmd->cmd_total_xfercount == 0)) {
5196                                 /* set pkt_resid to total to be sure */
5197                                 pkt->pkt_resid = cmd->cmd_total_xfercount;
5198                                 cmd->cmd_done = 1;
5199                         }
5200 
5201                         break;
5202                 }
5203         } else {
5204                 if (cmd->cmd_dir == USB_EP_DIR_OUT) {
5205                         if (cmd->cmd_total_xfercount == 0) {
5206                                 cmd->cmd_done = 1;
5207                         }
5208                 }
5209         }
5210 }
5211 
5212 
5213 /*
5214  * scsa2usb_init_bulk_req:
5215  *      Allocate (synchronously) and fill in a bulk-request
5216  */
5217 usb_bulk_req_t *
5218 scsa2usb_init_bulk_req(scsa2usb_state_t *scsa2usbp, size_t length,
5219     uint_t timeout, usb_req_attrs_t attrs, usb_flags_t flags)
5220 {
5221         usb_bulk_req_t  *req;
5222 
5223         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5224 
5225         req = usb_alloc_bulk_req(scsa2usbp->scsa2usb_dip, length,
5226             flags | USB_FLAGS_SLEEP);
5227 
5228         req->bulk_len = (uint_t)length;                      /* xfer length */
5229         req->bulk_timeout = scsa2usb_bulk_timeout(timeout); /* xfer timeout */
5230         req->bulk_attributes = attrs;                /* xfer attrs */
5231         req->bulk_client_private = (usb_opaque_t)scsa2usbp; /* statep */
5232 
5233         return (req);
5234 }
5235 
5236 
5237 /*
5238  * scsa2usb_bulk_timeout:
5239  *      ensure that bulk requests do not have infinite timeout values
5240  */
5241 int
5242 scsa2usb_bulk_timeout(int timeout)
5243 {
5244         return ((timeout == 0) ? scsa2usb_long_timeout : timeout);
5245 }
5246 
5247 
5248 /*
5249  * scsa2usb_clear_ept_stall:
5250  *      clear endpoint stall and reset pipes
5251  */
5252 int
5253 scsa2usb_clear_ept_stall(scsa2usb_state_t *scsa2usbp, uint_t ept_addr,
5254     usb_pipe_handle_t ph, char *what)
5255 {
5256         int rval;
5257         dev_info_t *dip = scsa2usbp->scsa2usb_dip;
5258 
5259         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5260         if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) {
5261 
5262                 return (USB_FAILURE);
5263         }
5264 
5265         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5266         rval = usb_clr_feature(dip, USB_DEV_REQ_RCPT_EP, 0, ept_addr,
5267             USB_FLAGS_SLEEP, NULL, NULL);
5268 
5269         usb_pipe_reset(dip, ph, USB_FLAGS_SLEEP, NULL, NULL);
5270 
5271         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5272         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5273             "scsa2usb_clear_ept_stall: on %s: ept = 0x%x rval = %d",
5274             what, ept_addr, rval);
5275 
5276         return (rval);
5277 }
5278 
5279 
5280 /*
5281  * scsa2usb_pkt_completion:
5282  *      Handle pkt completion.
5283  */
5284 static void
5285 scsa2usb_pkt_completion(scsa2usb_state_t *scsa2usbp, struct scsi_pkt *pkt)
5286 {
5287         scsa2usb_cmd_t *cmd = PKT2CMD(pkt);
5288         size_t len;
5289 
5290         ASSERT(pkt);
5291         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5292 
5293         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5294             "scsa2usb_pkt_completion:\n\tscsa2usbp = 0x%p "
5295             "reason=%d, status=%d state=0x%x stats=0x%x resid=0x%lx",
5296             (void *)scsa2usbp, pkt->pkt_reason, *(pkt->pkt_scbp),
5297             pkt->pkt_state, pkt->pkt_statistics, pkt->pkt_resid);
5298 
5299         if (pkt->pkt_reason == CMD_CMPLT) {
5300                 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5301                     STATE_SENT_CMD | STATE_GOT_STATUS;
5302                 if (cmd->cmd_xfercount) {
5303                         pkt->pkt_state |= STATE_XFERRED_DATA;
5304                 }
5305         } else {
5306                 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
5307                     STATE_SENT_CMD;
5308         }
5309 
5310         /*
5311          * don't zap the current state when in panic as this will
5312          * make debugging harder
5313          */
5314         if ((scsa2usbp->scsa2usb_cur_pkt == pkt) && !ddi_in_panic()) {
5315                 SCSA2USB_RESET_CUR_PKT(scsa2usbp);
5316 
5317                 len = sizeof (scsa2usbp->scsa2usb_last_cmd.cdb);
5318                 bzero(scsa2usbp->scsa2usb_last_cmd.cdb, len);
5319 
5320                 len = (len < cmd->cmd_cdblen) ? len : cmd->cmd_cdblen;
5321                 USB_DPRINTF_L3(DPRINT_MASK_SCSA,
5322                     scsa2usbp->scsa2usb_log_handle,
5323                     "scsa2usb_pkt_completion: save last cmd, len=%ld", len);
5324 
5325                 /* save the last command */
5326                 bcopy(pkt->pkt_cdbp, scsa2usbp->scsa2usb_last_cmd.cdb, len);
5327 
5328                 /* reset the scsa2usb_last_cmd.status value */
5329                 if ((pkt->pkt_cdbp[0] != SCMD_REQUEST_SENSE) &&
5330                     (pkt->pkt_cdbp[0] != SCMD_INQUIRY)) {
5331                         scsa2usbp->scsa2usb_last_cmd.status = 0;
5332                 }
5333 
5334                 /*
5335                  * set pkt state to NONE *before* calling back as the target
5336                  * driver will immediately submit the next packet
5337                  */
5338                 scsa2usbp->scsa2usb_pkt_state = SCSA2USB_PKT_NONE;
5339         }
5340 
5341         if (pkt->pkt_comp) {
5342                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5343                 scsi_hba_pkt_comp(pkt);
5344                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5345 
5346         }
5347 }
5348 
5349 
5350 /*
5351  * Even handling functions:
5352  *
5353  * scsa2usb_reconnect_event_cb:
5354  *      event handling
5355  */
5356 static int
5357 scsa2usb_reconnect_event_cb(dev_info_t *dip)
5358 {
5359         scsa2usb_state_t *scsa2usbp =
5360             ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5361         dev_info_t      *cdip;
5362         int             circ;
5363         int             rval = USB_SUCCESS;
5364 
5365         ASSERT(scsa2usbp != NULL);
5366 
5367         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5368             "scsa2usb_reconnect_event_cb: dip = 0x%p", (void *)dip);
5369 
5370         scsa2usb_restore_device_state(dip, scsa2usbp);
5371 
5372         USB_DPRINTF_L0(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5373             "Reinserted device is accessible again.");
5374 
5375         ndi_devi_enter(dip, &circ);
5376         for (cdip = ddi_get_child(dip); cdip; ) {
5377                 dev_info_t *next = ddi_get_next_sibling(cdip);
5378 
5379                 mutex_enter(&DEVI(cdip)->devi_lock);
5380                 DEVI_SET_DEVICE_REINSERTED(cdip);
5381                 mutex_exit(&DEVI(cdip)->devi_lock);
5382 
5383                 cdip = next;
5384         }
5385         ndi_devi_exit(dip, circ);
5386 
5387         /* stop suppressing warnings */
5388         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5389         scsa2usbp->scsa2usb_warning_given = B_FALSE;
5390         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5391 
5392         if (scsa2usbp->scsa2usb_ugen_hdl) {
5393                 rval = usb_ugen_reconnect_ev_cb(
5394                     scsa2usbp->scsa2usb_ugen_hdl);
5395         }
5396 
5397         return (rval);
5398 }
5399 
5400 
5401 /*
5402  * scsa2usb_all_waitQs_empty:
5403  *      check if all waitQs empty
5404  */
5405 static int
5406 scsa2usb_all_waitQs_empty(scsa2usb_state_t *scsa2usbp)
5407 {
5408         uint_t  lun;
5409 
5410         for (lun = 0; lun < SCSA2USB_MAX_LUNS; lun++) {
5411                 if (usba_list_entry_count(
5412                     &scsa2usbp->scsa2usb_waitQ[lun])) {
5413 
5414                         return (USB_FAILURE);
5415                 }
5416         }
5417 
5418         return (USB_SUCCESS);
5419 }
5420 
5421 
5422 /*
5423  * scsa2usb_disconnect_event_cb:
5424  *      callback for disconnect events
5425  */
5426 static int
5427 scsa2usb_disconnect_event_cb(dev_info_t *dip)
5428 {
5429         scsa2usb_state_t *scsa2usbp =
5430             ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5431         dev_info_t      *cdip;
5432         int             circ, i;
5433         int             rval = USB_SUCCESS;
5434 
5435         ASSERT(scsa2usbp != NULL);
5436 
5437         USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5438             "scsa2usb_disconnect_event_cb: dip = 0x%p", (void *)dip);
5439 
5440         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5441         scsa2usbp->scsa2usb_dev_state = USB_DEV_DISCONNECTED;
5442 
5443         /*
5444          * wait till the work thread is done, carry on regardless
5445          * if not.
5446          */
5447         for (i = 0; i < SCSA2USB_DRAIN_TIMEOUT; i++) {
5448                 if ((scsa2usbp->scsa2usb_work_thread_id == NULL) &&
5449                     (scsa2usbp->scsa2usb_cur_pkt == NULL) &&
5450                     (scsa2usb_all_waitQs_empty(scsa2usbp) ==
5451                     USB_SUCCESS)) {
5452 
5453                         break;
5454                 }
5455                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5456                 delay(drv_usectohz(1000000));
5457                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5458         }
5459         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5460 
5461         ndi_devi_enter(dip, &circ);
5462         for (cdip = ddi_get_child(dip); cdip; ) {
5463                 dev_info_t *next = ddi_get_next_sibling(cdip);
5464 
5465                 mutex_enter(&DEVI(cdip)->devi_lock);
5466                 DEVI_SET_DEVICE_REMOVED(cdip);
5467                 mutex_exit(&DEVI(cdip)->devi_lock);
5468 
5469                 cdip = next;
5470         }
5471         ndi_devi_exit(dip, circ);
5472 
5473         if (scsa2usbp->scsa2usb_ugen_hdl) {
5474                 rval = usb_ugen_disconnect_ev_cb(
5475                     scsa2usbp->scsa2usb_ugen_hdl);
5476         }
5477 
5478         return (rval);
5479 }
5480 
5481 
5482 /*
5483  * PM support
5484  *
5485  * scsa2usb_create_pm_components:
5486  *      create the pm components required for power management
5487  *      no mutex is need when calling USBA interfaces
5488  */
5489 static void
5490 scsa2usb_create_pm_components(dev_info_t *dip, scsa2usb_state_t *scsa2usbp)
5491 {
5492         scsa2usb_power_t *pm;
5493         uint_t          pwr_states;
5494 
5495         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5496 
5497         USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5498             "scsa2usb_create_pm_components: dip = 0x%p, scsa2usbp = 0x%p",
5499             (void *)dip, (void *)scsa2usbp);
5500 
5501         /*
5502          * determine if this device is on the blacklist
5503          * or if a conf file entry has disabled PM
5504          */
5505         if ((scsa2usbp->scsa2usb_attrs & SCSA2USB_ATTRS_PM) == 0) {
5506                 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5507                     "device cannot be power managed");
5508 
5509                 return;
5510         }
5511 
5512         /* Allocate the PM state structure */
5513         pm = kmem_zalloc(sizeof (scsa2usb_power_t), KM_SLEEP);
5514 
5515         scsa2usbp->scsa2usb_pm = pm;
5516         pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5517         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5518 
5519         if (usb_create_pm_components(dip, &pwr_states) ==
5520             USB_SUCCESS) {
5521                 if (usb_handle_remote_wakeup(dip,
5522                     USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) {
5523                         pm->scsa2usb_wakeup_enabled = 1;
5524                 }
5525 
5526                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5527                 pm->scsa2usb_pwr_states = (uint8_t)pwr_states;
5528                 scsa2usb_raise_power(scsa2usbp);
5529                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5530         }
5531 
5532         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5533 }
5534 
5535 
5536 /*
5537  * scsa2usb_raise_power:
5538  *      check if the device is using full power or not
5539  */
5540 static void
5541 scsa2usb_raise_power(scsa2usb_state_t *scsa2usbp)
5542 {
5543         USB_DPRINTF_L4(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5544             "scsa2usb_raise_power:");
5545 
5546         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5547 
5548         if (scsa2usbp->scsa2usb_pm) {
5549                 scsa2usb_pm_busy_component(scsa2usbp);
5550                 if (scsa2usbp->scsa2usb_pm->scsa2usb_current_power !=
5551                     USB_DEV_OS_FULL_PWR) {
5552                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5553                         (void) pm_raise_power(scsa2usbp->scsa2usb_dip,
5554                             0, USB_DEV_OS_FULL_PWR);
5555                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5556                 }
5557         }
5558 }
5559 
5560 
5561 /*
5562  * functions to handle power transition for OS levels 0 -> 3
5563  */
5564 static int
5565 scsa2usb_pwrlvl0(scsa2usb_state_t *scsa2usbp)
5566 {
5567         int     rval;
5568 
5569         switch (scsa2usbp->scsa2usb_dev_state) {
5570         case USB_DEV_ONLINE:
5571                 /* Deny the powerdown request if the device is busy */
5572                 if (scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy != 0) {
5573 
5574                         return (USB_FAILURE);
5575                 }
5576 
5577                 /*
5578                  * stop polling on interrupt pipe
5579                  */
5580                 scsa2usb_cbi_stop_intr_polling(scsa2usbp);
5581 
5582                 /* Issue USB D3 command to the device here */
5583                 rval = usb_set_device_pwrlvl3(scsa2usbp->scsa2usb_dip);
5584                 ASSERT(rval == USB_SUCCESS);
5585 
5586                 scsa2usbp->scsa2usb_dev_state = USB_DEV_PWRED_DOWN;
5587 
5588                 /* FALLTHRU */
5589         case USB_DEV_DISCONNECTED:
5590         case USB_DEV_SUSPENDED:
5591         case USB_DEV_PWRED_DOWN:
5592         default:
5593                 scsa2usbp->scsa2usb_pm->scsa2usb_current_power =
5594                     USB_DEV_OS_PWR_OFF;
5595 
5596                 return (USB_SUCCESS);
5597         }
5598 }
5599 
5600 
5601 static int
5602 scsa2usb_pwrlvl1(scsa2usb_state_t *scsa2usbp)
5603 {
5604         int     rval;
5605 
5606         /* Issue USB D2 command to the device here */
5607         rval = usb_set_device_pwrlvl2(scsa2usbp->scsa2usb_dip);
5608         ASSERT(rval == USB_SUCCESS);
5609 
5610         return (DDI_FAILURE);
5611 }
5612 
5613 
5614 static int
5615 scsa2usb_pwrlvl2(scsa2usb_state_t *scsa2usbp)
5616 {
5617         int     rval;
5618 
5619         /* Issue USB D1 command to the device here */
5620         rval = usb_set_device_pwrlvl1(scsa2usbp->scsa2usb_dip);
5621         ASSERT(rval == USB_SUCCESS);
5622 
5623         return (DDI_FAILURE);
5624 }
5625 
5626 
5627 static int
5628 scsa2usb_pwrlvl3(scsa2usb_state_t *scsa2usbp)
5629 {
5630         int     rval;
5631 
5632         /*
5633          * PM framework tries to put us in full power
5634          * during system shutdown. If we are disconnected
5635          * return success anyways
5636          */
5637         if (scsa2usbp->scsa2usb_dev_state != USB_DEV_DISCONNECTED) {
5638                 /* Issue USB D0 command to the device here */
5639                 rval = usb_set_device_pwrlvl0(scsa2usbp->scsa2usb_dip);
5640                 ASSERT(rval == USB_SUCCESS);
5641 
5642                 scsa2usbp->scsa2usb_dev_state = USB_DEV_ONLINE;
5643         }
5644         scsa2usbp->scsa2usb_pm->scsa2usb_current_power = USB_DEV_OS_FULL_PWR;
5645 
5646         return (DDI_SUCCESS);
5647 }
5648 
5649 
5650 /*
5651  * scsa2usb_power:
5652  *      power entry point
5653  */
5654 /* ARGSUSED */
5655 static int
5656 scsa2usb_power(dev_info_t *dip, int comp, int level)
5657 {
5658         scsa2usb_state_t        *scsa2usbp;
5659         scsa2usb_power_t        *pm;
5660         int                     rval = DDI_FAILURE;
5661 
5662         scsa2usbp = ddi_get_soft_state(scsa2usb_statep, ddi_get_instance(dip));
5663 
5664         USB_DPRINTF_L3(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5665             "scsa2usb_power: Begin scsa2usbp (%p): level = %d",
5666             (void *)scsa2usbp, level);
5667 
5668         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5669         if (SCSA2USB_BUSY(scsa2usbp)) {
5670                 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5671                     "scsa2usb_power: busy");
5672                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5673 
5674                 return (rval);
5675         }
5676 
5677         pm = scsa2usbp->scsa2usb_pm;
5678         if (pm == NULL) {
5679                 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5680                     "scsa2usb_power: pm NULL");
5681                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5682 
5683                 return (rval);
5684         }
5685 
5686         /* check if we are transitioning to a legal power level */
5687         if (USB_DEV_PWRSTATE_OK(pm->scsa2usb_pwr_states, level)) {
5688                 USB_DPRINTF_L2(DPRINT_MASK_PM, scsa2usbp->scsa2usb_log_handle,
5689                     "scsa2usb_power: illegal power level = %d "
5690                     "pwr_states: %x", level, pm->scsa2usb_pwr_states);
5691                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5692 
5693                 return (rval);
5694         }
5695 
5696         switch (level) {
5697         case USB_DEV_OS_PWR_OFF :
5698                 rval = scsa2usb_pwrlvl0(scsa2usbp);
5699                 break;
5700         case USB_DEV_OS_PWR_1 :
5701                 rval = scsa2usb_pwrlvl1(scsa2usbp);
5702                 break;
5703         case USB_DEV_OS_PWR_2 :
5704                 rval = scsa2usb_pwrlvl2(scsa2usbp);
5705                 break;
5706         case USB_DEV_OS_FULL_PWR :
5707                 rval = scsa2usb_pwrlvl3(scsa2usbp);
5708                 break;
5709         }
5710 
5711         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5712 
5713         return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
5714 }
5715 
5716 
5717 static void
5718 scsa2usb_pm_busy_component(scsa2usb_state_t *scsa2usbp)
5719 {
5720         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5721 
5722         if (scsa2usbp->scsa2usb_pm) {
5723                 scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy++;
5724 
5725                 USB_DPRINTF_L4(DPRINT_MASK_PM,
5726                     scsa2usbp->scsa2usb_log_handle,
5727                     "scsa2usb_pm_busy_component: %d",
5728                     scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5729 
5730                 mutex_exit(&scsa2usbp->scsa2usb_mutex);
5731 
5732                 if (pm_busy_component(scsa2usbp->scsa2usb_dip, 0) !=
5733                     DDI_SUCCESS) {
5734                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5735                         ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5736                         scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5737 
5738                         USB_DPRINTF_L2(DPRINT_MASK_PM,
5739                             scsa2usbp->scsa2usb_log_handle,
5740                             "scsa2usb_pm_busy_component failed: %d",
5741                             scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5742 
5743                         return;
5744                 }
5745                 mutex_enter(&scsa2usbp->scsa2usb_mutex);
5746         }
5747 }
5748 
5749 
5750 /*
5751  * scsa2usb_pm_idle_component:
5752  *      idles the device
5753  */
5754 static void
5755 scsa2usb_pm_idle_component(scsa2usb_state_t *scsa2usbp)
5756 {
5757         ASSERT(!mutex_owned(&scsa2usbp->scsa2usb_mutex));
5758 
5759         if (scsa2usbp->scsa2usb_pm) {
5760                 if (pm_idle_component(scsa2usbp->scsa2usb_dip, 0) ==
5761                     DDI_SUCCESS) {
5762                         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5763                         ASSERT(scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy > 0);
5764                         scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy--;
5765 
5766                         USB_DPRINTF_L4(DPRINT_MASK_PM,
5767                             scsa2usbp->scsa2usb_log_handle,
5768                             "scsa2usb_pm_idle_component: %d",
5769                             scsa2usbp->scsa2usb_pm->scsa2usb_pm_busy);
5770 
5771                         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5772                 }
5773         }
5774 }
5775 
5776 
5777 #ifdef  DEBUG
5778 /*
5779  * scsa2usb_print_cdb:
5780  *      prints CDB
5781  */
5782 void
5783 scsa2usb_print_cdb(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
5784 {
5785         uchar_t *c = (uchar_t *)&cmd->cmd_cdb;
5786 
5787         USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5788             "cmd = 0x%p opcode=%s "
5789             "cdb: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
5790             (void *)cmd,
5791             scsi_cname(cmd->cmd_cdb[SCSA2USB_OPCODE], scsa2usb_cmds),
5792             c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8],
5793             c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
5794 }
5795 #endif  /* DEBUG */
5796 
5797 
5798 #ifdef  SCSA2USB_BULK_ONLY_TEST
5799 /*
5800  * scsa2usb_test_mblk:
5801  *      This function sends a dummy data mblk_t to simulate
5802  *      the following test cases: 5 and 11.
5803  */
5804 static void
5805 scsa2usb_test_mblk(scsa2usb_state_t *scsa2usbp, boolean_t large)
5806 {
5807         int                     i, rval;
5808         size_t                  len;
5809         usb_flags_t             flags = USB_FLAGS_SLEEP;
5810         usb_bulk_req_t          *req;
5811 
5812         ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
5813 
5814         /* should we create a larger mblk? */
5815         len = (large == B_TRUE) ? DEV_BSIZE : USB_BULK_CBWCMD_LEN;
5816 
5817         req = scsa2usb_init_bulk_req(scsa2usbp, len,
5818             SCSA2USB_BULK_PIPE_TIMEOUT, 0, flags);
5819 
5820         /* fill up the data mblk */
5821         for (i = 0; i < len; i++) {
5822                 *req->bulk_data->b_wptr++ = (uchar_t)i;
5823         }
5824 
5825         mutex_exit(&scsa2usbp->scsa2usb_mutex);
5826         ASSERT(req->bulk_timeout);
5827         rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, flags);
5828         mutex_enter(&scsa2usbp->scsa2usb_mutex);
5829 
5830         USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle,
5831             "scsa2usb_test_mblk: Sent Data Out rval = 0x%x", rval);
5832 
5833         usb_free_bulk_req(req);
5834 }
5835 #endif  /* SCSA2USB_BULK_ONLY_TEST */