1/* 2 * Copyright (c) 2004-07 Applied Micro Circuits Corporation. 3 * Copyright (c) 2004-05 Vinod Kashyap. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: stable/11/sys/dev/twa/tw_osl_cam.c 335138 2018-06-14 14:46:20Z mav $ 28 */ 29 30/* 31 * AMCC'S 3ware driver for 9000 series storage controllers. 32 * 33 * Author: Vinod Kashyap 34 * Modifications by: Adam Radford 35 * Modifications by: Manjunath Ranganathaiah 36 */ 37 38 39/* 40 * FreeBSD CAM related functions. 41 */ 42 43 44#include <dev/twa/tw_osl_includes.h> 45 46#include <cam/cam.h> 47#include <cam/cam_ccb.h> 48#include <cam/cam_sim.h> 49#include <cam/cam_xpt_sim.h> 50#include <cam/cam_debug.h> 51#include <cam/cam_periph.h> 52 53#include <cam/scsi/scsi_all.h> 54#include <cam/scsi/scsi_message.h> 55 56static TW_VOID twa_action(struct cam_sim *sim, union ccb *ccb); 57static TW_VOID twa_poll(struct cam_sim *sim); 58 59static TW_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req, 60 union ccb *ccb); 61 62 63 64/* 65 * Function name: tw_osli_cam_attach 66 * Description: Attaches the driver to CAM. 67 * 68 * Input: sc -- ptr to OSL internal ctlr context 69 * Output: None 70 * Return value: 0 -- success 71 * non-zero-- failure 72 */ 73TW_INT32 74tw_osli_cam_attach(struct twa_softc *sc) 75{ 76 struct cam_devq *devq; 77 78 tw_osli_dbg_dprintf(3, sc, "entered"); 79 80 /* 81 * Create the device queue for our SIM. 82 */ 83 if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) { 84 tw_osli_printf(sc, "error = %d", 85 TW_CL_SEVERITY_ERROR_STRING, 86 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 87 0x2100, 88 "Failed to create SIM device queue", 89 ENOMEM); 90 return(ENOMEM); 91 } 92 93 /* 94 * Create a SIM entry. Though we can support TW_OSLI_MAX_NUM_REQUESTS 95 * simultaneous requests, we claim to be able to handle only 96 * TW_OSLI_MAX_NUM_IOS (two less), so that we always have a request 97 * packet available to service ioctls and AENs. 98 */ 99 tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc"); 100 sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc, 101 device_get_unit(sc->bus_dev), sc->sim_lock, 102 TW_OSLI_MAX_NUM_IOS, 1, devq); 103 if (sc->sim == NULL) { 104 cam_simq_free(devq); 105 tw_osli_printf(sc, "error = %d", 106 TW_CL_SEVERITY_ERROR_STRING, 107 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 108 0x2101, 109 "Failed to create a SIM entry", 110 ENOMEM); 111 return(ENOMEM); 112 } 113 114 /* 115 * Register the bus. 116 */ 117 tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register"); 118 mtx_lock(sc->sim_lock); 119 if (xpt_bus_register(sc->sim, sc->bus_dev, 0) != CAM_SUCCESS) { 120 cam_sim_free(sc->sim, TRUE); 121 sc->sim = NULL; /* so cam_detach will not try to free it */ 122 tw_osli_printf(sc, "error = %d", 123 TW_CL_SEVERITY_ERROR_STRING, 124 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 125 0x2102, 126 "Failed to register the bus", 127 ENXIO); 128 mtx_unlock(sc->sim_lock); 129 return(ENXIO); 130 } 131 132 tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path"); 133 if (xpt_create_path(&sc->path, NULL, 134 cam_sim_path(sc->sim), 135 CAM_TARGET_WILDCARD, 136 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 137 xpt_bus_deregister(cam_sim_path (sc->sim)); 138 /* Passing TRUE to cam_sim_free will free the devq as well. */ 139 cam_sim_free(sc->sim, TRUE); 140 tw_osli_printf(sc, "error = %d", 141 TW_CL_SEVERITY_ERROR_STRING, 142 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 143 0x2103, 144 "Failed to create path", 145 ENXIO); 146 mtx_unlock(sc->sim_lock); 147 return(ENXIO); 148 } 149 mtx_unlock(sc->sim_lock); 150 151 tw_osli_dbg_dprintf(3, sc, "exiting"); 152 return(0); 153} 154 155 156 157/* 158 * Function name: tw_osli_cam_detach 159 * Description: Detaches the driver from CAM. 160 * 161 * Input: sc -- ptr to OSL internal ctlr context 162 * Output: None 163 * Return value: None 164 */ 165TW_VOID 166tw_osli_cam_detach(struct twa_softc *sc) 167{ 168 tw_osli_dbg_dprintf(3, sc, "entered"); 169 170 mtx_lock(sc->sim_lock); 171 172 if (sc->path) 173 xpt_free_path(sc->path); 174 if (sc->sim) { 175 xpt_bus_deregister(cam_sim_path(sc->sim)); 176 /* Passing TRUE to cam_sim_free will free the devq as well. */ 177 cam_sim_free(sc->sim, TRUE); 178 } 179 /* It's ok have 1 hold count while destroying the mutex */ 180 mtx_destroy(sc->sim_lock); 181} 182 183 184 185/* 186 * Function name: tw_osli_execute_scsi 187 * Description: Build a fw cmd, based on a CAM style ccb, and 188 * send it down. 189 * 190 * Input: req -- ptr to OSL internal request context 191 * ccb -- ptr to CAM style ccb 192 * Output: None 193 * Return value: 0 -- success 194 * non-zero-- failure 195 */ 196TW_INT32 197tw_osli_execute_scsi(struct tw_osli_req_context *req, union ccb *ccb) 198{ 199 struct twa_softc *sc = req->ctlr; 200 struct tw_cl_req_packet *req_pkt; 201 struct tw_cl_scsi_req_packet *scsi_req; 202 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 203 struct ccb_scsiio *csio = &(ccb->csio); 204 TW_INT32 error; 205 206 tw_osli_dbg_dprintf(10, sc, "SCSI I/O request 0x%x", 207 csio->cdb_io.cdb_bytes[0]); 208 209 if (ccb_h->target_id >= TW_CL_MAX_NUM_UNITS) { 210 tw_osli_dbg_dprintf(3, sc, "Invalid target. PTL = %x %x %jx", 211 ccb_h->path_id, ccb_h->target_id, 212 (uintmax_t)ccb_h->target_lun); 213 ccb_h->status |= CAM_TID_INVALID; 214 xpt_done(ccb); 215 return(1); 216 } 217 if (ccb_h->target_lun >= TW_CL_MAX_NUM_LUNS) { 218 tw_osli_dbg_dprintf(3, sc, "Invalid lun. PTL = %x %x %jx", 219 ccb_h->path_id, ccb_h->target_id, 220 (uintmax_t)ccb_h->target_lun); 221 ccb_h->status |= CAM_LUN_INVALID; 222 xpt_done(ccb); 223 return(1); 224 } 225 226 if(ccb_h->flags & CAM_CDB_PHYS) { 227 tw_osli_printf(sc, "", 228 TW_CL_SEVERITY_ERROR_STRING, 229 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 230 0x2105, 231 "Physical CDB address!"); 232 ccb_h->status = CAM_REQ_INVALID; 233 xpt_done(ccb); 234 return(1); 235 } 236 237 /* 238 * We are going to work on this request. Mark it as enqueued (though 239 * we don't actually queue it...) 240 */ 241 ccb_h->status |= CAM_SIM_QUEUED; 242 243 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 244 if(ccb_h->flags & CAM_DIR_IN) 245 req->flags |= TW_OSLI_REQ_FLAGS_DATA_IN; 246 else 247 req->flags |= TW_OSLI_REQ_FLAGS_DATA_OUT; 248 } 249 250 /* Build the CL understood request packet for SCSI cmds. */ 251 req_pkt = &req->req_pkt; 252 req_pkt->status = 0; 253 req_pkt->tw_osl_callback = tw_osl_complete_io; 254 scsi_req = &(req_pkt->gen_req_pkt.scsi_req); 255 scsi_req->unit = ccb_h->target_id; 256 scsi_req->lun = ccb_h->target_lun; 257 scsi_req->sense_len = 0; 258 scsi_req->sense_data = (TW_UINT8 *)(&csio->sense_data); 259 scsi_req->scsi_status = 0; 260 if(ccb_h->flags & CAM_CDB_POINTER) 261 scsi_req->cdb = csio->cdb_io.cdb_ptr; 262 else 263 scsi_req->cdb = csio->cdb_io.cdb_bytes; 264 scsi_req->cdb_len = csio->cdb_len; 265 266 if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) { 267 tw_osli_printf(sc, "size = %d", 268 TW_CL_SEVERITY_ERROR_STRING, 269 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 270 0x2106, 271 "I/O size too big", 272 csio->dxfer_len); 273 ccb_h->status = CAM_REQ_TOO_BIG; 274 ccb_h->status &= ~CAM_SIM_QUEUED; 275 xpt_done(ccb); 276 return(1); 277 } 278 if ((ccb_h->flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { 279 if ((req->length = csio->dxfer_len) != 0) { 280 req->data = csio->data_ptr; 281 scsi_req->sgl_entries = 1; 282 } 283 } else 284 req->flags |= TW_OSLI_REQ_FLAGS_CCB; 285 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000); 286 287 /* 288 * twa_map_load_data_callback will fill in the SGL, 289 * and submit the I/O. 290 */ 291 error = tw_osli_map_request(req); 292 if ((error) && (req->flags & TW_OSLI_REQ_FLAGS_FAILED)) { 293 req->deadline = 0; 294 ccb_h->status = CAM_REQ_CMP_ERR; 295 ccb_h->status &= ~CAM_SIM_QUEUED; 296 xpt_done(ccb); 297 } 298 return(error); 299} 300 301 302 303/* 304 * Function name: twa_action 305 * Description: Driver entry point for CAM's use. 306 * 307 * Input: sim -- sim corresponding to the ctlr 308 * ccb -- ptr to CAM request 309 * Output: None 310 * Return value: None 311 */ 312TW_VOID 313twa_action(struct cam_sim *sim, union ccb *ccb) 314{ 315 struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim); 316 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 317 318 switch (ccb_h->func_code) { 319 case XPT_SCSI_IO: /* SCSI I/O */ 320 { 321 struct tw_osli_req_context *req; 322 323 req = tw_osli_get_request(sc); 324 if (req == NULL) { 325 tw_osli_dbg_dprintf(2, sc, "Cannot get request pkt."); 326 /* 327 * Freeze the simq to maintain ccb ordering. The next 328 * ccb that gets completed will unfreeze the simq. 329 */ 330 ccb_h->status &= ~CAM_SIM_QUEUED; 331 ccb_h->status |= CAM_REQUEUE_REQ; 332 xpt_done(ccb); 333 break; 334 } 335 336 if ((tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) { 337 ccb_h->status &= ~CAM_SIM_QUEUED; 338 ccb_h->status |= CAM_REQUEUE_REQ; 339 xpt_done(ccb); 340 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q); 341 break; 342 } 343 344 req->req_handle.osl_req_ctxt = req; 345 req->req_handle.is_io = TW_CL_TRUE; 346 req->orig_req = ccb; 347 if (tw_osli_execute_scsi(req, ccb)) 348 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q); 349 break; 350 } 351 352 case XPT_ABORT: 353 tw_osli_dbg_dprintf(2, sc, "Abort request."); 354 ccb_h->status = CAM_UA_ABORT; 355 xpt_done(ccb); 356 break; 357 358 case XPT_RESET_BUS: 359 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_FALSE, 360 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 361 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING, 362 "Received Reset Bus request from CAM", 363 " "); 364 365 tw_cl_set_reset_needed(&(sc->ctlr_handle)); 366 ccb_h->status = CAM_REQ_CMP; 367 xpt_done(ccb); 368 break; 369 370 case XPT_SET_TRAN_SETTINGS: 371 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS"); 372 373 /* 374 * This command is not supported, since it's very specific 375 * to SCSI, and we are doing ATA. 376 */ 377 ccb_h->status = CAM_FUNC_NOTAVAIL; 378 xpt_done(ccb); 379 break; 380 381 case XPT_GET_TRAN_SETTINGS: 382 { 383 struct ccb_trans_settings *cts = &ccb->cts; 384 struct ccb_trans_settings_scsi *scsi = 385 &cts->proto_specific.scsi; 386 struct ccb_trans_settings_spi *spi = 387 &cts->xport_specific.spi; 388 389 cts->protocol = PROTO_SCSI; 390 cts->protocol_version = SCSI_REV_2; 391 cts->transport = XPORT_SPI; 392 cts->transport_version = 2; 393 394 spi->valid = CTS_SPI_VALID_DISC; 395 spi->flags = CTS_SPI_FLAGS_DISC_ENB; 396 scsi->valid = CTS_SCSI_VALID_TQ; 397 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 398 tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS"); 399 ccb_h->status = CAM_REQ_CMP; 400 xpt_done(ccb); 401 break; 402 } 403 404 case XPT_CALC_GEOMETRY: 405 tw_osli_dbg_dprintf(3, sc, "XPT_CALC_GEOMETRY"); 406 cam_calc_geometry(&ccb->ccg, 1/* extended */); 407 xpt_done(ccb); 408 break; 409 410 case XPT_PATH_INQ: /* Path inquiry -- get twa properties */ 411 { 412 struct ccb_pathinq *path_inq = &ccb->cpi; 413 414 tw_osli_dbg_dprintf(3, sc, "XPT_PATH_INQ request"); 415 416 path_inq->version_num = 1; 417 path_inq->hba_inquiry = 0; 418 path_inq->target_sprt = 0; 419 path_inq->hba_misc = 0; 420 path_inq->hba_eng_cnt = 0; 421 path_inq->max_target = TW_CL_MAX_NUM_UNITS; 422 path_inq->max_lun = TW_CL_MAX_NUM_LUNS - 1; 423 path_inq->unit_number = cam_sim_unit(sim); 424 path_inq->bus_id = cam_sim_bus(sim); 425 path_inq->initiator_id = TW_CL_MAX_NUM_UNITS; 426 path_inq->base_transfer_speed = 100000; 427 strlcpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN); 428 strlcpy(path_inq->hba_vid, "3ware", HBA_IDLEN); 429 strlcpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN); 430 path_inq->transport = XPORT_SPI; 431 path_inq->transport_version = 2; 432 path_inq->protocol = PROTO_SCSI; 433 path_inq->protocol_version = SCSI_REV_2; 434 path_inq->maxio = TW_CL_MAX_IO_SIZE; 435 ccb_h->status = CAM_REQ_CMP; 436 xpt_done(ccb); 437 break; 438 } 439 440 default: 441 tw_osli_dbg_dprintf(3, sc, "func_code = %x", ccb_h->func_code); 442 ccb_h->status = CAM_REQ_INVALID; 443 xpt_done(ccb); 444 break; 445 } 446} 447 448 449 450/* 451 * Function name: twa_poll 452 * Description: Driver entry point called when interrupts are not 453 * available. 454 * 455 * Input: sim -- sim corresponding to the controller 456 * Output: None 457 * Return value: None 458 */ 459TW_VOID 460twa_poll(struct cam_sim *sim) 461{ 462 struct twa_softc *sc = (struct twa_softc *)(cam_sim_softc(sim)); 463 464 tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc); 465 tw_cl_interrupt(&(sc->ctlr_handle)); 466 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc); 467} 468 469 470 471/* 472 * Function name: tw_osli_request_bus_scan 473 * Description: Requests CAM for a scan of the bus. 474 * 475 * Input: sc -- ptr to per ctlr structure 476 * Output: None 477 * Return value: 0 -- success 478 * non-zero-- failure 479 */ 480TW_INT32 481tw_osli_request_bus_scan(struct twa_softc *sc) 482{ 483 union ccb *ccb; 484 485 tw_osli_dbg_dprintf(3, sc, "entering"); 486 487 /* If we get here before sc->sim is initialized, return an error. */ 488 if (!(sc->sim)) 489 return(ENXIO); 490 if ((ccb = xpt_alloc_ccb()) == NULL) 491 return(ENOMEM); 492 mtx_lock(sc->sim_lock); 493 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim), 494 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 495 xpt_free_ccb(ccb); 496 mtx_unlock(sc->sim_lock); 497 return(EIO); 498 } 499 500 xpt_rescan(ccb); 501 mtx_unlock(sc->sim_lock); 502 return(0); 503} 504 505 506 507/* 508 * Function name: tw_osli_disallow_new_requests 509 * Description: Calls the appropriate CAM function, so as to freeze 510 * the flow of new requests from CAM to this controller. 511 * 512 * Input: sc -- ptr to OSL internal ctlr context 513 * req_handle -- ptr to request handle sent by OSL. 514 * Output: None 515 * Return value: None 516 */ 517TW_VOID 518tw_osli_disallow_new_requests(struct twa_softc *sc, 519 struct tw_cl_req_handle *req_handle) 520{ 521 /* Only freeze/release the simq for IOs */ 522 if (req_handle->is_io) { 523 struct tw_osli_req_context *req = req_handle->osl_req_ctxt; 524 union ccb *ccb = (union ccb *)(req->orig_req); 525 526 xpt_freeze_simq(sc->sim, 1); 527 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 528 } 529} 530 531 532 533/* 534 * Function name: tw_osl_timeout 535 * Description: Call to timeout(). 536 * 537 * Input: req_handle -- ptr to request handle sent by OSL. 538 * Output: None 539 * Return value: None 540 */ 541TW_VOID 542tw_osl_timeout(struct tw_cl_req_handle *req_handle) 543{ 544 struct tw_osli_req_context *req = req_handle->osl_req_ctxt; 545 union ccb *ccb = (union ccb *)(req->orig_req); 546 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 547 548 req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000); 549} 550 551 552 553/* 554 * Function name: tw_osl_untimeout 555 * Description: Inverse of call to timeout(). 556 * 557 * Input: req_handle -- ptr to request handle sent by OSL. 558 * Output: None 559 * Return value: None 560 */ 561TW_VOID 562tw_osl_untimeout(struct tw_cl_req_handle *req_handle) 563{ 564 struct tw_osli_req_context *req = req_handle->osl_req_ctxt; 565 566 req->deadline = 0; 567} 568 569 570 571/* 572 * Function name: tw_osl_scan_bus 573 * Description: CL calls this function to request for a bus scan. 574 * 575 * Input: ctlr_handle -- ptr to controller handle 576 * Output: None 577 * Return value: None 578 */ 579TW_VOID 580tw_osl_scan_bus(struct tw_cl_ctlr_handle *ctlr_handle) 581{ 582 struct twa_softc *sc = ctlr_handle->osl_ctlr_ctxt; 583 TW_INT32 error; 584 585 if ((error = tw_osli_request_bus_scan(sc))) 586 tw_osli_printf(sc, "error = %d", 587 TW_CL_SEVERITY_ERROR_STRING, 588 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 589 0x2109, 590 "Bus scan request to CAM failed", 591 error); 592} 593 594 595 596/* 597 * Function name: tw_osl_complete_io 598 * Description: Called to complete CAM scsi requests. 599 * 600 * Input: req_handle -- ptr to request handle 601 * Output: None 602 * Return value: None 603 */ 604TW_VOID 605tw_osl_complete_io(struct tw_cl_req_handle *req_handle) 606{ 607 struct tw_osli_req_context *req = req_handle->osl_req_ctxt; 608 struct tw_cl_req_packet *req_pkt = 609 (struct tw_cl_req_packet *)(&req->req_pkt); 610 struct tw_cl_scsi_req_packet *scsi_req; 611 struct twa_softc *sc = req->ctlr; 612 union ccb *ccb = (union ccb *)(req->orig_req); 613 614 tw_osli_dbg_dprintf(10, sc, "entering"); 615 616 if (req->state != TW_OSLI_REQ_STATE_BUSY) 617 tw_osli_printf(sc, "request = %p, status = %d", 618 TW_CL_SEVERITY_ERROR_STRING, 619 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 620 0x210A, 621 "Unposted command completed!!", 622 req, req->state); 623 624 /* 625 * Remove request from the busy queue. Just mark it complete. 626 * There's no need to move it into the complete queue as we are 627 * going to be done with it right now. 628 */ 629 req->state = TW_OSLI_REQ_STATE_COMPLETE; 630 tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q); 631 632 tw_osli_unmap_request(req); 633 634 req->deadline = 0; 635 if (req->error_code) { 636 /* This request never got submitted to the firmware. */ 637 if (req->error_code == EBUSY) { 638 /* 639 * Cmd queue is full, or the Common Layer is out of 640 * resources. The simq will already have been frozen. 641 * When this ccb gets completed will unfreeze the simq. 642 */ 643 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 644 } 645 else if (req->error_code == EFBIG) 646 ccb->ccb_h.status = CAM_REQ_TOO_BIG; 647 else 648 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 649 } else { 650 scsi_req = &(req_pkt->gen_req_pkt.scsi_req); 651 if (req_pkt->status == TW_CL_ERR_REQ_SUCCESS) 652 ccb->ccb_h.status = CAM_REQ_CMP; 653 else { 654 if (req_pkt->status & TW_CL_ERR_REQ_INVALID_TARGET) 655 ccb->ccb_h.status |= CAM_SEL_TIMEOUT; 656 else if (req_pkt->status & TW_CL_ERR_REQ_INVALID_LUN) 657 ccb->ccb_h.status |= CAM_DEV_NOT_THERE; 658 else if (req_pkt->status & TW_CL_ERR_REQ_SCSI_ERROR) 659 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 660 else if (req_pkt->status & TW_CL_ERR_REQ_BUS_RESET) 661 ccb->ccb_h.status |= (CAM_REQUEUE_REQ | CAM_SCSI_BUS_RESET); 662 /* 663 * If none of the above errors occurred, simply 664 * mark completion error. 665 */ 666 if (ccb->ccb_h.status == 0) 667 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 668 669 if (req_pkt->status & TW_CL_ERR_REQ_AUTO_SENSE_VALID) { 670 ccb->csio.sense_len = scsi_req->sense_len; 671 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 672 } 673 } 674 675 ccb->csio.scsi_status = scsi_req->scsi_status; 676 } 677 678 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 679 mtx_lock(sc->sim_lock); 680 xpt_done(ccb); 681 mtx_unlock(sc->sim_lock); 682 if (! req->error_code) 683 /* twa_action will free the request otherwise */ 684 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q); 685} 686 687