Deleted Added
full compact
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 ---