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 2008 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 req->bulk_timeout = scsa2usb_bulk_timeout(SCSA2USB_BULK_PIPE_TIMEOUT); 290 291 for (nretry = 0; nretry < SCSA2USB_STATUS_RETRIES; nretry++) { 292 rval = scsa2usb_handle_status_start(scsa2usbp, req); 293 294 if ((rval != USB_SUCCESS) && 295 (req->bulk_completion_reason == USB_CR_STALL)) { 296 /* 297 * We ran into STALL condition here. 298 * If the condition cannot be cleared 299 * successfully, retry for limited times. 300 */ 301 scsa2usbp->scsa2usb_pkt_state = 302 SCSA2USB_PKT_PROCESS_CSW; 303 } else { 304 305 break; 306 } 307 } 308 309 if (rval == USB_SUCCESS) { 310 /* process CSW */ 311 rval = scsa2usb_handle_csw_result(scsa2usbp, req->bulk_data); 312 } else { 313 scsa2usb_bulk_only_handle_error(scsa2usbp, req); 314 315 return (TRAN_FATAL_ERROR); 316 } 317 318 SCSA2USB_FREE_BULK_REQ(req); /* free request */ 319 320 if ((rval == USB_SUCCESS) && /* CSW was ok */ 321 (scsa2usbp->scsa2usb_cur_pkt->pkt_reason == CMD_CMPLT) && 322 (cmd->cmd_xfercount != 0) && /* more data to xfer */ 323 !cmd->cmd_done) { /* we aren't done yet */ 324 scsa2usb_setup_next_xfer(scsa2usbp, cmd); 325 goto Cmd_Phase; 326 } 327 328 return (rval == USB_SUCCESS ? TRAN_ACCEPT : TRAN_FATAL_ERROR); 329 } 330 331 332 /* 333 * scsa2usb_fill_in_cbw: 334 * Fill in a CBW request packet. This 335 * packet is transported to the device 336 */ 337 static void 338 scsa2usb_fill_in_cbw(scsa2usb_state_t *scsa2usbp, 339 scsa2usb_cmd_t *cmd, mblk_t *mp) 340 { 341 int i; 342 int len; 343 uchar_t dir, *cdb = (uchar_t *)(&cmd->cmd_cdb); 344 345 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 346 347 *mp->b_wptr++ = CBW_MSB(CBW_SIGNATURE); /* CBW Signature */; 348 *mp->b_wptr++ = CBW_MID1(CBW_SIGNATURE); 349 *mp->b_wptr++ = CBW_MID2(CBW_SIGNATURE); 350 *mp->b_wptr++ = CBW_LSB(CBW_SIGNATURE); 351 *mp->b_wptr++ = CBW_LSB(cmd->cmd_tag); /* CBW Tag */ 352 *mp->b_wptr++ = CBW_MID2(cmd->cmd_tag); 353 *mp->b_wptr++ = CBW_MID1(cmd->cmd_tag); 354 *mp->b_wptr++ = CBW_MSB(cmd->cmd_tag); 355 356 dir = cmd->cmd_dir; 357 len = cmd->cmd_xfercount; 358 #ifdef SCSA2USB_BULK_ONLY_TEST 359 if (scsa2usb_test_case_2 && (cdb[0] == SCMD_READ_CAPACITY)) { 360 /* Host expects no data. The device wants data. Hn < Di */ 361 scsa2usb_test_case_2 = len = 0; 362 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 363 "TEST 2: Hn < Di cdb: 0x%x len: 0x%x", cdb[0], len); 364 } 365 366 if (scsa2usb_test_case_3 && (cmd->cmd_dir == CBW_DIR_OUT)) { 367 /* Host expects no data. The device wants data. Hn < Do */ 368 if (cdb[0] == SCMD_WRITE_G1) { 369 scsa2usb_test_case_3 = len = 0; 370 USB_DPRINTF_L1(DPRINT_MASK_SCSA, 371 scsa2usbp->scsa2usb_log_handle, 372 "TEST 3: Hn < Do cdb: 0x%x len:%x", cdb[0], len); 373 } 374 } 375 376 if (scsa2usb_test_case_4 && (cdb[0] == SCMD_READ_G1)) { 377 cdb[0] = 0x5e; 378 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 379 "TEST 4: Hi > Dn: changed cdb to 0x%x", cdb[0]); 380 scsa2usb_test_case_4 = 0; 381 } 382 383 if (scsa2usb_test_case_7 && (cmd->cmd_cdb[0] == SCMD_READ_G1)) { 384 len -= 0x10; 385 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 386 "TEST 7: Hi < Di cdb: 0x%x len: 0x%x", cdb[0], len); 387 scsa2usb_test_case_7 = 0; 388 } 389 390 if (scsa2usb_test_case_8 && (cdb[0] == SCMD_READ_G1)) { 391 dir = (dir == CBW_DIR_IN) ? CBW_DIR_OUT : dir; 392 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 393 "TEST 8: Hi <> Do cdb: 0x%x dir: 0x%x", cdb[0], dir); 394 } 395 396 if (scsa2usb_test_case_9 && (cdb[0] == SCMD_WRITE_G1)) { 397 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 398 "TEST 9: Ho <> Di (%x)", cdb[0]); 399 cdb[SCSA2USB_LEN_0] = cdb[SCSA2USB_LEN_1] = 0; 400 scsa2usb_test_case_9 = 0; 401 } 402 403 if (scsa2usb_test_case_10 && (cdb[0] == SCMD_WRITE_G1)) { 404 dir = (dir == CBW_DIR_OUT) ? CBW_DIR_IN : dir; 405 USB_DPRINTF_L1(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 406 "TEST 10: Ho <> Di cdb: 0x%x dir: 0x%x", cdb[0], dir); 407 } 408 409 /* 410 * This case occurs when the device intends to receive 411 * more data from the host than the host sends. 412 */ 413 if (scsa2usb_test_case_13) { 414 if ((cdb[0] == SCMD_WRITE_G1) || (cdb[0] == SCMD_READ_G1)) { 415 USB_DPRINTF_L1(DPRINT_MASK_SCSA, 416 scsa2usbp->scsa2usb_log_handle, "TEST 13: Ho < Do"); 417 418 len -= 30; 419 scsa2usb_test_case_13 = 0; 420 } 421 } 422 #endif /* SCSA2USB_BULK_ONLY_TEST */ 423 424 *mp->b_wptr++ = CBW_MSB(len); /* Transfer Length */ 425 *mp->b_wptr++ = CBW_MID1(len); 426 *mp->b_wptr++ = CBW_MID2(len); 427 *mp->b_wptr++ = CBW_LSB(len); 428 429 *mp->b_wptr++ = dir; /* Transfer Direction */ 430 *mp->b_wptr++ = cmd->cmd_pkt->pkt_address.a_lun; /* Lun # */ 431 *mp->b_wptr++ = cmd->cmd_actual_len; /* CDB Len */ 432 433 /* Copy the CDB out */ 434 for (i = 0; i < CBW_CDB_LEN; i++) { 435 *mp->b_wptr++ = *cdb++; 436 } 437 #ifdef DUMP_CWB 438 { 439 int len = mp->b_wptr - mp->b_rptr; 440 char *buf; 441 442 int i; 443 444 cmn_err(CE_CONT, "CWB: len=%d\n", len); 445 buf = kmem_zalloc(512, KM_SLEEP); 446 for (i = 0; i < len; i++) { 447 sprintf(&buf[strlen(buf)], "%02x ", mp->b_rptr[i]); 448 } 449 cmn_err(CE_CONT, "%s\n", buf); 450 kmem_free(buf, 512); 451 } 452 #endif 453 454 } 455 456 457 /* 458 * scsa2usb_bulk_only_handle_error: 459 * handle transport errors and start recovery 460 */ 461 static void 462 scsa2usb_bulk_only_handle_error(scsa2usb_state_t *scsa2usbp, 463 usb_bulk_req_t *req) 464 { 465 struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt; 466 467 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 468 "scsa2usb_bulk_only_handle_error: req = 0x%p, cr = 0x%x", 469 (void *)req, (req ? req->bulk_completion_reason : 0)); 470 471 if (req) { 472 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp); 473 474 /* invoke reset recovery */ 475 switch (req->bulk_completion_reason) { 476 case USB_CR_STALL: 477 if (pkt) { 478 pkt->pkt_reason = CMD_TRAN_ERR; 479 } 480 break; 481 case USB_CR_TIMEOUT: 482 if (pkt) { 483 pkt->pkt_reason = CMD_TIMEOUT; 484 pkt->pkt_statistics |= STAT_TIMEOUT; 485 } 486 break; 487 case USB_CR_DEV_NOT_RESP: 488 if (pkt) { 489 pkt->pkt_reason = CMD_DEV_GONE; 490 /* scsi_poll relies on this */ 491 pkt->pkt_state = STATE_GOT_BUS; 492 } 493 break; 494 default: 495 if (pkt) { 496 pkt->pkt_reason = CMD_TRAN_ERR; 497 } 498 } 499 scsa2usb_bulk_only_reset_recovery(scsa2usbp); 500 } 501 502 SCSA2USB_FREE_BULK_REQ(req); 503 } 504 505 506 /* 507 * scsa2usb_handle_status_start: 508 * Receive status data 509 */ 510 static int 511 scsa2usb_handle_status_start(scsa2usb_state_t *scsa2usbp, 512 usb_bulk_req_t *req) 513 { 514 int rval; 515 516 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 517 "scsa2usb_handle_status_start: req = 0x%p", (void *)req); 518 519 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 520 521 /* setup up for receiving CSW */ 522 #ifdef SCSA2USB_BULK_ONLY_TEST 523 req->bulk_attributes = 0; 524 #else 525 req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK; 526 #endif /* SCSA2USB_BULK_ONLY_TEST */ 527 req->bulk_len = CSW_LEN; 528 529 SCSA2USB_FREE_MSG(req->bulk_data); 530 req->bulk_data = allocb_wait(req->bulk_len, 531 BPRI_LO, STR_NOSIG, NULL); 532 533 /* Issue the request */ 534 mutex_exit(&scsa2usbp->scsa2usb_mutex); 535 536 ASSERT(req->bulk_timeout); 537 rval = usb_pipe_bulk_xfer(scsa2usbp->scsa2usb_bulkin_pipe, req, 538 USB_FLAGS_SLEEP); 539 mutex_enter(&scsa2usbp->scsa2usb_mutex); 540 541 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 542 "scsa2usb_handle_status_start: END rval = 0x%x", rval); 543 544 if (rval != USB_SUCCESS) { 545 if (scsa2usbp->scsa2usb_pkt_state == SCSA2USB_PKT_PROCESS_CSW) { 546 scsa2usb_bulk_only_reset_recovery(scsa2usbp); 547 548 return (rval); 549 } 550 551 if (req->bulk_completion_reason == USB_CR_STALL) { 552 (void) scsa2usb_clear_ept_stall(scsa2usbp, 553 scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress, 554 scsa2usbp->scsa2usb_bulkin_pipe, "bulk-in"); 555 } 556 } 557 558 return (rval); 559 } 560 561 562 /* 563 * scsa2usb_handle_csw_result: 564 * Handle status results 565 */ 566 static int 567 scsa2usb_handle_csw_result(scsa2usb_state_t *scsa2usbp, mblk_t *data) 568 { 569 int rval = USB_SUCCESS; 570 int residue; 571 char *msg = "CSW FAILED"; 572 uint_t signature, tag, status; 573 usb_bulk_csw_t csw; 574 struct scsi_pkt *pkt = scsa2usbp->scsa2usb_cur_pkt; 575 scsa2usb_cmd_t *cmd = PKT2CMD(pkt); 576 577 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 578 579 /* 580 * This shouldn't happen. It implies the device's 581 * firmware is bad and has returned NULL CSW. 582 * return failure back. 583 */ 584 if (data == NULL) { 585 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 586 "scsa2usb_handle_csw_result: data == NULL"); 587 588 return (USB_FAILURE); 589 } 590 591 /* check if we got back CSW_LEN or not */ 592 if (MBLKL(data) != CSW_LEN) { 593 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 594 "scsa2usb_handle_csw_result: no enough data (%ld)", 595 (long)(MBLKL(data))); 596 597 return (USB_FAILURE); 598 } 599 600 /* Read into csw */ 601 bcopy(data->b_rptr, &csw, CSW_LEN); 602 603 status = csw.csw_bCSWStatus; 604 signature = SCSA2USB_MK_32BIT(csw.csw_dCSWSignature3, 605 csw.csw_dCSWSignature2, csw.csw_dCSWSignature1, 606 csw.csw_dCSWSignature0); 607 residue = SCSA2USB_MK_32BIT(csw.csw_dCSWDataResidue3, 608 csw.csw_dCSWDataResidue2, csw.csw_dCSWDataResidue1, 609 csw.csw_dCSWDataResidue0); 610 tag = SCSA2USB_MK_32BIT(csw.csw_dCSWTag3, csw.csw_dCSWTag2, 611 csw.csw_dCSWTag1, csw.csw_dCSWTag0); 612 613 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 614 "CSW: Signature = 0x%x Status = 0%x Tag = 0x%x Residue = 0x%x", 615 signature, status, tag, residue); 616 617 /* Check for abnormal errors */ 618 if ((signature != CSW_SIGNATURE) || (tag != cmd->cmd_tag) || 619 (status > CSW_STATUS_PHASE_ERROR)) { 620 621 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 622 "CSW_ERR: Status = 0x%x, Tag = 0x%x xfercount = 0x%lx", 623 status, cmd->cmd_tag, cmd->cmd_total_xfercount); 624 625 return (USB_FAILURE); 626 } 627 628 switch (status) { 629 case CSW_STATUS_GOOD: 630 /* 631 * Fail the command if the device misbehaves and 632 * gives a good status but doesn't transfer any data. 633 * Otherwise we'll get into an infinite retry loop. 634 * 635 * We test only against cmd_total_xfercount here and 636 * assume that this will not happen on a command that 637 * transfers a large amount of data and therefore may 638 * be split into separate transfers. For a large data 639 * transfer it is assumed that the device will return 640 * an error status if the transfer does not occur. 641 * this isn't quite correct because a subsequent request 642 * sense may not give a valid sense key. 643 */ 644 if (!cmd->cmd_done && residue && 645 (residue == cmd->cmd_total_xfercount)) { 646 *(pkt->pkt_scbp) = STATUS_CHECK; 647 cmd->cmd_xfercount = 0; 648 cmd->cmd_done = 1; 649 } else { 650 msg = "CSW GOOD"; 651 } 652 break; 653 case CSW_STATUS_FAILED: 654 *(pkt->pkt_scbp) = STATUS_CHECK; /* Set check condition */ 655 cmd->cmd_done = 1; 656 break; 657 case CSW_STATUS_PHASE_ERROR: 658 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 659 "scsa2usb_handle_csw_result: Phase Error"); 660 661 /* invoke reset recovery */ 662 scsa2usb_bulk_only_handle_error(scsa2usbp, NULL); 663 664 return (USB_FAILURE); 665 default: /* shouldn't happen anymore */ 666 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 667 "scsa2usb_handle_csw_result: Invalid CSW"); 668 669 /* invoke reset recovery */ 670 scsa2usb_bulk_only_handle_error(scsa2usbp, NULL); 671 672 return (USB_SUCCESS); 673 } /* end of switch */ 674 675 /* Set resid */ 676 if (residue || cmd->cmd_resid_xfercount) { 677 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 678 scsa2usbp->scsa2usb_log_handle, 679 "total=0x%lx cmd_xfercount=0x%lx residue=0x%x " 680 "cmd_offset=0x%lx", 681 cmd->cmd_total_xfercount, cmd->cmd_xfercount, 682 residue, cmd->cmd_offset); 683 684 /* 685 * we need to adjust using the residue and 686 * assume worst case. Some devices lie about 687 * residue. some report a residue greater than 688 * the residue we have calculated. 689 * first adjust back the total_xfercount 690 */ 691 cmd->cmd_total_xfercount += cmd->cmd_xfercount - 692 cmd->cmd_resid_xfercount; 693 /* 694 * we need to adjust cmd_offset as well, or the data 695 * buffer for subsequent transfer may exceed the buffer 696 * boundary 697 */ 698 cmd->cmd_offset -= cmd->cmd_xfercount - 699 cmd->cmd_resid_xfercount; 700 701 /* 702 * now take the min of the reported residue by 703 * the device and the requested xfer count 704 * (just in case the device reported a residue greater 705 * than our request count). 706 * then take the max of this residue and the residue 707 * that the HCD reported and subtract this from 708 * the request count. This is the actual number 709 * of valid bytes transferred during the last transfer 710 * which we now subtract from the total_xfercount 711 */ 712 if ((!(scsa2usbp->scsa2usb_attrs & 713 SCSA2USB_ATTRS_USE_CSW_RESIDUE)) || 714 (residue < 0) || 715 (residue > cmd->cmd_total_xfercount)) { 716 /* some devices lie about the resid, ignore */ 717 cmd->cmd_total_xfercount -= 718 cmd->cmd_xfercount - cmd->cmd_resid_xfercount; 719 cmd->cmd_offset += 720 cmd->cmd_xfercount - cmd->cmd_resid_xfercount; 721 } else { 722 cmd->cmd_total_xfercount -= 723 cmd->cmd_xfercount - 724 max(min(residue, cmd->cmd_xfercount), 725 cmd->cmd_resid_xfercount); 726 cmd->cmd_offset += 727 cmd->cmd_xfercount - 728 max(min(residue, cmd->cmd_xfercount), 729 cmd->cmd_resid_xfercount); 730 /* 731 * if HCD does not report residue while the device 732 * reports a residue equivalent to the xfercount, 733 * it is very likely the device lies about the 734 * residue. we need to stop the command, or we'll 735 * get into an infinite retry loop. 736 */ 737 if ((cmd->cmd_resid_xfercount == 0) && 738 (residue == cmd->cmd_xfercount)) { 739 cmd->cmd_xfercount = 0; 740 cmd->cmd_done = 1; 741 } 742 } 743 744 pkt->pkt_resid = cmd->cmd_total_xfercount; 745 } 746 747 USB_DPRINTF_L3(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 748 "scsa2usb_handle_csw_result: %s, resid: 0x%lx", 749 msg, pkt->pkt_resid); 750 751 /* we are done and ready to callback */ 752 SCSA2USB_SET_PKT_DO_COMP_STATE(scsa2usbp); 753 754 return (rval); 755 } 756 757 758 /* 759 * scsa2usb_bulk_only_reset_recovery: 760 * Reset the USB device step-wise in case of errors. 761 * NOTE that the order of reset is very important. 762 */ 763 static void 764 scsa2usb_bulk_only_reset_recovery(scsa2usb_state_t *scsa2usbp) 765 { 766 int rval; 767 usb_cr_t completion_reason; 768 usb_cb_flags_t cb_flags; 769 770 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 771 "scsa2usb_bulk_only_reset_recovery: scsa2usbp = 0x%p", 772 (void *)scsa2usbp); 773 774 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 775 776 if (!(SCSA2USB_DEVICE_ACCESS_OK(scsa2usbp))) { 777 778 return; 779 } 780 781 /* 782 * assume that the reset will be successful. if it isn't, retrying 783 * from target driver won't help much 784 */ 785 if (scsa2usbp->scsa2usb_cur_pkt) { 786 scsa2usbp->scsa2usb_cur_pkt->pkt_statistics |= STAT_DEV_RESET; 787 } 788 789 /* set the reset condition */ 790 scsa2usbp->scsa2usb_pipe_state = SCSA2USB_PIPE_DEV_RESET; 791 792 /* Send a sync DEVICE-RESET request to the device */ 793 mutex_exit(&scsa2usbp->scsa2usb_mutex); 794 rval = usb_pipe_sync_ctrl_xfer(scsa2usbp->scsa2usb_dip, 795 scsa2usbp->scsa2usb_default_pipe, 796 USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF, 797 (uint8_t)BULK_ONLY_RESET, /* bRequest */ 798 0, /* wValue */ 799 scsa2usbp->scsa2usb_intfc_num, /* wIndex */ 800 0, /* wLength */ 801 NULL, 0, &completion_reason, &cb_flags, 0); 802 mutex_enter(&scsa2usbp->scsa2usb_mutex); 803 804 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 805 "\tbulk-only device-reset rval: %d", rval); 806 if (rval != USB_SUCCESS) { 807 goto exc_exit; 808 } 809 810 /* reset and clear STALL on bulk-in pipe */ 811 rval = scsa2usb_clear_ept_stall(scsa2usbp, 812 scsa2usbp->scsa2usb_bulkin_ept.bEndpointAddress, 813 scsa2usbp->scsa2usb_bulkin_pipe, "bulk-in"); 814 815 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 816 "\tbulk-in pipe clear stall: %d", rval); 817 if (rval != USB_SUCCESS) { 818 goto exc_exit; 819 } 820 821 /* reset and clear STALL on bulk-out pipe */ 822 rval = scsa2usb_clear_ept_stall(scsa2usbp, 823 scsa2usbp->scsa2usb_bulkout_ept.bEndpointAddress, 824 scsa2usbp->scsa2usb_bulkout_pipe, "bulk-out"); 825 826 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 827 "\tbulk-out pipe clear stall: %d", rval); 828 829 exc_exit: 830 /* clear the reset condition */ 831 scsa2usbp->scsa2usb_pipe_state &= ~SCSA2USB_PIPE_DEV_RESET; 832 } 833 834 835 /* 836 * scsa2usb_bulk_only_get_max_lun: 837 * this function returns the number of LUNs supported by the device 838 */ 839 int 840 scsa2usb_bulk_only_get_max_lun(scsa2usb_state_t *scsa2usbp) 841 { 842 int luns = 1, rval; 843 mblk_t *data = NULL; 844 usb_cr_t completion_reason; 845 usb_cb_flags_t cb_flags; 846 847 USB_DPRINTF_L4(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 848 "scsa2usb_bulk_only_get_max_lun:"); 849 850 ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex)); 851 852 mutex_exit(&scsa2usbp->scsa2usb_mutex); 853 rval = usb_pipe_sync_ctrl_xfer(scsa2usbp->scsa2usb_dip, 854 scsa2usbp->scsa2usb_default_pipe, 855 BULK_ONLY_GET_MAXLUN_BMREQ, /* bmRequestType */ 856 BULK_ONLY_GET_MAXLUN_REQ, /* bRequest */ 857 0, /* wValue */ 858 scsa2usbp->scsa2usb_intfc_num, /* wIndex */ 859 1, /* wLength */ 860 &data, 0, 861 &completion_reason, &cb_flags, 0); 862 mutex_enter(&scsa2usbp->scsa2usb_mutex); 863 864 if (rval != USB_SUCCESS) { 865 USB_DPRINTF_L2(DPRINT_MASK_SCSA, scsa2usbp->scsa2usb_log_handle, 866 "get max lun failed, rval=%d cr=%d cb=0x%x data=0x%p", 867 rval, completion_reason, cb_flags, (void *)data); 868 } else { 869 /* 870 * This check ensures that we have valid data returned back. 871 * Otherwise we assume that device supports only one LUN. 872 */ 873 if (MBLKL(data) != 1) { 874 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 875 scsa2usbp->scsa2usb_log_handle, 876 "device reported incorrect luns (adjusting to 1)"); 877 } else { 878 /* 879 * Set scsa2usb_n_luns to value returned by the device 880 * plus 1. (See Section 3.2) 881 */ 882 luns = *data->b_rptr + 1; 883 884 /* 885 * In case a device returns incorrect LUNs 886 * which are more than 15 or negative or 0; 887 * we assume 1. 888 */ 889 if ((luns >= SCSA2USB_MAX_LUNS) || (luns <= 0)) { 890 USB_DPRINTF_L2(DPRINT_MASK_SCSA, 891 scsa2usbp->scsa2usb_log_handle, 892 "device reported %d luns " 893 "(adjusting to 1)", luns); 894 luns = 1; 895 } 896 } 897 } 898 899 SCSA2USB_FREE_MSG(data); /* Free data */ 900 901 return (luns); 902 } 903