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