231 SLIST_INIT(&aha->free_aha_ccbs); 232 LIST_INIT(&aha->pending_ccbs); 233 SLIST_INIT(&aha->sg_maps); 234 aha->unit = unit; 235 aha->tag = tag; 236 aha->bsh = bsh; 237 aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID; 238 aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID; 239 240 if (aha->unit != AHA_TEMP_UNIT) { 241 aha_softcs[unit] = aha; 242 } 243 return (aha); 244} 245 246void 247aha_free(struct aha_softc *aha) 248{ 249 switch (aha->init_level) { 250 default: 251 case 8: 252 { 253 struct sg_map_node *sg_map; 254 255 while ((sg_map = SLIST_FIRST(&aha->sg_maps))!= NULL) { 256 SLIST_REMOVE_HEAD(&aha->sg_maps, links); 257 bus_dmamap_unload(aha->sg_dmat, 258 sg_map->sg_dmamap); 259 bus_dmamem_free(aha->sg_dmat, sg_map->sg_vaddr, 260 sg_map->sg_dmamap); 261 free(sg_map, M_DEVBUF); 262 } 263 bus_dma_tag_destroy(aha->sg_dmat); 264 } 265 case 7: 266 bus_dmamap_unload(aha->ccb_dmat, aha->ccb_dmamap); 267 case 6: 268 bus_dmamap_destroy(aha->ccb_dmat, aha->ccb_dmamap); 269 bus_dmamem_free(aha->ccb_dmat, aha->aha_ccb_array, 270 aha->ccb_dmamap); 271 case 5: 272 bus_dma_tag_destroy(aha->ccb_dmat); 273 case 4: 274 bus_dmamap_unload(aha->mailbox_dmat, aha->mailbox_dmamap); 275 case 3: 276 bus_dmamem_free(aha->mailbox_dmat, aha->in_boxes, 277 aha->mailbox_dmamap); 278 bus_dmamap_destroy(aha->mailbox_dmat, aha->mailbox_dmamap); 279 case 2: 280 bus_dma_tag_destroy(aha->buffer_dmat); 281 case 1: 282 bus_dma_tag_destroy(aha->mailbox_dmat); 283 case 0: 284 } 285 if (aha->unit != AHA_TEMP_UNIT) { 286 aha_softcs[aha->unit] = NULL; 287 } 288 free(aha, M_DEVBUF); 289} 290 291/* 292 * Probe the adapter and verify that the card is an Adaptec. 293 */ 294int 295aha_probe(struct aha_softc* aha) 296{ 297 u_int status; 298 u_int intstat; 299 int error; 300 board_id_data_t board_id; 301 302 /* 303 * See if the three I/O ports look reasonable. 304 * Touch the minimal number of registers in the 305 * failure case. 306 */ 307 status = aha_inb(aha, STATUS_REG); 308 if ((status == 0) 309 || (status & (DIAG_ACTIVE|CMD_REG_BUSY| 310 STATUS_REG_RSVD)) != 0) { 311 PRVERB(("%s: status reg test failed %x\n", aha_name(aha), 312 status)); 313 return (ENXIO); 314 } 315 316 intstat = aha_inb(aha, INTSTAT_REG); 317 if ((intstat & INTSTAT_REG_RSVD) != 0) { 318 PRVERB(("%s: Failed Intstat Reg Test\n", aha_name(aha))); 319 return (ENXIO); 320 } 321 322 /* 323 * Looking good so far. Final test is to reset the 324 * adapter and fetch the board ID and ensure we aren't 325 * looking at a BusLogic. 326 */ 327 if ((error = ahareset(aha, /*hard_reset*/TRUE)) != 0) { 328 PRVERB(("%s: Failed Reset\n", aha_name(aha))); 329 return (ENXIO); 330 } 331 332 /* 333 * Get the board ID. We use this to see if we're dealing with 334 * a buslogic card or a aha card (or clone). 335 */ 336 error = aha_cmd(aha, AOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0, 337 (u_int8_t*)&board_id, sizeof(board_id), 338 DEFAULT_CMD_TIMEOUT); 339 if (error != 0) { 340 PRVERB(("%s: INQUIRE failed %x\n", aha_name(aha), error)); 341 return (ENXIO); 342 } 343 aha->fw_major = board_id.firmware_rev_major; 344 aha->fw_minor = board_id.firmware_rev_minor; 345 aha->boardid = board_id.board_type; 346 347 /* 348 * The Buslogic cards have an id of either 0x41 or 0x42. So 349 * if those come up in the probe, we test the geometry register 350 * of the board. Adaptec boards that are this old will not have 351 * this register, and return 0xff, while buslogic cards will return 352 * something different. 353 * 354 * It appears that for reasons unknow, for the for the 355 * aha-1542B cards, we need to wait a little bit before trying 356 * to read the geometry register. I picked 10ms since we have 357 * reports that a for loop to 1000 did the trick, and this 358 * errs on the side of conservatism. Besides, no one will 359 * notice a 10mS delay here, even the 1542B card users :-) 360 * 361 * Some compatible cards return 0 here. Some cards also 362 * seem to return 0x7f. 363 * 364 * XXX I'm not sure how this will impact other cloned cards 365 * 366 * This really should be replaced with the esetup command, since 367 * that appears to be more reliable. This becomes more and more 368 * true over time as we discover more cards that don't read the 369 * geometry register consistantly. 370 */ 371 if (aha->boardid <= 0x42) { 372 /* Wait 10ms before reading */ 373 DELAY(10000); 374 status = aha_inb(aha, GEOMETRY_REG); 375 if (status != 0xff && status != 0x00 && status != 0x7f) { 376 PRVERB(("%s: Geometry Register test failed 0x%x\n", 377 aha_name(aha), status)); 378 return (ENXIO); 379 } 380 } 381 382 return (0); 383} 384 385/* 386 * Pull the boards setup information and record it in our softc. 387 */ 388int 389aha_fetch_adapter_info(struct aha_softc *aha) 390{ 391 setup_data_t setup_info; 392 config_data_t config_data; 393 u_int8_t length_param; 394 int error; 395 struct aha_extbios extbios; 396 397 switch (aha->boardid) { 398 case BOARD_1540_16HEAD_BIOS: 399 snprintf(aha->model, sizeof(aha->model), "1540 16 head BIOS"); 400 break; 401 case BOARD_1540_64HEAD_BIOS: 402 snprintf(aha->model, sizeof(aha->model), "1540 64 head BIOS"); 403 break; 404 case BOARD_1542: 405 snprintf(aha->model, sizeof(aha->model), "1540/1542 64 head BIOS"); 406 break; 407 case BOARD_1640: 408 snprintf(aha->model, sizeof(aha->model), "1640"); 409 break; 410 case BOARD_1740: 411 snprintf(aha->model, sizeof(aha->model), "1740A/1742A/1744"); 412 break; 413 case BOARD_1542C: 414 snprintf(aha->model, sizeof(aha->model), "1542C"); 415 break; 416 case BOARD_1542CF: 417 snprintf(aha->model, sizeof(aha->model), "1542CF"); 418 break; 419 case BOARD_1542CP: 420 snprintf(aha->model, sizeof(aha->model), "1542CP"); 421 break; 422 default: 423 snprintf(aha->model, sizeof(aha->model), "Unknown"); 424 break; 425 } 426 /* 427 * If we are a new type of 1542 board (anything newer than a 1542C) 428 * then disable the extended bios so that the 429 * mailbox interface is unlocked. 430 * This is also true for the 1542B Version 3.20. First Adaptec 431 * board that supports >1Gb drives. 432 * No need to check the extended bios flags as some of the 433 * extensions that cause us problems are not flagged in that byte. 434 */ 435 if (PROBABLY_NEW_BOARD(aha->boardid) || 436 (aha->boardid == 0x41 437 && aha->fw_major == 0x31 && 438 aha->fw_minor >= 0x34)) { 439 error = aha_cmd(aha, AOP_RETURN_EXT_BIOS_INFO, NULL, 440 /*paramlen*/0, (u_char *)&extbios, sizeof(extbios), 441 DEFAULT_CMD_TIMEOUT); 442 error = aha_cmd(aha, AOP_MBOX_IF_ENABLE, (u_int8_t *)&extbios, 443 /*paramlen*/2, NULL, 0, DEFAULT_CMD_TIMEOUT); 444 } 445 if (aha->boardid < 0x41) 446 printf("%s: Warning: aha-1542A won't likely work.\n", 447 aha_name(aha)); 448 449 aha->max_sg = 17; /* Need >= 17 to do 64k I/O */ 450 aha->diff_bus = 0; 451 aha->extended_lun = 0; 452 aha->extended_trans = 0; 453 aha->max_ccbs = 16; 454 /* Determine Sync/Wide/Disc settings */ 455 length_param = sizeof(setup_info); 456 error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, &length_param, 457 /*paramlen*/1, (u_int8_t*)&setup_info, 458 sizeof(setup_info), DEFAULT_CMD_TIMEOUT); 459 if (error != 0) { 460 printf("%s: aha_fetch_adapter_info - Failed " 461 "Get Setup Info\n", aha_name(aha)); 462 return (error); 463 } 464 if (setup_info.initiate_sync != 0) { 465 aha->sync_permitted = ALL_TARGETS; 466 } 467 aha->disc_permitted = ALL_TARGETS; 468 469 /* We need as many mailboxes as we can have ccbs */ 470 aha->num_boxes = aha->max_ccbs; 471 472 /* Determine our SCSI ID */ 473 474 error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 475 (u_int8_t*)&config_data, sizeof(config_data), 476 DEFAULT_CMD_TIMEOUT); 477 if (error != 0) { 478 printf("%s: aha_fetch_adapter_info - Failed Get Config\n", 479 aha_name(aha)); 480 return (error); 481 } 482 aha->scsi_id = config_data.scsi_id; 483 return (0); 484} 485 486/* 487 * Start the board, ready for normal operation 488 */ 489int 490aha_init(struct aha_softc* aha) 491{ 492 /* Announce the Adapter */ 493 printf("%s: AHA-%s FW Rev. %c.%c (ID=%x) ", aha_name(aha), 494 aha->model, aha->fw_major, aha->fw_minor, aha->boardid); 495 496 if (aha->diff_bus != 0) 497 printf("Diff "); 498 499 printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", aha->scsi_id, 500 aha->max_ccbs); 501 502 /* 503 * Create our DMA tags. These tags define the kinds of device 504 * accessible memory allocations and memory mappings we will 505 * need to perform during normal operation. 506 * 507 * Unless we need to further restrict the allocation, we rely 508 * on the restrictions of the parent dmat, hence the common 509 * use of MAXADDR and MAXSIZE. 510 */ 511 512 /* DMA tag for mapping buffers into device visible space. */ 513 if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0, 514 /*lowaddr*/BUS_SPACE_MAXADDR, 515 /*highaddr*/BUS_SPACE_MAXADDR, 516 /*filter*/NULL, /*filterarg*/NULL, 517 /*maxsize*/MAXBSIZE, /*nsegments*/AHA_NSEG, 518 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT, 519 /*flags*/BUS_DMA_ALLOCNOW, 520 &aha->buffer_dmat) != 0) { 521 goto error_exit; 522 } 523 524 aha->init_level++; 525 /* DMA tag for our mailboxes */ 526 if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0, 527 /*lowaddr*/BUS_SPACE_MAXADDR, 528 /*highaddr*/BUS_SPACE_MAXADDR, 529 /*filter*/NULL, /*filterarg*/NULL, 530 aha->num_boxes * (sizeof(aha_mbox_in_t) 531 + sizeof(aha_mbox_out_t)), 532 /*nsegments*/1, 533 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT, 534 /*flags*/0, &aha->mailbox_dmat) != 0) { 535 goto error_exit; 536 } 537 538 aha->init_level++; 539 540 /* Allocation for our mailboxes */ 541 if (bus_dmamem_alloc(aha->mailbox_dmat, (void **)&aha->out_boxes, 542 BUS_DMA_NOWAIT, &aha->mailbox_dmamap) != 0) { 543 goto error_exit; 544 } 545 546 aha->init_level++; 547 548 /* And permanently map them */ 549 bus_dmamap_load(aha->mailbox_dmat, aha->mailbox_dmamap, 550 aha->out_boxes, 551 aha->num_boxes * (sizeof(aha_mbox_in_t) 552 + sizeof(aha_mbox_out_t)), 553 ahamapmboxes, aha, /*flags*/0); 554 555 aha->init_level++; 556 557 aha->in_boxes = (aha_mbox_in_t *)&aha->out_boxes[aha->num_boxes]; 558 559 ahainitmboxes(aha); 560 561 /* DMA tag for our ccb structures */ 562 if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0, 563 /*lowaddr*/BUS_SPACE_MAXADDR, 564 /*highaddr*/BUS_SPACE_MAXADDR, 565 /*filter*/NULL, /*filterarg*/NULL, 566 aha->max_ccbs * sizeof(struct aha_ccb), 567 /*nsegments*/1, 568 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT, 569 /*flags*/0, &aha->ccb_dmat) != 0) { 570 goto error_exit; 571 } 572 573 aha->init_level++; 574 575 /* Allocation for our ccbs */ 576 if (bus_dmamem_alloc(aha->ccb_dmat, (void **)&aha->aha_ccb_array, 577 BUS_DMA_NOWAIT, &aha->ccb_dmamap) != 0) { 578 goto error_exit; 579 } 580 581 aha->init_level++; 582 583 /* And permanently map them */ 584 bus_dmamap_load(aha->ccb_dmat, aha->ccb_dmamap, 585 aha->aha_ccb_array, 586 aha->max_ccbs * sizeof(struct aha_ccb), 587 ahamapccbs, aha, /*flags*/0); 588 589 aha->init_level++; 590 591 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 592 if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0, 593 /*lowaddr*/BUS_SPACE_MAXADDR, 594 /*highaddr*/BUS_SPACE_MAXADDR, 595 /*filter*/NULL, /*filterarg*/NULL, 596 PAGE_SIZE, /*nsegments*/1, 597 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT, 598 /*flags*/0, &aha->sg_dmat) != 0) { 599 goto error_exit; 600 } 601 602 aha->init_level++; 603 604 /* Perform initial CCB allocation */ 605 bzero(aha->aha_ccb_array, aha->max_ccbs * sizeof(struct aha_ccb)); 606 ahaallocccbs(aha); 607 608 if (aha->num_ccbs == 0) { 609 printf("%s: aha_init - Unable to allocate initial ccbs\n", 610 aha_name(aha)); 611 goto error_exit; 612 } 613 614 /* 615 * Note that we are going and return (to probe) 616 */ 617 return 0; 618 619error_exit: 620 621 return (ENXIO); 622} 623 624int 625aha_attach(struct aha_softc *aha) 626{ 627 int tagged_dev_openings; 628 struct cam_devq *devq; 629 630 /* 631 * We don't do tagged queueing, since the aha cards don't 632 * support it. 633 */ 634 tagged_dev_openings = 0; 635 636 /* 637 * Create the device queue for our SIM. 638 */ 639 devq = cam_simq_alloc(aha->max_ccbs - 1); 640 if (devq == NULL) 641 return (ENOMEM); 642 643 /* 644 * Construct our SIM entry 645 */ 646 aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit, 647 2, tagged_dev_openings, devq); 648 if (aha->sim == NULL) { 649 cam_simq_free(devq); 650 return (ENOMEM); 651 } 652 653 if (xpt_bus_register(aha->sim, 0) != CAM_SUCCESS) { 654 cam_sim_free(aha->sim, /*free_devq*/TRUE); 655 return (ENXIO); 656 } 657 658 if (xpt_create_path(&aha->path, /*periph*/NULL, 659 cam_sim_path(aha->sim), CAM_TARGET_WILDCARD, 660 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 661 xpt_bus_deregister(cam_sim_path(aha->sim)); 662 cam_sim_free(aha->sim, /*free_devq*/TRUE); 663 return (ENXIO); 664 } 665 666 return (0); 667} 668 669char * 670aha_name(struct aha_softc *aha) 671{ 672 static char name[10]; 673 674 snprintf(name, sizeof(name), "aha%d", aha->unit); 675 return (name); 676} 677 678void 679aha_find_probe_range(int ioport, int *port_index, int *max_port_index) 680{ 681 if (ioport > 0) { 682 int i; 683 684 for (i = 0;i < AHA_NUM_ISAPORTS; i++) 685 if (ioport <= aha_isa_ports[i].addr) 686 break; 687 if ((i >= AHA_NUM_ISAPORTS) 688 || (ioport != aha_isa_ports[i].addr)) { 689 printf("\n" 690"aha_isa_probe: Invalid baseport of 0x%x specified.\n" 691"aha_isa_probe: Nearest valid baseport is 0x%x.\n" 692"aha_isa_probe: Failing probe.\n", 693 ioport, 694 (i < AHA_NUM_ISAPORTS) 695 ? aha_isa_ports[i].addr 696 : aha_isa_ports[AHA_NUM_ISAPORTS - 1].addr); 697 *port_index = *max_port_index = -1; 698 return; 699 } 700 *port_index = *max_port_index = aha_isa_ports[i].bio; 701 } else { 702 *port_index = 0; 703 *max_port_index = AHA_NUM_ISAPORTS - 1; 704 } 705} 706 707int 708aha_iop_from_bio(isa_compat_io_t bio_index) 709{ 710 if (bio_index >= 0 && bio_index < AHA_NUM_ISAPORTS) 711 return (aha_board_ports[bio_index]); 712 return (-1); 713} 714 715static void 716ahaallocccbs(struct aha_softc *aha) 717{ 718 struct aha_ccb *next_ccb; 719 struct sg_map_node *sg_map; 720 bus_addr_t physaddr; 721 aha_sg_t *segs; 722 int newcount; 723 int i; 724 725 next_ccb = &aha->aha_ccb_array[aha->num_ccbs]; 726 727 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 728 729 if (sg_map == NULL) 730 return; 731 732 /* Allocate S/G space for the next batch of CCBS */ 733 if (bus_dmamem_alloc(aha->sg_dmat, (void **)&sg_map->sg_vaddr, 734 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 735 free(sg_map, M_DEVBUF); 736 return; 737 } 738 739 SLIST_INSERT_HEAD(&aha->sg_maps, sg_map, links); 740 741 bus_dmamap_load(aha->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 742 PAGE_SIZE, ahamapsgs, aha, /*flags*/0); 743 744 segs = sg_map->sg_vaddr; 745 physaddr = sg_map->sg_physaddr; 746 747 newcount = (PAGE_SIZE / (AHA_NSEG * sizeof(aha_sg_t))); 748 for (i = 0; aha->num_ccbs < aha->max_ccbs && i < newcount; i++) { 749 int error; 750 751 next_ccb->sg_list = segs; 752 next_ccb->sg_list_phys = physaddr; 753 next_ccb->flags = ACCB_FREE; 754 error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0, 755 &next_ccb->dmamap); 756 if (error != 0) 757 break; 758 SLIST_INSERT_HEAD(&aha->free_aha_ccbs, next_ccb, links); 759 segs += AHA_NSEG; 760 physaddr += (AHA_NSEG * sizeof(aha_sg_t)); 761 next_ccb++; 762 aha->num_ccbs++; 763 } 764 765 /* Reserve a CCB for error recovery */ 766 if (aha->recovery_accb == NULL) { 767 aha->recovery_accb = SLIST_FIRST(&aha->free_aha_ccbs); 768 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 769 } 770} 771 772static __inline void 773ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb) 774{ 775 int s; 776 777 s = splcam(); 778 if ((accb->flags & ACCB_ACTIVE) != 0) 779 LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le); 780 if (aha->resource_shortage != 0 781 && (accb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 782 accb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 783 aha->resource_shortage = FALSE; 784 } 785 accb->flags = ACCB_FREE; 786 SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links); 787 aha->active_ccbs--; 788 splx(s); 789} 790 791static struct aha_ccb* 792ahagetccb(struct aha_softc *aha) 793{ 794 struct aha_ccb* accb; 795 int s; 796 797 s = splcam(); 798 if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) { 799 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 800 aha->active_ccbs++; 801 } else if (aha->num_ccbs < aha->max_ccbs) { 802 ahaallocccbs(aha); 803 accb = SLIST_FIRST(&aha->free_aha_ccbs); 804 if (accb == NULL) 805 printf("%s: Can't malloc ACCB\n", aha_name(aha)); 806 else { 807 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links); 808 aha->active_ccbs++; 809 } 810 } 811 splx(s); 812 813 return (accb); 814} 815 816static void 817ahaaction(struct cam_sim *sim, union ccb *ccb) 818{ 819 struct aha_softc *aha; 820 821 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n")); 822 823 aha = (struct aha_softc *)cam_sim_softc(sim); 824 825 switch (ccb->ccb_h.func_code) { 826 /* Common cases first */ 827 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 828 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 829 { 830 struct aha_ccb *accb; 831 struct aha_hccb *hccb; 832 833 /* 834 * get a accb to use. 835 */ 836 if ((accb = ahagetccb(aha)) == NULL) { 837 int s; 838 839 s = splcam(); 840 aha->resource_shortage = TRUE; 841 splx(s); 842 xpt_freeze_simq(aha->sim, /*count*/1); 843 ccb->ccb_h.status = CAM_REQUEUE_REQ; 844 xpt_done(ccb); 845 return; 846 } 847 848 hccb = &accb->hccb; 849 850 /* 851 * So we can find the ACCB when an abort is requested 852 */ 853 accb->ccb = ccb; 854 ccb->ccb_h.ccb_accb_ptr = accb; 855 ccb->ccb_h.ccb_aha_ptr = aha; 856 857 /* 858 * Put all the arguments for the xfer in the accb 859 */ 860 hccb->target = ccb->ccb_h.target_id; 861 hccb->lun = ccb->ccb_h.target_lun; 862 hccb->ahastat = 0; 863 hccb->sdstat = 0; 864 865 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 866 struct ccb_scsiio *csio; 867 struct ccb_hdr *ccbh; 868 869 csio = &ccb->csio; 870 ccbh = &csio->ccb_h; 871 hccb->opcode = aha->ccb_ccb_opcode; 872 hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0; 873 hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0; 874 hccb->cmd_len = csio->cdb_len; 875 if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) { 876 ccb->ccb_h.status = CAM_REQ_INVALID; 877 ahafreeccb(aha, accb); 878 xpt_done(ccb); 879 return; 880 } 881 hccb->sense_len = csio->sense_len; 882 if ((ccbh->flags & CAM_CDB_POINTER) != 0) { 883 if ((ccbh->flags & CAM_CDB_PHYS) == 0) { 884 bcopy(csio->cdb_io.cdb_ptr, 885 hccb->scsi_cdb, hccb->cmd_len); 886 } else { 887 /* I guess I could map it in... */ 888 ccbh->status = CAM_REQ_INVALID; 889 ahafreeccb(aha, accb); 890 xpt_done(ccb); 891 return; 892 } 893 } else { 894 bcopy(csio->cdb_io.cdb_bytes, 895 hccb->scsi_cdb, hccb->cmd_len); 896 } 897 /* 898 * If we have any data to send with this command, 899 * map it into bus space. 900 */ 901 /* Only use S/G if there is a transfer */ 902 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 903 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 904 /* 905 * We've been given a pointer 906 * to a single buffer. 907 */ 908 if ((ccbh->flags & CAM_DATA_PHYS)==0) { 909 int s; 910 int error; 911 912 s = splsoftvm(); 913 error = bus_dmamap_load( 914 aha->buffer_dmat, 915 accb->dmamap, 916 csio->data_ptr, 917 csio->dxfer_len, 918 ahaexecuteccb, 919 accb, 920 /*flags*/0); 921 if (error == EINPROGRESS) { 922 /* 923 * So as to maintain 924 * ordering, freeze the 925 * controller queue 926 * until our mapping is 927 * returned. 928 */ 929 xpt_freeze_simq(aha->sim, 930 1); 931 csio->ccb_h.status |= 932 CAM_RELEASE_SIMQ; 933 } 934 splx(s); 935 } else { 936 struct bus_dma_segment seg; 937 938 /* Pointer to physical buffer */ 939 seg.ds_addr = 940 (bus_addr_t)csio->data_ptr; 941 seg.ds_len = csio->dxfer_len; 942 ahaexecuteccb(accb, &seg, 1, 0); 943 } 944 } else { 945 struct bus_dma_segment *segs; 946 947 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 948 panic("ahaaction - Physical " 949 "segment pointers " 950 "unsupported"); 951 952 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 953 panic("ahaaction - Virtual " 954 "segment addresses " 955 "unsupported"); 956 957 /* Just use the segments provided */ 958 segs = (struct bus_dma_segment *) 959 csio->data_ptr; 960 ahaexecuteccb(accb, segs, 961 csio->sglist_cnt, 0); 962 } 963 } else { 964 ahaexecuteccb(accb, NULL, 0, 0); 965 } 966 } else { 967 hccb->opcode = INITIATOR_BUS_DEV_RESET; 968 /* No data transfer */ 969 hccb->datain = TRUE; 970 hccb->dataout = TRUE; 971 hccb->cmd_len = 0; 972 hccb->sense_len = 0; 973 ahaexecuteccb(accb, NULL, 0, 0); 974 } 975 break; 976 } 977 case XPT_EN_LUN: /* Enable LUN as a target */ 978 case XPT_TARGET_IO: /* Execute target I/O request */ 979 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 980 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 981 case XPT_ABORT: /* Abort the specified CCB */ 982 /* XXX Implement */ 983 ccb->ccb_h.status = CAM_REQ_INVALID; 984 xpt_done(ccb); 985 break; 986 case XPT_SET_TRAN_SETTINGS: 987 { 988 /* XXX Implement */ 989 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 990 xpt_done(ccb); 991 break; 992 } 993 case XPT_GET_TRAN_SETTINGS: 994 /* Get default/user set transfer settings for the target */ 995 { 996 struct ccb_trans_settings *cts; 997 u_int target_mask; 998 999 cts = &ccb->cts; 1000 target_mask = 0x01 << ccb->ccb_h.target_id; 1001 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1002 cts->flags = 0; 1003 if ((aha->disc_permitted & target_mask) != 0) 1004 cts->flags |= CCB_TRANS_DISC_ENB; 1005 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1006 if ((aha->sync_permitted & target_mask) != 0) { 1007 if (aha->boardid >= BOARD_1542CF) 1008 cts->sync_period = 25; 1009 else 1010 cts->sync_period = 50; 1011 } else 1012 cts->sync_period = 0; 1013 1014 if (cts->sync_period != 0) 1015 cts->sync_offset = 15; 1016 1017 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1018 | CCB_TRANS_SYNC_OFFSET_VALID 1019 | CCB_TRANS_BUS_WIDTH_VALID 1020 | CCB_TRANS_DISC_VALID 1021 | CCB_TRANS_TQ_VALID; 1022 } else { 1023 ahafetchtransinfo(aha, cts); 1024 } 1025 1026 ccb->ccb_h.status = CAM_REQ_CMP; 1027 xpt_done(ccb); 1028 break; 1029 } 1030 case XPT_CALC_GEOMETRY: 1031 { 1032 struct ccb_calc_geometry *ccg; 1033 u_int32_t size_mb; 1034 u_int32_t secs_per_cylinder; 1035 1036 ccg = &ccb->ccg; 1037 size_mb = ccg->volume_size 1038 / ((1024L * 1024L) / ccg->block_size); 1039 1040 if (size_mb >= 1024 && (aha->extended_trans != 0)) { 1041 if (size_mb >= 2048) { 1042 ccg->heads = 255; 1043 ccg->secs_per_track = 63; 1044 } else { 1045 ccg->heads = 128; 1046 ccg->secs_per_track = 32; 1047 } 1048 } else { 1049 ccg->heads = 64; 1050 ccg->secs_per_track = 32; 1051 } 1052 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1053 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1054 ccb->ccb_h.status = CAM_REQ_CMP; 1055 xpt_done(ccb); 1056 break; 1057 } 1058 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1059 { 1060 ahareset(aha, /*hardreset*/TRUE); 1061 ccb->ccb_h.status = CAM_REQ_CMP; 1062 xpt_done(ccb); 1063 break; 1064 } 1065 case XPT_TERM_IO: /* Terminate the I/O process */ 1066 /* XXX Implement */ 1067 ccb->ccb_h.status = CAM_REQ_INVALID; 1068 xpt_done(ccb); 1069 break; 1070 case XPT_PATH_INQ: /* Path routing inquiry */ 1071 { 1072 struct ccb_pathinq *cpi = &ccb->cpi; 1073 1074 cpi->version_num = 1; /* XXX??? */ 1075 cpi->hba_inquiry = PI_SDTR_ABLE; 1076 cpi->target_sprt = 0; 1077 cpi->hba_misc = 0; 1078 cpi->hba_eng_cnt = 0; 1079 cpi->max_target = 7; 1080 cpi->max_lun = 7; 1081 cpi->initiator_id = aha->scsi_id; 1082 cpi->bus_id = cam_sim_bus(sim); 1083 cpi->base_transfer_speed = 3300; 1084 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1085 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 1086 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1087 cpi->unit_number = cam_sim_unit(sim); 1088 cpi->ccb_h.status = CAM_REQ_CMP; 1089 xpt_done(ccb); 1090 break; 1091 } 1092 default: 1093 ccb->ccb_h.status = CAM_REQ_INVALID; 1094 xpt_done(ccb); 1095 break; 1096 } 1097} 1098 1099static void 1100ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1101{ 1102 struct aha_ccb *accb; 1103 union ccb *ccb; 1104 struct aha_softc *aha; 1105 int s; 1106 u_int32_t paddr; 1107 1108 accb = (struct aha_ccb *)arg; 1109 ccb = accb->ccb; 1110 aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr; 1111 1112 if (error != 0) { 1113 if (error != EFBIG) 1114 printf("%s: Unexepected error 0x%x returned from " 1115 "bus_dmamap_load\n", aha_name(aha), error); 1116 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 1117 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1118 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 1119 } 1120 ahafreeccb(aha, accb); 1121 xpt_done(ccb); 1122 return; 1123 } 1124 1125 if (nseg != 0) { 1126 aha_sg_t *sg; 1127 bus_dma_segment_t *end_seg; 1128 bus_dmasync_op_t op; 1129 1130 end_seg = dm_segs + nseg; 1131 1132 /* Copy the segments into our SG list */ 1133 sg = accb->sg_list; 1134 while (dm_segs < end_seg) { 1135 ahautoa24(dm_segs->ds_len, sg->len); 1136 ahautoa24(dm_segs->ds_addr, sg->addr); 1137 sg++; 1138 dm_segs++; 1139 } 1140 1141 if (nseg > 1) { 1142 accb->hccb.opcode = aha->ccb_sg_opcode; 1143 ahautoa24((sizeof(aha_sg_t) * nseg), 1144 accb->hccb.data_len); 1145 ahautoa24(accb->sg_list_phys, accb->hccb.data_addr); 1146 } else { 1147 bcopy(accb->sg_list->len, accb->hccb.data_len, 3); 1148 bcopy(accb->sg_list->addr, accb->hccb.data_addr, 3); 1149 } 1150 1151 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1152 op = BUS_DMASYNC_PREREAD; 1153 else 1154 op = BUS_DMASYNC_PREWRITE; 1155 1156 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op); 1157 1158 } else { 1159 accb->hccb.opcode = INITIATOR_CCB; 1160 ahautoa24(0, accb->hccb.data_len); 1161 ahautoa24(0, accb->hccb.data_addr); 1162 } 1163 1164 s = splcam(); 1165 1166 /* 1167 * Last time we need to check if this CCB needs to 1168 * be aborted. 1169 */ 1170 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1171 if (nseg != 0) 1172 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1173 ahafreeccb(aha, accb); 1174 xpt_done(ccb); 1175 splx(s); 1176 return; 1177 } 1178 1179 accb->flags = ACCB_ACTIVE; 1180 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1181 LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le); 1182 1183 ccb->ccb_h.timeout_ch = 1184 timeout(ahatimeout, (caddr_t)accb, 1185 (ccb->ccb_h.timeout * hz) / 1000); 1186 1187 /* Tell the adapter about this command */ 1188 if (aha->cur_outbox->action_code != AMBO_FREE) { 1189 /* 1190 * We should never encounter a busy mailbox. 1191 * If we do, warn the user, and treat it as 1192 * a resource shortage. If the controller is 1193 * hung, one of the pending transactions will 1194 * timeout causing us to start recovery operations. 1195 */ 1196 printf("%s: Encountered busy mailbox with %d out of %d " 1197 "commands active!!!", aha_name(aha), aha->active_ccbs, 1198 aha->max_ccbs); 1199 untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); 1200 if (nseg != 0) 1201 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1202 ahafreeccb(aha, accb); 1203 aha->resource_shortage = TRUE; 1204 xpt_freeze_simq(aha->sim, /*count*/1); 1205 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1206 xpt_done(ccb); 1207 return; 1208 } 1209 paddr = ahaccbvtop(aha, accb); 1210 ahautoa24(paddr, aha->cur_outbox->ccb_addr); 1211 aha->cur_outbox->action_code = AMBO_START; 1212 aha_outb(aha, COMMAND_REG, AOP_START_MBOX); 1213 1214 ahanextoutbox(aha); 1215 splx(s); 1216} 1217 1218void 1219aha_intr(void *arg) 1220{ 1221 struct aha_softc *aha; 1222 u_int intstat; 1223 1224 aha = (struct aha_softc *)arg; 1225 while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) { 1226 if ((intstat & CMD_COMPLETE) != 0) { 1227 aha->latched_status = aha_inb(aha, STATUS_REG); 1228 aha->command_cmp = TRUE; 1229 } 1230 1231 aha_outb(aha, CONTROL_REG, RESET_INTR); 1232 1233 if ((intstat & IMB_LOADED) != 0) { 1234 while (aha->cur_inbox->comp_code != AMBI_FREE) { 1235 u_int32_t paddr; 1236 paddr = aha_a24tou(aha->cur_inbox->ccb_addr); 1237 ahadone(aha, 1238 ahaccbptov(aha, paddr), 1239 aha->cur_inbox->comp_code); 1240 aha->cur_inbox->comp_code = AMBI_FREE; 1241 ahanextinbox(aha); 1242 } 1243 } 1244 1245 if ((intstat & SCSI_BUS_RESET) != 0) { 1246 ahareset(aha, /*hardreset*/FALSE); 1247 } 1248 } 1249} 1250 1251static void 1252ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code) 1253{ 1254 union ccb *ccb; 1255 struct ccb_scsiio *csio; 1256 1257 ccb = accb->ccb; 1258 csio = &accb->ccb->csio; 1259 1260 if ((accb->flags & ACCB_ACTIVE) == 0) { 1261 printf("%s: ahadone - Attempt to free non-active ACCB %p\n", 1262 aha_name(aha), (void *)accb); 1263 return; 1264 } 1265 1266 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1267 bus_dmasync_op_t op; 1268 1269 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1270 op = BUS_DMASYNC_POSTREAD; 1271 else 1272 op = BUS_DMASYNC_POSTWRITE; 1273 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op); 1274 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap); 1275 } 1276 1277 if (accb == aha->recovery_accb) { 1278 /* 1279 * The recovery ACCB does not have a CCB associated 1280 * with it, so short circuit the normal error handling. 1281 * We now traverse our list of pending CCBs and process 1282 * any that were terminated by the recovery CCBs action. 1283 * We also reinstate timeouts for all remaining, pending, 1284 * CCBs. 1285 */ 1286 struct cam_path *path; 1287 struct ccb_hdr *ccb_h; 1288 cam_status error; 1289 1290 /* Notify all clients that a BDR occured */ 1291 error = xpt_create_path(&path, /*periph*/NULL, 1292 cam_sim_path(aha->sim), 1293 accb->hccb.target, 1294 CAM_LUN_WILDCARD); 1295 1296 if (error == CAM_REQ_CMP) 1297 xpt_async(AC_SENT_BDR, path, NULL); 1298 1299 ccb_h = LIST_FIRST(&aha->pending_ccbs); 1300 while (ccb_h != NULL) { 1301 struct aha_ccb *pending_accb; 1302 1303 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1304 if (pending_accb->hccb.target == accb->hccb.target) { 1305 pending_accb->hccb.ahastat = AHASTAT_HA_BDR; 1306 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1307 ahadone(aha, pending_accb, AMBI_ERROR); 1308 } else { 1309 ccb_h->timeout_ch = 1310 timeout(ahatimeout, (caddr_t)pending_accb, 1311 (ccb_h->timeout * hz) / 1000); 1312 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1313 } 1314 } 1315 printf("%s: No longer in timeout\n", aha_name(aha)); 1316 return; 1317 } 1318 1319 untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch); 1320 1321 switch (comp_code) { 1322 case AMBI_FREE: 1323 printf("%s: ahadone - CCB completed with free status!\n", 1324 aha_name(aha)); 1325 break; 1326 case AMBI_NOT_FOUND: 1327 printf("%s: ahadone - CCB Abort failed to find CCB\n", 1328 aha_name(aha)); 1329 break; 1330 case AMBI_ABORT: 1331 case AMBI_ERROR: 1332 /* An error occured */ 1333 if (accb->hccb.opcode < INITIATOR_CCB_WRESID) 1334 csio->resid = 0; 1335 else 1336 csio->resid = aha_a24tou(accb->hccb.data_len); 1337 switch(accb->hccb.ahastat) { 1338 case AHASTAT_DATARUN_ERROR: 1339 { 1340 if (csio->resid <= 0) { 1341 csio->ccb_h.status = CAM_DATA_RUN_ERR; 1342 break; 1343 } 1344 /* FALLTHROUGH */ 1345 } 1346 case AHASTAT_NOERROR: 1347 csio->scsi_status = accb->hccb.sdstat; 1348 csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1349 switch(csio->scsi_status) { 1350 case SCSI_STATUS_CHECK_COND: 1351 case SCSI_STATUS_CMD_TERMINATED: 1352 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 1353 /* 1354 * The aha writes the sense data at different 1355 * offsets based on the scsi cmd len 1356 */ 1357 bcopy((caddr_t) &accb->hccb.scsi_cdb + 1358 accb->hccb.cmd_len, 1359 (caddr_t) &csio->sense_data, 1360 accb->hccb.sense_len); 1361 break; 1362 default: 1363 break; 1364 case SCSI_STATUS_OK: 1365 csio->ccb_h.status = CAM_REQ_CMP; 1366 break; 1367 } 1368 break; 1369 case AHASTAT_SELTIMEOUT: 1370 csio->ccb_h.status = CAM_SEL_TIMEOUT; 1371 break; 1372 case AHASTAT_UNEXPECTED_BUSFREE: 1373 csio->ccb_h.status = CAM_UNEXP_BUSFREE; 1374 break; 1375 case AHASTAT_INVALID_PHASE: 1376 csio->ccb_h.status = CAM_SEQUENCE_FAIL; 1377 break; 1378 case AHASTAT_INVALID_ACTION_CODE: 1379 panic("%s: Inavlid Action code", aha_name(aha)); 1380 break; 1381 case AHASTAT_INVALID_OPCODE: 1382 if (accb->hccb.opcode < INITIATOR_CCB_WRESID) 1383 panic("%s: Invalid CCB Opcode %x hccb = %p", 1384 aha_name(aha), accb->hccb.opcode, 1385 &accb->hccb); 1386 printf("%s: AHA-1540A detected, compensating\n", 1387 aha_name(aha)); 1388 aha->ccb_sg_opcode = INITIATOR_SG_CCB; 1389 aha->ccb_ccb_opcode = INITIATOR_CCB; 1390 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1391 csio->ccb_h.status = CAM_REQUEUE_REQ; 1392 break; 1393 case AHASTAT_LINKED_CCB_LUN_MISMATCH: 1394 /* We don't even support linked commands... */ 1395 panic("%s: Linked CCB Lun Mismatch", aha_name(aha)); 1396 break; 1397 case AHASTAT_INVALID_CCB_OR_SG_PARAM: 1398 panic("%s: Invalid CCB or SG list", aha_name(aha)); 1399 break; 1400 case AHASTAT_HA_SCSI_BUS_RESET: 1401 if ((csio->ccb_h.status & CAM_STATUS_MASK) 1402 != CAM_CMD_TIMEOUT) 1403 csio->ccb_h.status = CAM_SCSI_BUS_RESET; 1404 break; 1405 case AHASTAT_HA_BDR: 1406 if ((accb->flags & ACCB_DEVICE_RESET) == 0) 1407 csio->ccb_h.status = CAM_BDR_SENT; 1408 else 1409 csio->ccb_h.status = CAM_CMD_TIMEOUT; 1410 break; 1411 } 1412 if (csio->ccb_h.status != CAM_REQ_CMP) { 1413 xpt_freeze_devq(csio->ccb_h.path, /*count*/1); 1414 csio->ccb_h.status |= CAM_DEV_QFRZN; 1415 } 1416 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0) 1417 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1418 ahafreeccb(aha, accb); 1419 xpt_done(ccb); 1420 break; 1421 case AMBI_OK: 1422 /* All completed without incident */ 1423 /* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */ 1424 /* I don't think so since it works???? */ 1425 ccb->ccb_h.status |= CAM_REQ_CMP; 1426 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0) 1427 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1428 ahafreeccb(aha, accb); 1429 xpt_done(ccb); 1430 break; 1431 } 1432} 1433 1434static int 1435ahareset(struct aha_softc* aha, int hard_reset) 1436{ 1437 struct ccb_hdr *ccb_h; 1438 u_int status; 1439 u_int timeout; 1440 u_int8_t reset_type; 1441 1442 if (hard_reset != 0) 1443 reset_type = HARD_RESET; 1444 else 1445 reset_type = SOFT_RESET; 1446 aha_outb(aha, CONTROL_REG, reset_type); 1447 1448 /* Wait 5sec. for Diagnostic start */ 1449 timeout = 5 * 10000; 1450 while (--timeout) { 1451 status = aha_inb(aha, STATUS_REG); 1452 if ((status & DIAG_ACTIVE) != 0) 1453 break; 1454 DELAY(100); 1455 } 1456 if (timeout == 0) { 1457 PRVERB(("%s: ahareset - Diagnostic Active failed to " 1458 "assert. status = 0x%x\n", aha_name(aha), 1459 status)); 1460 return (ETIMEDOUT); 1461 } 1462 1463 /* Wait 10sec. for Diagnostic end */ 1464 timeout = 10 * 10000; 1465 while (--timeout) { 1466 status = aha_inb(aha, STATUS_REG); 1467 if ((status & DIAG_ACTIVE) == 0) 1468 break; 1469 DELAY(100); 1470 } 1471 if (timeout == 0) { 1472 panic("%s: ahareset - Diagnostic Active failed to drop. " 1473 "status = 0x%x\n", aha_name(aha), status); 1474 return (ETIMEDOUT); 1475 } 1476 1477 /* Wait for the host adapter to become ready or report a failure */ 1478 timeout = 10000; 1479 while (--timeout) { 1480 status = aha_inb(aha, STATUS_REG); 1481 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0) 1482 break; 1483 DELAY(100); 1484 } 1485 if (timeout == 0) { 1486 printf("%s: ahareset - Host adapter failed to come ready. " 1487 "status = 0x%x\n", aha_name(aha), status); 1488 return (ETIMEDOUT); 1489 } 1490 1491 /* If the diagnostics failed, tell the user */ 1492 if ((status & DIAG_FAIL) != 0 1493 || (status & HA_READY) == 0) { 1494 printf("%s: ahareset - Adapter failed diagnostics\n", 1495 aha_name(aha)); 1496 1497 if ((status & DATAIN_REG_READY) != 0) 1498 printf("%s: ahareset - Host Adapter Error " 1499 "code = 0x%x\n", aha_name(aha), 1500 aha_inb(aha, DATAIN_REG)); 1501 return (ENXIO); 1502 } 1503 1504 /* If we've allocated mailboxes, initialize them */ 1505 if (aha->init_level > 4) 1506 ahainitmboxes(aha); 1507 1508 /* If we've attached to the XPT, tell it about the event */ 1509 if (aha->path != NULL) 1510 xpt_async(AC_BUS_RESET, aha->path, NULL); 1511 1512 /* 1513 * Perform completion processing for all outstanding CCBs. 1514 */ 1515 while ((ccb_h = LIST_FIRST(&aha->pending_ccbs)) != NULL) { 1516 struct aha_ccb *pending_accb; 1517 1518 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1519 pending_accb->hccb.ahastat = AHASTAT_HA_SCSI_BUS_RESET; 1520 ahadone(aha, pending_accb, AMBI_ERROR); 1521 } 1522 1523 return (0); 1524} 1525 1526/* 1527 * Send a command to the adapter. 1528 */ 1529int 1530aha_cmd(struct aha_softc *aha, aha_op_t opcode, u_int8_t *params, 1531 u_int param_len, u_int8_t *reply_data, u_int reply_len, 1532 u_int cmd_timeout) 1533{ 1534 u_int timeout; 1535 u_int status; 1536 u_int saved_status; 1537 u_int intstat; 1538 u_int reply_buf_size; 1539 int s; 1540 int cmd_complete; 1541 int error; 1542 1543 /* No data returned to start */ 1544 reply_buf_size = reply_len; 1545 reply_len = 0; 1546 intstat = 0; 1547 cmd_complete = 0; 1548 saved_status = 0; 1549 error = 0; 1550 1551 /* 1552 * All commands except for the "start mailbox" and the "enable 1553 * outgoing mailbox read interrupt" commands cannot be issued 1554 * while there are pending transactions. Freeze our SIMQ 1555 * and wait for all completions to occur if necessary. 1556 */ 1557 timeout = 100000; 1558 s = splcam(); 1559 while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) { 1560 /* Fire the interrupt handler in case interrupts are blocked */ 1561 aha_intr(aha); 1562 splx(s); 1563 DELAY(100); 1564 s = splcam(); 1565 } 1566 splx(s); 1567 1568 if (timeout == 0) { 1569 printf("%s: aha_cmd: Timeout waiting for adapter idle\n", 1570 aha_name(aha)); 1571 return (ETIMEDOUT); 1572 } 1573 aha->command_cmp = 0; 1574 /* 1575 * Wait up to 10 sec. for the adapter to become 1576 * ready to accept commands. 1577 */ 1578 timeout = 100000; 1579 while (--timeout) { 1580 1581 status = aha_inb(aha, STATUS_REG); 1582 if ((status & HA_READY) != 0 1583 && (status & CMD_REG_BUSY) == 0) 1584 break; 1585 /* 1586 * Throw away any pending data which may be 1587 * left over from earlier commands that we 1588 * timedout on. 1589 */ 1590 if ((status & DATAIN_REG_READY) != 0) 1591 (void)aha_inb(aha, DATAIN_REG); 1592 DELAY(100); 1593 } 1594 if (timeout == 0) { 1595 printf("%s: aha_cmd: Timeout waiting for adapter ready, " 1596 "status = 0x%x\n", aha_name(aha), status); 1597 return (ETIMEDOUT); 1598 } 1599 1600 /* 1601 * Send the opcode followed by any necessary parameter bytes. 1602 */ 1603 aha_outb(aha, COMMAND_REG, opcode); 1604 1605 /* 1606 * Wait for up to 1sec to get the parameter list sent 1607 */ 1608 timeout = 10000; 1609 while (param_len && --timeout) { 1610 DELAY(100); 1611 s = splcam(); 1612 status = aha_inb(aha, STATUS_REG); 1613 intstat = aha_inb(aha, INTSTAT_REG); 1614 splx(s); 1615 1616 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1617 == (INTR_PENDING|CMD_COMPLETE)) { 1618 saved_status = status; 1619 cmd_complete = 1; 1620 break; 1621 } 1622 1623 if (aha->command_cmp != 0) { 1624 saved_status = aha->latched_status; 1625 cmd_complete = 1; 1626 break; 1627 } 1628 if ((status & DATAIN_REG_READY) != 0) 1629 break; 1630 if ((status & CMD_REG_BUSY) == 0) { 1631 aha_outb(aha, COMMAND_REG, *params++); 1632 param_len--; 1633 timeout = 10000; 1634 } 1635 } 1636 if (timeout == 0) { 1637 printf("%s: aha_cmd: Timeout sending parameters, " 1638 "status = 0x%x\n", aha_name(aha), status); 1639 error = ETIMEDOUT; 1640 } 1641 1642 /* 1643 * For all other commands, we wait for any output data 1644 * and the final comand completion interrupt. 1645 */ 1646 while (cmd_complete == 0 && --cmd_timeout) { 1647 1648 s = splcam(); 1649 status = aha_inb(aha, STATUS_REG); 1650 intstat = aha_inb(aha, INTSTAT_REG); 1651 splx(s); 1652 1653 if (aha->command_cmp != 0) { 1654 cmd_complete = 1; 1655 saved_status = aha->latched_status; 1656 } else if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1657 == (INTR_PENDING|CMD_COMPLETE)) { 1658 /* 1659 * Our poll (in case interrupts are blocked) 1660 * saw the CMD_COMPLETE interrupt. 1661 */ 1662 cmd_complete = 1; 1663 saved_status = status; 1664 } 1665 if ((status & DATAIN_REG_READY) != 0) { 1666 u_int8_t data; 1667 1668 data = aha_inb(aha, DATAIN_REG); 1669 if (reply_len < reply_buf_size) { 1670 *reply_data++ = data; 1671 } else { 1672 printf("%s: aha_cmd - Discarded reply data " 1673 "byte for opcode 0x%x\n", aha_name(aha), 1674 opcode); 1675 } 1676 /* 1677 * Reset timeout to ensure at least a second 1678 * between response bytes. 1679 */ 1680 cmd_timeout = MAX(cmd_timeout, 10000); 1681 reply_len++; 1682 } 1683 DELAY(100); 1684 } 1685 if (cmd_timeout == 0) { 1686 printf("%s: aha_cmd: Timeout waiting for reply data and " 1687 "command complete.\n%s: status = 0x%x, intstat = 0x%x, " 1688 "reply_len = %d\n", aha_name(aha), aha_name(aha), status, 1689 intstat, reply_len); 1690 return (ETIMEDOUT); 1691 } 1692 1693 /* 1694 * Clear any pending interrupts. Block interrupts so our 1695 * interrupt handler is not re-entered. 1696 */ 1697 s = splcam(); 1698 aha_intr(aha); 1699 splx(s); 1700 1701 if (error != 0) 1702 return (error); 1703 1704 /* 1705 * If the command was rejected by the controller, tell the caller. 1706 */ 1707 if ((saved_status & CMD_INVALID) != 0) { 1708 PRVERB(("%s: Invalid Command 0x%x\n", aha_name(aha), opcode)); 1709 /* 1710 * Some early adapters may not recover properly from 1711 * an invalid command. If it appears that the controller 1712 * has wedged (i.e. status was not cleared by our interrupt 1713 * reset above), perform a soft reset. 1714 */ 1715 DELAY(1000); 1716 status = aha_inb(aha, STATUS_REG); 1717 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY| 1718 CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0 1719 || (status & (HA_READY|INIT_REQUIRED)) 1720 != (HA_READY|INIT_REQUIRED)) { 1721 ahareset(aha, /*hard_reset*/FALSE); 1722 } 1723 return (EINVAL); 1724 } 1725 1726 if (param_len > 0) { 1727 /* The controller did not accept the full argument list */ 1728 PRVERB(("%s: Controller did not accept full argument list " 1729 "(%d > 0)\n", 1730 aha_name(aha), param_len)); 1731 return (E2BIG); 1732 } 1733 1734 if (reply_len != reply_buf_size) { 1735 /* Too much or too little data received */ 1736 PRVERB(("%s: Too much or too little data received (%d != %d)\n", 1737 aha_name(aha), reply_len, reply_buf_size)); 1738 return (EMSGSIZE); 1739 } 1740 1741 /* We were successful */ 1742 return (0); 1743} 1744 1745static int 1746ahainitmboxes(struct aha_softc *aha) 1747{ 1748 int error; 1749 init_24b_mbox_params_t init_mbox; 1750 1751 bzero(aha->in_boxes, sizeof(aha_mbox_in_t) * aha->num_boxes); 1752 bzero(aha->out_boxes, sizeof(aha_mbox_out_t) * aha->num_boxes); 1753 aha->cur_inbox = aha->in_boxes; 1754 aha->last_inbox = aha->in_boxes + aha->num_boxes - 1; 1755 aha->cur_outbox = aha->out_boxes; 1756 aha->last_outbox = aha->out_boxes + aha->num_boxes - 1; 1757 1758 /* Tell the adapter about them */ 1759 init_mbox.num_mboxes = aha->num_boxes; 1760 ahautoa24(aha->mailbox_physbase, init_mbox.base_addr); 1761 error = aha_cmd(aha, AOP_INITIALIZE_MBOX, (u_int8_t *)&init_mbox, 1762 /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL, 1763 /*reply_len*/0, DEFAULT_CMD_TIMEOUT); 1764 1765 if (error != 0) 1766 printf("ahainitmboxes: Initialization command failed\n"); 1767 return (error); 1768} 1769 1770/* 1771 * Update the XPT's idea of the negotiated transfer 1772 * parameters for a particular target. 1773 */ 1774static void 1775ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts) 1776{ 1777 setup_data_t setup_info; 1778 u_int target; 1779 u_int targ_offset; 1780 u_int sync_period; 1781 int error; 1782 u_int8_t param; 1783 targ_syncinfo_t sync_info; 1784 1785 target = cts->ccb_h.target_id; 1786 targ_offset = (target & 0x7); 1787 1788 /* 1789 * Inquire Setup Information. This command retreives 1790 * the sync info for older models. 1791 */ 1792 param = sizeof(setup_info); 1793 error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, ¶m, /*paramlen*/1, 1794 (u_int8_t*)&setup_info, sizeof(setup_info), 1795 DEFAULT_CMD_TIMEOUT); 1796 1797 if (error != 0) { 1798 printf("%s: ahafetchtransinfo - Inquire Setup Info Failed %d\n", 1799 aha_name(aha), error); 1800 return; 1801 } 1802 1803 sync_info = setup_info.syncinfo[targ_offset]; 1804 1805 if (sync_info.sync == 0) 1806 cts->sync_offset = 0; 1807 else 1808 cts->sync_offset = sync_info.offset; 1809 1810 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1811 1812 if (aha->boardid >= BOARD_1542CF) 1813 sync_period = 1000; 1814 else 1815 sync_period = 2000; 1816 sync_period += 500 * sync_info.period; 1817 1818 /* Convert ns value to standard SCSI sync rate */ 1819 if (cts->sync_offset != 0) 1820 cts->sync_period = scsi_calc_syncparam(sync_period); 1821 else 1822 cts->sync_period = 0; 1823 1824 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1825 | CCB_TRANS_SYNC_OFFSET_VALID 1826 | CCB_TRANS_BUS_WIDTH_VALID; 1827 xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); 1828} 1829 1830static void 1831ahamapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1832{ 1833 struct aha_softc* aha; 1834 1835 aha = (struct aha_softc*)arg; 1836 aha->mailbox_physbase = segs->ds_addr; 1837} 1838 1839static void 1840ahamapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1841{ 1842 struct aha_softc* aha; 1843 1844 aha = (struct aha_softc*)arg; 1845 aha->aha_ccb_physbase = segs->ds_addr; 1846} 1847 1848static void 1849ahamapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1850{ 1851 1852 struct aha_softc* aha; 1853 1854 aha = (struct aha_softc*)arg; 1855 SLIST_FIRST(&aha->sg_maps)->sg_physaddr = segs->ds_addr; 1856} 1857 1858static void 1859ahapoll(struct cam_sim *sim) 1860{ 1861 aha_intr(cam_sim_softc(sim)); 1862} 1863 1864static void 1865ahatimeout(void *arg) 1866{ 1867 struct aha_ccb *accb; 1868 union ccb *ccb; 1869 struct aha_softc *aha; 1870 int s; 1871 u_int32_t paddr; 1872 1873 accb = (struct aha_ccb *)arg; 1874 ccb = accb->ccb; 1875 aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr; 1876 xpt_print_path(ccb->ccb_h.path); 1877 printf("CCB %p - timed out\n", (void *)accb); 1878 1879 s = splcam(); 1880 1881 if ((accb->flags & ACCB_ACTIVE) == 0) { 1882 xpt_print_path(ccb->ccb_h.path); 1883 printf("CCB %p - timed out CCB already completed\n", 1884 (void *)accb); 1885 splx(s); 1886 return; 1887 } 1888 1889 /* 1890 * In order to simplify the recovery process, we ask the XPT 1891 * layer to halt the queue of new transactions and we traverse 1892 * the list of pending CCBs and remove their timeouts. This 1893 * means that the driver attempts to clear only one error 1894 * condition at a time. In general, timeouts that occur 1895 * close together are related anyway, so there is no benefit 1896 * in attempting to handle errors in parrallel. Timeouts will 1897 * be reinstated when the recovery process ends. 1898 */ 1899 if ((accb->flags & ACCB_DEVICE_RESET) == 0) { 1900 struct ccb_hdr *ccb_h; 1901 1902 if ((accb->flags & ACCB_RELEASE_SIMQ) == 0) { 1903 xpt_freeze_simq(aha->sim, /*count*/1); 1904 accb->flags |= ACCB_RELEASE_SIMQ; 1905 } 1906 1907 ccb_h = LIST_FIRST(&aha->pending_ccbs); 1908 while (ccb_h != NULL) { 1909 struct aha_ccb *pending_accb; 1910 1911 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr; 1912 untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch); 1913 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1914 } 1915 } 1916 1917 if ((accb->flags & ACCB_DEVICE_RESET) != 0 1918 || aha->cur_outbox->action_code != AMBO_FREE) { 1919 /* 1920 * Try a full host adapter/SCSI bus reset. 1921 * We do this only if we have already attempted 1922 * to clear the condition with a BDR, or we cannot 1923 * attempt a BDR for lack of mailbox resources. 1924 */ 1925 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1926 ahareset(aha, /*hardreset*/TRUE); 1927 printf("%s: No longer in timeout\n", aha_name(aha)); 1928 } else { 1929 /* 1930 * Send a Bus Device Reset message: 1931 * The target that is holding up the bus may not 1932 * be the same as the one that triggered this timeout 1933 * (different commands have different timeout lengths), 1934 * but we have no way of determining this from our 1935 * timeout handler. Our strategy here is to queue a 1936 * BDR message to the target of the timed out command. 1937 * If this fails, we'll get another timeout 2 seconds 1938 * later which will attempt a bus reset. 1939 */ 1940 accb->flags |= ACCB_DEVICE_RESET; 1941 ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz); 1942 aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET; 1943 1944 /* No Data Transfer */ 1945 aha->recovery_accb->hccb.datain = TRUE; 1946 aha->recovery_accb->hccb.dataout = TRUE; 1947 aha->recovery_accb->hccb.ahastat = 0; 1948 aha->recovery_accb->hccb.sdstat = 0; 1949 aha->recovery_accb->hccb.target = ccb->ccb_h.target_id; 1950 1951 /* Tell the adapter about this command */ 1952 paddr = ahaccbvtop(aha, aha->recovery_accb); 1953 ahautoa24(paddr, aha->cur_outbox->ccb_addr); 1954 aha->cur_outbox->action_code = AMBO_START; 1955 aha_outb(aha, COMMAND_REG, AOP_START_MBOX); 1956 ahanextoutbox(aha); 1957 } 1958 1959 splx(s); 1960} 1961 1962int 1963aha_detach(struct aha_softc *aha) 1964{ 1965 xpt_async(AC_LOST_DEVICE, aha->path, NULL); 1966 xpt_free_path(aha->path); 1967 xpt_bus_deregister(cam_sim_path(aha->sim)); 1968 cam_sim_free(aha->sim, /*free_devq*/TRUE); 1969 return (0); 1970}
|