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