231 AHC_MAX_QUEUE, devq); 232 233 if (sim2 == NULL) { 234 printf("ahc_attach: Unable to attach second " 235 "bus due to resource shortage"); 236 goto fail; 237 } 238 239 if (xpt_bus_register(sim2, bus_id2) != CAM_SUCCESS) { 240 printf("ahc_attach: Unable to attach second " 241 "bus due to resource shortage"); 242 /* 243 * We do not want to destroy the device queue 244 * because the first bus is using it. 245 */ 246 cam_sim_free(sim2, /*free_devq*/FALSE); 247 goto fail; 248 } 249 250 if (xpt_create_path(&path2, /*periph*/NULL, 251 cam_sim_path(sim2), 252 CAM_TARGET_WILDCARD, 253 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 254 xpt_bus_deregister(cam_sim_path(sim2)); 255 cam_sim_free(sim2, /*free_devq*/FALSE); 256 sim2 = NULL; 257 goto fail; 258 } 259 xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5); 260 csa.ccb_h.func_code = XPT_SASYNC_CB; 261 csa.event_enable = AC_LOST_DEVICE; 262 csa.callback = ahc_async; 263 csa.callback_arg = sim2; 264 xpt_action((union ccb *)&csa); 265 count++; 266 } 267 268fail: 269 if ((ahc->features & AHC_TWIN) != 0 270 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 271 ahc->platform_data->sim_b = sim; 272 ahc->platform_data->path_b = path; 273 ahc->platform_data->sim = sim2; 274 ahc->platform_data->path = path2; 275 } else { 276 ahc->platform_data->sim = sim; 277 ahc->platform_data->path = path; 278 ahc->platform_data->sim_b = sim2; 279 ahc->platform_data->path_b = path2; 280 } 281 282 if (count != 0) { 283 /* We have to wait until after any system dumps... */ 284 ahc->platform_data->eh = 285 EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown, 286 ahc, SHUTDOWN_PRI_DEFAULT); 287 ahc_intr_enable(ahc, TRUE); 288 } 289 290 ahc_unlock(ahc, &s); 291 return (count); 292} 293 294/* 295 * Catch an interrupt from the adapter 296 */ 297void 298ahc_platform_intr(void *arg) 299{ 300 struct ahc_softc *ahc; 301 302 ahc = (struct ahc_softc *)arg; 303 ahc_intr(ahc); 304} 305 306/* 307 * We have an scb which has been processed by the 308 * adaptor, now we look to see how the operation 309 * went. 310 */ 311void 312ahc_done(struct ahc_softc *ahc, struct scb *scb) 313{ 314 union ccb *ccb; 315 316 CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE, 317 ("ahc_done - scb %d\n", scb->hscb->tag)); 318 319 ccb = scb->io_ctx; 320 LIST_REMOVE(scb, pending_links); 321 if ((scb->flags & SCB_TIMEDOUT) != 0) 322 LIST_REMOVE(scb, timedout_links); 323 if ((scb->flags & SCB_UNTAGGEDQ) != 0) { 324 struct scb_tailq *untagged_q; 325 int target_offset; 326 327 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 328 untagged_q = &ahc->untagged_queues[target_offset]; 329 TAILQ_REMOVE(untagged_q, scb, links.tqe); 330 scb->flags &= ~SCB_UNTAGGEDQ; 331 ahc_run_untagged_queue(ahc, untagged_q); 332 } 333 334 untimeout(ahc_platform_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); 335 336 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 337 bus_dmasync_op_t op; 338 339 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 340 op = BUS_DMASYNC_POSTREAD; 341 else 342 op = BUS_DMASYNC_POSTWRITE; 343 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 344 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 345 } 346 347 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 348 struct cam_path *ccb_path; 349 350 /* 351 * If we have finally disconnected, clean up our 352 * pending device state. 353 * XXX - There may be error states that cause where 354 * we will remain connected. 355 */ 356 ccb_path = ccb->ccb_h.path; 357 if (ahc->pending_device != NULL 358 && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) { 359 360 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 361 ahc->pending_device = NULL; 362 } else { 363 if (bootverbose) { 364 xpt_print_path(ccb->ccb_h.path); 365 printf("Still connected\n"); 366 } 367 aic_freeze_ccb(ccb); 368 } 369 } 370 371 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) 372 ccb->ccb_h.status |= CAM_REQ_CMP; 373 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 374 ahc_free_scb(ahc, scb); 375 xpt_done(ccb); 376 return; 377 } 378 379 /* 380 * If the recovery SCB completes, we have to be 381 * out of our timeout. 382 */ 383 if ((scb->flags & SCB_RECOVERY_SCB) != 0) { 384 struct scb *list_scb; 385 386 ahc->scb_data->recovery_scbs--; 387 388 if (aic_get_transaction_status(scb) == CAM_BDR_SENT 389 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED) 390 aic_set_transaction_status(scb, CAM_CMD_TIMEOUT); 391 392 if (ahc->scb_data->recovery_scbs == 0) { 393 /* 394 * All recovery actions have completed successfully, 395 * so reinstate the timeouts for all other pending 396 * commands. 397 */ 398 LIST_FOREACH(list_scb, &ahc->pending_scbs, 399 pending_links) { 400 401 aic_scb_timer_reset(list_scb, 402 aic_get_timeout(scb)); 403 } 404 405 ahc_print_path(ahc, scb); 406 printf("no longer in timeout, status = %x\n", 407 ccb->ccb_h.status); 408 } 409 } 410 411 /* Don't clobber any existing error state */ 412 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) { 413 ccb->ccb_h.status |= CAM_REQ_CMP; 414 } else if ((scb->flags & SCB_SENSE) != 0) { 415 /* 416 * We performed autosense retrieval. 417 * 418 * Zero any sense not transferred by the 419 * device. The SCSI spec mandates that any 420 * untransfered data should be assumed to be 421 * zero. Complete the 'bounce' of sense information 422 * through buffers accessible via bus-space by 423 * copying it into the clients csio. 424 */ 425 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 426 memcpy(&ccb->csio.sense_data, 427 ahc_get_sense_buf(ahc, scb), 428 (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK) 429 - ccb->csio.sense_resid); 430 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 431 } 432 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 433 ahc_free_scb(ahc, scb); 434 xpt_done(ccb); 435} 436 437static void 438ahc_action(struct cam_sim *sim, union ccb *ccb) 439{ 440 struct ahc_softc *ahc; 441 struct ahc_tmode_lstate *lstate; 442 u_int target_id; 443 u_int our_id; 444 long s; 445 446 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n")); 447 448 ahc = (struct ahc_softc *)cam_sim_softc(sim); 449 450 target_id = ccb->ccb_h.target_id; 451 our_id = SIM_SCSI_ID(ahc, sim); 452 453 switch (ccb->ccb_h.func_code) { 454 /* Common cases first */ 455 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 456 case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/ 457 { 458 struct ahc_tmode_tstate *tstate; 459 cam_status status; 460 461 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 462 &lstate, TRUE); 463 464 if (status != CAM_REQ_CMP) { 465 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 466 /* Response from the black hole device */ 467 tstate = NULL; 468 lstate = ahc->black_hole; 469 } else { 470 ccb->ccb_h.status = status; 471 xpt_done(ccb); 472 break; 473 } 474 } 475 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 476 477 ahc_lock(ahc, &s); 478 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 479 sim_links.sle); 480 ccb->ccb_h.status = CAM_REQ_INPROG; 481 if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0) 482 ahc_run_tqinfifo(ahc, /*paused*/FALSE); 483 ahc_unlock(ahc, &s); 484 break; 485 } 486 487 /* 488 * The target_id represents the target we attempt to 489 * select. In target mode, this is the initiator of 490 * the original command. 491 */ 492 our_id = target_id; 493 target_id = ccb->csio.init_id; 494 /* FALLTHROUGH */ 495 } 496 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 497 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 498 { 499 struct scb *scb; 500 struct hardware_scb *hscb; 501 502 if ((ahc->flags & AHC_INITIATORROLE) == 0 503 && (ccb->ccb_h.func_code == XPT_SCSI_IO 504 || ccb->ccb_h.func_code == XPT_RESET_DEV)) { 505 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 506 xpt_done(ccb); 507 return; 508 } 509 510 /* 511 * get an scb to use. 512 */ 513 ahc_lock(ahc, &s); 514 if ((scb = ahc_get_scb(ahc)) == NULL) { 515 516 xpt_freeze_simq(sim, /*count*/1); 517 ahc->flags |= AHC_RESOURCE_SHORTAGE; 518 ahc_unlock(ahc, &s); 519 ccb->ccb_h.status = CAM_REQUEUE_REQ; 520 xpt_done(ccb); 521 return; 522 } 523 ahc_unlock(ahc, &s); 524 525 hscb = scb->hscb; 526 527 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 528 ("start scb(%p)\n", scb)); 529 scb->io_ctx = ccb; 530 /* 531 * So we can find the SCB when an abort is requested 532 */ 533 ccb->ccb_h.ccb_scb_ptr = scb; 534 535 /* 536 * Put all the arguments for the xfer in the scb 537 */ 538 hscb->control = 0; 539 hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id); 540 hscb->lun = ccb->ccb_h.target_lun; 541 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 542 hscb->cdb_len = 0; 543 scb->flags |= SCB_DEVICE_RESET; 544 hscb->control |= MK_MESSAGE; 545 ahc_execute_scb(scb, NULL, 0, 0); 546 } else { 547 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 548 struct target_data *tdata; 549 550 tdata = &hscb->shared_data.tdata; 551 if (ahc->pending_device == lstate) 552 scb->flags |= SCB_TARGET_IMMEDIATE; 553 hscb->control |= TARGET_SCB; 554 scb->flags |= SCB_TARGET_SCB; 555 tdata->target_phases = 0; 556 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 557 tdata->target_phases |= SPHASE_PENDING; 558 tdata->scsi_status = 559 ccb->csio.scsi_status; 560 } 561 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 562 tdata->target_phases |= NO_DISCONNECT; 563 564 tdata->initiator_tag = ccb->csio.tag_id; 565 } 566 if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) 567 hscb->control |= ccb->csio.tag_action; 568 569 ahc_setup_data(ahc, sim, &ccb->csio, scb); 570 } 571 break; 572 } 573 case XPT_NOTIFY_ACK: 574 case XPT_IMMED_NOTIFY: 575 { 576 struct ahc_tmode_tstate *tstate; 577 struct ahc_tmode_lstate *lstate; 578 cam_status status; 579 580 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 581 &lstate, TRUE); 582 583 if (status != CAM_REQ_CMP) { 584 ccb->ccb_h.status = status; 585 xpt_done(ccb); 586 break; 587 } 588 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 589 sim_links.sle); 590 ccb->ccb_h.status = CAM_REQ_INPROG; 591 ahc_send_lstate_events(ahc, lstate); 592 break; 593 } 594 case XPT_EN_LUN: /* Enable LUN as a target */ 595 ahc_handle_en_lun(ahc, sim, ccb); 596 xpt_done(ccb); 597 break; 598 case XPT_ABORT: /* Abort the specified CCB */ 599 { 600 ahc_abort_ccb(ahc, sim, ccb); 601 break; 602 } 603 case XPT_SET_TRAN_SETTINGS: 604 { 605 struct ahc_devinfo devinfo; 606 struct ccb_trans_settings *cts; 607 struct ccb_trans_settings_scsi *scsi; 608 struct ccb_trans_settings_spi *spi; 609 struct ahc_initiator_tinfo *tinfo; 610 struct ahc_tmode_tstate *tstate; 611 uint16_t *discenable; 612 uint16_t *tagenable; 613 u_int update_type; 614 615 cts = &ccb->cts; 616 scsi = &cts->proto_specific.scsi; 617 spi = &cts->xport_specific.spi; 618 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 619 cts->ccb_h.target_id, 620 cts->ccb_h.target_lun, 621 SIM_CHANNEL(ahc, sim), 622 ROLE_UNKNOWN); 623 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, 624 devinfo.our_scsiid, 625 devinfo.target, &tstate); 626 update_type = 0; 627 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 628 update_type |= AHC_TRANS_GOAL; 629 discenable = &tstate->discenable; 630 tagenable = &tstate->tagenable; 631 tinfo->curr.protocol_version = 632 cts->protocol_version; 633 tinfo->curr.transport_version = 634 cts->transport_version; 635 tinfo->goal.protocol_version = 636 cts->protocol_version; 637 tinfo->goal.transport_version = 638 cts->transport_version; 639 } else if (cts->type == CTS_TYPE_USER_SETTINGS) { 640 update_type |= AHC_TRANS_USER; 641 discenable = &ahc->user_discenable; 642 tagenable = &ahc->user_tagenable; 643 tinfo->user.protocol_version = 644 cts->protocol_version; 645 tinfo->user.transport_version = 646 cts->transport_version; 647 } else { 648 ccb->ccb_h.status = CAM_REQ_INVALID; 649 xpt_done(ccb); 650 break; 651 } 652 653 ahc_lock(ahc, &s); 654 655 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 656 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 657 *discenable |= devinfo.target_mask; 658 else 659 *discenable &= ~devinfo.target_mask; 660 } 661 662 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 663 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 664 *tagenable |= devinfo.target_mask; 665 else 666 *tagenable &= ~devinfo.target_mask; 667 } 668 669 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 670 ahc_validate_width(ahc, /*tinfo limit*/NULL, 671 &spi->bus_width, ROLE_UNKNOWN); 672 ahc_set_width(ahc, &devinfo, spi->bus_width, 673 update_type, /*paused*/FALSE); 674 } 675 676 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) { 677 if (update_type == AHC_TRANS_USER) 678 spi->ppr_options = tinfo->user.ppr_options; 679 else 680 spi->ppr_options = tinfo->goal.ppr_options; 681 } 682 683 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) { 684 if (update_type == AHC_TRANS_USER) 685 spi->sync_offset = tinfo->user.offset; 686 else 687 spi->sync_offset = tinfo->goal.offset; 688 } 689 690 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) { 691 if (update_type == AHC_TRANS_USER) 692 spi->sync_period = tinfo->user.period; 693 else 694 spi->sync_period = tinfo->goal.period; 695 } 696 697 if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) 698 || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { 699 struct ahc_syncrate *syncrate; 700 u_int maxsync; 701 702 if ((ahc->features & AHC_ULTRA2) != 0) 703 maxsync = AHC_SYNCRATE_DT; 704 else if ((ahc->features & AHC_ULTRA) != 0) 705 maxsync = AHC_SYNCRATE_ULTRA; 706 else 707 maxsync = AHC_SYNCRATE_FAST; 708 709 if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT) 710 spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ; 711 712 syncrate = ahc_find_syncrate(ahc, &spi->sync_period, 713 &spi->ppr_options, 714 maxsync); 715 ahc_validate_offset(ahc, /*tinfo limit*/NULL, 716 syncrate, &spi->sync_offset, 717 spi->bus_width, ROLE_UNKNOWN); 718 719 /* We use a period of 0 to represent async */ 720 if (spi->sync_offset == 0) { 721 spi->sync_period = 0; 722 spi->ppr_options = 0; 723 } 724 725 ahc_set_syncrate(ahc, &devinfo, syncrate, 726 spi->sync_period, spi->sync_offset, 727 spi->ppr_options, update_type, 728 /*paused*/FALSE); 729 } 730 ahc_unlock(ahc, &s); 731 ccb->ccb_h.status = CAM_REQ_CMP; 732 xpt_done(ccb); 733 break; 734 } 735 case XPT_GET_TRAN_SETTINGS: 736 /* Get default/user set transfer settings for the target */ 737 { 738 739 ahc_lock(ahc, &s); 740 ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim), 741 SIM_CHANNEL(ahc, sim), &ccb->cts); 742 ahc_unlock(ahc, &s); 743 xpt_done(ccb); 744 break; 745 } 746 case XPT_CALC_GEOMETRY: 747 { 748 int extended; 749 750 extended = SIM_IS_SCSIBUS_B(ahc, sim) 751 ? ahc->flags & AHC_EXTENDED_TRANS_B 752 : ahc->flags & AHC_EXTENDED_TRANS_A; 753 aic_calc_geometry(&ccb->ccg, extended); 754 xpt_done(ccb); 755 break; 756 } 757 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 758 { 759 int found; 760 761 ahc_lock(ahc, &s); 762 found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim), 763 /*initiate reset*/TRUE); 764 ahc_unlock(ahc, &s); 765 if (bootverbose) { 766 xpt_print_path(SIM_PATH(ahc, sim)); 767 printf("SCSI bus reset delivered. " 768 "%d SCBs aborted.\n", found); 769 } 770 ccb->ccb_h.status = CAM_REQ_CMP; 771 xpt_done(ccb); 772 break; 773 } 774 case XPT_TERM_IO: /* Terminate the I/O process */ 775 /* XXX Implement */ 776 ccb->ccb_h.status = CAM_REQ_INVALID; 777 xpt_done(ccb); 778 break; 779 case XPT_PATH_INQ: /* Path routing inquiry */ 780 { 781 struct ccb_pathinq *cpi = &ccb->cpi; 782 783 cpi->version_num = 1; /* XXX??? */ 784 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 785 if ((ahc->features & AHC_WIDE) != 0) 786 cpi->hba_inquiry |= PI_WIDE_16; 787 if ((ahc->features & AHC_TARGETMODE) != 0) { 788 cpi->target_sprt = PIT_PROCESSOR 789 | PIT_DISCONNECT 790 | PIT_TERM_IO; 791 } else { 792 cpi->target_sprt = 0; 793 } 794 cpi->hba_misc = 0; 795 cpi->hba_eng_cnt = 0; 796 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7; 797 cpi->max_lun = AHC_NUM_LUNS - 1; 798 if (SIM_IS_SCSIBUS_B(ahc, sim)) { 799 cpi->initiator_id = ahc->our_id_b; 800 if ((ahc->flags & AHC_RESET_BUS_B) == 0) 801 cpi->hba_misc |= PIM_NOBUSRESET; 802 } else { 803 cpi->initiator_id = ahc->our_id; 804 if ((ahc->flags & AHC_RESET_BUS_A) == 0) 805 cpi->hba_misc |= PIM_NOBUSRESET; 806 } 807 cpi->bus_id = cam_sim_bus(sim); 808 cpi->base_transfer_speed = 3300; 809 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 810 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 811 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 812 cpi->unit_number = cam_sim_unit(sim); 813 cpi->protocol = PROTO_SCSI; 814 cpi->protocol_version = SCSI_REV_2; 815 cpi->transport = XPORT_SPI; 816 cpi->transport_version = 2; 817 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST; 818 if ((ahc->features & AHC_DT) != 0) { 819 cpi->transport_version = 3; 820 cpi->xport_specific.spi.ppr_options = 821 SID_SPI_CLOCK_DT_ST; 822 } 823 cpi->ccb_h.status = CAM_REQ_CMP; 824 xpt_done(ccb); 825 break; 826 } 827 default: 828 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 829 xpt_done(ccb); 830 break; 831 } 832} 833 834static void 835ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel, 836 struct ccb_trans_settings *cts) 837{ 838 struct ahc_devinfo devinfo; 839 struct ccb_trans_settings_scsi *scsi; 840 struct ccb_trans_settings_spi *spi; 841 struct ahc_initiator_tinfo *targ_info; 842 struct ahc_tmode_tstate *tstate; 843 struct ahc_transinfo *tinfo; 844 845 scsi = &cts->proto_specific.scsi; 846 spi = &cts->xport_specific.spi; 847 ahc_compile_devinfo(&devinfo, our_id, 848 cts->ccb_h.target_id, 849 cts->ccb_h.target_lun, 850 channel, ROLE_UNKNOWN); 851 targ_info = ahc_fetch_transinfo(ahc, devinfo.channel, 852 devinfo.our_scsiid, 853 devinfo.target, &tstate); 854 855 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 856 tinfo = &targ_info->curr; 857 else 858 tinfo = &targ_info->user; 859 860 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 861 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 862 if (cts->type == CTS_TYPE_USER_SETTINGS) { 863 if ((ahc->user_discenable & devinfo.target_mask) != 0) 864 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 865 866 if ((ahc->user_tagenable & devinfo.target_mask) != 0) 867 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 868 } else { 869 if ((tstate->discenable & devinfo.target_mask) != 0) 870 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 871 872 if ((tstate->tagenable & devinfo.target_mask) != 0) 873 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 874 } 875 cts->protocol_version = tinfo->protocol_version; 876 cts->transport_version = tinfo->transport_version; 877 878 spi->sync_period = tinfo->period; 879 spi->sync_offset = tinfo->offset; 880 spi->bus_width = tinfo->width; 881 spi->ppr_options = tinfo->ppr_options; 882 883 cts->protocol = PROTO_SCSI; 884 cts->transport = XPORT_SPI; 885 spi->valid = CTS_SPI_VALID_SYNC_RATE 886 | CTS_SPI_VALID_SYNC_OFFSET 887 | CTS_SPI_VALID_BUS_WIDTH 888 | CTS_SPI_VALID_PPR_OPTIONS; 889 890 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 891 scsi->valid = CTS_SCSI_VALID_TQ; 892 spi->valid |= CTS_SPI_VALID_DISC; 893 } else { 894 scsi->valid = 0; 895 } 896 897 cts->ccb_h.status = CAM_REQ_CMP; 898} 899 900static void 901ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 902{ 903 struct ahc_softc *ahc; 904 struct cam_sim *sim; 905 906 sim = (struct cam_sim *)callback_arg; 907 ahc = (struct ahc_softc *)cam_sim_softc(sim); 908 switch (code) { 909 case AC_LOST_DEVICE: 910 { 911 struct ahc_devinfo devinfo; 912 long s; 913 914 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 915 xpt_path_target_id(path), 916 xpt_path_lun_id(path), 917 SIM_CHANNEL(ahc, sim), 918 ROLE_UNKNOWN); 919 920 /* 921 * Revert to async/narrow transfers 922 * for the next device. 923 */ 924 ahc_lock(ahc, &s); 925 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 926 AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE); 927 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL, 928 /*period*/0, /*offset*/0, /*ppr_options*/0, 929 AHC_TRANS_GOAL|AHC_TRANS_CUR, 930 /*paused*/FALSE); 931 ahc_unlock(ahc, &s); 932 break; 933 } 934 default: 935 break; 936 } 937} 938 939static void 940ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, 941 int error) 942{ 943 struct scb *scb; 944 union ccb *ccb; 945 struct ahc_softc *ahc; 946 struct ahc_initiator_tinfo *tinfo; 947 struct ahc_tmode_tstate *tstate; 948 u_int mask; 949 long s; 950 951 scb = (struct scb *)arg; 952 ccb = scb->io_ctx; 953 ahc = scb->ahc_softc; 954 955 if (error != 0) { 956 if (error == EFBIG) 957 aic_set_transaction_status(scb, CAM_REQ_TOO_BIG); 958 else 959 aic_set_transaction_status(scb, CAM_REQ_CMP_ERR); 960 if (nsegments != 0) 961 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 962 ahc_lock(ahc, &s); 963 ahc_free_scb(ahc, scb); 964 ahc_unlock(ahc, &s); 965 xpt_done(ccb); 966 return; 967 } 968 if (nsegments != 0) { 969 struct ahc_dma_seg *sg; 970 bus_dma_segment_t *end_seg; 971 bus_dmasync_op_t op; 972 973 end_seg = dm_segs + nsegments; 974 975 /* Copy the segments into our SG list */ 976 sg = scb->sg_list; 977 while (dm_segs < end_seg) { 978 uint32_t len; 979 980 sg->addr = aic_htole32(dm_segs->ds_addr); 981 len = dm_segs->ds_len 982 | ((dm_segs->ds_addr >> 8) & 0x7F000000); 983 sg->len = aic_htole32(len); 984 sg++; 985 dm_segs++; 986 } 987 988 /* 989 * Note where to find the SG entries in bus space. 990 * We also set the full residual flag which the 991 * sequencer will clear as soon as a data transfer 992 * occurs. 993 */ 994 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID); 995 996 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 997 op = BUS_DMASYNC_PREREAD; 998 else 999 op = BUS_DMASYNC_PREWRITE; 1000 1001 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 1002 1003 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 1004 struct target_data *tdata; 1005 1006 tdata = &scb->hscb->shared_data.tdata; 1007 tdata->target_phases |= DPHASE_PENDING; 1008 /* 1009 * CAM data direction is relative to the initiator. 1010 */ 1011 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1012 tdata->data_phase = P_DATAOUT; 1013 else 1014 tdata->data_phase = P_DATAIN; 1015 1016 /* 1017 * If the transfer is of an odd length and in the 1018 * "in" direction (scsi->HostBus), then it may 1019 * trigger a bug in the 'WideODD' feature of 1020 * non-Ultra2 chips. Force the total data-length 1021 * to be even by adding an extra, 1 byte, SG, 1022 * element. We do this even if we are not currently 1023 * negotiated wide as negotiation could occur before 1024 * this command is executed. 1025 */ 1026 if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0 1027 && (ccb->csio.dxfer_len & 0x1) != 0 1028 && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1029 1030 nsegments++; 1031 if (nsegments > AHC_NSEG) { 1032 1033 aic_set_transaction_status(scb, 1034 CAM_REQ_TOO_BIG); 1035 bus_dmamap_unload(ahc->buffer_dmat, 1036 scb->dmamap); 1037 ahc_lock(ahc, &s); 1038 ahc_free_scb(ahc, scb); 1039 ahc_unlock(ahc, &s); 1040 xpt_done(ccb); 1041 return; 1042 } 1043 sg->addr = aic_htole32(ahc->dma_bug_buf); 1044 sg->len = aic_htole32(1); 1045 sg++; 1046 } 1047 } 1048 sg--; 1049 sg->len |= aic_htole32(AHC_DMA_LAST_SEG); 1050 1051 /* Copy the first SG into the "current" data pointer area */ 1052 scb->hscb->dataptr = scb->sg_list->addr; 1053 scb->hscb->datacnt = scb->sg_list->len; 1054 } else { 1055 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL); 1056 scb->hscb->dataptr = 0; 1057 scb->hscb->datacnt = 0; 1058 } 1059 1060 scb->sg_count = nsegments; 1061 1062 ahc_lock(ahc, &s); 1063 1064 /* 1065 * Last time we need to check if this SCB needs to 1066 * be aborted. 1067 */ 1068 if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) { 1069 if (nsegments != 0) 1070 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 1071 ahc_free_scb(ahc, scb); 1072 ahc_unlock(ahc, &s); 1073 xpt_done(ccb); 1074 return; 1075 } 1076 1077 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid), 1078 SCSIID_OUR_ID(scb->hscb->scsiid), 1079 SCSIID_TARGET(ahc, scb->hscb->scsiid), 1080 &tstate); 1081 1082 mask = SCB_GET_TARGET_MASK(ahc, scb); 1083 scb->hscb->scsirate = tinfo->scsirate; 1084 scb->hscb->scsioffset = tinfo->curr.offset; 1085 if ((tstate->ultraenb & mask) != 0) 1086 scb->hscb->control |= ULTRAENB; 1087 1088 if ((tstate->discenable & mask) != 0 1089 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1090 scb->hscb->control |= DISCENB; 1091 1092 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 1093 && (tinfo->goal.width != 0 1094 || tinfo->goal.offset != 0 1095 || tinfo->goal.ppr_options != 0)) { 1096 scb->flags |= SCB_NEGOTIATE; 1097 scb->hscb->control |= MK_MESSAGE; 1098 } else if ((tstate->auto_negotiate & mask) != 0) { 1099 scb->flags |= SCB_AUTO_NEGOTIATE; 1100 scb->hscb->control |= MK_MESSAGE; 1101 } 1102 1103 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); 1104 1105 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1106 1107 /* 1108 * We only allow one untagged transaction 1109 * per target in the initiator role unless 1110 * we are storing a full busy target *lun* 1111 * table in SCB space. 1112 */ 1113 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 1114 && (ahc->flags & AHC_SCB_BTT) == 0) { 1115 struct scb_tailq *untagged_q; 1116 int target_offset; 1117 1118 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 1119 untagged_q = &(ahc->untagged_queues[target_offset]); 1120 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); 1121 scb->flags |= SCB_UNTAGGEDQ; 1122 if (TAILQ_FIRST(untagged_q) != scb) { 1123 ahc_unlock(ahc, &s); 1124 return; 1125 } 1126 } 1127 scb->flags |= SCB_ACTIVE; 1128 1129 /* 1130 * Timers are disabled while recovery is in progress. 1131 */ 1132 aic_scb_timer_start(scb); 1133 1134 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) { 1135 /* Define a mapping from our tag to the SCB. */ 1136 ahc->scb_data->scbindex[scb->hscb->tag] = scb; 1137 ahc_pause(ahc); 1138 if ((ahc->flags & AHC_PAGESCBS) == 0) 1139 ahc_outb(ahc, SCBPTR, scb->hscb->tag); 1140 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag); 1141 ahc_unpause(ahc); 1142 } else { 1143 ahc_queue_scb(ahc, scb); 1144 } 1145 1146 ahc_unlock(ahc, &s); 1147} 1148 1149static void 1150ahc_poll(struct cam_sim *sim) 1151{ 1152 struct ahc_softc *ahc; 1153 1154 ahc = (struct ahc_softc *)cam_sim_softc(sim); 1155 ahc_intr(ahc); 1156} 1157 1158static void 1159ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 1160 struct ccb_scsiio *csio, struct scb *scb) 1161{ 1162 struct hardware_scb *hscb; 1163 struct ccb_hdr *ccb_h; 1164 1165 hscb = scb->hscb; 1166 ccb_h = &csio->ccb_h; 1167 1168 csio->resid = 0; 1169 csio->sense_resid = 0; 1170 if (ccb_h->func_code == XPT_SCSI_IO) { 1171 hscb->cdb_len = csio->cdb_len; 1172 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) { 1173 1174 if (hscb->cdb_len > sizeof(hscb->cdb32) 1175 || (ccb_h->flags & CAM_CDB_PHYS) != 0) { 1176 u_long s; 1177 1178 aic_set_transaction_status(scb, 1179 CAM_REQ_INVALID); 1180 ahc_lock(ahc, &s); 1181 ahc_free_scb(ahc, scb); 1182 ahc_unlock(ahc, &s); 1183 xpt_done((union ccb *)csio); 1184 return; 1185 } 1186 if (hscb->cdb_len > 12) { 1187 memcpy(hscb->cdb32, 1188 csio->cdb_io.cdb_ptr, 1189 hscb->cdb_len); 1190 scb->flags |= SCB_CDB32_PTR; 1191 } else { 1192 memcpy(hscb->shared_data.cdb, 1193 csio->cdb_io.cdb_ptr, 1194 hscb->cdb_len); 1195 } 1196 } else { 1197 if (hscb->cdb_len > 12) { 1198 memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes, 1199 hscb->cdb_len); 1200 scb->flags |= SCB_CDB32_PTR; 1201 } else { 1202 memcpy(hscb->shared_data.cdb, 1203 csio->cdb_io.cdb_bytes, 1204 hscb->cdb_len); 1205 } 1206 } 1207 } 1208 1209 /* Only use S/G if there is a transfer */ 1210 if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1211 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 1212 /* We've been given a pointer to a single buffer */ 1213 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 1214 int s; 1215 int error; 1216 1217 s = splsoftvm(); 1218 error = bus_dmamap_load(ahc->buffer_dmat, 1219 scb->dmamap, 1220 csio->data_ptr, 1221 csio->dxfer_len, 1222 ahc_execute_scb, 1223 scb, /*flags*/0); 1224 if (error == EINPROGRESS) { 1225 /* 1226 * So as to maintain ordering, 1227 * freeze the controller queue 1228 * until our mapping is 1229 * returned. 1230 */ 1231 xpt_freeze_simq(sim, 1232 /*count*/1); 1233 scb->io_ctx->ccb_h.status |= 1234 CAM_RELEASE_SIMQ; 1235 } 1236 splx(s); 1237 } else { 1238 struct bus_dma_segment seg; 1239 1240 /* Pointer to physical buffer */ 1241 if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE) 1242 panic("ahc_setup_data - Transfer size " 1243 "larger than can device max"); 1244 1245 seg.ds_addr = 1246 (bus_addr_t)(vm_offset_t)csio->data_ptr; 1247 seg.ds_len = csio->dxfer_len; 1248 ahc_execute_scb(scb, &seg, 1, 0); 1249 } 1250 } else { 1251 struct bus_dma_segment *segs; 1252 1253 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) 1254 panic("ahc_setup_data - Physical segment " 1255 "pointers unsupported"); 1256 1257 if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) 1258 panic("ahc_setup_data - Virtual segment " 1259 "addresses unsupported"); 1260 1261 /* Just use the segments provided */ 1262 segs = (struct bus_dma_segment *)csio->data_ptr; 1263 ahc_execute_scb(scb, segs, csio->sglist_cnt, 0); 1264 } 1265 } else { 1266 ahc_execute_scb(scb, NULL, 0, 0); 1267 } 1268} 1269 1270static void 1271ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) 1272{ 1273 union ccb *abort_ccb; 1274 1275 abort_ccb = ccb->cab.abort_ccb; 1276 switch (abort_ccb->ccb_h.func_code) { 1277 case XPT_ACCEPT_TARGET_IO: 1278 case XPT_IMMED_NOTIFY: 1279 case XPT_CONT_TARGET_IO: 1280 { 1281 struct ahc_tmode_tstate *tstate; 1282 struct ahc_tmode_lstate *lstate; 1283 struct ccb_hdr_slist *list; 1284 cam_status status; 1285 1286 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate, 1287 &lstate, TRUE); 1288 1289 if (status != CAM_REQ_CMP) { 1290 ccb->ccb_h.status = status; 1291 break; 1292 } 1293 1294 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 1295 list = &lstate->accept_tios; 1296 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) 1297 list = &lstate->immed_notifies; 1298 else 1299 list = NULL; 1300 1301 if (list != NULL) { 1302 struct ccb_hdr *curelm; 1303 int found; 1304 1305 curelm = SLIST_FIRST(list); 1306 found = 0; 1307 if (curelm == &abort_ccb->ccb_h) { 1308 found = 1; 1309 SLIST_REMOVE_HEAD(list, sim_links.sle); 1310 } else { 1311 while(curelm != NULL) { 1312 struct ccb_hdr *nextelm; 1313 1314 nextelm = 1315 SLIST_NEXT(curelm, sim_links.sle); 1316 1317 if (nextelm == &abort_ccb->ccb_h) { 1318 found = 1; 1319 SLIST_NEXT(curelm, 1320 sim_links.sle) = 1321 SLIST_NEXT(nextelm, 1322 sim_links.sle); 1323 break; 1324 } 1325 curelm = nextelm; 1326 } 1327 } 1328 1329 if (found) { 1330 abort_ccb->ccb_h.status = CAM_REQ_ABORTED; 1331 xpt_done(abort_ccb); 1332 ccb->ccb_h.status = CAM_REQ_CMP; 1333 } else { 1334 xpt_print_path(abort_ccb->ccb_h.path); 1335 printf("Not found\n"); 1336 ccb->ccb_h.status = CAM_PATH_INVALID; 1337 } 1338 break; 1339 } 1340 /* FALLTHROUGH */ 1341 } 1342 case XPT_SCSI_IO: 1343 /* XXX Fully implement the hard ones */ 1344 ccb->ccb_h.status = CAM_UA_ABORT; 1345 break; 1346 default: 1347 ccb->ccb_h.status = CAM_REQ_INVALID; 1348 break; 1349 } 1350 xpt_done(ccb); 1351} 1352 1353void 1354ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, 1355 u_int lun, ac_code code, void *opt_arg) 1356{ 1357 struct ccb_trans_settings cts; 1358 struct cam_path *path; 1359 void *arg; 1360 int error; 1361 1362 arg = NULL; 1363 error = ahc_create_path(ahc, channel, target, lun, &path); 1364 1365 if (error != CAM_REQ_CMP) 1366 return; 1367 1368 switch (code) { 1369 case AC_TRANSFER_NEG: 1370 { 1371 struct ccb_trans_settings_scsi *scsi; 1372 1373 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1374 scsi = &cts.proto_specific.scsi; 1375 cts.ccb_h.path = path; 1376 cts.ccb_h.target_id = target; 1377 cts.ccb_h.target_lun = lun; 1378 ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id 1379 : ahc->our_id_b, 1380 channel, &cts); 1381 arg = &cts; 1382 scsi->valid &= ~CTS_SCSI_VALID_TQ; 1383 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1384 if (opt_arg == NULL) 1385 break; 1386 if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED) 1387 scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB; 1388 scsi->valid |= CTS_SCSI_VALID_TQ; 1389 break; 1390 } 1391 case AC_SENT_BDR: 1392 case AC_BUS_RESET: 1393 break; 1394 default: 1395 panic("ahc_send_async: Unexpected async event"); 1396 } 1397 xpt_async(code, path, arg); 1398 xpt_free_path(path); 1399} 1400 1401void 1402ahc_platform_set_tags(struct ahc_softc *ahc, 1403 struct ahc_devinfo *devinfo, int enable) 1404{ 1405} 1406 1407int 1408ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) 1409{ 1410 ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF, 1411 M_NOWAIT | M_ZERO); 1412 if (ahc->platform_data == NULL) 1413 return (ENOMEM); 1414 return (0); 1415} 1416 1417void 1418ahc_platform_free(struct ahc_softc *ahc) 1419{ 1420 struct ahc_platform_data *pdata; 1421 1422 pdata = ahc->platform_data; 1423 if (pdata != NULL) { 1424 if (pdata->regs != NULL) 1425 bus_release_resource(ahc->dev_softc, 1426 pdata->regs_res_type, 1427 pdata->regs_res_id, 1428 pdata->regs); 1429 1430 if (pdata->irq != NULL) 1431 bus_release_resource(ahc->dev_softc, 1432 pdata->irq_res_type, 1433 0, pdata->irq); 1434 1435 if (pdata->sim_b != NULL) { 1436 xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL); 1437 xpt_free_path(pdata->path_b); 1438 xpt_bus_deregister(cam_sim_path(pdata->sim_b)); 1439 cam_sim_free(pdata->sim_b, /*free_devq*/TRUE); 1440 } 1441 if (pdata->sim != NULL) { 1442 xpt_async(AC_LOST_DEVICE, pdata->path, NULL); 1443 xpt_free_path(pdata->path); 1444 xpt_bus_deregister(cam_sim_path(pdata->sim)); 1445 cam_sim_free(pdata->sim, /*free_devq*/TRUE); 1446 } 1447 if (pdata->eh != NULL) 1448 EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh); 1449 free(ahc->platform_data, M_DEVBUF); 1450 } 1451} 1452 1453int 1454ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) 1455{ 1456 /* We don't sort softcs under FreeBSD so report equal always */ 1457 return (0); 1458} 1459 1460int 1461ahc_detach(device_t dev) 1462{ 1463 struct ahc_softc *ahc; 1464 u_long l; 1465 u_long s; 1466 1467 ahc_list_lock(&l); 1468 device_printf(dev, "detaching device\n"); 1469 ahc = device_get_softc(dev); 1470 ahc = ahc_find_softc(ahc); 1471 if (ahc == NULL) { 1472 device_printf(dev, "aic7xxx already detached\n"); 1473 ahc_list_unlock(&l); 1474 return (ENOENT); 1475 } 1476 TAILQ_REMOVE(&ahc_tailq, ahc, links); 1477 ahc_list_unlock(&l); 1478 ahc_lock(ahc, &s); 1479 ahc_intr_enable(ahc, FALSE); 1480 bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih); 1481 ahc_unlock(ahc, &s); 1482 ahc_free(ahc); 1483 return (0); 1484} 1485 1486#if 0 1487static void 1488ahc_dump_targcmd(struct target_cmd *cmd) 1489{ 1490 uint8_t *byte; 1491 uint8_t *last_byte; 1492 int i; 1493 1494 byte = &cmd->initiator_channel; 1495 /* Debugging info for received commands */ 1496 last_byte = &cmd[1].initiator_channel; 1497 1498 i = 0; 1499 while (byte < last_byte) { 1500 if (i == 0) 1501 printf("\t"); 1502 printf("%#x", *byte++); 1503 i++; 1504 if (i == 8) { 1505 printf("\n"); 1506 i = 0; 1507 } else { 1508 printf(", "); 1509 } 1510 } 1511} 1512#endif 1513 1514static int 1515ahc_modevent(module_t mod, int type, void *data) 1516{ 1517 /* XXX Deal with busy status on unload. */ 1518 /* XXX Deal with unknown events */ 1519 return 0; 1520} 1521 1522static moduledata_t ahc_mod = { 1523 "ahc", 1524 ahc_modevent, 1525 NULL 1526}; 1527 1528DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1529MODULE_DEPEND(ahc, cam, 1, 1, 1); 1530MODULE_VERSION(ahc, 1);
| 232 AHC_MAX_QUEUE, devq); 233 234 if (sim2 == NULL) { 235 printf("ahc_attach: Unable to attach second " 236 "bus due to resource shortage"); 237 goto fail; 238 } 239 240 if (xpt_bus_register(sim2, bus_id2) != CAM_SUCCESS) { 241 printf("ahc_attach: Unable to attach second " 242 "bus due to resource shortage"); 243 /* 244 * We do not want to destroy the device queue 245 * because the first bus is using it. 246 */ 247 cam_sim_free(sim2, /*free_devq*/FALSE); 248 goto fail; 249 } 250 251 if (xpt_create_path(&path2, /*periph*/NULL, 252 cam_sim_path(sim2), 253 CAM_TARGET_WILDCARD, 254 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 255 xpt_bus_deregister(cam_sim_path(sim2)); 256 cam_sim_free(sim2, /*free_devq*/FALSE); 257 sim2 = NULL; 258 goto fail; 259 } 260 xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5); 261 csa.ccb_h.func_code = XPT_SASYNC_CB; 262 csa.event_enable = AC_LOST_DEVICE; 263 csa.callback = ahc_async; 264 csa.callback_arg = sim2; 265 xpt_action((union ccb *)&csa); 266 count++; 267 } 268 269fail: 270 if ((ahc->features & AHC_TWIN) != 0 271 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) { 272 ahc->platform_data->sim_b = sim; 273 ahc->platform_data->path_b = path; 274 ahc->platform_data->sim = sim2; 275 ahc->platform_data->path = path2; 276 } else { 277 ahc->platform_data->sim = sim; 278 ahc->platform_data->path = path; 279 ahc->platform_data->sim_b = sim2; 280 ahc->platform_data->path_b = path2; 281 } 282 283 if (count != 0) { 284 /* We have to wait until after any system dumps... */ 285 ahc->platform_data->eh = 286 EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown, 287 ahc, SHUTDOWN_PRI_DEFAULT); 288 ahc_intr_enable(ahc, TRUE); 289 } 290 291 ahc_unlock(ahc, &s); 292 return (count); 293} 294 295/* 296 * Catch an interrupt from the adapter 297 */ 298void 299ahc_platform_intr(void *arg) 300{ 301 struct ahc_softc *ahc; 302 303 ahc = (struct ahc_softc *)arg; 304 ahc_intr(ahc); 305} 306 307/* 308 * We have an scb which has been processed by the 309 * adaptor, now we look to see how the operation 310 * went. 311 */ 312void 313ahc_done(struct ahc_softc *ahc, struct scb *scb) 314{ 315 union ccb *ccb; 316 317 CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE, 318 ("ahc_done - scb %d\n", scb->hscb->tag)); 319 320 ccb = scb->io_ctx; 321 LIST_REMOVE(scb, pending_links); 322 if ((scb->flags & SCB_TIMEDOUT) != 0) 323 LIST_REMOVE(scb, timedout_links); 324 if ((scb->flags & SCB_UNTAGGEDQ) != 0) { 325 struct scb_tailq *untagged_q; 326 int target_offset; 327 328 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 329 untagged_q = &ahc->untagged_queues[target_offset]; 330 TAILQ_REMOVE(untagged_q, scb, links.tqe); 331 scb->flags &= ~SCB_UNTAGGEDQ; 332 ahc_run_untagged_queue(ahc, untagged_q); 333 } 334 335 untimeout(ahc_platform_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch); 336 337 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 338 bus_dmasync_op_t op; 339 340 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 341 op = BUS_DMASYNC_POSTREAD; 342 else 343 op = BUS_DMASYNC_POSTWRITE; 344 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 345 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 346 } 347 348 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 349 struct cam_path *ccb_path; 350 351 /* 352 * If we have finally disconnected, clean up our 353 * pending device state. 354 * XXX - There may be error states that cause where 355 * we will remain connected. 356 */ 357 ccb_path = ccb->ccb_h.path; 358 if (ahc->pending_device != NULL 359 && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) { 360 361 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 362 ahc->pending_device = NULL; 363 } else { 364 if (bootverbose) { 365 xpt_print_path(ccb->ccb_h.path); 366 printf("Still connected\n"); 367 } 368 aic_freeze_ccb(ccb); 369 } 370 } 371 372 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) 373 ccb->ccb_h.status |= CAM_REQ_CMP; 374 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 375 ahc_free_scb(ahc, scb); 376 xpt_done(ccb); 377 return; 378 } 379 380 /* 381 * If the recovery SCB completes, we have to be 382 * out of our timeout. 383 */ 384 if ((scb->flags & SCB_RECOVERY_SCB) != 0) { 385 struct scb *list_scb; 386 387 ahc->scb_data->recovery_scbs--; 388 389 if (aic_get_transaction_status(scb) == CAM_BDR_SENT 390 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED) 391 aic_set_transaction_status(scb, CAM_CMD_TIMEOUT); 392 393 if (ahc->scb_data->recovery_scbs == 0) { 394 /* 395 * All recovery actions have completed successfully, 396 * so reinstate the timeouts for all other pending 397 * commands. 398 */ 399 LIST_FOREACH(list_scb, &ahc->pending_scbs, 400 pending_links) { 401 402 aic_scb_timer_reset(list_scb, 403 aic_get_timeout(scb)); 404 } 405 406 ahc_print_path(ahc, scb); 407 printf("no longer in timeout, status = %x\n", 408 ccb->ccb_h.status); 409 } 410 } 411 412 /* Don't clobber any existing error state */ 413 if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) { 414 ccb->ccb_h.status |= CAM_REQ_CMP; 415 } else if ((scb->flags & SCB_SENSE) != 0) { 416 /* 417 * We performed autosense retrieval. 418 * 419 * Zero any sense not transferred by the 420 * device. The SCSI spec mandates that any 421 * untransfered data should be assumed to be 422 * zero. Complete the 'bounce' of sense information 423 * through buffers accessible via bus-space by 424 * copying it into the clients csio. 425 */ 426 memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); 427 memcpy(&ccb->csio.sense_data, 428 ahc_get_sense_buf(ahc, scb), 429 (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK) 430 - ccb->csio.sense_resid); 431 scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID; 432 } 433 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 434 ahc_free_scb(ahc, scb); 435 xpt_done(ccb); 436} 437 438static void 439ahc_action(struct cam_sim *sim, union ccb *ccb) 440{ 441 struct ahc_softc *ahc; 442 struct ahc_tmode_lstate *lstate; 443 u_int target_id; 444 u_int our_id; 445 long s; 446 447 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n")); 448 449 ahc = (struct ahc_softc *)cam_sim_softc(sim); 450 451 target_id = ccb->ccb_h.target_id; 452 our_id = SIM_SCSI_ID(ahc, sim); 453 454 switch (ccb->ccb_h.func_code) { 455 /* Common cases first */ 456 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 457 case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/ 458 { 459 struct ahc_tmode_tstate *tstate; 460 cam_status status; 461 462 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 463 &lstate, TRUE); 464 465 if (status != CAM_REQ_CMP) { 466 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 467 /* Response from the black hole device */ 468 tstate = NULL; 469 lstate = ahc->black_hole; 470 } else { 471 ccb->ccb_h.status = status; 472 xpt_done(ccb); 473 break; 474 } 475 } 476 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 477 478 ahc_lock(ahc, &s); 479 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 480 sim_links.sle); 481 ccb->ccb_h.status = CAM_REQ_INPROG; 482 if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0) 483 ahc_run_tqinfifo(ahc, /*paused*/FALSE); 484 ahc_unlock(ahc, &s); 485 break; 486 } 487 488 /* 489 * The target_id represents the target we attempt to 490 * select. In target mode, this is the initiator of 491 * the original command. 492 */ 493 our_id = target_id; 494 target_id = ccb->csio.init_id; 495 /* FALLTHROUGH */ 496 } 497 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 498 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 499 { 500 struct scb *scb; 501 struct hardware_scb *hscb; 502 503 if ((ahc->flags & AHC_INITIATORROLE) == 0 504 && (ccb->ccb_h.func_code == XPT_SCSI_IO 505 || ccb->ccb_h.func_code == XPT_RESET_DEV)) { 506 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 507 xpt_done(ccb); 508 return; 509 } 510 511 /* 512 * get an scb to use. 513 */ 514 ahc_lock(ahc, &s); 515 if ((scb = ahc_get_scb(ahc)) == NULL) { 516 517 xpt_freeze_simq(sim, /*count*/1); 518 ahc->flags |= AHC_RESOURCE_SHORTAGE; 519 ahc_unlock(ahc, &s); 520 ccb->ccb_h.status = CAM_REQUEUE_REQ; 521 xpt_done(ccb); 522 return; 523 } 524 ahc_unlock(ahc, &s); 525 526 hscb = scb->hscb; 527 528 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, 529 ("start scb(%p)\n", scb)); 530 scb->io_ctx = ccb; 531 /* 532 * So we can find the SCB when an abort is requested 533 */ 534 ccb->ccb_h.ccb_scb_ptr = scb; 535 536 /* 537 * Put all the arguments for the xfer in the scb 538 */ 539 hscb->control = 0; 540 hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id); 541 hscb->lun = ccb->ccb_h.target_lun; 542 if (ccb->ccb_h.func_code == XPT_RESET_DEV) { 543 hscb->cdb_len = 0; 544 scb->flags |= SCB_DEVICE_RESET; 545 hscb->control |= MK_MESSAGE; 546 ahc_execute_scb(scb, NULL, 0, 0); 547 } else { 548 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 549 struct target_data *tdata; 550 551 tdata = &hscb->shared_data.tdata; 552 if (ahc->pending_device == lstate) 553 scb->flags |= SCB_TARGET_IMMEDIATE; 554 hscb->control |= TARGET_SCB; 555 scb->flags |= SCB_TARGET_SCB; 556 tdata->target_phases = 0; 557 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 558 tdata->target_phases |= SPHASE_PENDING; 559 tdata->scsi_status = 560 ccb->csio.scsi_status; 561 } 562 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 563 tdata->target_phases |= NO_DISCONNECT; 564 565 tdata->initiator_tag = ccb->csio.tag_id; 566 } 567 if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) 568 hscb->control |= ccb->csio.tag_action; 569 570 ahc_setup_data(ahc, sim, &ccb->csio, scb); 571 } 572 break; 573 } 574 case XPT_NOTIFY_ACK: 575 case XPT_IMMED_NOTIFY: 576 { 577 struct ahc_tmode_tstate *tstate; 578 struct ahc_tmode_lstate *lstate; 579 cam_status status; 580 581 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 582 &lstate, TRUE); 583 584 if (status != CAM_REQ_CMP) { 585 ccb->ccb_h.status = status; 586 xpt_done(ccb); 587 break; 588 } 589 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 590 sim_links.sle); 591 ccb->ccb_h.status = CAM_REQ_INPROG; 592 ahc_send_lstate_events(ahc, lstate); 593 break; 594 } 595 case XPT_EN_LUN: /* Enable LUN as a target */ 596 ahc_handle_en_lun(ahc, sim, ccb); 597 xpt_done(ccb); 598 break; 599 case XPT_ABORT: /* Abort the specified CCB */ 600 { 601 ahc_abort_ccb(ahc, sim, ccb); 602 break; 603 } 604 case XPT_SET_TRAN_SETTINGS: 605 { 606 struct ahc_devinfo devinfo; 607 struct ccb_trans_settings *cts; 608 struct ccb_trans_settings_scsi *scsi; 609 struct ccb_trans_settings_spi *spi; 610 struct ahc_initiator_tinfo *tinfo; 611 struct ahc_tmode_tstate *tstate; 612 uint16_t *discenable; 613 uint16_t *tagenable; 614 u_int update_type; 615 616 cts = &ccb->cts; 617 scsi = &cts->proto_specific.scsi; 618 spi = &cts->xport_specific.spi; 619 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 620 cts->ccb_h.target_id, 621 cts->ccb_h.target_lun, 622 SIM_CHANNEL(ahc, sim), 623 ROLE_UNKNOWN); 624 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel, 625 devinfo.our_scsiid, 626 devinfo.target, &tstate); 627 update_type = 0; 628 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { 629 update_type |= AHC_TRANS_GOAL; 630 discenable = &tstate->discenable; 631 tagenable = &tstate->tagenable; 632 tinfo->curr.protocol_version = 633 cts->protocol_version; 634 tinfo->curr.transport_version = 635 cts->transport_version; 636 tinfo->goal.protocol_version = 637 cts->protocol_version; 638 tinfo->goal.transport_version = 639 cts->transport_version; 640 } else if (cts->type == CTS_TYPE_USER_SETTINGS) { 641 update_type |= AHC_TRANS_USER; 642 discenable = &ahc->user_discenable; 643 tagenable = &ahc->user_tagenable; 644 tinfo->user.protocol_version = 645 cts->protocol_version; 646 tinfo->user.transport_version = 647 cts->transport_version; 648 } else { 649 ccb->ccb_h.status = CAM_REQ_INVALID; 650 xpt_done(ccb); 651 break; 652 } 653 654 ahc_lock(ahc, &s); 655 656 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 657 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 658 *discenable |= devinfo.target_mask; 659 else 660 *discenable &= ~devinfo.target_mask; 661 } 662 663 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 664 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 665 *tagenable |= devinfo.target_mask; 666 else 667 *tagenable &= ~devinfo.target_mask; 668 } 669 670 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 671 ahc_validate_width(ahc, /*tinfo limit*/NULL, 672 &spi->bus_width, ROLE_UNKNOWN); 673 ahc_set_width(ahc, &devinfo, spi->bus_width, 674 update_type, /*paused*/FALSE); 675 } 676 677 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) { 678 if (update_type == AHC_TRANS_USER) 679 spi->ppr_options = tinfo->user.ppr_options; 680 else 681 spi->ppr_options = tinfo->goal.ppr_options; 682 } 683 684 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) { 685 if (update_type == AHC_TRANS_USER) 686 spi->sync_offset = tinfo->user.offset; 687 else 688 spi->sync_offset = tinfo->goal.offset; 689 } 690 691 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) { 692 if (update_type == AHC_TRANS_USER) 693 spi->sync_period = tinfo->user.period; 694 else 695 spi->sync_period = tinfo->goal.period; 696 } 697 698 if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) 699 || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { 700 struct ahc_syncrate *syncrate; 701 u_int maxsync; 702 703 if ((ahc->features & AHC_ULTRA2) != 0) 704 maxsync = AHC_SYNCRATE_DT; 705 else if ((ahc->features & AHC_ULTRA) != 0) 706 maxsync = AHC_SYNCRATE_ULTRA; 707 else 708 maxsync = AHC_SYNCRATE_FAST; 709 710 if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT) 711 spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ; 712 713 syncrate = ahc_find_syncrate(ahc, &spi->sync_period, 714 &spi->ppr_options, 715 maxsync); 716 ahc_validate_offset(ahc, /*tinfo limit*/NULL, 717 syncrate, &spi->sync_offset, 718 spi->bus_width, ROLE_UNKNOWN); 719 720 /* We use a period of 0 to represent async */ 721 if (spi->sync_offset == 0) { 722 spi->sync_period = 0; 723 spi->ppr_options = 0; 724 } 725 726 ahc_set_syncrate(ahc, &devinfo, syncrate, 727 spi->sync_period, spi->sync_offset, 728 spi->ppr_options, update_type, 729 /*paused*/FALSE); 730 } 731 ahc_unlock(ahc, &s); 732 ccb->ccb_h.status = CAM_REQ_CMP; 733 xpt_done(ccb); 734 break; 735 } 736 case XPT_GET_TRAN_SETTINGS: 737 /* Get default/user set transfer settings for the target */ 738 { 739 740 ahc_lock(ahc, &s); 741 ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim), 742 SIM_CHANNEL(ahc, sim), &ccb->cts); 743 ahc_unlock(ahc, &s); 744 xpt_done(ccb); 745 break; 746 } 747 case XPT_CALC_GEOMETRY: 748 { 749 int extended; 750 751 extended = SIM_IS_SCSIBUS_B(ahc, sim) 752 ? ahc->flags & AHC_EXTENDED_TRANS_B 753 : ahc->flags & AHC_EXTENDED_TRANS_A; 754 aic_calc_geometry(&ccb->ccg, extended); 755 xpt_done(ccb); 756 break; 757 } 758 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 759 { 760 int found; 761 762 ahc_lock(ahc, &s); 763 found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim), 764 /*initiate reset*/TRUE); 765 ahc_unlock(ahc, &s); 766 if (bootverbose) { 767 xpt_print_path(SIM_PATH(ahc, sim)); 768 printf("SCSI bus reset delivered. " 769 "%d SCBs aborted.\n", found); 770 } 771 ccb->ccb_h.status = CAM_REQ_CMP; 772 xpt_done(ccb); 773 break; 774 } 775 case XPT_TERM_IO: /* Terminate the I/O process */ 776 /* XXX Implement */ 777 ccb->ccb_h.status = CAM_REQ_INVALID; 778 xpt_done(ccb); 779 break; 780 case XPT_PATH_INQ: /* Path routing inquiry */ 781 { 782 struct ccb_pathinq *cpi = &ccb->cpi; 783 784 cpi->version_num = 1; /* XXX??? */ 785 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 786 if ((ahc->features & AHC_WIDE) != 0) 787 cpi->hba_inquiry |= PI_WIDE_16; 788 if ((ahc->features & AHC_TARGETMODE) != 0) { 789 cpi->target_sprt = PIT_PROCESSOR 790 | PIT_DISCONNECT 791 | PIT_TERM_IO; 792 } else { 793 cpi->target_sprt = 0; 794 } 795 cpi->hba_misc = 0; 796 cpi->hba_eng_cnt = 0; 797 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7; 798 cpi->max_lun = AHC_NUM_LUNS - 1; 799 if (SIM_IS_SCSIBUS_B(ahc, sim)) { 800 cpi->initiator_id = ahc->our_id_b; 801 if ((ahc->flags & AHC_RESET_BUS_B) == 0) 802 cpi->hba_misc |= PIM_NOBUSRESET; 803 } else { 804 cpi->initiator_id = ahc->our_id; 805 if ((ahc->flags & AHC_RESET_BUS_A) == 0) 806 cpi->hba_misc |= PIM_NOBUSRESET; 807 } 808 cpi->bus_id = cam_sim_bus(sim); 809 cpi->base_transfer_speed = 3300; 810 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 811 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 812 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 813 cpi->unit_number = cam_sim_unit(sim); 814 cpi->protocol = PROTO_SCSI; 815 cpi->protocol_version = SCSI_REV_2; 816 cpi->transport = XPORT_SPI; 817 cpi->transport_version = 2; 818 cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST; 819 if ((ahc->features & AHC_DT) != 0) { 820 cpi->transport_version = 3; 821 cpi->xport_specific.spi.ppr_options = 822 SID_SPI_CLOCK_DT_ST; 823 } 824 cpi->ccb_h.status = CAM_REQ_CMP; 825 xpt_done(ccb); 826 break; 827 } 828 default: 829 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 830 xpt_done(ccb); 831 break; 832 } 833} 834 835static void 836ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel, 837 struct ccb_trans_settings *cts) 838{ 839 struct ahc_devinfo devinfo; 840 struct ccb_trans_settings_scsi *scsi; 841 struct ccb_trans_settings_spi *spi; 842 struct ahc_initiator_tinfo *targ_info; 843 struct ahc_tmode_tstate *tstate; 844 struct ahc_transinfo *tinfo; 845 846 scsi = &cts->proto_specific.scsi; 847 spi = &cts->xport_specific.spi; 848 ahc_compile_devinfo(&devinfo, our_id, 849 cts->ccb_h.target_id, 850 cts->ccb_h.target_lun, 851 channel, ROLE_UNKNOWN); 852 targ_info = ahc_fetch_transinfo(ahc, devinfo.channel, 853 devinfo.our_scsiid, 854 devinfo.target, &tstate); 855 856 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) 857 tinfo = &targ_info->curr; 858 else 859 tinfo = &targ_info->user; 860 861 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 862 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 863 if (cts->type == CTS_TYPE_USER_SETTINGS) { 864 if ((ahc->user_discenable & devinfo.target_mask) != 0) 865 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 866 867 if ((ahc->user_tagenable & devinfo.target_mask) != 0) 868 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 869 } else { 870 if ((tstate->discenable & devinfo.target_mask) != 0) 871 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 872 873 if ((tstate->tagenable & devinfo.target_mask) != 0) 874 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 875 } 876 cts->protocol_version = tinfo->protocol_version; 877 cts->transport_version = tinfo->transport_version; 878 879 spi->sync_period = tinfo->period; 880 spi->sync_offset = tinfo->offset; 881 spi->bus_width = tinfo->width; 882 spi->ppr_options = tinfo->ppr_options; 883 884 cts->protocol = PROTO_SCSI; 885 cts->transport = XPORT_SPI; 886 spi->valid = CTS_SPI_VALID_SYNC_RATE 887 | CTS_SPI_VALID_SYNC_OFFSET 888 | CTS_SPI_VALID_BUS_WIDTH 889 | CTS_SPI_VALID_PPR_OPTIONS; 890 891 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 892 scsi->valid = CTS_SCSI_VALID_TQ; 893 spi->valid |= CTS_SPI_VALID_DISC; 894 } else { 895 scsi->valid = 0; 896 } 897 898 cts->ccb_h.status = CAM_REQ_CMP; 899} 900 901static void 902ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 903{ 904 struct ahc_softc *ahc; 905 struct cam_sim *sim; 906 907 sim = (struct cam_sim *)callback_arg; 908 ahc = (struct ahc_softc *)cam_sim_softc(sim); 909 switch (code) { 910 case AC_LOST_DEVICE: 911 { 912 struct ahc_devinfo devinfo; 913 long s; 914 915 ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim), 916 xpt_path_target_id(path), 917 xpt_path_lun_id(path), 918 SIM_CHANNEL(ahc, sim), 919 ROLE_UNKNOWN); 920 921 /* 922 * Revert to async/narrow transfers 923 * for the next device. 924 */ 925 ahc_lock(ahc, &s); 926 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 927 AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE); 928 ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL, 929 /*period*/0, /*offset*/0, /*ppr_options*/0, 930 AHC_TRANS_GOAL|AHC_TRANS_CUR, 931 /*paused*/FALSE); 932 ahc_unlock(ahc, &s); 933 break; 934 } 935 default: 936 break; 937 } 938} 939 940static void 941ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, 942 int error) 943{ 944 struct scb *scb; 945 union ccb *ccb; 946 struct ahc_softc *ahc; 947 struct ahc_initiator_tinfo *tinfo; 948 struct ahc_tmode_tstate *tstate; 949 u_int mask; 950 long s; 951 952 scb = (struct scb *)arg; 953 ccb = scb->io_ctx; 954 ahc = scb->ahc_softc; 955 956 if (error != 0) { 957 if (error == EFBIG) 958 aic_set_transaction_status(scb, CAM_REQ_TOO_BIG); 959 else 960 aic_set_transaction_status(scb, CAM_REQ_CMP_ERR); 961 if (nsegments != 0) 962 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 963 ahc_lock(ahc, &s); 964 ahc_free_scb(ahc, scb); 965 ahc_unlock(ahc, &s); 966 xpt_done(ccb); 967 return; 968 } 969 if (nsegments != 0) { 970 struct ahc_dma_seg *sg; 971 bus_dma_segment_t *end_seg; 972 bus_dmasync_op_t op; 973 974 end_seg = dm_segs + nsegments; 975 976 /* Copy the segments into our SG list */ 977 sg = scb->sg_list; 978 while (dm_segs < end_seg) { 979 uint32_t len; 980 981 sg->addr = aic_htole32(dm_segs->ds_addr); 982 len = dm_segs->ds_len 983 | ((dm_segs->ds_addr >> 8) & 0x7F000000); 984 sg->len = aic_htole32(len); 985 sg++; 986 dm_segs++; 987 } 988 989 /* 990 * Note where to find the SG entries in bus space. 991 * We also set the full residual flag which the 992 * sequencer will clear as soon as a data transfer 993 * occurs. 994 */ 995 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID); 996 997 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 998 op = BUS_DMASYNC_PREREAD; 999 else 1000 op = BUS_DMASYNC_PREWRITE; 1001 1002 bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op); 1003 1004 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 1005 struct target_data *tdata; 1006 1007 tdata = &scb->hscb->shared_data.tdata; 1008 tdata->target_phases |= DPHASE_PENDING; 1009 /* 1010 * CAM data direction is relative to the initiator. 1011 */ 1012 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1013 tdata->data_phase = P_DATAOUT; 1014 else 1015 tdata->data_phase = P_DATAIN; 1016 1017 /* 1018 * If the transfer is of an odd length and in the 1019 * "in" direction (scsi->HostBus), then it may 1020 * trigger a bug in the 'WideODD' feature of 1021 * non-Ultra2 chips. Force the total data-length 1022 * to be even by adding an extra, 1 byte, SG, 1023 * element. We do this even if we are not currently 1024 * negotiated wide as negotiation could occur before 1025 * this command is executed. 1026 */ 1027 if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0 1028 && (ccb->csio.dxfer_len & 0x1) != 0 1029 && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { 1030 1031 nsegments++; 1032 if (nsegments > AHC_NSEG) { 1033 1034 aic_set_transaction_status(scb, 1035 CAM_REQ_TOO_BIG); 1036 bus_dmamap_unload(ahc->buffer_dmat, 1037 scb->dmamap); 1038 ahc_lock(ahc, &s); 1039 ahc_free_scb(ahc, scb); 1040 ahc_unlock(ahc, &s); 1041 xpt_done(ccb); 1042 return; 1043 } 1044 sg->addr = aic_htole32(ahc->dma_bug_buf); 1045 sg->len = aic_htole32(1); 1046 sg++; 1047 } 1048 } 1049 sg--; 1050 sg->len |= aic_htole32(AHC_DMA_LAST_SEG); 1051 1052 /* Copy the first SG into the "current" data pointer area */ 1053 scb->hscb->dataptr = scb->sg_list->addr; 1054 scb->hscb->datacnt = scb->sg_list->len; 1055 } else { 1056 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL); 1057 scb->hscb->dataptr = 0; 1058 scb->hscb->datacnt = 0; 1059 } 1060 1061 scb->sg_count = nsegments; 1062 1063 ahc_lock(ahc, &s); 1064 1065 /* 1066 * Last time we need to check if this SCB needs to 1067 * be aborted. 1068 */ 1069 if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) { 1070 if (nsegments != 0) 1071 bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap); 1072 ahc_free_scb(ahc, scb); 1073 ahc_unlock(ahc, &s); 1074 xpt_done(ccb); 1075 return; 1076 } 1077 1078 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid), 1079 SCSIID_OUR_ID(scb->hscb->scsiid), 1080 SCSIID_TARGET(ahc, scb->hscb->scsiid), 1081 &tstate); 1082 1083 mask = SCB_GET_TARGET_MASK(ahc, scb); 1084 scb->hscb->scsirate = tinfo->scsirate; 1085 scb->hscb->scsioffset = tinfo->curr.offset; 1086 if ((tstate->ultraenb & mask) != 0) 1087 scb->hscb->control |= ULTRAENB; 1088 1089 if ((tstate->discenable & mask) != 0 1090 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1091 scb->hscb->control |= DISCENB; 1092 1093 if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0 1094 && (tinfo->goal.width != 0 1095 || tinfo->goal.offset != 0 1096 || tinfo->goal.ppr_options != 0)) { 1097 scb->flags |= SCB_NEGOTIATE; 1098 scb->hscb->control |= MK_MESSAGE; 1099 } else if ((tstate->auto_negotiate & mask) != 0) { 1100 scb->flags |= SCB_AUTO_NEGOTIATE; 1101 scb->hscb->control |= MK_MESSAGE; 1102 } 1103 1104 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); 1105 1106 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1107 1108 /* 1109 * We only allow one untagged transaction 1110 * per target in the initiator role unless 1111 * we are storing a full busy target *lun* 1112 * table in SCB space. 1113 */ 1114 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 1115 && (ahc->flags & AHC_SCB_BTT) == 0) { 1116 struct scb_tailq *untagged_q; 1117 int target_offset; 1118 1119 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); 1120 untagged_q = &(ahc->untagged_queues[target_offset]); 1121 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); 1122 scb->flags |= SCB_UNTAGGEDQ; 1123 if (TAILQ_FIRST(untagged_q) != scb) { 1124 ahc_unlock(ahc, &s); 1125 return; 1126 } 1127 } 1128 scb->flags |= SCB_ACTIVE; 1129 1130 /* 1131 * Timers are disabled while recovery is in progress. 1132 */ 1133 aic_scb_timer_start(scb); 1134 1135 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) { 1136 /* Define a mapping from our tag to the SCB. */ 1137 ahc->scb_data->scbindex[scb->hscb->tag] = scb; 1138 ahc_pause(ahc); 1139 if ((ahc->flags & AHC_PAGESCBS) == 0) 1140 ahc_outb(ahc, SCBPTR, scb->hscb->tag); 1141 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag); 1142 ahc_unpause(ahc); 1143 } else { 1144 ahc_queue_scb(ahc, scb); 1145 } 1146 1147 ahc_unlock(ahc, &s); 1148} 1149 1150static void 1151ahc_poll(struct cam_sim *sim) 1152{ 1153 struct ahc_softc *ahc; 1154 1155 ahc = (struct ahc_softc *)cam_sim_softc(sim); 1156 ahc_intr(ahc); 1157} 1158 1159static void 1160ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim, 1161 struct ccb_scsiio *csio, struct scb *scb) 1162{ 1163 struct hardware_scb *hscb; 1164 struct ccb_hdr *ccb_h; 1165 1166 hscb = scb->hscb; 1167 ccb_h = &csio->ccb_h; 1168 1169 csio->resid = 0; 1170 csio->sense_resid = 0; 1171 if (ccb_h->func_code == XPT_SCSI_IO) { 1172 hscb->cdb_len = csio->cdb_len; 1173 if ((ccb_h->flags & CAM_CDB_POINTER) != 0) { 1174 1175 if (hscb->cdb_len > sizeof(hscb->cdb32) 1176 || (ccb_h->flags & CAM_CDB_PHYS) != 0) { 1177 u_long s; 1178 1179 aic_set_transaction_status(scb, 1180 CAM_REQ_INVALID); 1181 ahc_lock(ahc, &s); 1182 ahc_free_scb(ahc, scb); 1183 ahc_unlock(ahc, &s); 1184 xpt_done((union ccb *)csio); 1185 return; 1186 } 1187 if (hscb->cdb_len > 12) { 1188 memcpy(hscb->cdb32, 1189 csio->cdb_io.cdb_ptr, 1190 hscb->cdb_len); 1191 scb->flags |= SCB_CDB32_PTR; 1192 } else { 1193 memcpy(hscb->shared_data.cdb, 1194 csio->cdb_io.cdb_ptr, 1195 hscb->cdb_len); 1196 } 1197 } else { 1198 if (hscb->cdb_len > 12) { 1199 memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes, 1200 hscb->cdb_len); 1201 scb->flags |= SCB_CDB32_PTR; 1202 } else { 1203 memcpy(hscb->shared_data.cdb, 1204 csio->cdb_io.cdb_bytes, 1205 hscb->cdb_len); 1206 } 1207 } 1208 } 1209 1210 /* Only use S/G if there is a transfer */ 1211 if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1212 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 1213 /* We've been given a pointer to a single buffer */ 1214 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 1215 int s; 1216 int error; 1217 1218 s = splsoftvm(); 1219 error = bus_dmamap_load(ahc->buffer_dmat, 1220 scb->dmamap, 1221 csio->data_ptr, 1222 csio->dxfer_len, 1223 ahc_execute_scb, 1224 scb, /*flags*/0); 1225 if (error == EINPROGRESS) { 1226 /* 1227 * So as to maintain ordering, 1228 * freeze the controller queue 1229 * until our mapping is 1230 * returned. 1231 */ 1232 xpt_freeze_simq(sim, 1233 /*count*/1); 1234 scb->io_ctx->ccb_h.status |= 1235 CAM_RELEASE_SIMQ; 1236 } 1237 splx(s); 1238 } else { 1239 struct bus_dma_segment seg; 1240 1241 /* Pointer to physical buffer */ 1242 if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE) 1243 panic("ahc_setup_data - Transfer size " 1244 "larger than can device max"); 1245 1246 seg.ds_addr = 1247 (bus_addr_t)(vm_offset_t)csio->data_ptr; 1248 seg.ds_len = csio->dxfer_len; 1249 ahc_execute_scb(scb, &seg, 1, 0); 1250 } 1251 } else { 1252 struct bus_dma_segment *segs; 1253 1254 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) 1255 panic("ahc_setup_data - Physical segment " 1256 "pointers unsupported"); 1257 1258 if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) 1259 panic("ahc_setup_data - Virtual segment " 1260 "addresses unsupported"); 1261 1262 /* Just use the segments provided */ 1263 segs = (struct bus_dma_segment *)csio->data_ptr; 1264 ahc_execute_scb(scb, segs, csio->sglist_cnt, 0); 1265 } 1266 } else { 1267 ahc_execute_scb(scb, NULL, 0, 0); 1268 } 1269} 1270 1271static void 1272ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) 1273{ 1274 union ccb *abort_ccb; 1275 1276 abort_ccb = ccb->cab.abort_ccb; 1277 switch (abort_ccb->ccb_h.func_code) { 1278 case XPT_ACCEPT_TARGET_IO: 1279 case XPT_IMMED_NOTIFY: 1280 case XPT_CONT_TARGET_IO: 1281 { 1282 struct ahc_tmode_tstate *tstate; 1283 struct ahc_tmode_lstate *lstate; 1284 struct ccb_hdr_slist *list; 1285 cam_status status; 1286 1287 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate, 1288 &lstate, TRUE); 1289 1290 if (status != CAM_REQ_CMP) { 1291 ccb->ccb_h.status = status; 1292 break; 1293 } 1294 1295 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 1296 list = &lstate->accept_tios; 1297 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) 1298 list = &lstate->immed_notifies; 1299 else 1300 list = NULL; 1301 1302 if (list != NULL) { 1303 struct ccb_hdr *curelm; 1304 int found; 1305 1306 curelm = SLIST_FIRST(list); 1307 found = 0; 1308 if (curelm == &abort_ccb->ccb_h) { 1309 found = 1; 1310 SLIST_REMOVE_HEAD(list, sim_links.sle); 1311 } else { 1312 while(curelm != NULL) { 1313 struct ccb_hdr *nextelm; 1314 1315 nextelm = 1316 SLIST_NEXT(curelm, sim_links.sle); 1317 1318 if (nextelm == &abort_ccb->ccb_h) { 1319 found = 1; 1320 SLIST_NEXT(curelm, 1321 sim_links.sle) = 1322 SLIST_NEXT(nextelm, 1323 sim_links.sle); 1324 break; 1325 } 1326 curelm = nextelm; 1327 } 1328 } 1329 1330 if (found) { 1331 abort_ccb->ccb_h.status = CAM_REQ_ABORTED; 1332 xpt_done(abort_ccb); 1333 ccb->ccb_h.status = CAM_REQ_CMP; 1334 } else { 1335 xpt_print_path(abort_ccb->ccb_h.path); 1336 printf("Not found\n"); 1337 ccb->ccb_h.status = CAM_PATH_INVALID; 1338 } 1339 break; 1340 } 1341 /* FALLTHROUGH */ 1342 } 1343 case XPT_SCSI_IO: 1344 /* XXX Fully implement the hard ones */ 1345 ccb->ccb_h.status = CAM_UA_ABORT; 1346 break; 1347 default: 1348 ccb->ccb_h.status = CAM_REQ_INVALID; 1349 break; 1350 } 1351 xpt_done(ccb); 1352} 1353 1354void 1355ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, 1356 u_int lun, ac_code code, void *opt_arg) 1357{ 1358 struct ccb_trans_settings cts; 1359 struct cam_path *path; 1360 void *arg; 1361 int error; 1362 1363 arg = NULL; 1364 error = ahc_create_path(ahc, channel, target, lun, &path); 1365 1366 if (error != CAM_REQ_CMP) 1367 return; 1368 1369 switch (code) { 1370 case AC_TRANSFER_NEG: 1371 { 1372 struct ccb_trans_settings_scsi *scsi; 1373 1374 cts.type = CTS_TYPE_CURRENT_SETTINGS; 1375 scsi = &cts.proto_specific.scsi; 1376 cts.ccb_h.path = path; 1377 cts.ccb_h.target_id = target; 1378 cts.ccb_h.target_lun = lun; 1379 ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id 1380 : ahc->our_id_b, 1381 channel, &cts); 1382 arg = &cts; 1383 scsi->valid &= ~CTS_SCSI_VALID_TQ; 1384 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 1385 if (opt_arg == NULL) 1386 break; 1387 if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED) 1388 scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB; 1389 scsi->valid |= CTS_SCSI_VALID_TQ; 1390 break; 1391 } 1392 case AC_SENT_BDR: 1393 case AC_BUS_RESET: 1394 break; 1395 default: 1396 panic("ahc_send_async: Unexpected async event"); 1397 } 1398 xpt_async(code, path, arg); 1399 xpt_free_path(path); 1400} 1401 1402void 1403ahc_platform_set_tags(struct ahc_softc *ahc, 1404 struct ahc_devinfo *devinfo, int enable) 1405{ 1406} 1407 1408int 1409ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) 1410{ 1411 ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF, 1412 M_NOWAIT | M_ZERO); 1413 if (ahc->platform_data == NULL) 1414 return (ENOMEM); 1415 return (0); 1416} 1417 1418void 1419ahc_platform_free(struct ahc_softc *ahc) 1420{ 1421 struct ahc_platform_data *pdata; 1422 1423 pdata = ahc->platform_data; 1424 if (pdata != NULL) { 1425 if (pdata->regs != NULL) 1426 bus_release_resource(ahc->dev_softc, 1427 pdata->regs_res_type, 1428 pdata->regs_res_id, 1429 pdata->regs); 1430 1431 if (pdata->irq != NULL) 1432 bus_release_resource(ahc->dev_softc, 1433 pdata->irq_res_type, 1434 0, pdata->irq); 1435 1436 if (pdata->sim_b != NULL) { 1437 xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL); 1438 xpt_free_path(pdata->path_b); 1439 xpt_bus_deregister(cam_sim_path(pdata->sim_b)); 1440 cam_sim_free(pdata->sim_b, /*free_devq*/TRUE); 1441 } 1442 if (pdata->sim != NULL) { 1443 xpt_async(AC_LOST_DEVICE, pdata->path, NULL); 1444 xpt_free_path(pdata->path); 1445 xpt_bus_deregister(cam_sim_path(pdata->sim)); 1446 cam_sim_free(pdata->sim, /*free_devq*/TRUE); 1447 } 1448 if (pdata->eh != NULL) 1449 EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh); 1450 free(ahc->platform_data, M_DEVBUF); 1451 } 1452} 1453 1454int 1455ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc) 1456{ 1457 /* We don't sort softcs under FreeBSD so report equal always */ 1458 return (0); 1459} 1460 1461int 1462ahc_detach(device_t dev) 1463{ 1464 struct ahc_softc *ahc; 1465 u_long l; 1466 u_long s; 1467 1468 ahc_list_lock(&l); 1469 device_printf(dev, "detaching device\n"); 1470 ahc = device_get_softc(dev); 1471 ahc = ahc_find_softc(ahc); 1472 if (ahc == NULL) { 1473 device_printf(dev, "aic7xxx already detached\n"); 1474 ahc_list_unlock(&l); 1475 return (ENOENT); 1476 } 1477 TAILQ_REMOVE(&ahc_tailq, ahc, links); 1478 ahc_list_unlock(&l); 1479 ahc_lock(ahc, &s); 1480 ahc_intr_enable(ahc, FALSE); 1481 bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih); 1482 ahc_unlock(ahc, &s); 1483 ahc_free(ahc); 1484 return (0); 1485} 1486 1487#if 0 1488static void 1489ahc_dump_targcmd(struct target_cmd *cmd) 1490{ 1491 uint8_t *byte; 1492 uint8_t *last_byte; 1493 int i; 1494 1495 byte = &cmd->initiator_channel; 1496 /* Debugging info for received commands */ 1497 last_byte = &cmd[1].initiator_channel; 1498 1499 i = 0; 1500 while (byte < last_byte) { 1501 if (i == 0) 1502 printf("\t"); 1503 printf("%#x", *byte++); 1504 i++; 1505 if (i == 8) { 1506 printf("\n"); 1507 i = 0; 1508 } else { 1509 printf(", "); 1510 } 1511 } 1512} 1513#endif 1514 1515static int 1516ahc_modevent(module_t mod, int type, void *data) 1517{ 1518 /* XXX Deal with busy status on unload. */ 1519 /* XXX Deal with unknown events */ 1520 return 0; 1521} 1522 1523static moduledata_t ahc_mod = { 1524 "ahc", 1525 ahc_modevent, 1526 NULL 1527}; 1528 1529DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1530MODULE_DEPEND(ahc, cam, 1, 1, 1); 1531MODULE_VERSION(ahc, 1);
|