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