4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
25 */
26
27 #include <sys/note.h>
28 #include <sys/types.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/buf.h>
32 #include <sys/uio.h>
33 #include <sys/cred.h>
34 #include <sys/poll.h>
35 #include <sys/mman.h>
36 #include <sys/kmem.h>
37 #include <sys/model.h>
38 #include <sys/file.h>
39 #include <sys/proc.h>
40 #include <sys/open.h>
41 #include <sys/user.h>
42 #include <sys/t_lock.h>
43 #include <sys/vm.h>
44 #include <sys/stat.h>
693 ddi_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t op, void *a, void *v)
694 {
695 int (*fp)();
696
697 if (!d || !r)
698 return (DDI_FAILURE);
699
700 if ((d = (dev_info_t *)DEVI(d)->devi_bus_ctl) == NULL)
701 return (DDI_FAILURE);
702
703 fp = DEVI(d)->devi_ops->devo_bus_ops->bus_ctl;
704 return ((*fp)(d, r, op, a, v));
705 }
706
707 #endif
708
709 /*
710 * DMA/DVMA setup
711 */
712
713 #if defined(__sparc)
714 static ddi_dma_lim_t standard_limits = {
715 (uint_t)0, /* addr_t dlim_addr_lo */
716 (uint_t)-1, /* addr_t dlim_addr_hi */
717 (uint_t)-1, /* uint_t dlim_cntr_max */
718 (uint_t)1, /* uint_t dlim_burstsizes */
719 (uint_t)1, /* uint_t dlim_minxfer */
720 0 /* uint_t dlim_dmaspeed */
721 };
722 #elif defined(__x86)
723 static ddi_dma_lim_t standard_limits = {
724 (uint_t)0, /* addr_t dlim_addr_lo */
725 (uint_t)0xffffff, /* addr_t dlim_addr_hi */
726 (uint_t)0, /* uint_t dlim_cntr_max */
727 (uint_t)0x00000001, /* uint_t dlim_burstsizes */
728 (uint_t)DMA_UNIT_8, /* uint_t dlim_minxfer */
729 (uint_t)0, /* uint_t dlim_dmaspeed */
730 (uint_t)0x86<<24+0, /* uint_t dlim_version */
731 (uint_t)0xffff, /* uint_t dlim_adreg_max */
732 (uint_t)0xffff, /* uint_t dlim_ctreg_max */
733 (uint_t)512, /* uint_t dlim_granular */
734 (int)1, /* int dlim_sgllen */
735 (uint_t)0xffffffff /* uint_t dlim_reqsizes */
736 };
737
738 #endif
739
740 #if !defined(__sparc)
741 /*
742 * Request bus_dma_ctl parent to fiddle with a dma request.
743 *
744 * (The sparc version is in sparc_subr.s)
745 */
746 int
747 ddi_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
748 ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
749 off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
750 {
751 int (*fp)();
752
753 if (dip != ddi_root_node())
754 dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_ctl;
755 fp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_ctl;
756 return ((*fp) (dip, rdip, handle, request, offp, lenp, objp, flags));
757 }
758 #endif
759
914 return ((*funcp)(dip, rdip, h));
915 }
916
917 #endif /* !__sparc */
918
919 /*
920 * DMA burst sizes, and transfer minimums
921 */
922
923 int
924 ddi_dma_burstsizes(ddi_dma_handle_t handle)
925 {
926 ddi_dma_impl_t *dimp = (ddi_dma_impl_t *)handle;
927
928 if (!dimp)
929 return (0);
930 else
931 return (dimp->dmai_burstsizes);
932 }
933
934 int
935 ddi_iomin(dev_info_t *a, int i, int stream)
936 {
937 int r;
938
939 /*
940 * Make sure that the initial value is sane
941 */
942 if (i & (i - 1))
943 return (0);
944 if (i == 0)
945 i = (stream) ? 4 : 1;
946
947 r = ddi_ctlops(a, a,
948 DDI_CTLOPS_IOMIN, (void *)(uintptr_t)stream, (void *)&i);
949 if (r != DDI_SUCCESS || (i & (i - 1)))
950 return (0);
951 return (i);
952 }
953
954 /*
955 * Given two DMA attribute structures, apply the attributes
956 * of one to the other, following the rules of attributes
957 * and the wishes of the caller.
958 *
959 * The rules of DMA attribute structures are that you cannot
960 * make things *less* restrictive as you apply one set
961 * of attributes to another.
962 *
963 */
964 void
965 ddi_dma_attr_merge(ddi_dma_attr_t *attr, ddi_dma_attr_t *mod)
966 {
967 attr->dma_attr_addr_lo =
968 MAX(attr->dma_attr_addr_lo, mod->dma_attr_addr_lo);
969 attr->dma_attr_addr_hi =
970 MIN(attr->dma_attr_addr_hi, mod->dma_attr_addr_hi);
971 attr->dma_attr_count_max =
972 MIN(attr->dma_attr_count_max, mod->dma_attr_count_max);
973 attr->dma_attr_align =
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
25 */
26
27 #include <sys/note.h>
28 #include <sys/types.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/buf.h>
32 #include <sys/uio.h>
33 #include <sys/cred.h>
34 #include <sys/poll.h>
35 #include <sys/mman.h>
36 #include <sys/kmem.h>
37 #include <sys/model.h>
38 #include <sys/file.h>
39 #include <sys/proc.h>
40 #include <sys/open.h>
41 #include <sys/user.h>
42 #include <sys/t_lock.h>
43 #include <sys/vm.h>
44 #include <sys/stat.h>
693 ddi_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t op, void *a, void *v)
694 {
695 int (*fp)();
696
697 if (!d || !r)
698 return (DDI_FAILURE);
699
700 if ((d = (dev_info_t *)DEVI(d)->devi_bus_ctl) == NULL)
701 return (DDI_FAILURE);
702
703 fp = DEVI(d)->devi_ops->devo_bus_ops->bus_ctl;
704 return ((*fp)(d, r, op, a, v));
705 }
706
707 #endif
708
709 /*
710 * DMA/DVMA setup
711 */
712
713 #if !defined(__sparc)
714 /*
715 * Request bus_dma_ctl parent to fiddle with a dma request.
716 *
717 * (The sparc version is in sparc_subr.s)
718 */
719 int
720 ddi_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
721 ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
722 off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
723 {
724 int (*fp)();
725
726 if (dip != ddi_root_node())
727 dip = (dev_info_t *)DEVI(dip)->devi_bus_dma_ctl;
728 fp = DEVI(dip)->devi_ops->devo_bus_ops->bus_dma_ctl;
729 return ((*fp) (dip, rdip, handle, request, offp, lenp, objp, flags));
730 }
731 #endif
732
887 return ((*funcp)(dip, rdip, h));
888 }
889
890 #endif /* !__sparc */
891
892 /*
893 * DMA burst sizes, and transfer minimums
894 */
895
896 int
897 ddi_dma_burstsizes(ddi_dma_handle_t handle)
898 {
899 ddi_dma_impl_t *dimp = (ddi_dma_impl_t *)handle;
900
901 if (!dimp)
902 return (0);
903 else
904 return (dimp->dmai_burstsizes);
905 }
906
907 /*
908 * Given two DMA attribute structures, apply the attributes
909 * of one to the other, following the rules of attributes
910 * and the wishes of the caller.
911 *
912 * The rules of DMA attribute structures are that you cannot
913 * make things *less* restrictive as you apply one set
914 * of attributes to another.
915 *
916 */
917 void
918 ddi_dma_attr_merge(ddi_dma_attr_t *attr, ddi_dma_attr_t *mod)
919 {
920 attr->dma_attr_addr_lo =
921 MAX(attr->dma_attr_addr_lo, mod->dma_attr_addr_lo);
922 attr->dma_attr_addr_hi =
923 MIN(attr->dma_attr_addr_hi, mod->dma_attr_addr_hi);
924 attr->dma_attr_count_max =
925 MIN(attr->dma_attr_count_max, mod->dma_attr_count_max);
926 attr->dma_attr_align =
|