106 TW_OSLI_MAX_NUM_IOS - 1, 1, devq); 107 if (sc->sim == NULL) { 108 cam_simq_free(devq); 109 tw_osli_printf(sc, "error = %d", 110 TW_CL_SEVERITY_ERROR_STRING, 111 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 112 0x2101, 113 "Failed to create a SIM entry", 114 ENOMEM); 115 return(ENOMEM); 116 } 117 118 /* 119 * Register the bus. 120 */ 121 tw_osli_dbg_dprintf(3, sc, "Calling xpt_bus_register"); 122 mtx_lock(&Giant); 123 if (xpt_bus_register(sc->sim, 0) != CAM_SUCCESS) { 124 cam_sim_free(sc->sim, TRUE); 125 sc->sim = NULL; /* so cam_detach will not try to free it */ 126 tw_osli_printf(sc, "error = %d", 127 TW_CL_SEVERITY_ERROR_STRING, 128 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 129 0x2102, 130 "Failed to register the bus", 131 ENXIO); 132 return(ENXIO); 133 } 134 135 tw_osli_dbg_dprintf(3, sc, "Calling xpt_create_path"); 136 if (xpt_create_path(&sc->path, NULL, 137 cam_sim_path(sc->sim), 138 CAM_TARGET_WILDCARD, 139 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 140 xpt_bus_deregister(cam_sim_path (sc->sim)); 141 /* Passing TRUE to cam_sim_free will free the devq as well. */ 142 cam_sim_free(sc->sim, TRUE); 143 tw_osli_printf(sc, "error = %d", 144 TW_CL_SEVERITY_ERROR_STRING, 145 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 146 0x2103, 147 "Failed to create path", 148 ENXIO); 149 return(ENXIO); 150 } 151 152 tw_osli_dbg_dprintf(3, sc, "Calling xpt_setup_ccb"); 153 xpt_setup_ccb(&csa.ccb_h, sc->path, 5); 154 csa.ccb_h.func_code = XPT_SASYNC_CB; 155 csa.event_enable = AC_FOUND_DEVICE | AC_LOST_DEVICE; 156 csa.callback = twa_async; 157 csa.callback_arg = sc; 158 xpt_action((union ccb *)&csa); 159 mtx_unlock(&Giant); 160 161 tw_osli_dbg_dprintf(3, sc, "Calling tw_osli_request_bus_scan"); 162 /* 163 * Request a bus scan, so that CAM gets to know of 164 * the logical units that we control. 165 */ 166 if ((error = tw_osli_request_bus_scan(sc))) 167 tw_osli_printf(sc, "error = %d", 168 TW_CL_SEVERITY_ERROR_STRING, 169 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 170 0x2104, 171 "Bus scan request to CAM failed", 172 error); 173 174 tw_osli_dbg_dprintf(3, sc, "exiting"); 175 return(0); 176} 177 178 179 180/* 181 * Function name: tw_osli_cam_detach 182 * Description: Detaches the driver from CAM. 183 * 184 * Input: sc -- ptr to OSL internal ctlr context 185 * Output: None 186 * Return value: None 187 */ 188TW_VOID 189tw_osli_cam_detach(struct twa_softc *sc) 190{ 191 tw_osli_dbg_dprintf(3, sc, "entered"); 192 193 mtx_lock(&Giant); 194 if (sc->path) 195 xpt_free_path(sc->path); 196 if (sc->sim) { 197 xpt_bus_deregister(cam_sim_path(sc->sim)); 198 /* Passing TRUE to cam_sim_free will free the devq as well. */ 199 cam_sim_free(sc->sim, TRUE); 200 } 201 mtx_unlock(&Giant); 202} 203 204 205 206/* 207 * Function name: tw_osli_execute_scsi 208 * Description: Build a fw cmd, based on a CAM style ccb, and 209 * send it down. 210 * 211 * Input: req -- ptr to OSL internal request context 212 * ccb -- ptr to CAM style ccb 213 * Output: None 214 * Return value: 0 -- success 215 * non-zero-- failure 216 */ 217TW_INT32 218tw_osli_execute_scsi(struct tw_osli_req_context *req, union ccb *ccb) 219{ 220 struct twa_softc *sc = req->ctlr; 221 struct tw_cl_req_packet *req_pkt; 222 struct tw_cl_scsi_req_packet *scsi_req; 223 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 224 struct ccb_scsiio *csio = &(ccb->csio); 225 TW_INT32 error; 226 227 tw_osli_dbg_dprintf(10, sc, "SCSI I/O request 0x%x", 228 csio->cdb_io.cdb_bytes[0]); 229 230 if (ccb_h->target_id >= TW_CL_MAX_NUM_UNITS) { 231 tw_osli_dbg_dprintf(3, sc, "Invalid target. PTL = %x %x %x", 232 ccb_h->path_id, ccb_h->target_id, ccb_h->target_lun); 233 ccb_h->status |= CAM_TID_INVALID; 234 xpt_done(ccb); 235 return(1); 236 } 237 if (ccb_h->target_lun >= TW_CL_MAX_NUM_LUNS) { 238 tw_osli_dbg_dprintf(3, sc, "Invalid lun. PTL = %x %x %x", 239 ccb_h->path_id, ccb_h->target_id, ccb_h->target_lun); 240 ccb_h->status |= CAM_LUN_INVALID; 241 xpt_done(ccb); 242 return(1); 243 } 244 245 if(ccb_h->flags & CAM_CDB_PHYS) { 246 tw_osli_printf(sc, "", 247 TW_CL_SEVERITY_ERROR_STRING, 248 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 249 0x2105, 250 "Physical CDB address!"); 251 ccb_h->status = CAM_REQ_CMP_ERR; 252 xpt_done(ccb); 253 return(1); 254 } 255 256 /* 257 * We are going to work on this request. Mark it as enqueued (though 258 * we don't actually queue it...) 259 */ 260 ccb_h->status |= CAM_SIM_QUEUED; 261 262 if((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 263 if(ccb_h->flags & CAM_DIR_IN) 264 req->flags |= TW_OSLI_REQ_FLAGS_DATA_IN; 265 else 266 req->flags |= TW_OSLI_REQ_FLAGS_DATA_OUT; 267 } 268 269 /* Build the CL understood request packet for SCSI cmds. */ 270 req_pkt = &req->req_pkt; 271 req_pkt->status = 0; 272 req_pkt->tw_osl_callback = tw_osl_complete_io; 273 scsi_req = &(req_pkt->gen_req_pkt.scsi_req); 274 scsi_req->unit = ccb_h->target_id; 275 scsi_req->lun = ccb_h->target_lun; 276 scsi_req->sense_len = 0; 277 scsi_req->sense_data = (TW_UINT8 *)(&csio->sense_data); 278 scsi_req->scsi_status = 0; 279 if(ccb_h->flags & CAM_CDB_POINTER) 280 scsi_req->cdb = csio->cdb_io.cdb_ptr; 281 else 282 scsi_req->cdb = csio->cdb_io.cdb_bytes; 283 scsi_req->cdb_len = csio->cdb_len; 284 285 if (!(ccb_h->flags & CAM_DATA_PHYS)) { 286 /* Virtual data addresses. Need to convert them... */ 287 tw_osli_dbg_dprintf(3, sc, 288 "XPT_SCSI_IO: Single virtual address!"); 289 if (!(ccb_h->flags & CAM_SCATTER_VALID)) { 290 if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) { 291 tw_osli_printf(sc, "size = %d", 292 TW_CL_SEVERITY_ERROR_STRING, 293 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 294 0x2106, 295 "I/O size too big", 296 csio->dxfer_len); 297 ccb_h->status = CAM_REQ_TOO_BIG; 298 xpt_done(ccb); 299 return(1); 300 } 301 302 if ((req->length = csio->dxfer_len)) { 303 req->data = csio->data_ptr; 304 scsi_req->sgl_entries = 1; 305 } 306 } else { 307 tw_osli_printf(sc, "", 308 TW_CL_SEVERITY_ERROR_STRING, 309 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 310 0x2107, 311 "XPT_SCSI_IO: Got SGList"); 312 ccb_h->status = CAM_REQ_CMP_ERR; 313 xpt_done(ccb); 314 return(1); 315 } 316 } else { 317 /* Data addresses are physical. */ 318 tw_osli_printf(sc, "", 319 TW_CL_SEVERITY_ERROR_STRING, 320 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 321 0x2108, 322 "XPT_SCSI_IO: Physical data addresses"); 323 ccb_h->status = CAM_REQ_CMP_ERR; 324 ccb_h->status |= CAM_RELEASE_SIMQ; 325 ccb_h->status &= ~CAM_SIM_QUEUED; 326 xpt_done(ccb); 327 return(1); 328 } 329 330 ccb_h->timeout_ch = timeout(twa_timeout, req, 331 (ccb_h->timeout * hz) / 1000); 332 /* 333 * twa_map_load_data_callback will fill in the SGL, 334 * and submit the I/O. 335 */ 336 error = tw_osli_map_request(req); 337 return(error); 338} 339 340 341 342/* 343 * Function name: twa_action 344 * Description: Driver entry point for CAM's use. 345 * 346 * Input: sim -- sim corresponding to the ctlr 347 * ccb -- ptr to CAM request 348 * Output: None 349 * Return value: None 350 */ 351TW_VOID 352twa_action(struct cam_sim *sim, union ccb *ccb) 353{ 354 struct twa_softc *sc = (struct twa_softc *)cam_sim_softc(sim); 355 struct ccb_hdr *ccb_h = &(ccb->ccb_h); 356 357 switch (ccb_h->func_code) { 358 case XPT_SCSI_IO: /* SCSI I/O */ 359 { 360 struct tw_osli_req_context *req; 361 362 if ((sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) || 363 ((req = tw_osli_get_request(sc)) == NULL)) { 364 tw_osli_dbg_dprintf(2, sc, 365 "simq frozen/Cannot get request pkt."); 366 /* 367 * Freeze the simq to maintain ccb ordering. The next 368 * ccb that gets completed will unfreeze the simq. 369 */ 370 tw_osli_disallow_new_requests(sc); 371 ccb_h->status |= CAM_REQUEUE_REQ; 372 xpt_done(ccb); 373 break; 374 } 375 req->req_handle.osl_req_ctxt = req; 376 req->orig_req = ccb; 377 if (tw_osli_execute_scsi(req, ccb)) 378 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q); 379 break; 380 } 381 382 case XPT_ABORT: 383 tw_osli_dbg_dprintf(2, sc, "Abort request."); 384 ccb_h->status = CAM_UA_ABORT; 385 xpt_done(ccb); 386 break; 387 388 case XPT_RESET_BUS: 389 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE, 390 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 391 0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING, 392 "Received Reset Bus request from CAM", 393 " "); 394 395 if (tw_cl_reset_ctlr(&sc->ctlr_handle)) { 396 tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE, 397 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 398 0x2109, 0x1, TW_CL_SEVERITY_ERROR_STRING, 399 "Failed to reset bus", 400 " "); 401 ccb_h->status = CAM_REQ_CMP_ERR; 402 } 403 else 404 ccb_h->status = CAM_REQ_CMP; 405 406 xpt_done(ccb); 407 break; 408 409 case XPT_SET_TRAN_SETTINGS: 410 tw_osli_dbg_dprintf(3, sc, "XPT_SET_TRAN_SETTINGS"); 411 412 /* 413 * This command is not supported, since it's very specific 414 * to SCSI, and we are doing ATA. 415 */ 416 ccb_h->status = CAM_FUNC_NOTAVAIL; 417 xpt_done(ccb); 418 break; 419 420 case XPT_GET_TRAN_SETTINGS: 421 { 422 struct ccb_trans_settings *cts = &ccb->cts; 423 struct ccb_trans_settings_scsi *scsi = 424 &cts->proto_specific.scsi; 425 struct ccb_trans_settings_spi *spi = 426 &cts->xport_specific.spi; 427 428 cts->protocol = PROTO_SCSI; 429 cts->protocol_version = SCSI_REV_2; 430 cts->transport = XPORT_SPI; 431 cts->transport_version = 2; 432 433 spi->valid = CTS_SPI_VALID_DISC; 434 spi->flags = CTS_SPI_FLAGS_DISC_ENB; 435 scsi->valid = CTS_SCSI_VALID_TQ; 436 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 437 tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS"); 438 ccb_h->status = CAM_REQ_CMP; 439 xpt_done(ccb); 440 break; 441 } 442 443 case XPT_CALC_GEOMETRY: 444 tw_osli_dbg_dprintf(3, sc, "XPT_CALC_GEOMETRY"); 445 cam_calc_geometry(&ccb->ccg, 1/* extended */); 446 xpt_done(ccb); 447 break; 448 449 case XPT_PATH_INQ: /* Path inquiry -- get twa properties */ 450 { 451 struct ccb_pathinq *path_inq = &ccb->cpi; 452 453 tw_osli_dbg_dprintf(3, sc, "XPT_PATH_INQ request"); 454 455 path_inq->version_num = 1; 456 path_inq->hba_inquiry = 0; 457 path_inq->target_sprt = 0; 458 path_inq->hba_misc = 0; 459 path_inq->hba_eng_cnt = 0; 460 path_inq->max_target = TW_CL_MAX_NUM_UNITS; 461 path_inq->max_lun = TW_CL_MAX_NUM_LUNS - 1; 462 path_inq->unit_number = cam_sim_unit(sim); 463 path_inq->bus_id = cam_sim_bus(sim); 464 path_inq->initiator_id = TW_CL_MAX_NUM_UNITS; 465 path_inq->base_transfer_speed = 100000; 466 strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN); 467 strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN); 468 strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN); 469 path_inq->transport = XPORT_SPI; 470 path_inq->transport_version = 2; 471 path_inq->protocol = PROTO_SCSI; 472 path_inq->protocol_version = SCSI_REV_2; 473 ccb_h->status = CAM_REQ_CMP; 474 xpt_done(ccb); 475 break; 476 } 477 478 default: 479 tw_osli_dbg_dprintf(3, sc, "func_code = %x", ccb_h->func_code); 480 ccb_h->status = CAM_REQ_INVALID; 481 xpt_done(ccb); 482 break; 483 } 484} 485 486 487 488/* 489 * Function name: twa_poll 490 * Description: Driver entry point called when interrupts are not 491 * available. 492 * 493 * Input: sim -- sim corresponding to the controller 494 * Output: None 495 * Return value: None 496 */ 497TW_VOID 498twa_poll(struct cam_sim *sim) 499{ 500 struct twa_softc *sc = (struct twa_softc *)(cam_sim_softc(sim)); 501 502 tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc); 503 /* 504 * It's been observed that twa_poll can get called (from 505 * dashutdown --> xpt_polled_action) even when interrupts are 506 * active, in which case, the ISR might clear the interrupt, 507 * leaving the call to tw_cl_interrupt below, no way of determining 508 * that the response from firmware is ready, resulting in 509 * tw_cl_deferred_interrupt never getting called. To cover this case, 510 * we will make the call to tw_cl_deferred_interrupt not dependent 511 * on the return value from tw_cl_interrupt. 512 */ 513 tw_cl_interrupt(&(sc->ctlr_handle)); 514 tw_cl_deferred_interrupt(&(sc->ctlr_handle)); 515 tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc); 516} 517 518 519 520/* 521 * Function name: twa_async 522 * Description: Driver entry point for CAM to notify driver of special 523 * events. We don't use this for now. 524 * 525 * Input: callback_arg -- ptr to per ctlr structure 526 * code -- code associated with the event 527 * path -- cam path 528 * arg -- 529 * Output: None 530 * Return value: 0 -- success 531 * non-zero-- failure 532 */ 533TW_VOID 534twa_async(TW_VOID *callback_arg, TW_UINT32 code, 535 struct cam_path *path, TW_VOID *arg) 536{ 537#ifdef TW_OSL_DEBUG 538 struct twa_softc *sc = (struct twa_softc *)callback_arg; 539#endif /* TW_OSL_DEBUG */ 540 541 tw_osli_dbg_dprintf(3, sc, "sc = %p, code = %x, path = %p, arg = %p", 542 sc, code, path, arg); 543} 544 545 546 547/* 548 * Function name: twa_timeout 549 * Description: Driver entry point for being alerted on a request 550 * timing out. 551 * 552 * Input: arg -- ptr to timed out request 553 * Output: None 554 * Return value: None 555 */ 556static TW_VOID 557twa_timeout(TW_VOID *arg) 558{ 559 struct tw_osli_req_context *req = 560 (struct tw_osli_req_context *)arg; 561 562 tw_cl_create_event(&(req->ctlr->ctlr_handle), TW_CL_TRUE, 563 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 564 0x210B, 0x1, TW_CL_SEVERITY_ERROR_STRING, 565 "Request timed out!", 566 "request = %p", req); 567 tw_cl_reset_ctlr(&(req->ctlr->ctlr_handle)); 568} 569 570 571 572/* 573 * Function name: tw_osli_request_bus_scan 574 * Description: Requests CAM for a scan of the bus. 575 * 576 * Input: sc -- ptr to per ctlr structure 577 * Output: None 578 * Return value: 0 -- success 579 * non-zero-- failure 580 */ 581TW_INT32 582tw_osli_request_bus_scan(struct twa_softc *sc) 583{ 584 struct cam_path *path; 585 union ccb *ccb; 586 587 tw_osli_dbg_dprintf(3, sc, "entering"); 588 589 /* If we get here before sc->sim is initialized, return an error. */ 590 if (!(sc->sim)) 591 return(ENXIO); 592 if ((ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK)) == NULL) 593 return(ENOMEM); 594 bzero(ccb, sizeof(union ccb)); 595 mtx_lock(&Giant); 596 if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->sim), 597 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) 598 return(EIO); 599 600 xpt_setup_ccb(&ccb->ccb_h, path, 5); 601 ccb->ccb_h.func_code = XPT_SCAN_BUS; 602 ccb->ccb_h.cbfcnp = twa_bus_scan_cb; 603 ccb->crcn.flags = CAM_FLAG_NONE; 604 xpt_action(ccb); 605 mtx_unlock(&Giant); 606 return(0); 607} 608 609 610 611/* 612 * Function name: twa_bus_scan_cb 613 * Description: Callback from CAM on a bus scan request. 614 * 615 * Input: periph -- we don't use this 616 * ccb -- bus scan request ccb that we sent to CAM 617 * Output: None 618 * Return value: None 619 */ 620static TW_VOID 621twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb) 622{ 623 tw_osli_dbg_printf(3, "entering"); 624 625 if (ccb->ccb_h.status != CAM_REQ_CMP) 626 printf("cam_scan_callback: failure status = %x\n", 627 ccb->ccb_h.status); 628 else 629 tw_osli_dbg_printf(3, "success"); 630 631 xpt_free_path(ccb->ccb_h.path); 632 free(ccb, M_TEMP); 633} 634 635 636 637/* 638 * Function name: tw_osli_allow_new_requests 639 * Description: Sets the appropriate status bits in a ccb such that, 640 * when the ccb is completed by a call to xpt_done, 641 * CAM knows that it's ok to unfreeze the flow of new 642 * requests to this controller, if the flow is frozen. 643 * 644 * Input: sc -- ptr to OSL internal ctlr context 645 * ccb -- ptr to CAM request 646 * Output: None 647 * Return value: None 648 */ 649TW_VOID 650tw_osli_allow_new_requests(struct twa_softc *sc, TW_VOID *ccb) 651{ 652 ((union ccb *)(ccb))->ccb_h.status |= CAM_RELEASE_SIMQ; 653 sc->state &= ~TW_OSLI_CTLR_STATE_SIMQ_FROZEN; 654} 655 656 657 658/* 659 * Function name: tw_osli_disallow_new_requests 660 * Description: Calls the appropriate CAM function, so as to freeze 661 * the flow of new requests from CAM to this controller. 662 * 663 * Input: sc -- ptr to OSL internal ctlr context 664 * Output: None 665 * Return value: None 666 */ 667TW_VOID 668tw_osli_disallow_new_requests(struct twa_softc *sc) 669{ 670 mtx_lock(&Giant); 671 xpt_freeze_simq(sc->sim, 1); 672 mtx_unlock(&Giant); 673 sc->state |= TW_OSLI_CTLR_STATE_SIMQ_FROZEN; 674} 675 676 677 678/* 679 * Function name: tw_osl_ctlr_busy 680 * Description: CL calls this function on cmd queue full or otherwise, 681 * when it is too busy to accept new requests. 682 * 683 * Input: ctlr_handle -- ptr to controller handle 684 * req_handle -- ptr to request handle sent by OSL. 685 * Output: None 686 * Return value: None 687 */ 688TW_VOID 689tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle, 690 struct tw_cl_req_handle *req_handle) 691{ 692 tw_osli_disallow_new_requests(ctlr_handle->osl_ctlr_ctxt); 693} 694 695 696 697/* 698 * Function name: tw_osl_scan_bus 699 * Description: CL calls this function to request for a bus scan. 700 * 701 * Input: ctlr_handle -- ptr to controller handle 702 * Output: None 703 * Return value: None 704 */ 705TW_VOID 706tw_osl_scan_bus(struct tw_cl_ctlr_handle *ctlr_handle) 707{ 708 struct twa_softc *sc = ctlr_handle->osl_ctlr_ctxt; 709 TW_INT32 error; 710 711 if ((error = tw_osli_request_bus_scan(sc))) 712 tw_osli_printf(sc, "error = %d", 713 TW_CL_SEVERITY_ERROR_STRING, 714 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 715 0x2109, 716 "Bus scan request to CAM failed", 717 error); 718} 719 720 721 722/* 723 * Function name: tw_osl_complete_io 724 * Description: Called to complete CAM scsi requests. 725 * 726 * Input: req_handle -- ptr to request handle 727 * Output: None 728 * Return value: None 729 */ 730TW_VOID 731tw_osl_complete_io(struct tw_cl_req_handle *req_handle) 732{ 733 struct tw_osli_req_context *req = req_handle->osl_req_ctxt; 734 struct tw_cl_req_packet *req_pkt = 735 (struct tw_cl_req_packet *)(&req->req_pkt); 736 struct tw_cl_scsi_req_packet *scsi_req; 737 struct twa_softc *sc = req->ctlr; 738 union ccb *ccb = (union ccb *)(req->orig_req); 739 740 tw_osli_dbg_dprintf(10, sc, "entering"); 741 742 if (req->state != TW_OSLI_REQ_STATE_BUSY) 743 tw_osli_printf(sc, "request = %p, status = %d", 744 TW_CL_SEVERITY_ERROR_STRING, 745 TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 746 0x210A, 747 "Unposted command completed!!", 748 req, req->state); 749 750 /* 751 * Remove request from the busy queue. Just mark it complete. 752 * There's no need to move it into the complete queue as we are 753 * going to be done with it right now. 754 */ 755 req->state = TW_OSLI_REQ_STATE_COMPLETE; 756 tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q); 757 758 tw_osli_unmap_request(req); 759 760 untimeout(twa_timeout, req, ccb->ccb_h.timeout_ch); 761 if (req->error_code) { 762 /* This request never got submitted to the firmware. */ 763 if (req->error_code == EBUSY) { 764 /* 765 * Cmd queue is full, or the Common Layer is out of 766 * resources. The simq will already have been frozen 767 * by CL's call to tw_osl_ctlr_busy, and this will 768 * maintain ccb ordering. The next ccb that gets 769 * completed will unfreeze the simq. 770 */ 771 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 772 } 773 else if (req->error_code == EFBIG) 774 ccb->ccb_h.status = CAM_REQ_TOO_BIG; 775 else 776 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 777 } else { 778 scsi_req = &(req_pkt->gen_req_pkt.scsi_req); 779 if (req_pkt->status == TW_CL_ERR_REQ_SUCCESS) 780 ccb->ccb_h.status = CAM_REQ_CMP; 781 else { 782 if (req_pkt->status & TW_CL_ERR_REQ_INVALID_TARGET) 783 ccb->ccb_h.status |= CAM_TID_INVALID; 784 else if (req_pkt->status & TW_CL_ERR_REQ_INVALID_LUN) 785 ccb->ccb_h.status |= CAM_LUN_INVALID; 786 else if (req_pkt->status & TW_CL_ERR_REQ_SCSI_ERROR) 787 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 788 else if (req_pkt->status & TW_CL_ERR_REQ_BUS_RESET) 789 ccb->ccb_h.status |= CAM_SCSI_BUS_RESET; 790 /* 791 * If none of the above errors occurred, simply 792 * mark completion error. 793 */ 794 if (ccb->ccb_h.status == 0) 795 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 796 797 if (req_pkt->status & TW_CL_ERR_REQ_AUTO_SENSE_VALID) { 798 ccb->csio.sense_len = scsi_req->sense_len; 799 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 800 } 801 } 802 803 ccb->csio.scsi_status = scsi_req->scsi_status; 804 /* If simq is frozen, unfreeze it. */ 805 if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) 806 tw_osli_allow_new_requests(sc, (TW_VOID *)ccb); 807 } 808 809 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 810 xpt_done(ccb); 811 if (! req->error_code) 812 /* twa_action will free the request otherwise */ 813 tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q); 814} 815
|