scsi_da.c (166861) | scsi_da.c (168752) |
---|---|
1/*- 2 * Implementation of SCSI Direct Access Peripheral driver for CAM. 3 * 4 * Copyright (c) 1997 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Implementation of SCSI Direct Access Peripheral driver for CAM. 3 * 4 * Copyright (c) 1997 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 166861 2007-02-21 07:45:02Z n_hibma $"); | 30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_da.c 168752 2007-04-15 08:49:19Z scottl $"); |
31 32#include <sys/param.h> 33 34#ifdef _KERNEL 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/bio.h> 38#include <sys/sysctl.h> 39#include <sys/taskqueue.h> | 31 32#include <sys/param.h> 33 34#ifdef _KERNEL 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/bio.h> 38#include <sys/sysctl.h> 39#include <sys/taskqueue.h> |
40#include <sys/lock.h> 41#include <sys/mutex.h> |
|
40#endif /* _KERNEL */ 41 42#include <sys/devicestat.h> 43#include <sys/conf.h> 44#include <sys/eventhandler.h> 45#include <sys/malloc.h> 46#include <sys/cons.h> 47 --- 8 unchanged lines hidden (view full) --- 56#include <stdio.h> 57#include <string.h> 58#endif /* _KERNEL */ 59 60#include <cam/cam.h> 61#include <cam/cam_ccb.h> 62#include <cam/cam_periph.h> 63#include <cam/cam_xpt_periph.h> | 42#endif /* _KERNEL */ 43 44#include <sys/devicestat.h> 45#include <sys/conf.h> 46#include <sys/eventhandler.h> 47#include <sys/malloc.h> 48#include <sys/cons.h> 49 --- 8 unchanged lines hidden (view full) --- 58#include <stdio.h> 59#include <string.h> 60#endif /* _KERNEL */ 61 62#include <cam/cam.h> 63#include <cam/cam_ccb.h> 64#include <cam/cam_periph.h> 65#include <cam/cam_xpt_periph.h> |
66#include <cam/cam_sim.h> |
|
64 65#include <cam/scsi/scsi_message.h> 66 67#ifndef _KERNEL 68#include <cam/scsi/scsi_da.h> 69#endif /* !_KERNEL */ 70 71#ifdef _KERNEL --- 56 unchanged lines hidden (view full) --- 128 int ordered_tag_count; 129 int outstanding_cmds; 130 struct disk_params params; 131 struct disk *disk; 132 union ccb saved_ccb; 133 struct task sysctl_task; 134 struct sysctl_ctx_list sysctl_ctx; 135 struct sysctl_oid *sysctl_tree; | 67 68#include <cam/scsi/scsi_message.h> 69 70#ifndef _KERNEL 71#include <cam/scsi/scsi_da.h> 72#endif /* !_KERNEL */ 73 74#ifdef _KERNEL --- 56 unchanged lines hidden (view full) --- 131 int ordered_tag_count; 132 int outstanding_cmds; 133 struct disk_params params; 134 struct disk *disk; 135 union ccb saved_ccb; 136 struct task sysctl_task; 137 struct sysctl_ctx_list sysctl_ctx; 138 struct sysctl_oid *sysctl_tree; |
139 struct callout sendordered_c; |
|
136}; 137 138struct da_quirk_entry { 139 struct scsi_inquiry_pattern inq_pat; 140 da_quirks quirks; 141}; 142 143static const char quantum[] = "QUANTUM"; --- 402 unchanged lines hidden (view full) --- 546static struct periph_driver dadriver = 547{ 548 dainit, "da", 549 TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0 550}; 551 552PERIPHDRIVER_DECLARE(da, dadriver); 553 | 140}; 141 142struct da_quirk_entry { 143 struct scsi_inquiry_pattern inq_pat; 144 da_quirks quirks; 145}; 146 147static const char quantum[] = "QUANTUM"; --- 402 unchanged lines hidden (view full) --- 550static struct periph_driver dadriver = 551{ 552 dainit, "da", 553 TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0 554}; 555 556PERIPHDRIVER_DECLARE(da, dadriver); 557 |
554static SLIST_HEAD(,da_softc) softc_list; 555 | |
556static int 557daopen(struct disk *dp) 558{ 559 struct cam_periph *periph; 560 struct da_softc *softc; 561 int unit; 562 int error; | 558static int 559daopen(struct disk *dp) 560{ 561 struct cam_periph *periph; 562 struct da_softc *softc; 563 int unit; 564 int error; |
563 int s; | |
564 | 565 |
565 s = splsoftcam(); | |
566 periph = (struct cam_periph *)dp->d_drv1; 567 if (periph == NULL) { | 566 periph = (struct cam_periph *)dp->d_drv1; 567 if (periph == NULL) { |
568 splx(s); | |
569 return (ENXIO); 570 } | 568 return (ENXIO); 569 } |
571 unit = periph->unit_number; | |
572 | 570 |
571 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 572 return(ENXIO); 573 } 574 575 cam_periph_lock(periph); 576 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { 577 cam_periph_unlock(periph); 578 cam_periph_release(periph); 579 return (error); 580 } 581 582 unit = periph->unit_number; |
|
573 softc = (struct da_softc *)periph->softc; | 583 softc = (struct da_softc *)periph->softc; |
584 softc->flags |= DA_FLAG_OPEN; |
|
574 575 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 576 ("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit, 577 unit)); 578 | 585 586 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 587 ("daopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit, 588 unit)); 589 |
579 if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) 580 return (error); /* error code from tsleep */ 581 582 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 583 return(ENXIO); 584 softc->flags |= DA_FLAG_OPEN; 585 | |
586 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) { 587 /* Invalidate our pack information. */ 588 softc->flags &= ~DA_FLAG_PACK_INVALID; 589 } | 590 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) { 591 /* Invalidate our pack information. */ 592 softc->flags &= ~DA_FLAG_PACK_INVALID; 593 } |
590 splx(s); | |
591 592 error = dagetcapacity(periph); 593 594 if (error == 0) { 595 596 softc->disk->d_sectorsize = softc->params.secsize; 597 softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; 598 /* XXX: these are not actually "firmware" values, so they may be wrong */ --- 6 unchanged lines hidden (view full) --- 605 if (error == 0) { 606 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && 607 (softc->quirks & DA_Q_NO_PREVENT) == 0) 608 daprevent(periph, PR_PREVENT); 609 } else { 610 softc->flags &= ~DA_FLAG_OPEN; 611 cam_periph_release(periph); 612 } | 594 595 error = dagetcapacity(periph); 596 597 if (error == 0) { 598 599 softc->disk->d_sectorsize = softc->params.secsize; 600 softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; 601 /* XXX: these are not actually "firmware" values, so they may be wrong */ --- 6 unchanged lines hidden (view full) --- 608 if (error == 0) { 609 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && 610 (softc->quirks & DA_Q_NO_PREVENT) == 0) 611 daprevent(periph, PR_PREVENT); 612 } else { 613 softc->flags &= ~DA_FLAG_OPEN; 614 cam_periph_release(periph); 615 } |
616 cam_periph_unhold(periph); |
|
613 cam_periph_unlock(periph); 614 return (error); 615} 616 617static int 618daclose(struct disk *dp) 619{ 620 struct cam_periph *periph; 621 struct da_softc *softc; | 617 cam_periph_unlock(periph); 618 return (error); 619} 620 621static int 622daclose(struct disk *dp) 623{ 624 struct cam_periph *periph; 625 struct da_softc *softc; |
622 int error; | 626 int error; |
623 624 periph = (struct cam_periph *)dp->d_drv1; 625 if (periph == NULL) 626 return (ENXIO); 627 | 627 628 periph = (struct cam_periph *)dp->d_drv1; 629 if (periph == NULL) 630 return (ENXIO); 631 |
628 softc = (struct da_softc *)periph->softc; 629 630 if ((error = cam_periph_lock(periph, PRIBIO)) != 0) { 631 return (error); /* error code from tsleep */ | 632 cam_periph_lock(periph); 633 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { 634 cam_periph_unlock(periph); 635 cam_periph_release(periph); 636 return (error); |
632 } 633 | 637 } 638 |
639 softc = (struct da_softc *)periph->softc; 640 |
|
634 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { 635 union ccb *ccb; 636 637 ccb = cam_periph_getccb(periph, /*priority*/1); 638 639 scsi_synchronize_cache(&ccb->csio, 640 /*retries*/1, 641 /*cbfcnp*/dadone, --- 45 unchanged lines hidden (view full) --- 687 * If we've got removeable media, mark the blocksize as 688 * unavailable, since it could change when new media is 689 * inserted. 690 */ 691 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE; 692 } 693 694 softc->flags &= ~DA_FLAG_OPEN; | 641 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { 642 union ccb *ccb; 643 644 ccb = cam_periph_getccb(periph, /*priority*/1); 645 646 scsi_synchronize_cache(&ccb->csio, 647 /*retries*/1, 648 /*cbfcnp*/dadone, --- 45 unchanged lines hidden (view full) --- 694 * If we've got removeable media, mark the blocksize as 695 * unavailable, since it could change when new media is 696 * inserted. 697 */ 698 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE; 699 } 700 701 softc->flags &= ~DA_FLAG_OPEN; |
702 cam_periph_unhold(periph); |
|
695 cam_periph_unlock(periph); 696 cam_periph_release(periph); 697 return (0); 698} 699 700/* 701 * Actually translate the requested transfer into one the physical driver 702 * can understand. The transfer is described by a buf and will include 703 * only one physical transfer. 704 */ 705static void 706dastrategy(struct bio *bp) 707{ 708 struct cam_periph *periph; 709 struct da_softc *softc; | 703 cam_periph_unlock(periph); 704 cam_periph_release(periph); 705 return (0); 706} 707 708/* 709 * Actually translate the requested transfer into one the physical driver 710 * can understand. The transfer is described by a buf and will include 711 * only one physical transfer. 712 */ 713static void 714dastrategy(struct bio *bp) 715{ 716 struct cam_periph *periph; 717 struct da_softc *softc; |
710 int s; | |
711 712 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 713 if (periph == NULL) { 714 biofinish(bp, NULL, ENXIO); 715 return; 716 } 717 softc = (struct da_softc *)periph->softc; | 718 719 periph = (struct cam_periph *)bp->bio_disk->d_drv1; 720 if (periph == NULL) { 721 biofinish(bp, NULL, ENXIO); 722 return; 723 } 724 softc = (struct da_softc *)periph->softc; |
725 726 cam_periph_lock(periph); 727 |
|
718#if 0 719 /* 720 * check it's not too big a transfer for our adapter 721 */ 722 scsi_minphys(bp,&sd_switch); 723#endif 724 725 /* 726 * Mask interrupts so that the pack cannot be invalidated until 727 * after we are in the queue. Otherwise, we might not properly 728 * clean up one of the buffers. 729 */ | 728#if 0 729 /* 730 * check it's not too big a transfer for our adapter 731 */ 732 scsi_minphys(bp,&sd_switch); 733#endif 734 735 /* 736 * Mask interrupts so that the pack cannot be invalidated until 737 * after we are in the queue. Otherwise, we might not properly 738 * clean up one of the buffers. 739 */ |
730 s = splbio(); | |
731 732 /* 733 * If the device has been made invalid, error out 734 */ 735 if ((softc->flags & DA_FLAG_PACK_INVALID)) { | 740 741 /* 742 * If the device has been made invalid, error out 743 */ 744 if ((softc->flags & DA_FLAG_PACK_INVALID)) { |
736 splx(s); | 745 cam_periph_unlock(periph); |
737 biofinish(bp, NULL, ENXIO); 738 return; 739 } 740 741 /* 742 * Place it in the queue of disk activities for this disk 743 */ 744 bioq_disksort(&softc->bio_queue, bp); 745 | 746 biofinish(bp, NULL, ENXIO); 747 return; 748 } 749 750 /* 751 * Place it in the queue of disk activities for this disk 752 */ 753 bioq_disksort(&softc->bio_queue, bp); 754 |
746 splx(s); 747 | |
748 /* 749 * Schedule ourselves for performing the work. 750 */ 751 xpt_schedule(periph, /* XXX priority */1); | 755 /* 756 * Schedule ourselves for performing the work. 757 */ 758 xpt_schedule(periph, /* XXX priority */1); |
759 cam_periph_unlock(periph); |
|
752 753 return; 754} 755 756static int 757dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) 758{ 759 struct cam_periph *periph; --- 8 unchanged lines hidden (view full) --- 768 return (ENXIO); 769 softc = (struct da_softc *)periph->softc; 770 secsize = softc->params.secsize; 771 772 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) 773 return (ENXIO); 774 775 if (length > 0) { | 760 761 return; 762} 763 764static int 765dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) 766{ 767 struct cam_periph *periph; --- 8 unchanged lines hidden (view full) --- 776 return (ENXIO); 777 softc = (struct da_softc *)periph->softc; 778 secsize = softc->params.secsize; 779 780 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) 781 return (ENXIO); 782 783 if (length > 0) { |
784 periph->flags |= CAM_PERIPH_POLLED; |
|
776 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1); 777 csio.ccb_h.ccb_state = DA_CCB_DUMP; 778 scsi_read_write(&csio, 779 /*retries*/1, 780 dadone, 781 MSG_ORDERED_Q_TAG, 782 /*read*/FALSE, 783 /*byte2*/0, --- 9 unchanged lines hidden (view full) --- 793 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 794 printf("Aborting dump due to I/O error.\n"); 795 if ((csio.ccb_h.status & CAM_STATUS_MASK) == 796 CAM_SCSI_STATUS_ERROR) 797 scsi_sense_print(&csio); 798 else 799 printf("status == 0x%x, scsi status == 0x%x\n", 800 csio.ccb_h.status, csio.scsi_status); | 785 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1); 786 csio.ccb_h.ccb_state = DA_CCB_DUMP; 787 scsi_read_write(&csio, 788 /*retries*/1, 789 dadone, 790 MSG_ORDERED_Q_TAG, 791 /*read*/FALSE, 792 /*byte2*/0, --- 9 unchanged lines hidden (view full) --- 802 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 803 printf("Aborting dump due to I/O error.\n"); 804 if ((csio.ccb_h.status & CAM_STATUS_MASK) == 805 CAM_SCSI_STATUS_ERROR) 806 scsi_sense_print(&csio); 807 else 808 printf("status == 0x%x, scsi status == 0x%x\n", 809 csio.ccb_h.status, csio.scsi_status); |
810 periph->flags |= CAM_PERIPH_POLLED; |
|
801 return(EIO); 802 } 803 return(0); | 811 return(EIO); 812 } 813 return(0); |
804 } | 814 } |
805 806 /* 807 * Sync the disk cache contents to the physical media. 808 */ 809 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { 810 811 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1); 812 csio.ccb_h.ccb_state = DA_CCB_DUMP; --- 22 unchanged lines hidden (view full) --- 835 } else { 836 xpt_print(periph->path, "Synchronize cache " 837 "failed, status == 0x%x, scsi status == " 838 "0x%x\n", csio.ccb_h.status, 839 csio.scsi_status); 840 } 841 } 842 } | 815 816 /* 817 * Sync the disk cache contents to the physical media. 818 */ 819 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { 820 821 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1); 822 csio.ccb_h.ccb_state = DA_CCB_DUMP; --- 22 unchanged lines hidden (view full) --- 845 } else { 846 xpt_print(periph->path, "Synchronize cache " 847 "failed, status == 0x%x, scsi status == " 848 "0x%x\n", csio.ccb_h.status, 849 csio.scsi_status); 850 } 851 } 852 } |
853 periph->flags &= ~CAM_PERIPH_POLLED; |
|
843 return (0); 844} 845 846static void 847dainit(void) 848{ 849 cam_status status; 850 struct cam_path *path; 851 | 854 return (0); 855} 856 857static void 858dainit(void) 859{ 860 cam_status status; 861 struct cam_path *path; 862 |
852 SLIST_INIT(&softc_list); 853 | |
854 /* 855 * Install a global async callback. This callback will 856 * receive async callbacks like "new device found". 857 */ 858 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID, 859 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 860 861 if (status == CAM_REQ_CMP) { --- 9 unchanged lines hidden (view full) --- 871 xpt_free_path(path); 872 } 873 874 if (status != CAM_REQ_CMP) { 875 printf("da: Failed to attach master async callback " 876 "due to status 0x%x!\n", status); 877 } else if (da_send_ordered) { 878 | 863 /* 864 * Install a global async callback. This callback will 865 * receive async callbacks like "new device found". 866 */ 867 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID, 868 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 869 870 if (status == CAM_REQ_CMP) { --- 9 unchanged lines hidden (view full) --- 880 xpt_free_path(path); 881 } 882 883 if (status != CAM_REQ_CMP) { 884 printf("da: Failed to attach master async callback " 885 "due to status 0x%x!\n", status); 886 } else if (da_send_ordered) { 887 |
879 /* 880 * Schedule a periodic event to occasionally send an 881 * ordered tag to a device. 882 */ 883 timeout(dasendorderedtag, NULL, 884 (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL); 885 | |
886 /* Register our shutdown event handler */ 887 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 888 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) 889 printf("dainit: shutdown event registration failed!\n"); 890 } 891} 892 893static void 894daoninvalidate(struct cam_periph *periph) 895{ | 888 /* Register our shutdown event handler */ 889 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 890 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) 891 printf("dainit: shutdown event registration failed!\n"); 892 } 893} 894 895static void 896daoninvalidate(struct cam_periph *periph) 897{ |
896 int s; | |
897 struct da_softc *softc; 898 struct ccb_setasync csa; 899 900 softc = (struct da_softc *)periph->softc; 901 902 /* 903 * De-register any async callbacks. 904 */ 905 xpt_setup_ccb(&csa.ccb_h, periph->path, 906 /* priority */ 5); 907 csa.ccb_h.func_code = XPT_SASYNC_CB; 908 csa.event_enable = 0; 909 csa.callback = daasync; 910 csa.callback_arg = periph; 911 xpt_action((union ccb *)&csa); 912 913 softc->flags |= DA_FLAG_PACK_INVALID; 914 915 /* | 898 struct da_softc *softc; 899 struct ccb_setasync csa; 900 901 softc = (struct da_softc *)periph->softc; 902 903 /* 904 * De-register any async callbacks. 905 */ 906 xpt_setup_ccb(&csa.ccb_h, periph->path, 907 /* priority */ 5); 908 csa.ccb_h.func_code = XPT_SASYNC_CB; 909 csa.event_enable = 0; 910 csa.callback = daasync; 911 csa.callback_arg = periph; 912 xpt_action((union ccb *)&csa); 913 914 softc->flags |= DA_FLAG_PACK_INVALID; 915 916 /* |
916 * Although the oninvalidate() routines are always called at 917 * splsoftcam, we need to be at splbio() here to keep the buffer 918 * queue from being modified while we traverse it. 919 */ 920 s = splbio(); 921 922 /* | |
923 * Return all queued I/O with ENXIO. 924 * XXX Handle any transactions queued to the card 925 * with XPT_ABORT_CCB. 926 */ 927 bioq_flush(&softc->bio_queue, NULL, ENXIO); | 917 * Return all queued I/O with ENXIO. 918 * XXX Handle any transactions queued to the card 919 * with XPT_ABORT_CCB. 920 */ 921 bioq_flush(&softc->bio_queue, NULL, ENXIO); |
928 splx(s); | |
929 | 922 |
930 SLIST_REMOVE(&softc_list, softc, da_softc, links); 931 | |
932 disk_gone(softc->disk); 933 xpt_print(periph->path, "lost device\n"); 934} 935 936static void 937dacleanup(struct cam_periph *periph) 938{ 939 struct da_softc *softc; --- 4 unchanged lines hidden (view full) --- 944 /* 945 * If we can't free the sysctl tree, oh well... 946 */ 947 if ((softc->flags & DA_FLAG_SCTX_INIT) != 0 948 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { 949 xpt_print(periph->path, "can't remove sysctl context\n"); 950 } 951 disk_destroy(softc->disk); | 923 disk_gone(softc->disk); 924 xpt_print(periph->path, "lost device\n"); 925} 926 927static void 928dacleanup(struct cam_periph *periph) 929{ 930 struct da_softc *softc; --- 4 unchanged lines hidden (view full) --- 935 /* 936 * If we can't free the sysctl tree, oh well... 937 */ 938 if ((softc->flags & DA_FLAG_SCTX_INIT) != 0 939 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { 940 xpt_print(periph->path, "can't remove sysctl context\n"); 941 } 942 disk_destroy(softc->disk); |
943 944 /* 945 * XXX Gotta drop the periph lock so that the drain can complete with 946 * deadlocking on the lock. Hopefully dropping here is safe. 947 */ 948 cam_periph_unlock(periph); 949 callout_drain(&softc->sendordered_c); 950 cam_periph_lock(periph); |
|
952 free(softc, M_DEVBUF); 953} 954 955static void 956daasync(void *callback_arg, u_int32_t code, 957 struct cam_path *path, void *arg) 958{ 959 struct cam_periph *periph; 960 961 periph = (struct cam_periph *)callback_arg; 962 switch (code) { 963 case AC_FOUND_DEVICE: 964 { 965 struct ccb_getdev *cgd; | 951 free(softc, M_DEVBUF); 952} 953 954static void 955daasync(void *callback_arg, u_int32_t code, 956 struct cam_path *path, void *arg) 957{ 958 struct cam_periph *periph; 959 960 periph = (struct cam_periph *)callback_arg; 961 switch (code) { 962 case AC_FOUND_DEVICE: 963 { 964 struct ccb_getdev *cgd; |
965 struct cam_sim *sim; |
|
966 cam_status status; 967 968 cgd = (struct ccb_getdev *)arg; 969 if (cgd == NULL) 970 break; 971 972 if (SID_TYPE(&cgd->inq_data) != T_DIRECT 973 && SID_TYPE(&cgd->inq_data) != T_RBC 974 && SID_TYPE(&cgd->inq_data) != T_OPTICAL) 975 break; 976 977 /* 978 * Allocate a peripheral instance for 979 * this device and start the probe 980 * process. 981 */ | 966 cam_status status; 967 968 cgd = (struct ccb_getdev *)arg; 969 if (cgd == NULL) 970 break; 971 972 if (SID_TYPE(&cgd->inq_data) != T_DIRECT 973 && SID_TYPE(&cgd->inq_data) != T_RBC 974 && SID_TYPE(&cgd->inq_data) != T_OPTICAL) 975 break; 976 977 /* 978 * Allocate a peripheral instance for 979 * this device and start the probe 980 * process. 981 */ |
982 sim = xpt_path_sim(cgd->ccb_h.path); |
|
982 status = cam_periph_alloc(daregister, daoninvalidate, 983 dacleanup, dastart, 984 "da", CAM_PERIPH_BIO, 985 cgd->ccb_h.path, daasync, 986 AC_FOUND_DEVICE, cgd); 987 988 if (status != CAM_REQ_CMP 989 && status != CAM_REQ_INPROG) 990 printf("daasync: Unable to attach to new device " 991 "due to status 0x%x\n", status); 992 break; 993 } 994 case AC_SENT_BDR: 995 case AC_BUS_RESET: 996 { 997 struct da_softc *softc; 998 struct ccb_hdr *ccbh; | 983 status = cam_periph_alloc(daregister, daoninvalidate, 984 dacleanup, dastart, 985 "da", CAM_PERIPH_BIO, 986 cgd->ccb_h.path, daasync, 987 AC_FOUND_DEVICE, cgd); 988 989 if (status != CAM_REQ_CMP 990 && status != CAM_REQ_INPROG) 991 printf("daasync: Unable to attach to new device " 992 "due to status 0x%x\n", status); 993 break; 994 } 995 case AC_SENT_BDR: 996 case AC_BUS_RESET: 997 { 998 struct da_softc *softc; 999 struct ccb_hdr *ccbh; |
999 int s; | |
1000 1001 softc = (struct da_softc *)periph->softc; | 1000 1001 softc = (struct da_softc *)periph->softc; |
1002 s = splsoftcam(); | |
1003 /* 1004 * Don't fail on the expected unit attention 1005 * that will occur. 1006 */ 1007 softc->flags |= DA_FLAG_RETRY_UA; 1008 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 1009 ccbh->ccb_state |= DA_CCB_RETRY_UA; | 1002 /* 1003 * Don't fail on the expected unit attention 1004 * that will occur. 1005 */ 1006 softc->flags |= DA_FLAG_RETRY_UA; 1007 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) 1008 ccbh->ccb_state |= DA_CCB_RETRY_UA; |
1010 splx(s); | |
1011 /* FALLTHROUGH*/ 1012 } 1013 default: 1014 cam_periph_async(periph, code, path, arg); 1015 break; 1016 } 1017} 1018 1019static void 1020dasysctlinit(void *context, int pending) 1021{ 1022 struct cam_periph *periph; 1023 struct da_softc *softc; 1024 char tmpstr[80], tmpstr2[80]; 1025 1026 periph = (struct cam_periph *)context; | 1009 /* FALLTHROUGH*/ 1010 } 1011 default: 1012 cam_periph_async(periph, code, path, arg); 1013 break; 1014 } 1015} 1016 1017static void 1018dasysctlinit(void *context, int pending) 1019{ 1020 struct cam_periph *periph; 1021 struct da_softc *softc; 1022 char tmpstr[80], tmpstr2[80]; 1023 1024 periph = (struct cam_periph *)context; |
1027 softc = (struct da_softc *)periph->softc; | 1025 if (cam_periph_acquire(periph) != CAM_REQ_CMP) 1026 return; |
1028 | 1027 |
1028 softc = (struct da_softc *)periph->softc; |
|
1029 snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); 1030 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); 1031 1032 mtx_lock(&Giant); 1033 sysctl_ctx_init(&softc->sysctl_ctx); 1034 softc->flags |= DA_FLAG_SCTX_INIT; 1035 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 1036 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2, 1037 CTLFLAG_RD, 0, tmpstr); 1038 if (softc->sysctl_tree == NULL) { 1039 printf("dasysctlinit: unable to allocate sysctl tree\n"); 1040 mtx_unlock(&Giant); | 1029 snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); 1030 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); 1031 1032 mtx_lock(&Giant); 1033 sysctl_ctx_init(&softc->sysctl_ctx); 1034 softc->flags |= DA_FLAG_SCTX_INIT; 1035 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 1036 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2, 1037 CTLFLAG_RD, 0, tmpstr); 1038 if (softc->sysctl_tree == NULL) { 1039 printf("dasysctlinit: unable to allocate sysctl tree\n"); 1040 mtx_unlock(&Giant); |
1041 cam_periph_release(periph); |
|
1041 return; 1042 } 1043 1044 /* 1045 * Now register the sysctl handler, so the user can the value on 1046 * the fly. 1047 */ 1048 SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), 1049 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, 1050 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I", 1051 "Minimum CDB size"); 1052 1053 mtx_unlock(&Giant); | 1042 return; 1043 } 1044 1045 /* 1046 * Now register the sysctl handler, so the user can the value on 1047 * the fly. 1048 */ 1049 SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), 1050 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, 1051 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I", 1052 "Minimum CDB size"); 1053 1054 mtx_unlock(&Giant); |
1055 cam_periph_release(periph); |
|
1054} 1055 1056static int 1057dacmdsizesysctl(SYSCTL_HANDLER_ARGS) 1058{ 1059 int error, value; 1060 1061 value = *(int *)arg1; --- 21 unchanged lines hidden (view full) --- 1083 *(int *)arg1 = value; 1084 1085 return (0); 1086} 1087 1088static cam_status 1089daregister(struct cam_periph *periph, void *arg) 1090{ | 1056} 1057 1058static int 1059dacmdsizesysctl(SYSCTL_HANDLER_ARGS) 1060{ 1061 int error, value; 1062 1063 value = *(int *)arg1; --- 21 unchanged lines hidden (view full) --- 1085 *(int *)arg1 = value; 1086 1087 return (0); 1088} 1089 1090static cam_status 1091daregister(struct cam_periph *periph, void *arg) 1092{ |
1091 int s; | |
1092 struct da_softc *softc; 1093 struct ccb_setasync csa; 1094 struct ccb_pathinq cpi; 1095 struct ccb_getdev *cgd; 1096 char tmpstr[80]; 1097 caddr_t match; 1098 1099 cgd = (struct ccb_getdev *)arg; --- 73 unchanged lines hidden (view full) --- 1173 softc->minimum_cmd_size = 10; 1174 else if ((softc->minimum_cmd_size > 10) 1175 && (softc->minimum_cmd_size <= 12)) 1176 softc->minimum_cmd_size = 12; 1177 else if (softc->minimum_cmd_size > 12) 1178 softc->minimum_cmd_size = 16; 1179 1180 /* | 1093 struct da_softc *softc; 1094 struct ccb_setasync csa; 1095 struct ccb_pathinq cpi; 1096 struct ccb_getdev *cgd; 1097 char tmpstr[80]; 1098 caddr_t match; 1099 1100 cgd = (struct ccb_getdev *)arg; --- 73 unchanged lines hidden (view full) --- 1174 softc->minimum_cmd_size = 10; 1175 else if ((softc->minimum_cmd_size > 10) 1176 && (softc->minimum_cmd_size <= 12)) 1177 softc->minimum_cmd_size = 12; 1178 else if (softc->minimum_cmd_size > 12) 1179 softc->minimum_cmd_size = 16; 1180 1181 /* |
1181 * Block our timeout handler while we 1182 * add this softc to the dev list. 1183 */ 1184 s = splsoftclock(); 1185 SLIST_INSERT_HEAD(&softc_list, softc, links); 1186 splx(s); 1187 1188 /* | |
1189 * Register this media as a disk 1190 */ 1191 | 1182 * Register this media as a disk 1183 */ 1184 |
1185 mtx_unlock(periph->sim->mtx); |
|
1192 softc->disk = disk_alloc(); 1193 softc->disk->d_open = daopen; 1194 softc->disk->d_close = daclose; 1195 softc->disk->d_strategy = dastrategy; 1196 softc->disk->d_dump = dadump; 1197 softc->disk->d_name = "da"; 1198 softc->disk->d_drv1 = periph; 1199 softc->disk->d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */ 1200 softc->disk->d_unit = periph->unit_number; | 1186 softc->disk = disk_alloc(); 1187 softc->disk->d_open = daopen; 1188 softc->disk->d_close = daclose; 1189 softc->disk->d_strategy = dastrategy; 1190 softc->disk->d_dump = dadump; 1191 softc->disk->d_name = "da"; 1192 softc->disk->d_drv1 = periph; 1193 softc->disk->d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */ 1194 softc->disk->d_unit = periph->unit_number; |
1201 softc->disk->d_flags = DISKFLAG_NEEDSGIANT; | 1195 softc->disk->d_flags = 0; |
1202 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) 1203 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; 1204 disk_create(softc->disk, DISK_VERSION); | 1196 if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) 1197 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; 1198 disk_create(softc->disk, DISK_VERSION); |
1199 mtx_lock(periph->sim->mtx); |
|
1205 1206 /* 1207 * Add async callbacks for bus reset and 1208 * bus device reset calls. I don't bother 1209 * checking if this fails as, in most cases, 1210 * the system will function just fine without 1211 * them and the only alternative would be to 1212 * not attach the device on failure. 1213 */ 1214 xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5); 1215 csa.ccb_h.func_code = XPT_SASYNC_CB; 1216 csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE; 1217 csa.callback = daasync; 1218 csa.callback_arg = periph; 1219 xpt_action((union ccb *)&csa); | 1200 1201 /* 1202 * Add async callbacks for bus reset and 1203 * bus device reset calls. I don't bother 1204 * checking if this fails as, in most cases, 1205 * the system will function just fine without 1206 * them and the only alternative would be to 1207 * not attach the device on failure. 1208 */ 1209 xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5); 1210 csa.ccb_h.func_code = XPT_SASYNC_CB; 1211 csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE; 1212 csa.callback = daasync; 1213 csa.callback_arg = periph; 1214 xpt_action((union ccb *)&csa); |
1215 |
|
1220 /* | 1216 /* |
1221 * Lock this peripheral until we are setup. 1222 * This first call can't block | 1217 * Take an exclusive refcount on the periph while dastart is called 1218 * to finish the probe. The reference will be dropped in dadone at 1219 * the end of probe. |
1223 */ | 1220 */ |
1224 (void)cam_periph_lock(periph, PRIBIO); | 1221 (void)cam_periph_hold(periph, PRIBIO); |
1225 xpt_schedule(periph, /*priority*/5); 1226 | 1222 xpt_schedule(periph, /*priority*/5); 1223 |
1224 /* 1225 * Schedule a periodic event to occasionally send an 1226 * ordered tag to a device. 1227 */ 1228 callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0); 1229 callout_reset(&softc->sendordered_c, 1230 (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL, 1231 dasendorderedtag, softc); 1232 |
|
1227 return(CAM_REQ_CMP); 1228} 1229 1230static void 1231dastart(struct cam_periph *periph, union ccb *start_ccb) 1232{ 1233 struct da_softc *softc; 1234 1235 softc = (struct da_softc *)periph->softc; 1236 | 1233 return(CAM_REQ_CMP); 1234} 1235 1236static void 1237dastart(struct cam_periph *periph, union ccb *start_ccb) 1238{ 1239 struct da_softc *softc; 1240 1241 softc = (struct da_softc *)periph->softc; 1242 |
1237 | |
1238 switch (softc->state) { 1239 case DA_STATE_NORMAL: 1240 { 1241 /* Pull a buffer from the queue and get going on it */ 1242 struct bio *bp; | 1243 switch (softc->state) { 1244 case DA_STATE_NORMAL: 1245 { 1246 /* Pull a buffer from the queue and get going on it */ 1247 struct bio *bp; |
1243 int s; | |
1244 1245 /* 1246 * See if there is a buf with work for us to do.. 1247 */ | 1248 1249 /* 1250 * See if there is a buf with work for us to do.. 1251 */ |
1248 s = splbio(); | |
1249 bp = bioq_first(&softc->bio_queue); 1250 if (periph->immediate_priority <= periph->pinfo.priority) { 1251 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 1252 ("queuing for immediate ccb\n")); 1253 start_ccb->ccb_h.ccb_state = DA_CCB_WAITING; 1254 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 1255 periph_links.sle); 1256 periph->immediate_priority = CAM_PRIORITY_NONE; | 1252 bp = bioq_first(&softc->bio_queue); 1253 if (periph->immediate_priority <= periph->pinfo.priority) { 1254 CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, 1255 ("queuing for immediate ccb\n")); 1256 start_ccb->ccb_h.ccb_state = DA_CCB_WAITING; 1257 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 1258 periph_links.sle); 1259 periph->immediate_priority = CAM_PRIORITY_NONE; |
1257 splx(s); | |
1258 wakeup(&periph->ccb_list); 1259 } else if (bp == NULL) { | 1260 wakeup(&periph->ccb_list); 1261 } else if (bp == NULL) { |
1260 splx(s); | |
1261 xpt_release_ccb(start_ccb); 1262 } else { | 1262 xpt_release_ccb(start_ccb); 1263 } else { |
1263 int oldspl; | |
1264 u_int8_t tag_code; 1265 1266 bioq_remove(&softc->bio_queue, bp); 1267 1268 if ((softc->flags & DA_FLAG_NEED_OTAG) != 0) { 1269 softc->flags &= ~DA_FLAG_NEED_OTAG; 1270 softc->ordered_tag_count++; 1271 tag_code = MSG_ORDERED_Q_TAG; --- 30 unchanged lines hidden (view full) --- 1302 break; 1303 } 1304 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO; 1305 1306 /* 1307 * Block out any asyncronous callbacks 1308 * while we touch the pending ccb list. 1309 */ | 1264 u_int8_t tag_code; 1265 1266 bioq_remove(&softc->bio_queue, bp); 1267 1268 if ((softc->flags & DA_FLAG_NEED_OTAG) != 0) { 1269 softc->flags &= ~DA_FLAG_NEED_OTAG; 1270 softc->ordered_tag_count++; 1271 tag_code = MSG_ORDERED_Q_TAG; --- 30 unchanged lines hidden (view full) --- 1302 break; 1303 } 1304 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO; 1305 1306 /* 1307 * Block out any asyncronous callbacks 1308 * while we touch the pending ccb list. 1309 */ |
1310 oldspl = splcam(); | |
1311 LIST_INSERT_HEAD(&softc->pending_ccbs, 1312 &start_ccb->ccb_h, periph_links.le); 1313 softc->outstanding_cmds++; | 1310 LIST_INSERT_HEAD(&softc->pending_ccbs, 1311 &start_ccb->ccb_h, periph_links.le); 1312 softc->outstanding_cmds++; |
1314 splx(oldspl); | |
1315 1316 /* We expect a unit attention from this device */ 1317 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) { 1318 start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA; 1319 softc->flags &= ~DA_FLAG_RETRY_UA; 1320 } 1321 1322 start_ccb->ccb_h.ccb_bp = bp; 1323 bp = bioq_first(&softc->bio_queue); | 1313 1314 /* We expect a unit attention from this device */ 1315 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) { 1316 start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA; 1317 softc->flags &= ~DA_FLAG_RETRY_UA; 1318 } 1319 1320 start_ccb->ccb_h.ccb_bp = bp; 1321 bp = bioq_first(&softc->bio_queue); |
1324 splx(s); | |
1325 1326 xpt_action(start_ccb); 1327 } 1328 1329 if (bp != NULL) { 1330 /* Have more work to do, so ensure we stay scheduled */ 1331 xpt_schedule(periph, /* XXX priority */1); 1332 } --- 108 unchanged lines hidden (view full) --- 1441 struct ccb_scsiio *csio; 1442 1443 softc = (struct da_softc *)periph->softc; 1444 csio = &done_ccb->csio; 1445 switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) { 1446 case DA_CCB_BUFFER_IO: 1447 { 1448 struct bio *bp; | 1322 1323 xpt_action(start_ccb); 1324 } 1325 1326 if (bp != NULL) { 1327 /* Have more work to do, so ensure we stay scheduled */ 1328 xpt_schedule(periph, /* XXX priority */1); 1329 } --- 108 unchanged lines hidden (view full) --- 1438 struct ccb_scsiio *csio; 1439 1440 softc = (struct da_softc *)periph->softc; 1441 csio = &done_ccb->csio; 1442 switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) { 1443 case DA_CCB_BUFFER_IO: 1444 { 1445 struct bio *bp; |
1449 int oldspl; | |
1450 1451 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 1452 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1453 int error; | 1446 1447 bp = (struct bio *)done_ccb->ccb_h.ccb_bp; 1448 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1449 int error; |
1454 int s; | |
1455 int sf; 1456 1457 if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0) 1458 sf = SF_RETRY_UA; 1459 else 1460 sf = 0; 1461 1462 error = daerror(done_ccb, CAM_RETRY_SELTO, sf); 1463 if (error == ERESTART) { 1464 /* 1465 * A retry was scheuled, so 1466 * just return. 1467 */ 1468 return; 1469 } 1470 if (error != 0) { 1471 | 1450 int sf; 1451 1452 if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0) 1453 sf = SF_RETRY_UA; 1454 else 1455 sf = 0; 1456 1457 error = daerror(done_ccb, CAM_RETRY_SELTO, sf); 1458 if (error == ERESTART) { 1459 /* 1460 * A retry was scheuled, so 1461 * just return. 1462 */ 1463 return; 1464 } 1465 if (error != 0) { 1466 |
1472 s = splbio(); 1473 | |
1474 if (error == ENXIO) { 1475 /* 1476 * Catastrophic error. Mark our pack as 1477 * invalid. 1478 */ 1479 /* 1480 * XXX See if this is really a media 1481 * XXX change first? --- 4 unchanged lines hidden (view full) --- 1486 } 1487 1488 /* 1489 * return all queued I/O with EIO, so that 1490 * the client can retry these I/Os in the 1491 * proper order should it attempt to recover. 1492 */ 1493 bioq_flush(&softc->bio_queue, NULL, EIO); | 1467 if (error == ENXIO) { 1468 /* 1469 * Catastrophic error. Mark our pack as 1470 * invalid. 1471 */ 1472 /* 1473 * XXX See if this is really a media 1474 * XXX change first? --- 4 unchanged lines hidden (view full) --- 1479 } 1480 1481 /* 1482 * return all queued I/O with EIO, so that 1483 * the client can retry these I/Os in the 1484 * proper order should it attempt to recover. 1485 */ 1486 bioq_flush(&softc->bio_queue, NULL, EIO); |
1494 splx(s); | |
1495 bp->bio_error = error; 1496 bp->bio_resid = bp->bio_bcount; 1497 bp->bio_flags |= BIO_ERROR; 1498 } else { 1499 bp->bio_resid = csio->resid; 1500 bp->bio_error = 0; 1501 if (bp->bio_resid != 0) 1502 bp->bio_flags |= BIO_ERROR; --- 11 unchanged lines hidden (view full) --- 1514 if (csio->resid > 0) 1515 bp->bio_flags |= BIO_ERROR; 1516 } 1517 1518 /* 1519 * Block out any asyncronous callbacks 1520 * while we touch the pending ccb list. 1521 */ | 1487 bp->bio_error = error; 1488 bp->bio_resid = bp->bio_bcount; 1489 bp->bio_flags |= BIO_ERROR; 1490 } else { 1491 bp->bio_resid = csio->resid; 1492 bp->bio_error = 0; 1493 if (bp->bio_resid != 0) 1494 bp->bio_flags |= BIO_ERROR; --- 11 unchanged lines hidden (view full) --- 1506 if (csio->resid > 0) 1507 bp->bio_flags |= BIO_ERROR; 1508 } 1509 1510 /* 1511 * Block out any asyncronous callbacks 1512 * while we touch the pending ccb list. 1513 */ |
1522 oldspl = splcam(); | |
1523 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 1524 softc->outstanding_cmds--; 1525 if (softc->outstanding_cmds == 0) 1526 softc->flags |= DA_FLAG_WENT_IDLE; | 1514 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); 1515 softc->outstanding_cmds--; 1516 if (softc->outstanding_cmds == 0) 1517 softc->flags |= DA_FLAG_WENT_IDLE; |
1527 splx(oldspl); | |
1528 1529 biodone(bp); 1530 break; 1531 } 1532 case DA_CCB_PROBE: 1533 case DA_CCB_PROBE2: 1534 { 1535 struct scsi_read_capacity_data *rdcap; --- 169 unchanged lines hidden (view full) --- 1705 * Since our peripheral may be invalidated by an error 1706 * above or an external event, we must release our CCB 1707 * before releasing the probe lock on the peripheral. 1708 * The peripheral will only go away once the last lock 1709 * is removed, and we need it around for the CCB release 1710 * operation. 1711 */ 1712 xpt_release_ccb(done_ccb); | 1518 1519 biodone(bp); 1520 break; 1521 } 1522 case DA_CCB_PROBE: 1523 case DA_CCB_PROBE2: 1524 { 1525 struct scsi_read_capacity_data *rdcap; --- 169 unchanged lines hidden (view full) --- 1695 * Since our peripheral may be invalidated by an error 1696 * above or an external event, we must release our CCB 1697 * before releasing the probe lock on the peripheral. 1698 * The peripheral will only go away once the last lock 1699 * is removed, and we need it around for the CCB release 1700 * operation. 1701 */ 1702 xpt_release_ccb(done_ccb); |
1713 cam_periph_unlock(periph); | 1703 cam_periph_unhold(periph); |
1714 return; 1715 } 1716 case DA_CCB_WAITING: 1717 { 1718 /* Caller will release the CCB */ 1719 wakeup(&done_ccb->ccb_h.cbfcnp); 1720 return; 1721 } --- 106 unchanged lines hidden (view full) --- 1828 error = 0; 1829 sense_flags = SF_RETRY_UA; 1830 if (softc->flags & DA_FLAG_PACK_REMOVABLE) 1831 sense_flags |= SF_NO_PRINT; 1832 1833 /* Do a read capacity */ 1834 rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcaplong), 1835 M_TEMP, | 1704 return; 1705 } 1706 case DA_CCB_WAITING: 1707 { 1708 /* Caller will release the CCB */ 1709 wakeup(&done_ccb->ccb_h.cbfcnp); 1710 return; 1711 } --- 106 unchanged lines hidden (view full) --- 1818 error = 0; 1819 sense_flags = SF_RETRY_UA; 1820 if (softc->flags & DA_FLAG_PACK_REMOVABLE) 1821 sense_flags |= SF_NO_PRINT; 1822 1823 /* Do a read capacity */ 1824 rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcaplong), 1825 M_TEMP, |
1836 M_WAITOK); | 1826 M_NOWAIT); 1827 if (rcap == NULL) 1828 return (ENOMEM); |
1837 1838 ccb = cam_periph_getccb(periph, /*priority*/1); 1839 scsi_read_capacity(&ccb->csio, 1840 /*retries*/4, 1841 /*cbfncp*/dadone, 1842 MSG_SIMPLE_Q_TAG, 1843 rcap, 1844 SSD_FULL_SIZE, --- 109 unchanged lines hidden (view full) --- 1954 dp->secs_per_track = ccg.secs_per_track; 1955 dp->cylinders = ccg.cylinders; 1956 } 1957} 1958 1959static void 1960dasendorderedtag(void *arg) 1961{ | 1829 1830 ccb = cam_periph_getccb(periph, /*priority*/1); 1831 scsi_read_capacity(&ccb->csio, 1832 /*retries*/4, 1833 /*cbfncp*/dadone, 1834 MSG_SIMPLE_Q_TAG, 1835 rcap, 1836 SSD_FULL_SIZE, --- 109 unchanged lines hidden (view full) --- 1946 dp->secs_per_track = ccg.secs_per_track; 1947 dp->cylinders = ccg.cylinders; 1948 } 1949} 1950 1951static void 1952dasendorderedtag(void *arg) 1953{ |
1962 struct da_softc *softc; 1963 int s; 1964 if (da_send_ordered) { 1965 for (softc = SLIST_FIRST(&softc_list); 1966 softc != NULL; 1967 softc = SLIST_NEXT(softc, links)) { 1968 s = splsoftcam(); 1969 if ((softc->ordered_tag_count == 0) 1970 && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) { 1971 softc->flags |= DA_FLAG_NEED_OTAG; 1972 } 1973 if (softc->outstanding_cmds > 0) 1974 softc->flags &= ~DA_FLAG_WENT_IDLE; | 1954 struct da_softc *softc = arg; |
1975 | 1955 |
1976 softc->ordered_tag_count = 0; 1977 splx(s); | 1956 if (da_send_ordered) { 1957 if ((softc->ordered_tag_count == 0) 1958 && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) { 1959 softc->flags |= DA_FLAG_NEED_OTAG; |
1978 } | 1960 } |
1979 /* Queue us up again */ 1980 timeout(dasendorderedtag, NULL, 1981 (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL); | 1961 if (softc->outstanding_cmds > 0) 1962 softc->flags &= ~DA_FLAG_WENT_IDLE; 1963 1964 softc->ordered_tag_count = 0; |
1982 } | 1965 } |
1966 /* Queue us up again */ 1967 callout_reset(&softc->sendordered_c, 1968 (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL, 1969 dasendorderedtag, softc); |
|
1983} 1984 1985/* 1986 * Step through all DA peripheral drivers, and if the device is still open, 1987 * sync the disk cache to physical media. 1988 */ 1989static void 1990dashutdown(void * arg, int howto) --- 94 unchanged lines hidden --- | 1970} 1971 1972/* 1973 * Step through all DA peripheral drivers, and if the device is still open, 1974 * sync the disk cache to physical media. 1975 */ 1976static void 1977dashutdown(void * arg, int howto) --- 94 unchanged lines hidden --- |