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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25 26 /* 27 * scsa2usb_ms_bulkonly.c: 28 * 29 * This file implements USB Mass Storage Class 30 * Bulk Only (BO) transport v1.0 31 * http://www.usb.org/developers/data/devclass/usbmassbulk_10.pdf 32 */ 33 #include <sys/usb/usba/usbai_version.h> 34 #include <sys/scsi/scsi.h> 35 #include <sys/callb.h> /* needed by scsa2usb.h */ 36 #include <sys/strsubr.h> 37 #include <sys/strsun.h> 38 39 #include <sys/usb/usba.h> 40 #include <sys/usb/usba/usba_private.h> 41 #include <sys/usb/usba/usba_ugen.h> 42 43 #include <sys/usb/clients/mass_storage/usb_bulkonly.h> 44 #include <sys/usb/scsa2usb/scsa2usb.h> 45 46 /* 47 * Function Prototypes 48 */ 49 int scsa2usb_bulk_only_transport(scsa2usb_state_t *, 50 scsa2usb_cmd_t *); 51 static void scsa2usb_fill_in_cbw(scsa2usb_state_t *, scsa2usb_cmd_t *, 52 mblk_t *); 53 static void scsa2usb_bulk_only_reset_recovery(scsa2usb_state_t *); 54 static void scsa2usb_bulk_only_handle_error(scsa2usb_state_t *, 55 usb_bulk_req_t *); 56 int scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *); 57 static int scsa2usb_handle_status_start(scsa2usb_state_t *, 58 usb_bulk_req_t *); 59 static int scsa2usb_handle_csw_result(scsa2usb_state_t *, mblk_t *); 60 61 62 /* extern functions */ 63 extern void scsa2usb_setup_next_xfer(scsa2usb_state_t *, scsa2usb_cmd_t *); 64 extern int scsa2usb_handle_data_start(scsa2usb_state_t *, 65 scsa2usb_cmd_t *, usb_bulk_req_t *); 66 extern void scsa2usb_handle_data_done(scsa2usb_state_t *, scsa2usb_cmd_t *, 67 usb_bulk_req_t *); 68 extern usb_bulk_req_t *scsa2usb_init_bulk_req(scsa2usb_state_t *, 69 size_t, uint_t, usb_req_attrs_t, usb_flags_t); 70 extern int scsa2usb_bulk_timeout(int); 71 extern int scsa2usb_clear_ept_stall(scsa2usb_state_t *, uint_t, 72 usb_pipe_handle_t, char *); 73 extern void scsa2usb_close_usb_pipes(scsa2usb_state_t *); 74 75 #ifdef DEBUG /* debugging information */ 76 extern void scsa2usb_print_cdb(scsa2usb_state_t *, scsa2usb_cmd_t *); 77 #endif /* DEBUG */ 78 79 80 #ifdef SCSA2USB_BULK_ONLY_TEST 81 /* 82 * Test 13 cases. (See USB Mass Storage Class - Bulk Only Transport). 83 * We are not covering test cases 1, 6, and 12 as these are the "good" 84 * test cases and are tested as part of the normal drive access operations. 85 * 86 * NOTE: This is for testing only. It will be replaced by a uscsi test. 87 */ 88 int scsa2usb_test_case_2 = 0; 89 int scsa2usb_test_case_3 = 0; 90 int scsa2usb_test_case_4 = 0; 91 int scsa2usb_test_case_7 = 0; 92 extern int scsa2usb_test_case_8; 93 int scsa2usb_test_case_9 = 0; 94 extern int scsa2usb_test_case_10; 95 int scsa2usb_test_case_13 = 0; 96 #endif /* SCSA2USB_BULK_ONLY_TEST */ 97 98 99 /* 100 * scsa2usb_bulk_only_transport: 101 * Implements the BO state machine by these steps: 102 * a) Issues CBW to a Bulk Only device. 103 * b) Start Data Phase if applicable 104 * c) Start Status Phase 105 * 106 * returns TRAN_* values 107 * 108 * scsa2usb_bulk_only_state_machine: 109 * 110 * scsa2usb_bulk_only_transport() handles the normal transitions or 111 * continuation after clearing stalls or error recovery. 112 * 113 * Command Phase: 114 * prepare a valid CBW and transport it on bulk-out pipe 115 * if error on bulkout: 116 * set pkt_reason to CMD_TRAN_ERR 117 * new pkt state is SCSA2USB_PKT_DO_COMP 118 * reset recovery synchronously 119 * else 120 * proceed to data phase 121 * 122 * Data Phase: 123 * if data in: 124 * setup data in on bulkin 125 * else if data out: 126 * setup data out on bulkout 127 * 128 * data: (in) 129 * copy data transferred so far, no more data to transfer 130 * 131 * if stall on bulkin pipe 132 * terminate data transfers, set cmd_done 133 * clear stall on bulkin syncrhonously 134 * else if other exception 135 * set pkt_reason to CMD_TRAN_ERR 136 * new pkt state is SCSA2USB_PKT_DO_COMP 137 * reset recovery syncrhonously 138 * else (no error) 139 * receive status 140 * 141 * data: (out) 142 * if stall on bulkout pipe 143 * terminate data transfers, set cmd_done 144 * clear stall on bulkout synchronously USBA 145 * else if other exception 146 * set pkt_reason to CMD_TRAN_ERR 147 * new pkt state is SCSA2USB_PKT_DO_COMP 148 * reset recovery synchronously 149 * else (no error) 150 * receive status 151 * 152 * Status Phase: 153 * 154 * if stall (first attempt) 155 * new pkt state is SCSA2USB_PKT_PROCESS_CSW 156 * setup receiving status on bulkin 157 * if stall (second attempt) 158 * new pkt state is SCSA2USB_PKT_DO_COMP 159 * reset recovery synchronously, we are hosed. 160 * else 161 * goto check CSW 162 * else 163 * goto check CSW 164 * 165 * check CSW: 166 * - check length equals 13, signature, and matching tag 167 * - check status is less than or equal to 2 168 * - check residue is less than or equal to data length 169 * adjust residue based on if we got valid data 170 * 171 * if not OK 172 * new pkt state is SCSA2USB_PKT_DO_COMP 173 * set pkt reason CMD_TRAN_ERR 174 * reset recovery synchronously, we are hosed 175 * else if phase error 176 * new pkt state is SCSA2USB_PKT_DO_COMP 177 * set pkt reason CMD_TRAN_ERR 178 * reset recovery synchronously 179 * else if (status < 2) 180 * if status is equal to 1 181 * set check condition 182 * if residue 183 * calculate residue from data xferred and DataResidue 184 * 185 * set pkt_residue 186 * goto SCSA2USB_PKT_DO_COMP 187 * 188 * The reset recovery walks sequentially thru device reset, clearing 189 * stalls and pipe resets. When the reset recovery completes we return 190 * to the taskq thread. 191 * 192 * Clearing stalls clears the stall condition, resets the pipe, and 193 * then returns to the transport. 194 */ 195 int 196 scsa2usb_bulk_only_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd) 197 { 198 int rval; 199 int nretry; 200 usb_bulk_req_t *req; 201 202 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 203 204 Cmd_Phase: 205 /* 206 * Start Command Phase 207 * Initialize a bulk_req_t 208 */ 209 req = scsa2usb_init_bulk_req(scsa2usbp, USB_BULK_CBWCMD_LEN, 210 SCSA2USB_BULK_PIPE_TIMEOUT, USB_ATTRS_PIPE_RESET, USB_FLAGS_SLEEP); 211 212 scsa2usb_fill_in_cbw(scsa2usbp, cmd, req->bulk_data); /* Fill CBW */ 213 SCSA2USB_PRINT_CDB(scsa2usbp, cmd); /* Print CDB */ 214 215 /* Send a Bulk Command Block Wrapper (CBW) to the device */ 216 mutex_exit(&scsa2usbp->scsa2usb_mutex); 217 218 ASSERT(req->bulk_timeout); 219 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkout_pipe, req, 220 USB_FLAGS_SLEEP); 221 mutex_enter(&scsa2usbp->scsa2usb_mutex); 222 223 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 224 "scsa2usb_bulk_only_transport: " 225 "sent cmd = 0x%x Tag = 0x%x DataXferLen = 0x%lx rval = %d", 226 cmd->cmd_cdb[SCSA2USB_OPCODE], cmd->cmd_tag, cmd->cmd_xfercount, 227 rval); 228 229 if (rval != USB_SUCCESS) { 230 scsa2usb_bulk_only_handle_error(scsa2usbp, req); 231 232 return (TRAN_FATAL_ERROR); 233 } 234 235 /* free the data */ 236 SCSA2USB_FREE_MSG(req->bulk_data); 237 req->bulk_data = NULL; 238 239 Data_Phase: 240 /* 241 * Start Data Phase 242 * re-set timeout 243 */ 244 req->bulk_timeout = scsa2usb_bulk_timeout(cmd->cmd_timeout); 245 246 /* 247 * we've not transferred any data yet; updated in 248 * scsa2usb_handle_data_done 249 */ 250 cmd->cmd_resid_xfercount = cmd->cmd_xfercount; 251 252 if (cmd->cmd_xfercount) { 253 /* start I/O to/from the device */ 254 rval = scsa2usb_handle_data_start(scsa2usbp, cmd, req); 255 256 /* handle data returned, if any */ 257 scsa2usb_handle_data_done(scsa2usbp, cmd, req); 258 259 if (rval != USB_SUCCESS) { 260 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 261 scsa2usbp->scsa2usb_log_handle, 262 "data xfer phase, error = %d, cr = %d", 263 rval, req->bulk_completion_reason); 264 /* 265 * we ran into an error 266 */ 267 if (req->bulk_completion_reason == USB_CR_STALL) { 268 if (scsa2usbp->scsa2usb_cur_pkt) { 269 scsa2usbp->scsa2usb_cur_pkt-> 270 pkt_reason = CMD_TRAN_ERR; 271 } 272 } else { 273 scsa2usb_bulk_only_handle_error(scsa2usbp, req); 274 275 return (TRAN_FATAL_ERROR); 276 } 277 } /* end of else */ 278 279 /* free the data */ 280 SCSA2USB_FREE_MSG(req->bulk_data); 281 req->bulk_data = NULL; 282 } 283 284 Status_Phase: 285 /* 286 * Start status phase 287 * read in CSW 288 */ 289 for (nretry = 0; nretry < SCSA2USB_STATUS_RETRIES; nretry++) { 290 rval = scsa2usb_handle_status_start(scsa2usbp, req); 291 292 if ((rval != USB_SUCCESS) && 293 (req->bulk_completion_reason == USB_CR_STALL)) { 294 /* 295 * We ran into STALL condition here. 296 * If the condition cannot be cleared 297 * successfully, retry for limited times. 298 */ 299 scsa2usbp->scsa2usb_pkt_state = 300 SCSA2USB_PKT_PROCESS_CSW; 301 } else { 302 303 break; 304 } 305 } 306 307 if (rval == USB_SUCCESS) { 308 /* process CSW */ 309 rval = scsa2usb_handle_csw_result(scsa2usbp, req->bulk_data); 310 } else { 311 scsa2usb_bulk_only_handle_error(scsa2usbp, req); 312 313 return (TRAN_FATAL_ERROR); 314 } 315 316 SCSA2USB_FREE_BULK_REQ(req); /* free request */ 317 318 if ((rval == USB_SUCCESS) && /* CSW was ok */ 319 (scsa2usbp->scsa2usb_cur_pkt->pkt_reason == CMD_CMPLT) && 320 (cmd->cmd_xfercount != 0) && /* more data to xfer */ 321 !cmd->cmd_done) { /* we aren't done yet */ 322 scsa2usb_setup_next_xfer(scsa2usbp, cmd); 323 goto Cmd_Phase; 324 } 325 326 return (rval == USB_SUCCESS ? TRAN_ACCEPT : TRAN_FATAL_ERROR); 327 } 328 329 330 /* 331 * scsa2usb_fill_in_cbw: 332 * Fill in a CBW request packet. This 333 * packet is transported to the device 334 */ 335 static void 336 scsa2usb_fill_in_cbw(scsa2usb_state_t *scsa2usbp, 337 scsa2usb_cmd_t *cmd, mblk_t *mp) 338 { 339 int i; 340 int len; 341 uchar_t dir, *cdb = (uchar_t *)(&cmd->cmd_cdb); 342 343 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 344 345 *mp->b_wptr++ = CBW_MSB(CBW_SIGNATURE); /* CBW Signature */; 346 *mp->b_wptr++ = CBW_MID1(CBW_SIGNATURE); 347 *mp->b_wptr++ = CBW_MID2(CBW_SIGNATURE); 348 *mp->b_wptr++ = CBW_LSB(CBW_SIGNATURE); 349 *mp->b_wptr++ = CBW_LSB(cmd->cmd_tag); /* CBW Tag */ 350 *mp->b_wptr++ = CBW_MID2(cmd->cmd_tag); 351 *mp->b_wptr++ = CBW_MID1(cmd->cmd_tag); 352 *mp->b_wptr++ = CBW_MSB(cmd->cmd_tag); 353 354 dir = cmd->cmd_dir; 355 len = cmd->cmd_xfercount; 356 #ifdef SCSA2USB_BULK_ONLY_TEST 357 if (scsa2usb_test_case_2 && (cdb[0] == SCMD_READ_CAPACITY)) { 358 /* Host expects no data. The device wants data. Hn < Di */ 359 scsa2usb_test_case_2 = len = 0; 360 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 361 "TEST 2: Hn < Di cdb: 0x%x len: 0x%x", cdb[0], len); 362 } 363 364 if (scsa2usb_test_case_3 && (cmd->cmd_dir == CBW_DIR_OUT)) { 365 /* Host expects no data. The device wants data. Hn < Do */ 366 if (cdb[0] == SCMD_WRITE_G1) { 367 scsa2usb_test_case_3 = len = 0; 368 USB_DPRINTF_L1(DPRINT_MASK_SCSA, 369 scsa2usbp->scsa2usb_log_handle, 370 "TEST 3: Hn < Do cdb: 0x%x len:%x", cdb[0], len); 371 } 372 } 373 374 if (scsa2usb_test_case_4 && (cdb[0] == SCMD_READ_G1)) { 375 cdb[0] = 0x5e; 376 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 377 "TEST 4: Hi > Dn: changed cdb to 0x%x", cdb[0]); 378 scsa2usb_test_case_4 = 0; 379 } 380 381 if (scsa2usb_test_case_7 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) { 382 len -= 0x10; 383 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 384 "TEST 7: Hi < Di cdb: 0x%x len: 0x%x", cdb[0], len); 385 scsa2usb_test_case_7 = 0; 386 } 387 388 if (scsa2usb_test_case_8 && (cdb[0] == SCMD_READ_G1)) { 389 dir = (dir == CBW_DIR_IN) ? CBW_DIR_OUT : dir; 390 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 391 "TEST 8: Hi <> Do cdb: 0x%x dir: 0x%x", cdb[0], dir); 392 } 393 394 if (scsa2usb_test_case_9 && (cdb[0] == SCMD_WRITE_G1)) { 395 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 396 "TEST 9: Ho <> Di (%x)", cdb[0]); 397 cdb[SCSA2USB_LEN_0] = cdb[SCSA2USB_LEN_1] = 0; 398 scsa2usb_test_case_9 = 0; 399 } 400 401 if (scsa2usb_test_case_10 && (cdb[0] == SCMD_WRITE_G1)) { 402 dir = (dir == CBW_DIR_OUT) ? CBW_DIR_IN : dir; 403 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 404 "TEST 10: Ho <> Di cdb: 0x%x dir: 0x%x", cdb[0], dir); 405 } 406 407 /* 408 * This case occurs when the device intends to receive 409 * more data from the host than the host sends. 410 */ 411 if (scsa2usb_test_case_13) { 412 if ((cdb[0] == SCMD_WRITE_G1) || (cdb[0] == SCMD_READ_G1)) { 413 USB_DPRINTF_L1(DPRINT_MASK_SCSA, 414 scsa2usbp->scsa2usb_log_handle, "TEST 13: Ho < Do"); 415 416 len -= 30; 417 scsa2usb_test_case_13 = 0; 418 } 419 } 420 #endif /* SCSA2USB_BULK_ONLY_TEST */ 421 422 *mp->b_wptr++ = CBW_MSB(len); /* Transfer Length */ 423 *mp->b_wptr++ = CBW_MID1(len); 424 *mp->b_wptr++ = CBW_MID2(len); 425 *mp->b_wptr++ = CBW_LSB(len); 426 427 *mp->b_wptr++ = dir; /* Transfer Direction */ 428 *mp->b_wptr++ = cmd->cmd_pkt->pkt_address.a_lun; /* Lun # */ 429 *mp->b_wptr++ = cmd->cmd_actual_len; /* CDB Len */ 430 431 /* Copy the CDB out */ 432 for (i = 0; i < CBW_CDB_LEN; i++) { 433 *mp->b_wptr++ = *cdb++; 434 } 435 #ifdef DUMP_CWB 436 { 437 int len = mp->b_wptr - mp->b_rptr; 438 char *buf; 439 440 int i; 441 442 cmn_err(CE_CONT, "CWB: len=%d\n", len); 443 buf = kmem_zalloc(512, KM_SLEEP); 444 for (i = 0; i < len; i++) { 445 sprintf(&buf[strlen(buf)], "%02x ", mp->b_rptr[i]); 446 } 447 cmn_err(CE_CONT, "%s\n", buf); 448 kmem_free(buf, 512); 449 } 450 #endif 451 452 } 453 454 455 /* 456 * scsa2usb_bulk_only_handle_error: 457 * handle transport errors and start recovery 458 */ 459 static void 460 scsa2usb_bulk_only_handle_error(scsa2usb_state_t *scsa2usbp, 461 usb_bulk_req_t *req) 462 { 463 struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt; 464 465 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 466 "scsa2usb_bulk_only_handle_error: req = 0x%p, cr = 0x%x", 467 (void *)req, (req ? req->bulk_completion_reason : 0)); 468 469 if (req) { 470 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp); 471 472 /* invoke reset recovery */ 473 switch (req->bulk_completion_reason) { 474 case USB_CR_STALL: 475 if (pkt) { 476 pkt->pkt_reason = CMD_TRAN_ERR; 477 } 478 break; 479 case USB_CR_TIMEOUT: 480 if (pkt) { 481 pkt->pkt_reason = CMD_TIMEOUT; 482 pkt->pkt_statistics |= STAT_TIMEOUT; 483 } 484 break; 485 case USB_CR_DEV_NOT_RESP: 486 if (pkt) { 487 pkt->pkt_reason = CMD_DEV_GONE; 488 /* scsi_poll relies on this */ 489 pkt->pkt_state = STATE_GOT_BUS; 490 } 491 break; 492 default: 493 if (pkt) { 494 pkt->pkt_reason = CMD_TRAN_ERR; 495 } 496 } 497 scsa2usb_bulk_only_reset_recovery(scsa2usbp); 498 } 499 500 SCSA2USB_FREE_BULK_REQ(req); 501 } 502 503 504 /* 505 * scsa2usb_handle_status_start: 506 * Receive status data 507 */ 508 static int 509 scsa2usb_handle_status_start(scsa2usb_state_t *scsa2usbp, 510 usb_bulk_req_t *req) 511 { 512 int rval; 513 514 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 515 "scsa2usb_handle_status_start: req = 0x%p", (void *)req); 516 517 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 518 519 /* setup up for receiving CSW */ 520 #ifdef SCSA2USB_BULK_ONLY_TEST 521 req->bulk_attributes = 0; 522 #else 523 req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK; 524 #endif /* SCSA2USB_BULK_ONLY_TEST */ 525 req->bulk_len = CSW_LEN; 526 527 SCSA2USB_FREE_MSG(req->bulk_data); 528 req->bulk_data = allocb_wait(req->bulk_len, 529 BPRI_LO, STR_NOSIG, NULL); 530 531 /* Issue the request */ 532 mutex_exit(&scsa2usbp->scsa2usb_mutex); 533 534 ASSERT(req->bulk_timeout); 535 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe, req, 536 USB_FLAGS_SLEEP); 537 mutex_enter(&scsa2usbp->scsa2usb_mutex); 538 539 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 540 "scsa2usb_handle_status_start: END rval = 0x%x", rval); 541 542 if (rval != USB_SUCCESS) { 543 if (scsa2usbp->scsa2usb_pkt_state == SCSA2USB_PKT_PROCESS_CSW) { 544 scsa2usb_bulk_only_reset_recovery(scsa2usbp); 545 546 return (rval); 547 } 548 549 if (req->bulk_completion_reason == USB_CR_STALL) { 550 (void) scsa2usb_clear_ept_stall(scsa2usbp, 551 scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress, 552 scsa2usbp->scsa2usb_bulkin_pipe, "bulk-in"); 553 } 554 } 555 556 return (rval); 557 } 558 559 560 /* 561 * scsa2usb_handle_csw_result: 562 * Handle status results 563 */ 564 static int 565 scsa2usb_handle_csw_result(scsa2usb_state_t *scsa2usbp, mblk_t *data) 566 { 567 int rval = USB_SUCCESS; 568 int residue; 569 char *msg = "CSW FAILED"; 570 uint_t signature, tag, status; 571 usb_bulk_csw_t csw; 572 struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt; 573 scsa2usb_cmd_t *cmd = PKT2CMD(pkt); 574 575 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 576 577 /* 578 * This shouldn't happen. It implies the device's 579 * firmware is bad and has returned NULL CSW. 580 * return failure back. 581 */ 582 if (data == NULL) { 583 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 584 "scsa2usb_handle_csw_result: data == NULL"); 585 586 return (USB_FAILURE); 587 } 588 589 /* check if we got back CSW_LEN or not */ 590 if (MBLKL(data) != CSW_LEN) { 591 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 592 "scsa2usb_handle_csw_result: no enough data (%ld)", 593 (long)(MBLKL(data))); 594 595 return (USB_FAILURE); 596 } 597 598 /* Read into csw */ 599 bcopy(data->b_rptr, &csw, CSW_LEN); 600 601 status = csw.csw_bCSWStatus; 602 signature = SCSA2USB_MK_32BIT(csw.csw_dCSWSignature3, 603 csw.csw_dCSWSignature2, csw.csw_dCSWSignature1, 604 csw.csw_dCSWSignature0); 605 residue = SCSA2USB_MK_32BIT(csw.csw_dCSWDataResidue3, 606 csw.csw_dCSWDataResidue2, csw.csw_dCSWDataResidue1, 607 csw.csw_dCSWDataResidue0); 608 tag = SCSA2USB_MK_32BIT(csw.csw_dCSWTag3, csw.csw_dCSWTag2, 609 csw.csw_dCSWTag1, csw.csw_dCSWTag0); 610 611 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 612 "CSW: Signature = 0x%x Status = 0%x Tag = 0x%x Residue = 0x%x", 613 signature, status, tag, residue); 614 615 /* Check for abnormal errors */ 616 if ((signature != CSW_SIGNATURE) || (tag != cmd->cmd_tag) || 617 (status > CSW_STATUS_PHASE_ERROR)) { 618 619 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 620 "CSW_ERR: Status = 0x%x, Tag = 0x%x xfercount = 0x%lx", 621 status, cmd->cmd_tag, cmd->cmd_total_xfercount); 622 623 return (USB_FAILURE); 624 } 625 626 switch (status) { 627 case CSW_STATUS_GOOD: 628 /* 629 * Fail the command if the device misbehaves and 630 * gives a good status but doesn't transfer any data. 631 * Otherwise we'll get into an infinite retry loop. 632 * 633 * We test only against cmd_total_xfercount here and 634 * assume that this will not happen on a command that 635 * transfers a large amount of data and therefore may 636 * be split into separate transfers. For a large data 637 * transfer it is assumed that the device will return 638 * an error status if the transfer does not occur. 639 * this isn't quite correct because a subsequent request 640 * sense may not give a valid sense key. 641 */ 642 if (!cmd->cmd_done && residue && 643 (residue == cmd->cmd_total_xfercount)) { 644 *(pkt->pkt_scbp) = STATUS_CHECK; 645 cmd->cmd_xfercount = 0; 646 cmd->cmd_done = 1; 647 } else { 648 msg = "CSW GOOD"; 649 } 650 break; 651 case CSW_STATUS_FAILED: 652 *(pkt->pkt_scbp) = STATUS_CHECK; /* Set check condition */ 653 cmd->cmd_done = 1; 654 break; 655 case CSW_STATUS_PHASE_ERROR: 656 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 657 "scsa2usb_handle_csw_result: Phase Error"); 658 659 /* invoke reset recovery */ 660 scsa2usb_bulk_only_handle_error(scsa2usbp, NULL); 661 662 return (USB_FAILURE); 663 default: /* shouldn't happen anymore */ 664 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 665 "scsa2usb_handle_csw_result: Invalid CSW"); 666 667 /* invoke reset recovery */ 668 scsa2usb_bulk_only_handle_error(scsa2usbp, NULL); 669 670 return (USB_SUCCESS); 671 } /* end of switch */ 672 673 /* Set resid */ 674 if (residue || cmd->cmd_resid_xfercount) { 675 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 676 scsa2usbp->scsa2usb_log_handle, 677 "total=0x%lx cmd_xfercount=0x%lx residue=0x%x " 678 "cmd_offset=0x%lx", 679 cmd->cmd_total_xfercount, cmd->cmd_xfercount, 680 residue, cmd->cmd_offset); 681 682 /* 683 * we need to adjust using the residue and 684 * assume worst case. Some devices lie about 685 * residue. some report a residue greater than 686 * the residue we have calculated. 687 * first adjust back the total_xfercount 688 */ 689 cmd->cmd_total_xfercount += cmd->cmd_xfercount - 690 cmd->cmd_resid_xfercount; 691 /* 692 * we need to adjust cmd_offset as well, or the data 693 * buffer for subsequent transfer may exceed the buffer 694 * boundary 695 */ 696 cmd->cmd_offset -= cmd->cmd_xfercount - 697 cmd->cmd_resid_xfercount; 698 699 /* 700 * now take the min of the reported residue by 701 * the device and the requested xfer count 702 * (just in case the device reported a residue greater 703 * than our request count). 704 * then take the max of this residue and the residue 705 * that the HCD reported and subtract this from 706 * the request count. This is the actual number 707 * of valid bytes transferred during the last transfer 708 * which we now subtract from the total_xfercount 709 */ 710 if ((!(scsa2usbp->scsa2usb_attrs & 711 SCSA2USB_ATTRS_USE_CSW_RESIDUE)) || 712 (residue < 0) || 713 (residue > cmd->cmd_total_xfercount)) { 714 /* some devices lie about the resid, ignore */ 715 cmd->cmd_total_xfercount -= 716 cmd->cmd_xfercount - cmd->cmd_resid_xfercount; 717 cmd->cmd_offset += 718 cmd->cmd_xfercount - cmd->cmd_resid_xfercount; 719 } else { 720 cmd->cmd_total_xfercount -= 721 cmd->cmd_xfercount - 722 max(min(residue, cmd->cmd_xfercount), 723 cmd->cmd_resid_xfercount); 724 cmd->cmd_offset += 725 cmd->cmd_xfercount - 726 max(min(residue, cmd->cmd_xfercount), 727 cmd->cmd_resid_xfercount); 728 /* 729 * if HCD does not report residue while the device 730 * reports a residue equivalent to the xfercount, 731 * it is very likely the device lies about the 732 * residue. we need to stop the command, or we'll 733 * get into an infinite retry loop. 734 */ 735 if ((cmd->cmd_resid_xfercount == 0) && 736 (residue == cmd->cmd_xfercount)) { 737 cmd->cmd_xfercount = 0; 738 cmd->cmd_done = 1; 739 } 740 } 741 742 pkt->pkt_resid = cmd->cmd_total_xfercount; 743 } 744 745 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 746 "scsa2usb_handle_csw_result: %s, resid: 0x%lx", 747 msg, pkt->pkt_resid); 748 749 /* we are done and ready to callback */ 750 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp); 751 752 return (rval); 753 } 754 755 756 /* 757 * scsa2usb_bulk_only_reset_recovery: 758 * Reset the USB device step-wise in case of errors. 759 * NOTE that the order of reset is very important. 760 */ 761 static void 762 scsa2usb_bulk_only_reset_recovery(scsa2usb_state_t *scsa2usbp) 763 { 764 int rval; 765 usb_cr_t completion_reason; 766 usb_cb_flags_t cb_flags; 767 768 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 769 "scsa2usb_bulk_only_reset_recovery: scsa2usbp = 0x%p", 770 (void *)scsa2usbp); 771 772 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 773 774 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) { 775 776 return; 777 } 778 779 /* 780 * assume that the reset will be successful. if it isn't, retrying 781 * from target driver won't help much 782 */ 783 if (scsa2usbp->scsa2usb_cur_pkt) { 784 scsa2usbp->scsa2usb_cur_pkt->pkt_statistics |= STAT_DEV_RESET; 785 } 786 787 /* set the reset condition */ 788 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_DEV_RESET; 789 790 /* Send a sync DEVICE-RESET request to the device */ 791 mutex_exit(&scsa2usbp->scsa2usb_mutex); 792 rval = usb_pipe_sync_ctrl_xfer(scsa2usbp->scsa2usb_dip, 793 scsa2usbp->scsa2usb_default_pipe, 794 USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF, 795 (uint8_t)BULK_ONLY_RESET, /* bRequest */ 796 0, /* wValue */ 797 scsa2usbp->scsa2usb_intfc_num, /* wIndex */ 798 0, /* wLength */ 799 NULL, 0, &completion_reason, &cb_flags, 0); 800 mutex_enter(&scsa2usbp->scsa2usb_mutex); 801 802 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 803 "\tbulk-only device-reset rval: %d", rval); 804 if (rval != USB_SUCCESS) { 805 goto exc_exit; 806 } 807 808 /* reset and clear STALL on bulk-in pipe */ 809 rval = scsa2usb_clear_ept_stall(scsa2usbp, 810 scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress, 811 scsa2usbp->scsa2usb_bulkin_pipe, "bulk-in"); 812 813 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 814 "\tbulk-in pipe clear stall: %d", rval); 815 if (rval != USB_SUCCESS) { 816 goto exc_exit; 817 } 818 819 /* reset and clear STALL on bulk-out pipe */ 820 rval = scsa2usb_clear_ept_stall(scsa2usbp, 821 scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress, 822 scsa2usbp->scsa2usb_bulkout_pipe, "bulk-out"); 823 824 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 825 "\tbulk-out pipe clear stall: %d", rval); 826 827 exc_exit: 828 /* clear the reset condition */ 829 scsa2usbp->scsa2usb_pipe_state &= ~SCSA2USB_PIPE_DEV_RESET; 830 } 831 832 833 /* 834 * scsa2usb_bulk_only_get_max_lun: 835 * this function returns the number of LUNs supported by the device 836 */ 837 int 838 scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *scsa2usbp) 839 { 840 int luns = 1, rval; 841 mblk_t *data = NULL; 842 usb_cr_t completion_reason; 843 usb_cb_flags_t cb_flags; 844 845 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 846 "scsa2usb_bulk_only_get_max_lun:"); 847 848 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 849 850 mutex_exit(&scsa2usbp->scsa2usb_mutex); 851 rval = usb_pipe_sync_ctrl_xfer(scsa2usbp->scsa2usb_dip, 852 scsa2usbp->scsa2usb_default_pipe, 853 BULK_ONLY_GET_MAXLUN_BMREQ, /* bmRequestType */ 854 BULK_ONLY_GET_MAXLUN_REQ, /* bRequest */ 855 0, /* wValue */ 856 scsa2usbp->scsa2usb_intfc_num, /* wIndex */ 857 1, /* wLength */ 858 &data, 0, 859 &completion_reason, &cb_flags, 0); 860 mutex_enter(&scsa2usbp->scsa2usb_mutex); 861 862 if (rval != USB_SUCCESS) { 863 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 864 "get max lun failed, rval=%d cr=%d cb=0x%x data=0x%p", 865 rval, completion_reason, cb_flags, (void *)data); 866 } else { 867 /* 868 * This check ensures that we have valid data returned back. 869 * Otherwise we assume that device supports only one LUN. 870 */ 871 if (MBLKL(data) != 1) { 872 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 873 scsa2usbp->scsa2usb_log_handle, 874 "device reported incorrect luns (adjusting to 1)"); 875 } else { 876 /* 877 * Set scsa2usb_n_luns to value returned by the device 878 * plus 1. (See Section 3.2) 879 */ 880 luns = *data->b_rptr + 1; 881 882 /* 883 * In case a device returns incorrect LUNs 884 * which are more than 15 or negative or 0; 885 * we assume 1. 886 */ 887 if ((luns >= SCSA2USB_MAX_LUNS) || (luns <= 0)) { 888 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 889 scsa2usbp->scsa2usb_log_handle, 890 "device reported %d luns " 891 "(adjusting to 1)", luns); 892 luns = 1; 893 } 894 } 895 } 896 897 SCSA2USB_FREE_MSG(data); /* Free data */ 898 899 return (luns); 900 } 901