338} 339 340/* 341 * sbp_probe() 342 */ 343static int 344sbp_probe(device_t dev) 345{ 346 device_t pa; 347 348SBP_DEBUG(0) 349 printf("sbp_probe\n"); 350END_DEBUG 351 352 pa = device_get_parent(dev); 353 if(device_get_unit(dev) != device_get_unit(pa)){ 354 return(ENXIO); 355 } 356 357 device_set_desc(dev, "SBP-2/SCSI over FireWire"); 358 359#if 0 360 if (bootverbose) 361 debug = bootverbose; 362#endif 363 364 return (0); 365} 366 367static void 368sbp_show_sdev_info(struct sbp_dev *sdev, int new) 369{ 370 struct fw_device *fwdev; 371 372 printf("%s:%d:%d ", 373 device_get_nameunit(sdev->target->sbp->fd.dev), 374 sdev->target->target_id, 375 sdev->lun_id 376 ); 377 if (new == 2) { 378 return; 379 } 380 fwdev = sdev->target->fwdev; 381 printf("ordered:%d type:%d EUI:%08x%08x node:%d " 382 "speed:%d maxrec:%d", 383 (sdev->type & 0x40) >> 6, 384 (sdev->type & 0x1f), 385 fwdev->eui.hi, 386 fwdev->eui.lo, 387 fwdev->dst, 388 fwdev->speed, 389 fwdev->maxrec 390 ); 391 if (new) 392 printf(" new!\n"); 393 else 394 printf("\n"); 395 sbp_show_sdev_info(sdev, 2); 396 printf("'%s' '%s' '%s'\n", sdev->vendor, sdev->product, sdev->revision); 397} 398 399static struct { 400 int bus; 401 int target; 402 struct fw_eui64 eui; 403} wired[] = { 404 /* Bus Target EUI64 */ 405#if 0 406 {0, 2, {0x00018ea0, 0x01fd0154}}, /* Logitec HDD */ 407 {0, 0, {0x00018ea6, 0x00100682}}, /* Logitec DVD */ 408 {0, 1, {0x00d03200, 0xa412006a}}, /* Yano HDD */ 409#endif 410 {-1, -1, {0,0}} 411}; 412 413static int 414sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev) 415{ 416 int bus, i, target=-1; 417 char w[SBP_NUM_TARGETS]; 418 419 bzero(w, sizeof(w)); 420 bus = device_get_unit(sbp->fd.dev); 421 422 /* XXX wired-down configuration should be gotten from 423 tunable or device hint */ 424 for (i = 0; wired[i].bus >= 0; i ++) { 425 if (wired[i].bus == bus) { 426 w[wired[i].target] = 1; 427 if (wired[i].eui.hi == fwdev->eui.hi && 428 wired[i].eui.lo == fwdev->eui.lo) 429 target = wired[i].target; 430 } 431 } 432 if (target >= 0) { 433 if(target < SBP_NUM_TARGETS && 434 sbp->targets[target].fwdev == NULL) 435 return(target); 436 device_printf(sbp->fd.dev, 437 "target %d is not free for %08x:%08x\n", 438 target, fwdev->eui.hi, fwdev->eui.lo); 439 target = -1; 440 } 441 /* non-wired target */ 442 for (i = 0; i < SBP_NUM_TARGETS; i ++) 443 if (sbp->targets[i].fwdev == NULL && w[i] == 0) { 444 target = i; 445 break; 446 } 447 448 return target; 449} 450 451static void 452sbp_alloc_lun(struct sbp_target *target) 453{ 454 struct crom_context cc; 455 struct csrreg *reg; 456 struct sbp_dev *sdev, **newluns; 457 struct sbp_softc *sbp; 458 int maxlun, lun, i; 459 460 sbp = target->sbp; 461 crom_init_context(&cc, target->fwdev->csrrom); 462 /* XXX shoud parse appropriate unit directories only */ 463 maxlun = -1; 464 while (cc.depth >= 0) { 465 reg = crom_search_key(&cc, CROM_LUN); 466 if (reg == NULL) 467 break; 468 lun = reg->val & 0xffff; 469SBP_DEBUG(0) 470 printf("target %d lun %d found\n", target->target_id, lun); 471END_DEBUG 472 if (maxlun < lun) 473 maxlun = lun; 474 crom_next(&cc); 475 } 476 if (maxlun < 0) 477 printf("%s:%d no LUN found\n", 478 device_get_nameunit(target->sbp->fd.dev), 479 target->target_id); 480 481 maxlun ++; 482 if (maxlun >= SBP_NUM_LUNS) 483 maxlun = SBP_NUM_LUNS; 484 485 /* Invalidiate stale devices */ 486 for (lun = 0; lun < target->num_lun; lun ++) { 487 sdev = target->luns[lun]; 488 if (sdev == NULL) 489 continue; 490 sdev->flags &= ~VALID_LUN; 491 if (lun >= maxlun) { 492 /* lost device */ 493 sbp_cam_detach_sdev(sdev); 494 sbp_free_sdev(sdev); 495 target->luns[lun] = NULL; 496 } 497 } 498 499 /* Reallocate */ 500 if (maxlun != target->num_lun) { 501 newluns = (struct sbp_dev **) realloc(target->luns, 502 sizeof(struct sbp_dev *) * maxlun, 503 M_SBP, M_NOWAIT | M_ZERO); 504 505 if (newluns == NULL) { 506 printf("%s: realloc failed\n", __func__); 507 newluns = target->luns; 508 maxlun = target->num_lun; 509 } 510 511 /* 512 * We must zero the extended region for the case 513 * realloc() doesn't allocate new buffer. 514 */ 515 if (maxlun > target->num_lun) 516 bzero(&newluns[target->num_lun], 517 sizeof(struct sbp_dev *) * 518 (maxlun - target->num_lun)); 519 520 target->luns = newluns; 521 target->num_lun = maxlun; 522 } 523 524 crom_init_context(&cc, target->fwdev->csrrom); 525 while (cc.depth >= 0) { 526 int new = 0; 527 528 reg = crom_search_key(&cc, CROM_LUN); 529 if (reg == NULL) 530 break; 531 lun = reg->val & 0xffff; 532 if (lun >= SBP_NUM_LUNS) { 533 printf("too large lun %d\n", lun); 534 goto next; 535 } 536 537 sdev = target->luns[lun]; 538 if (sdev == NULL) { 539 sdev = malloc(sizeof(struct sbp_dev), 540 M_SBP, M_NOWAIT | M_ZERO); 541 if (sdev == NULL) { 542 printf("%s: malloc failed\n", __func__); 543 goto next; 544 } 545 target->luns[lun] = sdev; 546 sdev->lun_id = lun; 547 sdev->target = target; 548 STAILQ_INIT(&sdev->ocbs); 549 CALLOUT_INIT(&sdev->login_callout); 550 sdev->status = SBP_DEV_RESET; 551 new = 1; 552 } 553 sdev->flags |= VALID_LUN; 554 sdev->type = (reg->val & 0xff0000) >> 16; 555 556 if (new == 0) 557 goto next; 558 559 fwdma_malloc(sbp->fd.fc, 560 /* alignment */ sizeof(uint32_t), 561 SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT); 562 if (sdev->dma.v_addr == NULL) { 563 printf("%s: dma space allocation failed\n", 564 __func__); 565 free(sdev, M_SBP); 566 target->luns[lun] = NULL; 567 goto next; 568 } 569 sdev->login = (struct sbp_login_res *) sdev->dma.v_addr; 570 sdev->ocb = (struct sbp_ocb *) 571 ((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE); 572 bzero((char *)sdev->ocb, 573 sizeof (struct sbp_ocb) * SBP_QUEUE_LEN); 574 575 STAILQ_INIT(&sdev->free_ocbs); 576 for (i = 0; i < SBP_QUEUE_LEN; i++) { 577 struct sbp_ocb *ocb; 578 ocb = &sdev->ocb[i]; 579 ocb->bus_addr = sdev->dma.bus_addr 580 + SBP_LOGIN_SIZE 581 + sizeof(struct sbp_ocb) * i 582 + offsetof(struct sbp_ocb, orb[0]); 583 if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) { 584 printf("sbp_attach: cannot create dmamap\n"); 585 /* XXX */ 586 goto next; 587 } 588 sbp_free_ocb(sdev, ocb); 589 } 590next: 591 crom_next(&cc); 592 } 593 594 for (lun = 0; lun < target->num_lun; lun ++) { 595 sdev = target->luns[lun]; 596 if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) { 597 sbp_cam_detach_sdev(sdev); 598 sbp_free_sdev(sdev); 599 target->luns[lun] = NULL; 600 } 601 } 602} 603 604static struct sbp_target * 605sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev) 606{ 607 int i; 608 struct sbp_target *target; 609 struct crom_context cc; 610 struct csrreg *reg; 611 612SBP_DEBUG(1) 613 printf("sbp_alloc_target\n"); 614END_DEBUG 615 i = sbp_new_target(sbp, fwdev); 616 if (i < 0) { 617 device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n"); 618 return NULL; 619 } 620 /* new target */ 621 target = &sbp->targets[i]; 622 target->sbp = sbp; 623 target->fwdev = fwdev; 624 target->target_id = i; 625 /* XXX we may want to reload mgm port after each bus reset */ 626 /* XXX there might be multiple management agents */ 627 crom_init_context(&cc, target->fwdev->csrrom); 628 reg = crom_search_key(&cc, CROM_MGM); 629 if (reg == NULL || reg->val == 0) { 630 printf("NULL management address\n"); 631 target->fwdev = NULL; 632 return NULL; 633 } 634 target->mgm_hi = 0xffff; 635 target->mgm_lo = 0xf0000000 | (reg->val << 2); 636 target->mgm_ocb_cur = NULL; 637SBP_DEBUG(1) 638 printf("target:%d mgm_port: %x\n", i, target->mgm_lo); 639END_DEBUG 640 STAILQ_INIT(&target->xferlist); 641 target->n_xfer = 0; 642 STAILQ_INIT(&target->mgm_ocb_queue); 643 CALLOUT_INIT(&target->mgm_ocb_timeout); 644 CALLOUT_INIT(&target->scan_callout); 645 646 target->luns = NULL; 647 target->num_lun = 0; 648 return target; 649} 650 651static void 652sbp_probe_lun(struct sbp_dev *sdev) 653{ 654 struct fw_device *fwdev; 655 struct crom_context c, *cc = &c; 656 struct csrreg *reg; 657 658 bzero(sdev->vendor, sizeof(sdev->vendor)); 659 bzero(sdev->product, sizeof(sdev->product)); 660 661 fwdev = sdev->target->fwdev; 662 crom_init_context(cc, fwdev->csrrom); 663 /* get vendor string */ 664 crom_search_key(cc, CSRKEY_VENDOR); 665 crom_next(cc); 666 crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor)); 667 /* skip to the unit directory for SBP-2 */ 668 while ((reg = crom_search_key(cc, CSRKEY_VER)) != NULL) { 669 if (reg->val == CSRVAL_T10SBP2) 670 break; 671 crom_next(cc); 672 } 673 /* get firmware revision */ 674 reg = crom_search_key(cc, CSRKEY_FIRM_VER); 675 if (reg != NULL) 676 snprintf(sdev->revision, sizeof(sdev->revision), 677 "%06x", reg->val); 678 /* get product string */ 679 crom_search_key(cc, CSRKEY_MODEL); 680 crom_next(cc); 681 crom_parse_text(cc, sdev->product, sizeof(sdev->product)); 682} 683 684static void 685sbp_login_callout(void *arg) 686{ 687 struct sbp_dev *sdev = (struct sbp_dev *)arg; 688 sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL); 689} 690 691static void 692sbp_login(struct sbp_dev *sdev) 693{ 694 struct timeval delta; 695 struct timeval t; 696 int ticks = 0; 697 698 microtime(&delta); 699 timevalsub(&delta, &sdev->target->sbp->last_busreset); 700 t.tv_sec = login_delay / 1000; 701 t.tv_usec = (login_delay % 1000) * 1000; 702 timevalsub(&t, &delta); 703 if (t.tv_sec >= 0 && t.tv_usec > 0) 704 ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000; 705SBP_DEBUG(0) 706 printf("%s: sec = %jd usec = %ld ticks = %d\n", __func__, 707 (intmax_t)t.tv_sec, t.tv_usec, ticks); 708END_DEBUG 709 callout_reset(&sdev->login_callout, ticks, 710 sbp_login_callout, (void *)(sdev)); 711} 712 713#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \ 714 && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2)) 715 716static void 717sbp_probe_target(void *arg) 718{ 719 struct sbp_target *target = (struct sbp_target *)arg; 720 struct sbp_softc *sbp; 721 struct sbp_dev *sdev; 722 struct firewire_comm *fc; 723 int i, alive; 724 725 alive = SBP_FWDEV_ALIVE(target->fwdev); 726SBP_DEBUG(1) 727 printf("sbp_probe_target %d\n", target->target_id); 728 if (!alive) 729 printf("not alive\n"); 730END_DEBUG 731 732 sbp = target->sbp; 733 fc = target->sbp->fd.fc; 734 sbp_alloc_lun(target); 735 736 /* XXX untimeout mgm_ocb and dequeue */ 737 for (i=0; i < target->num_lun; i++) { 738 sdev = target->luns[i]; 739 if (sdev == NULL) 740 continue; 741 if (alive && (sdev->status != SBP_DEV_DEAD)) { 742 if (sdev->path != NULL) { 743 SBP_LOCK(sbp); 744 xpt_freeze_devq(sdev->path, 1); 745 sdev->freeze ++; 746 SBP_UNLOCK(sbp); 747 } 748 sbp_probe_lun(sdev); 749SBP_DEBUG(0) 750 sbp_show_sdev_info(sdev, 751 (sdev->status == SBP_DEV_RESET)); 752END_DEBUG 753 754 sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET); 755 switch (sdev->status) { 756 case SBP_DEV_RESET: 757 /* new or revived target */ 758 if (auto_login) 759 sbp_login(sdev); 760 break; 761 case SBP_DEV_TOATTACH: 762 case SBP_DEV_PROBE: 763 case SBP_DEV_ATTACHED: 764 case SBP_DEV_RETRY: 765 default: 766 sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL); 767 break; 768 } 769 } else { 770 switch (sdev->status) { 771 case SBP_DEV_ATTACHED: 772SBP_DEBUG(0) 773 /* the device has gone */ 774 sbp_show_sdev_info(sdev, 2); 775 printf("lost target\n"); 776END_DEBUG 777 if (sdev->path) { 778 SBP_LOCK(sbp); 779 xpt_freeze_devq(sdev->path, 1); 780 sdev->freeze ++; 781 SBP_UNLOCK(sbp); 782 } 783 sdev->status = SBP_DEV_RETRY; 784 sbp_cam_detach_sdev(sdev); 785 sbp_free_sdev(sdev); 786 target->luns[i] = NULL; 787 break; 788 case SBP_DEV_PROBE: 789 case SBP_DEV_TOATTACH: 790 sdev->status = SBP_DEV_RESET; 791 break; 792 case SBP_DEV_RETRY: 793 case SBP_DEV_RESET: 794 case SBP_DEV_DEAD: 795 break; 796 } 797 } 798 } 799} 800 801static void 802sbp_post_busreset(void *arg) 803{ 804 struct sbp_softc *sbp; 805 806 sbp = (struct sbp_softc *)arg; 807SBP_DEBUG(0) 808 printf("sbp_post_busreset\n"); 809END_DEBUG 810 if ((sbp->sim->flags & SIMQ_FREEZED) == 0) { 811 SBP_LOCK(sbp); 812 xpt_freeze_simq(sbp->sim, /*count*/1); 813 sbp->sim->flags |= SIMQ_FREEZED; 814 SBP_UNLOCK(sbp); 815 } 816 microtime(&sbp->last_busreset); 817} 818 819static void 820sbp_post_explore(void *arg) 821{ 822 struct sbp_softc *sbp = (struct sbp_softc *)arg; 823 struct sbp_target *target; 824 struct fw_device *fwdev; 825 int i, alive; 826 827SBP_DEBUG(0) 828 printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold); 829END_DEBUG 830 /* We need physical access */ 831 if (!firewire_phydma_enable) 832 return; 833 834 if (sbp_cold > 0) 835 sbp_cold --; 836 837#if 0 838 /* 839 * XXX don't let CAM the bus rest. 840 * CAM tries to do something with freezed (DEV_RETRY) devices. 841 */ 842 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL); 843#endif 844 845 /* Garbage Collection */ 846 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){ 847 target = &sbp->targets[i]; 848 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) 849 if (target->fwdev == NULL || target->fwdev == fwdev) 850 break; 851 if (fwdev == NULL) { 852 /* device has removed in lower driver */ 853 sbp_cam_detach_target(target); 854 sbp_free_target(target); 855 } 856 } 857 /* traverse device list */ 858 STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) { 859SBP_DEBUG(0) 860 printf("sbp_post_explore: EUI:%08x%08x ", 861 fwdev->eui.hi, fwdev->eui.lo); 862 if (fwdev->status != FWDEVATTACHED) 863 printf("not attached, state=%d.\n", fwdev->status); 864 else 865 printf("attached\n"); 866END_DEBUG 867 alive = SBP_FWDEV_ALIVE(fwdev); 868 for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){ 869 target = &sbp->targets[i]; 870 if(target->fwdev == fwdev ) { 871 /* known target */ 872 break; 873 } 874 } 875 if(i == SBP_NUM_TARGETS){ 876 if (alive) { 877 /* new target */ 878 target = sbp_alloc_target(sbp, fwdev); 879 if (target == NULL) 880 continue; 881 } else { 882 continue; 883 } 884 } 885 sbp_probe_target((void *)target); 886 if (target->num_lun == 0) 887 sbp_free_target(target); 888 } 889 SBP_LOCK(sbp); 890 xpt_release_simq(sbp->sim, /*run queue*/TRUE); 891 sbp->sim->flags &= ~SIMQ_FREEZED; 892 SBP_UNLOCK(sbp); 893} 894 895#if NEED_RESPONSE 896static void 897sbp_loginres_callback(struct fw_xfer *xfer){ 898 int s; 899 struct sbp_dev *sdev; 900 sdev = (struct sbp_dev *)xfer->sc; 901SBP_DEBUG(1) 902 sbp_show_sdev_info(sdev, 2); 903 printf("sbp_loginres_callback\n"); 904END_DEBUG 905 /* recycle */ 906 s = splfw(); 907 STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link); 908 splx(s); 909 return; 910} 911#endif 912 913static __inline void 914sbp_xfer_free(struct fw_xfer *xfer) 915{ 916 struct sbp_dev *sdev; 917 int s; 918 919 sdev = (struct sbp_dev *)xfer->sc; 920 fw_xfer_unload(xfer); 921 s = splfw(); 922 SBP_LOCK(sdev->target->sbp); 923 STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link); 924 SBP_UNLOCK(sdev->target->sbp); 925 splx(s); 926} 927 928static void 929sbp_reset_start_callback(struct fw_xfer *xfer) 930{ 931 struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc; 932 struct sbp_target *target = sdev->target; 933 int i; 934 935 if (xfer->resp != 0) { 936 sbp_show_sdev_info(sdev, 2); 937 printf("sbp_reset_start failed: resp=%d\n", xfer->resp); 938 } 939 940 for (i = 0; i < target->num_lun; i++) { 941 tsdev = target->luns[i]; 942 if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN) 943 sbp_login(tsdev); 944 } 945} 946 947static void 948sbp_reset_start(struct sbp_dev *sdev) 949{ 950 struct fw_xfer *xfer; 951 struct fw_pkt *fp; 952 953SBP_DEBUG(0) 954 sbp_show_sdev_info(sdev, 2); 955 printf("sbp_reset_start\n"); 956END_DEBUG 957 958 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0); 959 xfer->hand = sbp_reset_start_callback; 960 fp = &xfer->send.hdr; 961 fp->mode.wreqq.dest_hi = 0xffff; 962 fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START; 963 fp->mode.wreqq.data = htonl(0xf); 964 fw_asyreq(xfer->fc, -1, xfer); 965} 966 967static void 968sbp_mgm_callback(struct fw_xfer *xfer) 969{ 970 struct sbp_dev *sdev; 971 int resp; 972 973 sdev = (struct sbp_dev *)xfer->sc; 974 975SBP_DEBUG(1) 976 sbp_show_sdev_info(sdev, 2); 977 printf("sbp_mgm_callback\n"); 978END_DEBUG 979 resp = xfer->resp; 980 sbp_xfer_free(xfer); 981#if 0 982 if (resp != 0) { 983 sbp_show_sdev_info(sdev, 2); 984 printf("management ORB failed(%d) ... RESET_START\n", resp); 985 sbp_reset_start(sdev); 986 } 987#endif 988 return; 989} 990 991static struct sbp_dev * 992sbp_next_dev(struct sbp_target *target, int lun) 993{ 994 struct sbp_dev **sdevp; 995 int i; 996 997 for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun; 998 i++, sdevp++) 999 if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE) 1000 return(*sdevp); 1001 return(NULL); 1002} 1003 1004#define SCAN_PRI 1 1005static void 1006sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb) 1007{ 1008 struct sbp_target *target; 1009 struct sbp_dev *sdev; 1010 1011 sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr; 1012 target = sdev->target; 1013SBP_DEBUG(0) 1014 sbp_show_sdev_info(sdev, 2); 1015 printf("sbp_cam_scan_lun\n"); 1016END_DEBUG 1017 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 1018 sdev->status = SBP_DEV_ATTACHED; 1019 } else { 1020 sbp_show_sdev_info(sdev, 2); 1021 printf("scan failed\n"); 1022 } 1023 sdev = sbp_next_dev(target, sdev->lun_id + 1); 1024 if (sdev == NULL) { 1025 free(ccb, M_SBP); 1026 return; 1027 } 1028 /* reuse ccb */ 1029 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI); 1030 ccb->ccb_h.ccb_sdev_ptr = sdev; 1031 xpt_action(ccb); 1032 xpt_release_devq(sdev->path, sdev->freeze, TRUE); 1033 sdev->freeze = 1; 1034} 1035 1036static void 1037sbp_cam_scan_target(void *arg) 1038{ 1039 struct sbp_target *target = (struct sbp_target *)arg; 1040 struct sbp_dev *sdev; 1041 union ccb *ccb; 1042 1043 sdev = sbp_next_dev(target, 0); 1044 if (sdev == NULL) { 1045 printf("sbp_cam_scan_target: nothing to do for target%d\n", 1046 target->target_id); 1047 return; 1048 } 1049SBP_DEBUG(0) 1050 sbp_show_sdev_info(sdev, 2); 1051 printf("sbp_cam_scan_target\n"); 1052END_DEBUG 1053 ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO); 1054 if (ccb == NULL) { 1055 printf("sbp_cam_scan_target: malloc failed\n"); 1056 return; 1057 } 1058 xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI); 1059 ccb->ccb_h.func_code = XPT_SCAN_LUN; 1060 ccb->ccb_h.cbfcnp = sbp_cam_scan_lun; 1061 ccb->ccb_h.flags |= CAM_DEV_QFREEZE; 1062 ccb->crcn.flags = CAM_FLAG_NONE; 1063 ccb->ccb_h.ccb_sdev_ptr = sdev; 1064 1065 /* The scan is in progress now. */ 1066 SBP_LOCK(target->sbp); 1067 xpt_action(ccb); 1068 xpt_release_devq(sdev->path, sdev->freeze, TRUE); 1069 sdev->freeze = 1; 1070 SBP_UNLOCK(target->sbp); 1071} 1072 1073static __inline void 1074sbp_scan_dev(struct sbp_dev *sdev) 1075{ 1076 sdev->status = SBP_DEV_PROBE; 1077 callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000, 1078 sbp_cam_scan_target, (void *)sdev->target); 1079} 1080 1081static void 1082sbp_do_attach(struct fw_xfer *xfer) 1083{ 1084 struct sbp_dev *sdev; 1085 struct sbp_target *target; 1086 struct sbp_softc *sbp; 1087 1088 sdev = (struct sbp_dev *)xfer->sc; 1089 target = sdev->target; 1090 sbp = target->sbp; 1091SBP_DEBUG(0) 1092 sbp_show_sdev_info(sdev, 2); 1093 printf("sbp_do_attach\n"); 1094END_DEBUG 1095 sbp_xfer_free(xfer); 1096 1097 if (sdev->path == NULL) 1098 xpt_create_path(&sdev->path, xpt_periph, 1099 cam_sim_path(target->sbp->sim), 1100 target->target_id, sdev->lun_id); 1101 1102 /* 1103 * Let CAM scan the bus if we are in the boot process. 1104 * XXX xpt_scan_bus cannot detect LUN larger than 0 1105 * if LUN 0 doesn't exists. 1106 */ 1107 if (sbp_cold > 0) { 1108 sdev->status = SBP_DEV_ATTACHED; 1109 return; 1110 } 1111 1112 sbp_scan_dev(sdev); 1113 return; 1114} 1115 1116static void 1117sbp_agent_reset_callback(struct fw_xfer *xfer) 1118{ 1119 struct sbp_dev *sdev; 1120 1121 sdev = (struct sbp_dev *)xfer->sc; 1122SBP_DEBUG(1) 1123 sbp_show_sdev_info(sdev, 2); 1124 printf("%s\n", __func__); 1125END_DEBUG 1126 if (xfer->resp != 0) { 1127 sbp_show_sdev_info(sdev, 2); 1128 printf("%s: resp=%d\n", __func__, xfer->resp); 1129 } 1130 1131 sbp_xfer_free(xfer); 1132 if (sdev->path) { 1133 SBP_LOCK(sdev->target->sbp); 1134 xpt_release_devq(sdev->path, sdev->freeze, TRUE); 1135 sdev->freeze = 0; 1136 SBP_UNLOCK(sdev->target->sbp); 1137 } 1138} 1139 1140static void 1141sbp_agent_reset(struct sbp_dev *sdev) 1142{ 1143 struct fw_xfer *xfer; 1144 struct fw_pkt *fp; 1145 1146SBP_DEBUG(0) 1147 sbp_show_sdev_info(sdev, 2); 1148 printf("sbp_agent_reset\n"); 1149END_DEBUG 1150 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04); 1151 if (xfer == NULL) 1152 return; 1153 if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE) 1154 xfer->hand = sbp_agent_reset_callback; 1155 else 1156 xfer->hand = sbp_do_attach; 1157 fp = &xfer->send.hdr; 1158 fp->mode.wreqq.data = htonl(0xf); 1159 fw_asyreq(xfer->fc, -1, xfer); 1160 sbp_abort_all_ocbs(sdev, CAM_BDR_SENT); 1161} 1162 1163static void 1164sbp_busy_timeout_callback(struct fw_xfer *xfer) 1165{ 1166 struct sbp_dev *sdev; 1167 1168 sdev = (struct sbp_dev *)xfer->sc; 1169SBP_DEBUG(1) 1170 sbp_show_sdev_info(sdev, 2); 1171 printf("sbp_busy_timeout_callback\n"); 1172END_DEBUG 1173 sbp_xfer_free(xfer); 1174 sbp_agent_reset(sdev); 1175} 1176 1177static void 1178sbp_busy_timeout(struct sbp_dev *sdev) 1179{ 1180 struct fw_pkt *fp; 1181 struct fw_xfer *xfer; 1182SBP_DEBUG(0) 1183 sbp_show_sdev_info(sdev, 2); 1184 printf("sbp_busy_timeout\n"); 1185END_DEBUG 1186 xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0); 1187 1188 xfer->hand = sbp_busy_timeout_callback; 1189 fp = &xfer->send.hdr; 1190 fp->mode.wreqq.dest_hi = 0xffff; 1191 fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT; 1192 fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf); 1193 fw_asyreq(xfer->fc, -1, xfer); 1194} 1195 1196static void 1197sbp_orb_pointer_callback(struct fw_xfer *xfer) 1198{ 1199 struct sbp_dev *sdev; 1200 sdev = (struct sbp_dev *)xfer->sc; 1201 1202SBP_DEBUG(2) 1203 sbp_show_sdev_info(sdev, 2); 1204 printf("%s\n", __func__); 1205END_DEBUG 1206 if (xfer->resp != 0) { 1207 /* XXX */ 1208 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1209 } 1210 sbp_xfer_free(xfer); 1211 1212 SBP_LOCK(sdev->target->sbp); 1213 sdev->flags &= ~ORB_POINTER_ACTIVE; 1214 1215 if ((sdev->flags & ORB_POINTER_NEED) != 0) { 1216 struct sbp_ocb *ocb; 1217 1218 sdev->flags &= ~ORB_POINTER_NEED; 1219 ocb = STAILQ_FIRST(&sdev->ocbs); 1220 if (ocb != NULL) 1221 sbp_orb_pointer(sdev, ocb); 1222 } 1223 SBP_UNLOCK(sdev->target->sbp); 1224 return; 1225} 1226 1227static void 1228sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb) 1229{ 1230 struct fw_xfer *xfer; 1231 struct fw_pkt *fp; 1232SBP_DEBUG(1) 1233 sbp_show_sdev_info(sdev, 2); 1234 printf("%s: 0x%08x\n", __func__, (uint32_t)ocb->bus_addr); 1235END_DEBUG 1236 1237 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); 1238 1239 if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) { 1240SBP_DEBUG(0) 1241 printf("%s: orb pointer active\n", __func__); 1242END_DEBUG 1243 sdev->flags |= ORB_POINTER_NEED; 1244 return; 1245 } 1246 1247 sdev->flags |= ORB_POINTER_ACTIVE; 1248 xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQB, 0x08); 1249 if (xfer == NULL) 1250 return; 1251 xfer->hand = sbp_orb_pointer_callback; 1252 1253 fp = &xfer->send.hdr; 1254 fp->mode.wreqb.len = 8; 1255 fp->mode.wreqb.extcode = 0; 1256 xfer->send.payload[0] = 1257 htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16)); 1258 xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr); 1259 1260 /* 1261 * sbp_xfer_free() will attempt to acquire 1262 * the SBP lock on entrance. Also, this removes 1263 * a LOR between the firewire layer and sbp 1264 */ 1265 SBP_UNLOCK(sdev->target->sbp); 1266 if(fw_asyreq(xfer->fc, -1, xfer) != 0){ 1267 sbp_xfer_free(xfer); 1268 ocb->ccb->ccb_h.status = CAM_REQ_INVALID; 1269 xpt_done(ocb->ccb); 1270 } 1271 SBP_LOCK(sdev->target->sbp); 1272} 1273 1274static void 1275sbp_doorbell_callback(struct fw_xfer *xfer) 1276{ 1277 struct sbp_dev *sdev; 1278 sdev = (struct sbp_dev *)xfer->sc; 1279 1280SBP_DEBUG(1) 1281 sbp_show_sdev_info(sdev, 2); 1282 printf("sbp_doorbell_callback\n"); 1283END_DEBUG 1284 if (xfer->resp != 0) { 1285 /* XXX */ 1286 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1287 } 1288 sbp_xfer_free(xfer); 1289 sdev->flags &= ~ORB_DOORBELL_ACTIVE; 1290 if ((sdev->flags & ORB_DOORBELL_NEED) != 0) { 1291 sdev->flags &= ~ORB_DOORBELL_NEED; 1292 SBP_LOCK(sdev->target->sbp); 1293 sbp_doorbell(sdev); 1294 SBP_UNLOCK(sdev->target->sbp); 1295 } 1296 return; 1297} 1298 1299static void 1300sbp_doorbell(struct sbp_dev *sdev) 1301{ 1302 struct fw_xfer *xfer; 1303 struct fw_pkt *fp; 1304SBP_DEBUG(1) 1305 sbp_show_sdev_info(sdev, 2); 1306 printf("sbp_doorbell\n"); 1307END_DEBUG 1308 1309 if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) { 1310 sdev->flags |= ORB_DOORBELL_NEED; 1311 return; 1312 } 1313 sdev->flags |= ORB_DOORBELL_ACTIVE; 1314 xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQQ, 0x10); 1315 if (xfer == NULL) 1316 return; 1317 xfer->hand = sbp_doorbell_callback; 1318 fp = &xfer->send.hdr; 1319 fp->mode.wreqq.data = htonl(0xf); 1320 fw_asyreq(xfer->fc, -1, xfer); 1321} 1322 1323static struct fw_xfer * 1324sbp_write_cmd_locked(struct sbp_dev *sdev, int tcode, int offset) 1325{ 1326 struct fw_xfer *xfer; 1327 struct fw_pkt *fp; 1328 struct sbp_target *target; 1329 int s, new = 0; 1330 1331 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); 1332 1333 target = sdev->target; 1334 s = splfw(); 1335 xfer = STAILQ_FIRST(&target->xferlist); 1336 if (xfer == NULL) { 1337 if (target->n_xfer > 5 /* XXX */) { 1338 printf("sbp: no more xfer for this target\n"); 1339 splx(s); 1340 return(NULL); 1341 } 1342 xfer = fw_xfer_alloc_buf(M_SBP, 8, 0); 1343 if(xfer == NULL){ 1344 printf("sbp: fw_xfer_alloc_buf failed\n"); 1345 splx(s); 1346 return NULL; 1347 } 1348 target->n_xfer ++; 1349 if (debug) 1350 printf("sbp: alloc %d xfer\n", target->n_xfer); 1351 new = 1; 1352 } else { 1353 STAILQ_REMOVE_HEAD(&target->xferlist, link); 1354 } 1355 splx(s); 1356 1357 if (new) { 1358 xfer->recv.pay_len = 0; 1359 xfer->send.spd = min(sdev->target->fwdev->speed, max_speed); 1360 xfer->fc = sdev->target->sbp->fd.fc; 1361 } 1362 1363 if (tcode == FWTCODE_WREQB) 1364 xfer->send.pay_len = 8; 1365 else 1366 xfer->send.pay_len = 0; 1367 1368 xfer->sc = (caddr_t)sdev; 1369 fp = &xfer->send.hdr; 1370 fp->mode.wreqq.dest_hi = sdev->login->cmd_hi; 1371 fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset; 1372 fp->mode.wreqq.tlrt = 0; 1373 fp->mode.wreqq.tcode = tcode; 1374 fp->mode.wreqq.pri = 0; 1375 fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst; 1376 1377 return xfer; 1378 1379} 1380 1381static struct fw_xfer * 1382sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset) 1383{ 1384 struct sbp_softc *sbp = sdev->target->sbp; 1385 struct fw_xfer *xfer; 1386 1387 SBP_LOCK(sbp); 1388 xfer = sbp_write_cmd_locked(sdev, tcode, offset); 1389 SBP_UNLOCK(sbp); 1390 1391 return (xfer); 1392} 1393 1394static void 1395sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb) 1396{ 1397 struct fw_xfer *xfer; 1398 struct fw_pkt *fp; 1399 struct sbp_ocb *ocb; 1400 struct sbp_target *target; 1401 int s, nid; 1402 1403 target = sdev->target; 1404 nid = target->sbp->fd.fc->nodeid | FWLOCALBUS; 1405 1406 s = splfw(); 1407 SBP_LOCK(target->sbp); 1408 if (func == ORB_FUN_RUNQUEUE) { 1409 ocb = STAILQ_FIRST(&target->mgm_ocb_queue); 1410 if (target->mgm_ocb_cur != NULL || ocb == NULL) { 1411 SBP_UNLOCK(target->sbp); 1412 splx(s); 1413 return; 1414 } 1415 STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb); 1416 SBP_UNLOCK(target->sbp); 1417 goto start; 1418 } 1419 if ((ocb = sbp_get_ocb(sdev)) == NULL) { 1420 SBP_UNLOCK(target->sbp); 1421 splx(s); 1422 /* XXX */ 1423 return; 1424 } 1425 SBP_UNLOCK(target->sbp); 1426 ocb->flags = OCB_ACT_MGM; 1427 ocb->sdev = sdev; 1428 1429 bzero((void *)ocb->orb, sizeof(ocb->orb)); 1430 ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI); 1431 ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id)); 1432 1433SBP_DEBUG(0) 1434 sbp_show_sdev_info(sdev, 2); 1435 printf("%s\n", orb_fun_name[(func>>16)&0xf]); 1436END_DEBUG 1437 switch (func) { 1438 case ORB_FUN_LGI: 1439 ocb->orb[0] = ocb->orb[1] = 0; /* password */ 1440 ocb->orb[2] = htonl(nid << 16); 1441 ocb->orb[3] = htonl(sdev->dma.bus_addr); 1442 ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id); 1443 if (ex_login) 1444 ocb->orb[4] |= htonl(ORB_EXV); 1445 ocb->orb[5] = htonl(SBP_LOGIN_SIZE); 1446 fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD); 1447 break; 1448 case ORB_FUN_ATA: 1449 ocb->orb[0] = htonl((0 << 16) | 0); 1450 ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff); 1451 /* fall through */ 1452 case ORB_FUN_RCN: 1453 case ORB_FUN_LGO: 1454 case ORB_FUN_LUR: 1455 case ORB_FUN_RST: 1456 case ORB_FUN_ATS: 1457 ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id); 1458 break; 1459 } 1460 1461 if (target->mgm_ocb_cur != NULL) { 1462 /* there is a standing ORB */ 1463 SBP_LOCK(target->sbp); 1464 STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb); 1465 SBP_UNLOCK(target->sbp); 1466 splx(s); 1467 return; 1468 } 1469start: 1470 target->mgm_ocb_cur = ocb; 1471 splx(s); 1472 1473 callout_reset(&target->mgm_ocb_timeout, 5*hz, 1474 sbp_mgm_timeout, (caddr_t)ocb); 1475 xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0); 1476 if(xfer == NULL){ 1477 return; 1478 } 1479 xfer->hand = sbp_mgm_callback; 1480 1481 fp = &xfer->send.hdr; 1482 fp->mode.wreqb.dest_hi = sdev->target->mgm_hi; 1483 fp->mode.wreqb.dest_lo = sdev->target->mgm_lo; 1484 fp->mode.wreqb.len = 8; 1485 fp->mode.wreqb.extcode = 0; 1486 xfer->send.payload[0] = htonl(nid << 16); 1487 xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff); 1488SBP_DEBUG(0) 1489 sbp_show_sdev_info(sdev, 2); 1490 printf("mgm orb: %08x\n", (uint32_t)ocb->bus_addr); 1491END_DEBUG 1492 1493 fw_asyreq(xfer->fc, -1, xfer); 1494} 1495 1496static void 1497sbp_print_scsi_cmd(struct sbp_ocb *ocb) 1498{ 1499 struct ccb_scsiio *csio; 1500 1501 csio = &ocb->ccb->csio; 1502 printf("%s:%d:%d XPT_SCSI_IO: " 1503 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" 1504 ", flags: 0x%02x, " 1505 "%db cmd/%db data/%db sense\n", 1506 device_get_nameunit(ocb->sdev->target->sbp->fd.dev), 1507 ocb->ccb->ccb_h.target_id, ocb->ccb->ccb_h.target_lun, 1508 csio->cdb_io.cdb_bytes[0], 1509 csio->cdb_io.cdb_bytes[1], 1510 csio->cdb_io.cdb_bytes[2], 1511 csio->cdb_io.cdb_bytes[3], 1512 csio->cdb_io.cdb_bytes[4], 1513 csio->cdb_io.cdb_bytes[5], 1514 csio->cdb_io.cdb_bytes[6], 1515 csio->cdb_io.cdb_bytes[7], 1516 csio->cdb_io.cdb_bytes[8], 1517 csio->cdb_io.cdb_bytes[9], 1518 ocb->ccb->ccb_h.flags & CAM_DIR_MASK, 1519 csio->cdb_len, csio->dxfer_len, 1520 csio->sense_len); 1521} 1522 1523static void 1524sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb) 1525{ 1526 struct sbp_cmd_status *sbp_cmd_status; 1527 struct scsi_sense_data *sense; 1528 1529 sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data; 1530 sense = &ocb->ccb->csio.sense_data; 1531 1532SBP_DEBUG(0) 1533 sbp_print_scsi_cmd(ocb); 1534 /* XXX need decode status */ 1535 sbp_show_sdev_info(ocb->sdev, 2); 1536 printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n", 1537 sbp_cmd_status->status, 1538 sbp_cmd_status->sfmt, 1539 sbp_cmd_status->valid, 1540 sbp_cmd_status->s_key, 1541 sbp_cmd_status->s_code, 1542 sbp_cmd_status->s_qlfr, 1543 sbp_status->len 1544 ); 1545END_DEBUG 1546 1547 switch (sbp_cmd_status->status) { 1548 case SCSI_STATUS_CHECK_COND: 1549 case SCSI_STATUS_BUSY: 1550 case SCSI_STATUS_CMD_TERMINATED: 1551 if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){ 1552 sense->error_code = SSD_CURRENT_ERROR; 1553 }else{ 1554 sense->error_code = SSD_DEFERRED_ERROR; 1555 } 1556 if(sbp_cmd_status->valid) 1557 sense->error_code |= SSD_ERRCODE_VALID; 1558 sense->flags = sbp_cmd_status->s_key; 1559 if(sbp_cmd_status->mark) 1560 sense->flags |= SSD_FILEMARK; 1561 if(sbp_cmd_status->eom) 1562 sense->flags |= SSD_EOM; 1563 if(sbp_cmd_status->ill_len) 1564 sense->flags |= SSD_ILI; 1565 1566 bcopy(&sbp_cmd_status->info, &sense->info[0], 4); 1567 1568 if (sbp_status->len <= 1) 1569 /* XXX not scsi status. shouldn't be happened */ 1570 sense->extra_len = 0; 1571 else if (sbp_status->len <= 4) 1572 /* add_sense_code(_qual), info, cmd_spec_info */ 1573 sense->extra_len = 6; 1574 else 1575 /* fru, sense_key_spec */ 1576 sense->extra_len = 10; 1577 1578 bcopy(&sbp_cmd_status->cdb, &sense->cmd_spec_info[0], 4); 1579 1580 sense->add_sense_code = sbp_cmd_status->s_code; 1581 sense->add_sense_code_qual = sbp_cmd_status->s_qlfr; 1582 sense->fru = sbp_cmd_status->fru; 1583 1584 bcopy(&sbp_cmd_status->s_keydep[0], 1585 &sense->sense_key_spec[0], 3); 1586 1587 ocb->ccb->csio.scsi_status = sbp_cmd_status->status;; 1588 ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR 1589 | CAM_AUTOSNS_VALID; 1590/* 1591{ 1592 uint8_t j, *tmp; 1593 tmp = sense; 1594 for( j = 0 ; j < 32 ; j+=8){ 1595 printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n", 1596 tmp[j], tmp[j+1], tmp[j+2], tmp[j+3], 1597 tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]); 1598 } 1599 1600} 1601*/ 1602 break; 1603 default: 1604 sbp_show_sdev_info(ocb->sdev, 2); 1605 printf("sbp_scsi_status: unknown scsi status 0x%x\n", 1606 sbp_cmd_status->status); 1607 } 1608} 1609 1610static void 1611sbp_fix_inq_data(struct sbp_ocb *ocb) 1612{ 1613 union ccb *ccb; 1614 struct sbp_dev *sdev; 1615 struct scsi_inquiry_data *inq; 1616 1617 ccb = ocb->ccb; 1618 sdev = ocb->sdev; 1619 1620 if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD) 1621 return; 1622SBP_DEBUG(1) 1623 sbp_show_sdev_info(sdev, 2); 1624 printf("sbp_fix_inq_data\n"); 1625END_DEBUG 1626 inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr; 1627 switch (SID_TYPE(inq)) { 1628 case T_DIRECT: 1629#if 0 1630 /* 1631 * XXX Convert Direct Access device to RBC. 1632 * I've never seen FireWire DA devices which support READ_6. 1633 */ 1634 if (SID_TYPE(inq) == T_DIRECT) 1635 inq->device |= T_RBC; /* T_DIRECT == 0 */ 1636#endif 1637 /* fall through */ 1638 case T_RBC: 1639 /* 1640 * Override vendor/product/revision information. 1641 * Some devices sometimes return strange strings. 1642 */ 1643#if 1 1644 bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor)); 1645 bcopy(sdev->product, inq->product, sizeof(inq->product)); 1646 bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision)); 1647#endif 1648 break; 1649 } 1650 /* 1651 * Force to enable/disable tagged queuing. 1652 * XXX CAM also checks SCP_QUEUE_DQUE flag in the control mode page. 1653 */ 1654 if (sbp_tags > 0) 1655 inq->flags |= SID_CmdQue; 1656 else if (sbp_tags < 0) 1657 inq->flags &= ~SID_CmdQue; 1658 1659} 1660 1661static void 1662sbp_recv1(struct fw_xfer *xfer) 1663{ 1664 struct fw_pkt *rfp; 1665#if NEED_RESPONSE 1666 struct fw_pkt *sfp; 1667#endif 1668 struct sbp_softc *sbp; 1669 struct sbp_dev *sdev; 1670 struct sbp_ocb *ocb; 1671 struct sbp_login_res *login_res = NULL; 1672 struct sbp_status *sbp_status; 1673 struct sbp_target *target; 1674 int orb_fun, status_valid0, status_valid, t, l, reset_agent = 0; 1675 uint32_t addr; 1676/* 1677 uint32_t *ld; 1678 ld = xfer->recv.buf; 1679printf("sbp %x %d %d %08x %08x %08x %08x\n", 1680 xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3])); 1681printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7])); 1682printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11])); 1683*/ 1684 sbp = (struct sbp_softc *)xfer->sc; 1685 if (xfer->resp != 0){ 1686 printf("sbp_recv: xfer->resp = %d\n", xfer->resp); 1687 goto done0; 1688 } 1689 if (xfer->recv.payload == NULL){ 1690 printf("sbp_recv: xfer->recv.payload == NULL\n"); 1691 goto done0; 1692 } 1693 rfp = &xfer->recv.hdr; 1694 if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){ 1695 printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode); 1696 goto done0; 1697 } 1698 sbp_status = (struct sbp_status *)xfer->recv.payload; 1699 addr = rfp->mode.wreqb.dest_lo; 1700SBP_DEBUG(2) 1701 printf("received address 0x%x\n", addr); 1702END_DEBUG 1703 t = SBP_ADDR2TRG(addr); 1704 if (t >= SBP_NUM_TARGETS) { 1705 device_printf(sbp->fd.dev, 1706 "sbp_recv1: invalid target %d\n", t); 1707 goto done0; 1708 } 1709 target = &sbp->targets[t]; 1710 l = SBP_ADDR2LUN(addr); 1711 if (l >= target->num_lun || target->luns[l] == NULL) { 1712 device_printf(sbp->fd.dev, 1713 "sbp_recv1: invalid lun %d (target=%d)\n", l, t); 1714 goto done0; 1715 } 1716 sdev = target->luns[l]; 1717 1718 ocb = NULL; 1719 switch (sbp_status->src) { 1720 case 0: 1721 case 1: 1722 /* check mgm_ocb_cur first */ 1723 ocb = target->mgm_ocb_cur; 1724 if (ocb != NULL) { 1725 if (OCB_MATCH(ocb, sbp_status)) { 1726 callout_stop(&target->mgm_ocb_timeout); 1727 target->mgm_ocb_cur = NULL; 1728 break; 1729 } 1730 } 1731 ocb = sbp_dequeue_ocb(sdev, sbp_status); 1732 if (ocb == NULL) { 1733 sbp_show_sdev_info(sdev, 2); 1734#if defined(__DragonFly__) || __FreeBSD_version < 500000 1735 printf("No ocb(%lx) on the queue\n", 1736#else 1737 printf("No ocb(%x) on the queue\n", 1738#endif 1739 ntohl(sbp_status->orb_lo)); 1740 } 1741 break; 1742 case 2: 1743 /* unsolicit */ 1744 sbp_show_sdev_info(sdev, 2); 1745 printf("unsolicit status received\n"); 1746 break; 1747 default: 1748 sbp_show_sdev_info(sdev, 2); 1749 printf("unknown sbp_status->src\n"); 1750 } 1751 1752 status_valid0 = (sbp_status->src < 2 1753 && sbp_status->resp == ORB_RES_CMPL 1754 && sbp_status->dead == 0); 1755 status_valid = (status_valid0 && sbp_status->status == 0); 1756 1757 if (!status_valid0 || debug > 2){ 1758 int status; 1759SBP_DEBUG(0) 1760 sbp_show_sdev_info(sdev, 2); 1761 printf("ORB status src:%x resp:%x dead:%x" 1762#if defined(__DragonFly__) || __FreeBSD_version < 500000 1763 " len:%x stat:%x orb:%x%08lx\n", 1764#else 1765 " len:%x stat:%x orb:%x%08x\n", 1766#endif 1767 sbp_status->src, sbp_status->resp, sbp_status->dead, 1768 sbp_status->len, sbp_status->status, 1769 ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo)); 1770END_DEBUG 1771 sbp_show_sdev_info(sdev, 2); 1772 status = sbp_status->status; 1773 switch(sbp_status->resp) { 1774 case 0: 1775 if (status > MAX_ORB_STATUS0) 1776 printf("%s\n", orb_status0[MAX_ORB_STATUS0]); 1777 else 1778 printf("%s\n", orb_status0[status]); 1779 break; 1780 case 1: 1781 printf("Obj: %s, Error: %s\n", 1782 orb_status1_object[(status>>6) & 3], 1783 orb_status1_serial_bus_error[status & 0xf]); 1784 break; 1785 case 2: 1786 printf("Illegal request\n"); 1787 break; 1788 case 3: 1789 printf("Vendor dependent\n"); 1790 break; 1791 default: 1792 printf("unknown respose code %d\n", sbp_status->resp); 1793 } 1794 } 1795 1796 /* we have to reset the fetch agent if it's dead */ 1797 if (sbp_status->dead) { 1798 if (sdev->path) { 1799 SBP_LOCK(sbp); 1800 xpt_freeze_devq(sdev->path, 1); 1801 sdev->freeze ++; 1802 SBP_UNLOCK(sbp); 1803 } 1804 reset_agent = 1; 1805 } 1806 1807 if (ocb == NULL) 1808 goto done; 1809 1810 switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){ 1811 case ORB_FMT_NOP: 1812 break; 1813 case ORB_FMT_VED: 1814 break; 1815 case ORB_FMT_STD: 1816 switch(ocb->flags) { 1817 case OCB_ACT_MGM: 1818 orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK; 1819 reset_agent = 0; 1820 switch(orb_fun) { 1821 case ORB_FUN_LGI: 1822 fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD); 1823 login_res = sdev->login; 1824 login_res->len = ntohs(login_res->len); 1825 login_res->id = ntohs(login_res->id); 1826 login_res->cmd_hi = ntohs(login_res->cmd_hi); 1827 login_res->cmd_lo = ntohl(login_res->cmd_lo); 1828 if (status_valid) { 1829SBP_DEBUG(0) 1830sbp_show_sdev_info(sdev, 2); 1831printf("login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo, ntohs(login_res->recon_hold)); 1832END_DEBUG 1833 sbp_busy_timeout(sdev); 1834 } else { 1835 /* forgot logout? */ 1836 sbp_show_sdev_info(sdev, 2); 1837 printf("login failed\n"); 1838 sdev->status = SBP_DEV_RESET; 1839 } 1840 break; 1841 case ORB_FUN_RCN: 1842 login_res = sdev->login; 1843 if (status_valid) { 1844SBP_DEBUG(0) 1845sbp_show_sdev_info(sdev, 2); 1846printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo); 1847END_DEBUG 1848#if 1 1849 if (sdev->status == SBP_DEV_ATTACHED) 1850 sbp_scan_dev(sdev); 1851 else 1852 sbp_agent_reset(sdev); 1853#else 1854 sdev->status = SBP_DEV_ATTACHED; 1855 sbp_mgm_orb(sdev, ORB_FUN_ATS, NULL); 1856#endif 1857 } else { 1858 /* reconnection hold time exceed? */ 1859SBP_DEBUG(0) 1860 sbp_show_sdev_info(sdev, 2); 1861 printf("reconnect failed\n"); 1862END_DEBUG 1863 sbp_login(sdev); 1864 } 1865 break; 1866 case ORB_FUN_LGO: 1867 sdev->status = SBP_DEV_RESET; 1868 break; 1869 case ORB_FUN_RST: 1870 sbp_busy_timeout(sdev); 1871 break; 1872 case ORB_FUN_LUR: 1873 case ORB_FUN_ATA: 1874 case ORB_FUN_ATS: 1875 sbp_agent_reset(sdev); 1876 break; 1877 default: 1878 sbp_show_sdev_info(sdev, 2); 1879 printf("unknown function %d\n", orb_fun); 1880 break; 1881 } 1882 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL); 1883 break; 1884 case OCB_ACT_CMD: 1885 sdev->timeout = 0; 1886 if(ocb->ccb != NULL){ 1887 union ccb *ccb; 1888/* 1889 uint32_t *ld; 1890 ld = ocb->ccb->csio.data_ptr; 1891 if(ld != NULL && ocb->ccb->csio.dxfer_len != 0) 1892 printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]); 1893 else 1894 printf("ptr NULL\n"); 1895printf("len %d\n", sbp_status->len); 1896*/ 1897 ccb = ocb->ccb; 1898 if(sbp_status->len > 1){ 1899 sbp_scsi_status(sbp_status, ocb); 1900 }else{ 1901 if(sbp_status->resp != ORB_RES_CMPL){ 1902 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1903 }else{ 1904 ccb->ccb_h.status = CAM_REQ_CMP; 1905 } 1906 } 1907 /* fix up inq data */ 1908 if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY) 1909 sbp_fix_inq_data(ocb); 1910 SBP_LOCK(sbp); 1911 xpt_done(ccb); 1912 SBP_UNLOCK(sbp); 1913 } 1914 break; 1915 default: 1916 break; 1917 } 1918 } 1919 1920 if (!use_doorbell) 1921 sbp_free_ocb(sdev, ocb); 1922done: 1923 if (reset_agent) 1924 sbp_agent_reset(sdev); 1925 1926done0: 1927 xfer->recv.pay_len = SBP_RECV_LEN; 1928/* The received packet is usually small enough to be stored within 1929 * the buffer. In that case, the controller return ack_complete and 1930 * no respose is necessary. 1931 * 1932 * XXX fwohci.c and firewire.c should inform event_code such as 1933 * ack_complete or ack_pending to upper driver. 1934 */ 1935#if NEED_RESPONSE 1936 xfer->send.off = 0; 1937 sfp = (struct fw_pkt *)xfer->send.buf; 1938 sfp->mode.wres.dst = rfp->mode.wreqb.src; 1939 xfer->dst = sfp->mode.wres.dst; 1940 xfer->spd = min(sdev->target->fwdev->speed, max_speed); 1941 xfer->hand = sbp_loginres_callback; 1942 1943 sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt; 1944 sfp->mode.wres.tcode = FWTCODE_WRES; 1945 sfp->mode.wres.rtcode = 0; 1946 sfp->mode.wres.pri = 0; 1947 1948 fw_asyreq(xfer->fc, -1, xfer); 1949#else 1950 /* recycle */ 1951 /* we don't need a lock here because bottom half is serialized */ 1952 STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link); 1953#endif 1954 1955 return; 1956 1957} 1958 1959static void 1960sbp_recv(struct fw_xfer *xfer) 1961{ 1962 int s; 1963 1964 s = splcam(); 1965 sbp_recv1(xfer); 1966 splx(s); 1967} 1968/* 1969 * sbp_attach() 1970 */ 1971static int 1972sbp_attach(device_t dev) 1973{ 1974 struct sbp_softc *sbp; 1975 struct cam_devq *devq; 1976 struct firewire_comm *fc; 1977 int i, s, error; 1978 1979 if (DFLTPHYS > SBP_MAXPHYS) 1980 device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than " 1981 "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024, 1982 SBP_MAXPHYS / 1024); 1983 1984 if (!firewire_phydma_enable) 1985 device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 " 1986 "for SBP over FireWire.\n"); 1987SBP_DEBUG(0) 1988 printf("sbp_attach (cold=%d)\n", cold); 1989END_DEBUG 1990 1991 if (cold) 1992 sbp_cold ++; 1993 sbp = ((struct sbp_softc *)device_get_softc(dev)); 1994 bzero(sbp, sizeof(struct sbp_softc)); 1995 sbp->fd.dev = dev; 1996 sbp->fd.fc = fc = device_get_ivars(dev); 1997 mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF); 1998 1999 if (max_speed < 0) 2000 max_speed = fc->speed; 2001 2002 error = bus_dma_tag_create(/*parent*/fc->dmat, 2003 /* XXX shoud be 4 for sane backend? */ 2004 /*alignment*/1, 2005 /*boundary*/0, 2006 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 2007 /*highaddr*/BUS_SPACE_MAXADDR, 2008 /*filter*/NULL, /*filterarg*/NULL, 2009 /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX, 2010 /*maxsegsz*/SBP_SEG_MAX, 2011 /*flags*/BUS_DMA_ALLOCNOW, 2012#if defined(__FreeBSD__) && __FreeBSD_version >= 501102 2013 /*lockfunc*/busdma_lock_mutex, 2014 /*lockarg*/&sbp->mtx, 2015#endif 2016 &sbp->dmat); 2017 if (error != 0) { 2018 printf("sbp_attach: Could not allocate DMA tag " 2019 "- error %d\n", error); 2020 return (ENOMEM); 2021 } 2022 2023 devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB); 2024 if (devq == NULL) 2025 return (ENXIO); 2026 2027 for( i = 0 ; i < SBP_NUM_TARGETS ; i++){ 2028 sbp->targets[i].fwdev = NULL; 2029 sbp->targets[i].luns = NULL; 2030 } 2031 2032 sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp, 2033 device_get_unit(dev), 2034 &sbp->mtx, 2035 /*untagged*/ 1, 2036 /*tagged*/ SBP_QUEUE_LEN - 1, 2037 devq); 2038 2039 if (sbp->sim == NULL) { 2040 cam_simq_free(devq); 2041 return (ENXIO); 2042 } 2043 2044 SBP_LOCK(sbp); 2045 if (xpt_bus_register(sbp->sim, dev, /*bus*/0) != CAM_SUCCESS) 2046 goto fail; 2047 2048 if (xpt_create_path(&sbp->path, xpt_periph, cam_sim_path(sbp->sim), 2049 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 2050 xpt_bus_deregister(cam_sim_path(sbp->sim)); 2051 goto fail; 2052 } 2053 SBP_UNLOCK(sbp); 2054 2055 /* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */ 2056 sbp->fwb.start = ((u_int64_t)SBP_BIND_HI << 32) | SBP_DEV2ADDR(0, 0); 2057 sbp->fwb.end = sbp->fwb.start + 0xffff; 2058 /* pre-allocate xfer */ 2059 STAILQ_INIT(&sbp->fwb.xferlist); 2060 fw_xferlist_add(&sbp->fwb.xferlist, M_SBP, 2061 /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2, 2062 fc, (void *)sbp, sbp_recv); 2063 2064 fw_bindadd(fc, &sbp->fwb); 2065 2066 sbp->fd.post_busreset = sbp_post_busreset; 2067 sbp->fd.post_explore = sbp_post_explore; 2068 2069 if (fc->status != -1) { 2070 s = splfw(); 2071 sbp_post_busreset((void *)sbp); 2072 sbp_post_explore((void *)sbp); 2073 splx(s); 2074 } 2075 SBP_LOCK(sbp); 2076 xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL); 2077 SBP_UNLOCK(sbp); 2078 2079 return (0); 2080fail: 2081 SBP_UNLOCK(sbp); 2082 cam_sim_free(sbp->sim, /*free_devq*/TRUE); 2083 return (ENXIO); 2084} 2085 2086static int 2087sbp_logout_all(struct sbp_softc *sbp) 2088{ 2089 struct sbp_target *target; 2090 struct sbp_dev *sdev; 2091 int i, j; 2092 2093SBP_DEBUG(0) 2094 printf("sbp_logout_all\n"); 2095END_DEBUG 2096 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) { 2097 target = &sbp->targets[i]; 2098 if (target->luns == NULL) 2099 continue; 2100 for (j = 0; j < target->num_lun; j++) { 2101 sdev = target->luns[j]; 2102 if (sdev == NULL) 2103 continue; 2104 callout_stop(&sdev->login_callout); 2105 if (sdev->status >= SBP_DEV_TOATTACH && 2106 sdev->status <= SBP_DEV_ATTACHED) 2107 sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL); 2108 } 2109 } 2110 2111 return 0; 2112} 2113 2114static int 2115sbp_shutdown(device_t dev) 2116{ 2117 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev)); 2118 2119 sbp_logout_all(sbp); 2120 return (0); 2121} 2122 2123static void 2124sbp_free_sdev(struct sbp_dev *sdev) 2125{ 2126 int i; 2127 2128 if (sdev == NULL) 2129 return; 2130 for (i = 0; i < SBP_QUEUE_LEN; i++) 2131 bus_dmamap_destroy(sdev->target->sbp->dmat, 2132 sdev->ocb[i].dmamap); 2133 fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma); 2134 free(sdev, M_SBP); 2135 sdev = NULL; 2136} 2137 2138static void 2139sbp_free_target(struct sbp_target *target) 2140{ 2141 struct sbp_softc *sbp; 2142 struct fw_xfer *xfer, *next; 2143 int i; 2144 2145 if (target->luns == NULL) 2146 return; 2147 callout_stop(&target->mgm_ocb_timeout); 2148 sbp = target->sbp; 2149 for (i = 0; i < target->num_lun; i++) 2150 sbp_free_sdev(target->luns[i]); 2151 2152 for (xfer = STAILQ_FIRST(&target->xferlist); 2153 xfer != NULL; xfer = next) { 2154 next = STAILQ_NEXT(xfer, link); 2155 fw_xfer_free_buf(xfer); 2156 } 2157 STAILQ_INIT(&target->xferlist); 2158 free(target->luns, M_SBP); 2159 target->num_lun = 0;; 2160 target->luns = NULL; 2161 target->fwdev = NULL; 2162} 2163 2164static int 2165sbp_detach(device_t dev) 2166{ 2167 struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev)); 2168 struct firewire_comm *fc = sbp->fd.fc; 2169 int i; 2170 2171SBP_DEBUG(0) 2172 printf("sbp_detach\n"); 2173END_DEBUG 2174 2175 for (i = 0; i < SBP_NUM_TARGETS; i ++) 2176 sbp_cam_detach_target(&sbp->targets[i]); 2177 2178 SBP_LOCK(sbp); 2179 xpt_async(AC_LOST_DEVICE, sbp->path, NULL); 2180 xpt_free_path(sbp->path); 2181 xpt_bus_deregister(cam_sim_path(sbp->sim)); 2182 cam_sim_free(sbp->sim, /*free_devq*/ TRUE); 2183 SBP_UNLOCK(sbp); 2184 2185 sbp_logout_all(sbp); 2186 2187 /* XXX wait for logout completion */ 2188 pause("sbpdtc", hz/2); 2189 2190 for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) 2191 sbp_free_target(&sbp->targets[i]); 2192 2193 fw_bindremove(fc, &sbp->fwb); 2194 fw_xferlist_remove(&sbp->fwb.xferlist); 2195 2196 bus_dma_tag_destroy(sbp->dmat); 2197 mtx_destroy(&sbp->mtx); 2198 2199 return (0); 2200} 2201 2202static void 2203sbp_cam_detach_sdev(struct sbp_dev *sdev) 2204{ 2205 if (sdev == NULL) 2206 return; 2207 if (sdev->status == SBP_DEV_DEAD) 2208 return; 2209 if (sdev->status == SBP_DEV_RESET) 2210 return; 2211 sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE); 2212 if (sdev->path) { 2213 SBP_LOCK(sdev->target->sbp); 2214 xpt_release_devq(sdev->path, 2215 sdev->freeze, TRUE); 2216 sdev->freeze = 0; 2217 xpt_async(AC_LOST_DEVICE, sdev->path, NULL); 2218 xpt_free_path(sdev->path); 2219 sdev->path = NULL; 2220 SBP_UNLOCK(sdev->target->sbp); 2221 } 2222} 2223 2224static void 2225sbp_cam_detach_target(struct sbp_target *target) 2226{ 2227 int i; 2228 2229 if (target->luns != NULL) { 2230SBP_DEBUG(0) 2231 printf("sbp_detach_target %d\n", target->target_id); 2232END_DEBUG 2233 callout_stop(&target->scan_callout); 2234 for (i = 0; i < target->num_lun; i++) 2235 sbp_cam_detach_sdev(target->luns[i]); 2236 } 2237} 2238 2239static void 2240sbp_target_reset(struct sbp_dev *sdev, int method) 2241{ 2242 int i; 2243 struct sbp_target *target = sdev->target; 2244 struct sbp_dev *tsdev; 2245 2246 for (i = 0; i < target->num_lun; i++) { 2247 tsdev = target->luns[i]; 2248 if (tsdev == NULL) 2249 continue; 2250 if (tsdev->status == SBP_DEV_DEAD) 2251 continue; 2252 if (tsdev->status == SBP_DEV_RESET) 2253 continue; 2254 SBP_LOCK(target->sbp); 2255 xpt_freeze_devq(tsdev->path, 1); 2256 tsdev->freeze ++; 2257 SBP_UNLOCK(target->sbp); 2258 sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT); 2259 if (method == 2) 2260 tsdev->status = SBP_DEV_LOGIN; 2261 } 2262 switch(method) { 2263 case 1: 2264 printf("target reset\n"); 2265 sbp_mgm_orb(sdev, ORB_FUN_RST, NULL); 2266 break; 2267 case 2: 2268 printf("reset start\n"); 2269 sbp_reset_start(sdev); 2270 break; 2271 } 2272 2273} 2274 2275static void 2276sbp_mgm_timeout(void *arg) 2277{ 2278 struct sbp_ocb *ocb = (struct sbp_ocb *)arg; 2279 struct sbp_dev *sdev = ocb->sdev; 2280 struct sbp_target *target = sdev->target; 2281 2282 sbp_show_sdev_info(sdev, 2); 2283 printf("request timeout(mgm orb:0x%08x) ... ", 2284 (uint32_t)ocb->bus_addr); 2285 target->mgm_ocb_cur = NULL; 2286 sbp_free_ocb(sdev, ocb); 2287#if 0 2288 /* XXX */ 2289 printf("run next request\n"); 2290 sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL); 2291#endif 2292#if 1 2293 printf("reset start\n"); 2294 sbp_reset_start(sdev); 2295#endif 2296} 2297 2298static void 2299sbp_timeout(void *arg) 2300{ 2301 struct sbp_ocb *ocb = (struct sbp_ocb *)arg; 2302 struct sbp_dev *sdev = ocb->sdev; 2303 2304 sbp_show_sdev_info(sdev, 2); 2305 printf("request timeout(cmd orb:0x%08x) ... ", 2306 (uint32_t)ocb->bus_addr); 2307 2308 sdev->timeout ++; 2309 switch(sdev->timeout) { 2310 case 1: 2311 printf("agent reset\n"); 2312 SBP_LOCK(sdev->target->sbp); 2313 xpt_freeze_devq(sdev->path, 1); 2314 sdev->freeze ++; 2315 SBP_UNLOCK(sdev->target->sbp); 2316 sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT); 2317 sbp_agent_reset(sdev); 2318 break; 2319 case 2: 2320 case 3: 2321 sbp_target_reset(sdev, sdev->timeout - 1); 2322 break; 2323#if 0 2324 default: 2325 /* XXX give up */ 2326 sbp_cam_detach_target(target); 2327 if (target->luns != NULL) 2328 free(target->luns, M_SBP); 2329 target->num_lun = 0;; 2330 target->luns = NULL; 2331 target->fwdev = NULL; 2332#endif 2333 } 2334} 2335 2336static void 2337sbp_action1(struct cam_sim *sim, union ccb *ccb) 2338{ 2339 2340 struct sbp_softc *sbp = (struct sbp_softc *)sim->softc; 2341 struct sbp_target *target = NULL; 2342 struct sbp_dev *sdev = NULL; 2343 2344 /* target:lun -> sdev mapping */ 2345 if (sbp != NULL 2346 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD 2347 && ccb->ccb_h.target_id < SBP_NUM_TARGETS) { 2348 target = &sbp->targets[ccb->ccb_h.target_id]; 2349 if (target->fwdev != NULL 2350 && ccb->ccb_h.target_lun != CAM_LUN_WILDCARD 2351 && ccb->ccb_h.target_lun < target->num_lun) { 2352 sdev = target->luns[ccb->ccb_h.target_lun]; 2353 if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED && 2354 sdev->status != SBP_DEV_PROBE) 2355 sdev = NULL; 2356 } 2357 } 2358 2359SBP_DEBUG(1) 2360 if (sdev == NULL) 2361 printf("invalid target %d lun %d\n", 2362 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 2363END_DEBUG 2364 2365 switch (ccb->ccb_h.func_code) { 2366 case XPT_SCSI_IO: 2367 case XPT_RESET_DEV: 2368 case XPT_GET_TRAN_SETTINGS: 2369 case XPT_SET_TRAN_SETTINGS: 2370 case XPT_CALC_GEOMETRY: 2371 if (sdev == NULL) { 2372SBP_DEBUG(1) 2373 printf("%s:%d:%d:func_code 0x%04x: " 2374 "Invalid target (target needed)\n", 2375 device_get_nameunit(sbp->fd.dev), 2376 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 2377 ccb->ccb_h.func_code); 2378END_DEBUG 2379 2380 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 2381 xpt_done(ccb); 2382 return; 2383 } 2384 break; 2385 case XPT_PATH_INQ: 2386 case XPT_NOOP: 2387 /* The opcodes sometimes aimed at a target (sc is valid), 2388 * sometimes aimed at the SIM (sc is invalid and target is 2389 * CAM_TARGET_WILDCARD) 2390 */ 2391 if (sbp == NULL && 2392 ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) { 2393SBP_DEBUG(0) 2394 printf("%s:%d:%d func_code 0x%04x: " 2395 "Invalid target (no wildcard)\n", 2396 device_get_nameunit(sbp->fd.dev), 2397 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 2398 ccb->ccb_h.func_code); 2399END_DEBUG 2400 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 2401 xpt_done(ccb); 2402 return; 2403 } 2404 break; 2405 default: 2406 /* XXX Hm, we should check the input parameters */ 2407 break; 2408 } 2409 2410 switch (ccb->ccb_h.func_code) { 2411 case XPT_SCSI_IO: 2412 { 2413 struct ccb_scsiio *csio; 2414 struct sbp_ocb *ocb; 2415 int speed; 2416 void *cdb; 2417 2418 csio = &ccb->csio; 2419 mtx_assert(sim->mtx, MA_OWNED); 2420 2421SBP_DEBUG(2) 2422 printf("%s:%d:%d XPT_SCSI_IO: " 2423 "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x" 2424 ", flags: 0x%02x, " 2425 "%db cmd/%db data/%db sense\n", 2426 device_get_nameunit(sbp->fd.dev), 2427 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 2428 csio->cdb_io.cdb_bytes[0], 2429 csio->cdb_io.cdb_bytes[1], 2430 csio->cdb_io.cdb_bytes[2], 2431 csio->cdb_io.cdb_bytes[3], 2432 csio->cdb_io.cdb_bytes[4], 2433 csio->cdb_io.cdb_bytes[5], 2434 csio->cdb_io.cdb_bytes[6], 2435 csio->cdb_io.cdb_bytes[7], 2436 csio->cdb_io.cdb_bytes[8], 2437 csio->cdb_io.cdb_bytes[9], 2438 ccb->ccb_h.flags & CAM_DIR_MASK, 2439 csio->cdb_len, csio->dxfer_len, 2440 csio->sense_len); 2441END_DEBUG 2442 if(sdev == NULL){ 2443 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 2444 xpt_done(ccb); 2445 return; 2446 } 2447#if 0 2448 /* if we are in probe stage, pass only probe commands */ 2449 if (sdev->status == SBP_DEV_PROBE) { 2450 char *name; 2451 name = xpt_path_periph(ccb->ccb_h.path)->periph_name; 2452 printf("probe stage, periph name: %s\n", name); 2453 if (strcmp(name, "probe") != 0) { 2454 ccb->ccb_h.status = CAM_REQUEUE_REQ; 2455 xpt_done(ccb); 2456 return; 2457 } 2458 } 2459#endif 2460 if ((ocb = sbp_get_ocb(sdev)) == NULL) { 2461 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 2462 if (sdev->freeze == 0) { 2463 SBP_LOCK(sdev->target->sbp); 2464 xpt_freeze_devq(sdev->path, 1); 2465 sdev->freeze ++; 2466 SBP_UNLOCK(sdev->target->sbp); 2467 } 2468 xpt_done(ccb); 2469 return; 2470 } 2471 2472 ocb->flags = OCB_ACT_CMD; 2473 ocb->sdev = sdev; 2474 ocb->ccb = ccb; 2475 ccb->ccb_h.ccb_sdev_ptr = sdev; 2476 ocb->orb[0] = htonl(1 << 31); 2477 ocb->orb[1] = 0; 2478 ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) ); 2479 ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET); 2480 speed = min(target->fwdev->speed, max_speed); 2481 ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed) 2482 | ORB_CMD_MAXP(speed + 7)); 2483 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){ 2484 ocb->orb[4] |= htonl(ORB_CMD_IN); 2485 } 2486 2487 if (csio->ccb_h.flags & CAM_SCATTER_VALID) 2488 printf("sbp: CAM_SCATTER_VALID\n"); 2489 if (csio->ccb_h.flags & CAM_DATA_PHYS) 2490 printf("sbp: CAM_DATA_PHYS\n"); 2491 2492 if (csio->ccb_h.flags & CAM_CDB_POINTER) 2493 cdb = (void *)csio->cdb_io.cdb_ptr; 2494 else 2495 cdb = (void *)&csio->cdb_io.cdb_bytes; 2496 bcopy(cdb, (void *)&ocb->orb[5], csio->cdb_len); 2497/* 2498printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3])); 2499printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7])); 2500*/ 2501 if (ccb->csio.dxfer_len > 0) { 2502 int s, error; 2503 2504 s = splsoftvm(); 2505 error = bus_dmamap_load(/*dma tag*/sbp->dmat, 2506 /*dma map*/ocb->dmamap, 2507 ccb->csio.data_ptr, 2508 ccb->csio.dxfer_len, 2509 sbp_execute_ocb, 2510 ocb, 2511 /*flags*/0); 2512 splx(s); 2513 if (error) 2514 printf("sbp: bus_dmamap_load error %d\n", error); 2515 } else 2516 sbp_execute_ocb(ocb, NULL, 0, 0); 2517 break; 2518 } 2519 case XPT_CALC_GEOMETRY: 2520 { 2521 struct ccb_calc_geometry *ccg; 2522#if defined(__DragonFly__) || __FreeBSD_version < 501100 2523 uint32_t size_mb; 2524 uint32_t secs_per_cylinder; 2525 int extended = 1; 2526#endif 2527 2528 ccg = &ccb->ccg; 2529 if (ccg->block_size == 0) { 2530 printf("sbp_action1: block_size is 0.\n"); 2531 ccb->ccb_h.status = CAM_REQ_INVALID; 2532 xpt_done(ccb); 2533 break; 2534 } 2535SBP_DEBUG(1) 2536 printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: " 2537#if defined(__DragonFly__) || __FreeBSD_version < 500000 2538 "Volume size = %d\n", 2539#else 2540 "Volume size = %jd\n", 2541#endif 2542 device_get_nameunit(sbp->fd.dev), 2543 cam_sim_path(sbp->sim), 2544 ccb->ccb_h.target_id, ccb->ccb_h.target_lun, 2545#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 2546 (uintmax_t) 2547#endif 2548 ccg->volume_size); 2549END_DEBUG 2550 2551#if defined(__DragonFly__) || __FreeBSD_version < 501100 2552 size_mb = ccg->volume_size 2553 / ((1024L * 1024L) / ccg->block_size); 2554 2555 if (size_mb > 1024 && extended) { 2556 ccg->heads = 255; 2557 ccg->secs_per_track = 63; 2558 } else { 2559 ccg->heads = 64; 2560 ccg->secs_per_track = 32; 2561 } 2562 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 2563 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 2564 ccb->ccb_h.status = CAM_REQ_CMP; 2565#else 2566 cam_calc_geometry(ccg, /*extended*/1); 2567#endif 2568 xpt_done(ccb); 2569 break; 2570 } 2571 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 2572 { 2573 2574SBP_DEBUG(1) 2575 printf("%s:%d:XPT_RESET_BUS: \n", 2576 device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim)); 2577END_DEBUG 2578 2579 ccb->ccb_h.status = CAM_REQ_INVALID; 2580 xpt_done(ccb); 2581 break; 2582 } 2583 case XPT_PATH_INQ: /* Path routing inquiry */ 2584 { 2585 struct ccb_pathinq *cpi = &ccb->cpi; 2586 2587SBP_DEBUG(1) 2588 printf("%s:%d:%d XPT_PATH_INQ:.\n", 2589 device_get_nameunit(sbp->fd.dev), 2590 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 2591END_DEBUG 2592 cpi->version_num = 1; /* XXX??? */ 2593 cpi->hba_inquiry = PI_TAG_ABLE; 2594 cpi->target_sprt = 0; 2595 cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE; 2596 cpi->hba_eng_cnt = 0; 2597 cpi->max_target = SBP_NUM_TARGETS - 1; 2598 cpi->max_lun = SBP_NUM_LUNS - 1; 2599 cpi->initiator_id = SBP_INITIATOR; 2600 cpi->bus_id = sim->bus_id; 2601 cpi->base_transfer_speed = 400 * 1000 / 8; 2602 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 2603 strncpy(cpi->hba_vid, "SBP", HBA_IDLEN); 2604 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); 2605 cpi->unit_number = sim->unit_number; 2606 cpi->transport = XPORT_SPI; /* XX should have a FireWire */ 2607 cpi->transport_version = 2; 2608 cpi->protocol = PROTO_SCSI; 2609 cpi->protocol_version = SCSI_REV_2; 2610 2611 cpi->ccb_h.status = CAM_REQ_CMP; 2612 xpt_done(ccb); 2613 break; 2614 } 2615 case XPT_GET_TRAN_SETTINGS: 2616 { 2617 struct ccb_trans_settings *cts = &ccb->cts; 2618 struct ccb_trans_settings_scsi *scsi = 2619 &cts->proto_specific.scsi; 2620 struct ccb_trans_settings_spi *spi = 2621 &cts->xport_specific.spi; 2622 2623 cts->protocol = PROTO_SCSI; 2624 cts->protocol_version = SCSI_REV_2; 2625 cts->transport = XPORT_SPI; /* should have a FireWire */ 2626 cts->transport_version = 2; 2627 spi->valid = CTS_SPI_VALID_DISC; 2628 spi->flags = CTS_SPI_FLAGS_DISC_ENB; 2629 scsi->valid = CTS_SCSI_VALID_TQ; 2630 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 2631SBP_DEBUG(1) 2632 printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n", 2633 device_get_nameunit(sbp->fd.dev), 2634 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 2635END_DEBUG 2636 cts->ccb_h.status = CAM_REQ_CMP; 2637 xpt_done(ccb); 2638 break; 2639 } 2640 case XPT_ABORT: 2641 ccb->ccb_h.status = CAM_UA_ABORT; 2642 xpt_done(ccb); 2643 break; 2644 case XPT_SET_TRAN_SETTINGS: 2645 /* XXX */ 2646 default: 2647 ccb->ccb_h.status = CAM_REQ_INVALID; 2648 xpt_done(ccb); 2649 break; 2650 } 2651 return; 2652} 2653 2654static void 2655sbp_action(struct cam_sim *sim, union ccb *ccb) 2656{ 2657 int s; 2658 2659 s = splfw(); 2660 sbp_action1(sim, ccb); 2661 splx(s); 2662} 2663 2664static void 2665sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error) 2666{ 2667 int i; 2668 struct sbp_ocb *ocb; 2669 struct sbp_ocb *prev; 2670 bus_dma_segment_t *s; 2671 2672 if (error) 2673 printf("sbp_execute_ocb: error=%d\n", error); 2674 2675 ocb = (struct sbp_ocb *)arg; 2676 2677SBP_DEBUG(2) 2678 printf("sbp_execute_ocb: seg %d", seg); 2679 for (i = 0; i < seg; i++) 2680#if defined(__DragonFly__) || __FreeBSD_version < 500000 2681 printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len); 2682#else 2683 printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr, 2684 (uintmax_t)segments[i].ds_len); 2685#endif 2686 printf("\n"); 2687END_DEBUG 2688 2689 if (seg == 1) { 2690 /* direct pointer */ 2691 s = &segments[0]; 2692 if (s->ds_len > SBP_SEG_MAX) 2693 panic("ds_len > SBP_SEG_MAX, fix busdma code"); 2694 ocb->orb[3] = htonl(s->ds_addr); 2695 ocb->orb[4] |= htonl(s->ds_len); 2696 } else if(seg > 1) { 2697 /* page table */ 2698 for (i = 0; i < seg; i++) { 2699 s = &segments[i]; 2700SBP_DEBUG(0) 2701 /* XXX LSI Logic "< 16 byte" bug might be hit */ 2702 if (s->ds_len < 16) 2703 printf("sbp_execute_ocb: warning, " 2704#if defined(__DragonFly__) || __FreeBSD_version < 500000 2705 "segment length(%d) is less than 16." 2706#else 2707 "segment length(%zd) is less than 16." 2708#endif 2709 "(seg=%d/%d)\n", s->ds_len, i+1, seg); 2710END_DEBUG 2711 if (s->ds_len > SBP_SEG_MAX) 2712 panic("ds_len > SBP_SEG_MAX, fix busdma code"); 2713 ocb->ind_ptr[i].hi = htonl(s->ds_len << 16); 2714 ocb->ind_ptr[i].lo = htonl(s->ds_addr); 2715 } 2716 ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg); 2717 } 2718 2719 if (seg > 0) 2720 bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap, 2721 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ? 2722 BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 2723 prev = sbp_enqueue_ocb(ocb->sdev, ocb); 2724 fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE); 2725 if (use_doorbell) { 2726 if (prev == NULL) { 2727 if (ocb->sdev->last_ocb != NULL) 2728 sbp_doorbell(ocb->sdev); 2729 else 2730 sbp_orb_pointer(ocb->sdev, ocb); 2731 } 2732 } else { 2733 if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) { 2734 ocb->sdev->flags &= ~ORB_LINK_DEAD; 2735 sbp_orb_pointer(ocb->sdev, ocb); 2736 } 2737 } 2738} 2739 2740static void 2741sbp_poll(struct cam_sim *sim) 2742{ 2743 struct sbp_softc *sbp; 2744 struct firewire_comm *fc; 2745 2746 sbp = (struct sbp_softc *)sim->softc; 2747 fc = sbp->fd.fc; 2748 2749 fc->poll(fc, 0, -1); 2750 2751 return; 2752} 2753 2754static struct sbp_ocb * 2755sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status) 2756{ 2757 struct sbp_ocb *ocb; 2758 struct sbp_ocb *next; 2759 int s = splfw(), order = 0; 2760 int flags; 2761 2762SBP_DEBUG(1) 2763 sbp_show_sdev_info(sdev, 2); 2764#if defined(__DragonFly__) || __FreeBSD_version < 500000 2765 printf("%s: 0x%08lx src %d\n", 2766#else 2767 printf("%s: 0x%08x src %d\n", 2768#endif 2769 __func__, ntohl(sbp_status->orb_lo), sbp_status->src); 2770END_DEBUG 2771 SBP_LOCK(sdev->target->sbp); 2772 for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) { 2773 next = STAILQ_NEXT(ocb, ocb); 2774 flags = ocb->flags; 2775 if (OCB_MATCH(ocb, sbp_status)) { 2776 /* found */ 2777 STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb); 2778 if (ocb->ccb != NULL) 2779 untimeout(sbp_timeout, (caddr_t)ocb, 2780 ocb->ccb->ccb_h.timeout_ch); 2781 if (ntohl(ocb->orb[4]) & 0xffff) { 2782 bus_dmamap_sync(sdev->target->sbp->dmat, 2783 ocb->dmamap, 2784 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ? 2785 BUS_DMASYNC_POSTREAD : 2786 BUS_DMASYNC_POSTWRITE); 2787 bus_dmamap_unload(sdev->target->sbp->dmat, 2788 ocb->dmamap); 2789 } 2790 if (!use_doorbell) { 2791 if (sbp_status->src == SRC_NO_NEXT) { 2792 if (next != NULL) 2793 sbp_orb_pointer(sdev, next); 2794 else if (order > 0) { 2795 /* 2796 * Unordered execution 2797 * We need to send pointer for 2798 * next ORB 2799 */ 2800 sdev->flags |= ORB_LINK_DEAD; 2801 } 2802 } 2803 } else { 2804 /* 2805 * XXX this is not correct for unordered 2806 * execution. 2807 */ 2808 if (sdev->last_ocb != NULL) { 2809 SBP_UNLOCK(sdev->target->sbp); 2810 sbp_free_ocb(sdev, sdev->last_ocb); 2811 SBP_LOCK(sdev->target->sbp); 2812 } 2813 sdev->last_ocb = ocb; 2814 if (next != NULL && 2815 sbp_status->src == SRC_NO_NEXT) 2816 sbp_doorbell(sdev); 2817 } 2818 break; 2819 } else 2820 order ++; 2821 } 2822 SBP_UNLOCK(sdev->target->sbp); 2823 splx(s); 2824SBP_DEBUG(0) 2825 if (ocb && order > 0) { 2826 sbp_show_sdev_info(sdev, 2); 2827 printf("unordered execution order:%d\n", order); 2828 } 2829END_DEBUG 2830 return (ocb); 2831} 2832 2833static struct sbp_ocb * 2834sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb) 2835{ 2836 int s = splfw(); 2837 struct sbp_ocb *prev, *prev2; 2838 2839 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); 2840SBP_DEBUG(1) 2841 sbp_show_sdev_info(sdev, 2); 2842#if defined(__DragonFly__) || __FreeBSD_version < 500000 2843 printf("%s: 0x%08x\n", __func__, ocb->bus_addr); 2844#else 2845 printf("%s: 0x%08jx\n", __func__, (uintmax_t)ocb->bus_addr); 2846#endif 2847END_DEBUG 2848 prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb); 2849 STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb); 2850 2851 if (ocb->ccb != NULL) 2852 ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb, 2853 (ocb->ccb->ccb_h.timeout * hz) / 1000); 2854 2855 if (use_doorbell && prev == NULL) 2856 prev2 = sdev->last_ocb; 2857 2858 if (prev2 != NULL && (ocb->sdev->flags & ORB_LINK_DEAD) == 0) { 2859SBP_DEBUG(1) 2860#if defined(__DragonFly__) || __FreeBSD_version < 500000 2861 printf("linking chain 0x%x -> 0x%x\n", 2862 prev2->bus_addr, ocb->bus_addr); 2863#else 2864 printf("linking chain 0x%jx -> 0x%jx\n", 2865 (uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr); 2866#endif 2867END_DEBUG 2868 /* 2869 * Suppress compiler optimization so that orb[1] must be written first. 2870 * XXX We may need an explicit memory barrier for other architectures 2871 * other than i386/amd64. 2872 */ 2873 *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr); 2874 *(volatile uint32_t *)&prev2->orb[0] = 0; 2875 } 2876 splx(s); 2877 2878 return prev; 2879} 2880 2881static struct sbp_ocb * 2882sbp_get_ocb(struct sbp_dev *sdev) 2883{ 2884 struct sbp_ocb *ocb; 2885 int s = splfw(); 2886 2887 mtx_assert(&sdev->target->sbp->mtx, MA_OWNED); 2888 ocb = STAILQ_FIRST(&sdev->free_ocbs); 2889 if (ocb == NULL) { 2890 sdev->flags |= ORB_SHORTAGE; 2891 printf("ocb shortage!!!\n"); 2892 splx(s); 2893 return NULL; 2894 } 2895 STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb); 2896 splx(s); 2897 ocb->ccb = NULL; 2898 return (ocb); 2899} 2900 2901static void 2902sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb) 2903{ 2904 ocb->flags = 0; 2905 ocb->ccb = NULL; 2906 2907 SBP_LOCK(sdev->target->sbp); 2908 STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb); 2909 if ((sdev->flags & ORB_SHORTAGE) != 0) { 2910 int count; 2911 2912 sdev->flags &= ~ORB_SHORTAGE; 2913 count = sdev->freeze; 2914 sdev->freeze = 0; 2915 xpt_release_devq(sdev->path, count, TRUE); 2916 } 2917 SBP_UNLOCK(sdev->target->sbp); 2918} 2919 2920static void 2921sbp_abort_ocb(struct sbp_ocb *ocb, int status) 2922{ 2923 struct sbp_dev *sdev; 2924 2925 sdev = ocb->sdev; 2926SBP_DEBUG(0) 2927 sbp_show_sdev_info(sdev, 2); 2928#if defined(__DragonFly__) || __FreeBSD_version < 500000 2929 printf("sbp_abort_ocb 0x%x\n", ocb->bus_addr); 2930#else 2931 printf("sbp_abort_ocb 0x%jx\n", (uintmax_t)ocb->bus_addr); 2932#endif 2933END_DEBUG 2934SBP_DEBUG(1) 2935 if (ocb->ccb != NULL) 2936 sbp_print_scsi_cmd(ocb); 2937END_DEBUG 2938 if (ntohl(ocb->orb[4]) & 0xffff) { 2939 bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap, 2940 (ntohl(ocb->orb[4]) & ORB_CMD_IN) ? 2941 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 2942 bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap); 2943 } 2944 if (ocb->ccb != NULL) { 2945 untimeout(sbp_timeout, (caddr_t)ocb, 2946 ocb->ccb->ccb_h.timeout_ch); 2947 ocb->ccb->ccb_h.status = status; 2948 SBP_LOCK(sdev->target->sbp); 2949 xpt_done(ocb->ccb); 2950 SBP_UNLOCK(sdev->target->sbp); 2951 } 2952 sbp_free_ocb(sdev, ocb); 2953} 2954 2955static void 2956sbp_abort_all_ocbs(struct sbp_dev *sdev, int status) 2957{ 2958 int s; 2959 struct sbp_ocb *ocb, *next; 2960 STAILQ_HEAD(, sbp_ocb) temp; 2961 2962 s = splfw(); 2963 2964 STAILQ_INIT(&temp); 2965 SBP_LOCK(sdev->target->sbp); 2966 STAILQ_CONCAT(&temp, &sdev->ocbs); 2967 STAILQ_INIT(&sdev->ocbs); 2968 SBP_UNLOCK(sdev->target->sbp); 2969 2970 for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) { 2971 next = STAILQ_NEXT(ocb, ocb); 2972 sbp_abort_ocb(ocb, status); 2973 } 2974 if (sdev->last_ocb != NULL) { 2975 sbp_free_ocb(sdev, sdev->last_ocb); 2976 sdev->last_ocb = NULL; 2977 } 2978 2979 splx(s); 2980} 2981 2982static devclass_t sbp_devclass; 2983 2984static device_method_t sbp_methods[] = { 2985 /* device interface */ 2986 DEVMETHOD(device_identify, sbp_identify), 2987 DEVMETHOD(device_probe, sbp_probe), 2988 DEVMETHOD(device_attach, sbp_attach), 2989 DEVMETHOD(device_detach, sbp_detach), 2990 DEVMETHOD(device_shutdown, sbp_shutdown), 2991 2992 { 0, 0 } 2993}; 2994 2995static driver_t sbp_driver = { 2996 "sbp", 2997 sbp_methods, 2998 sizeof(struct sbp_softc), 2999}; 3000#ifdef __DragonFly__ 3001DECLARE_DUMMY_MODULE(sbp); 3002#endif 3003DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0); 3004MODULE_VERSION(sbp, 1); 3005MODULE_DEPEND(sbp, firewire, 1, 1, 1); 3006MODULE_DEPEND(sbp, cam, 1, 1, 1);
|