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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
28 */
29
30 /*
31 * sun4 specific DDI implementation
32 */
33 #include <sys/cpuvar.h>
34 #include <sys/ddi_subrdefs.h>
35 #include <sys/machsystm.h>
36 #include <sys/sunndi.h>
37 #include <sys/sysmacros.h>
38 #include <sys/ontrap.h>
39 #include <vm/seg_kmem.h>
40 #include <sys/membar.h>
41 #include <sys/dditypes.h>
42 #include <sys/ndifm.h>
43 #include <sys/fm/io/ddi.h>
44 #include <sys/ivintr.h>
45 #include <sys/bootconf.h>
46 #include <sys/conf.h>
47 #include <sys/ethernet.h>
1114 ASSERT((uintptr_t)addr + size - (uintptr_t)raddr <= rsize);
1115
1116 addr[-3] = (size_t)endian_flags;
1117 addr[-2] = (size_t)raddr;
1118 addr[-1] = rsize;
1119
1120 return (addr);
1121 }
1122
1123 static void
1124 kfreea(void *addr)
1125 {
1126 size_t *saddr = addr;
1127
1128 if (saddr[-3] == DDI_STRUCTURE_LE_ACC)
1129 vmem_free(little_endian_arena, (void *)saddr[-2], saddr[-1]);
1130 else
1131 vmem_free(big_endian_arena, (void *)saddr[-2], saddr[-1]);
1132 }
1133
1134 int
1135 i_ddi_mem_alloc(dev_info_t *dip, ddi_dma_attr_t *attr,
1136 size_t length, int cansleep, int flags,
1137 ddi_device_acc_attr_t *accattrp,
1138 caddr_t *kaddrp, size_t *real_length, ddi_acc_hdl_t *handlep)
1139 {
1140 caddr_t a;
1141 int iomin, align, streaming;
1142 uint_t endian_flags = DDI_NEVERSWAP_ACC;
1143
1144 #if defined(lint)
1145 *handlep = *handlep;
1146 #endif
1147
1148 /*
1149 * Check legality of arguments
1150 */
1151 if (length == 0 || kaddrp == NULL || attr == NULL) {
1152 return (DDI_FAILURE);
1153 }
1164 streaming = (flags & DDI_DMA_STREAMING) ? 1 : 0;
1165
1166 /*
1167 * Drivers for 64-bit capable SBus devices will encode
1168 * the burtsizes for 64-bit xfers in the upper 16-bits.
1169 * For DMA alignment, we use the most restrictive
1170 * alignment of 32-bit and 64-bit xfers.
1171 */
1172 iomin = (attr->dma_attr_burstsizes & 0xffff) |
1173 ((attr->dma_attr_burstsizes >> 16) & 0xffff);
1174 /*
1175 * If a driver set burtsizes to 0, we give him byte alignment.
1176 * Otherwise align at the burtsizes boundary.
1177 */
1178 if (iomin == 0)
1179 iomin = 1;
1180 else
1181 iomin = 1 << (ddi_fls(iomin) - 1);
1182 iomin = maxbit(iomin, attr->dma_attr_minxfer);
1183 iomin = maxbit(iomin, attr->dma_attr_align);
1184 iomin = ddi_iomin(dip, iomin, streaming);
1185 if (iomin == 0)
1186 return (DDI_FAILURE);
1187
1188 ASSERT((iomin & (iomin - 1)) == 0);
1189 ASSERT(iomin >= attr->dma_attr_minxfer);
1190 ASSERT(iomin >= attr->dma_attr_align);
1191
1192 length = P2ROUNDUP(length, iomin);
1193 align = iomin;
1194
1195 if (accattrp != NULL)
1196 endian_flags = accattrp->devacc_attr_endian_flags;
1197
1198 a = kalloca(length, align, cansleep, endian_flags);
1199 if ((*kaddrp = a) == 0) {
1200 return (DDI_FAILURE);
1201 } else {
1202 if (real_length) {
1203 *real_length = length;
1204 }
|
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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
28 */
29
30 /*
31 * sun4 specific DDI implementation
32 */
33 #include <sys/cpuvar.h>
34 #include <sys/ddi_subrdefs.h>
35 #include <sys/machsystm.h>
36 #include <sys/sunndi.h>
37 #include <sys/sysmacros.h>
38 #include <sys/ontrap.h>
39 #include <vm/seg_kmem.h>
40 #include <sys/membar.h>
41 #include <sys/dditypes.h>
42 #include <sys/ndifm.h>
43 #include <sys/fm/io/ddi.h>
44 #include <sys/ivintr.h>
45 #include <sys/bootconf.h>
46 #include <sys/conf.h>
47 #include <sys/ethernet.h>
1114 ASSERT((uintptr_t)addr + size - (uintptr_t)raddr <= rsize);
1115
1116 addr[-3] = (size_t)endian_flags;
1117 addr[-2] = (size_t)raddr;
1118 addr[-1] = rsize;
1119
1120 return (addr);
1121 }
1122
1123 static void
1124 kfreea(void *addr)
1125 {
1126 size_t *saddr = addr;
1127
1128 if (saddr[-3] == DDI_STRUCTURE_LE_ACC)
1129 vmem_free(little_endian_arena, (void *)saddr[-2], saddr[-1]);
1130 else
1131 vmem_free(big_endian_arena, (void *)saddr[-2], saddr[-1]);
1132 }
1133
1134 /*
1135 * This used to be ddi_iomin, but we were the only remaining caller, so
1136 * we've made it private and moved it here.
1137 */
1138 static int
1139 i_ddi_iomin(dev_info_t *a, int i, int stream)
1140 {
1141 int r;
1142
1143 /*
1144 * Make sure that the initial value is sane
1145 */
1146 if (i & (i - 1))
1147 return (0);
1148 if (i == 0)
1149 i = (stream) ? 4 : 1;
1150
1151 r = ddi_ctlops(a, a,
1152 DDI_CTLOPS_IOMIN, (void *)(uintptr_t)stream, (void *)&i);
1153 if (r != DDI_SUCCESS || (i & (i - 1)))
1154 return (0);
1155 return (i);
1156 }
1157
1158 int
1159 i_ddi_mem_alloc(dev_info_t *dip, ddi_dma_attr_t *attr,
1160 size_t length, int cansleep, int flags,
1161 ddi_device_acc_attr_t *accattrp,
1162 caddr_t *kaddrp, size_t *real_length, ddi_acc_hdl_t *handlep)
1163 {
1164 caddr_t a;
1165 int iomin, align, streaming;
1166 uint_t endian_flags = DDI_NEVERSWAP_ACC;
1167
1168 #if defined(lint)
1169 *handlep = *handlep;
1170 #endif
1171
1172 /*
1173 * Check legality of arguments
1174 */
1175 if (length == 0 || kaddrp == NULL || attr == NULL) {
1176 return (DDI_FAILURE);
1177 }
1188 streaming = (flags & DDI_DMA_STREAMING) ? 1 : 0;
1189
1190 /*
1191 * Drivers for 64-bit capable SBus devices will encode
1192 * the burtsizes for 64-bit xfers in the upper 16-bits.
1193 * For DMA alignment, we use the most restrictive
1194 * alignment of 32-bit and 64-bit xfers.
1195 */
1196 iomin = (attr->dma_attr_burstsizes & 0xffff) |
1197 ((attr->dma_attr_burstsizes >> 16) & 0xffff);
1198 /*
1199 * If a driver set burtsizes to 0, we give him byte alignment.
1200 * Otherwise align at the burtsizes boundary.
1201 */
1202 if (iomin == 0)
1203 iomin = 1;
1204 else
1205 iomin = 1 << (ddi_fls(iomin) - 1);
1206 iomin = maxbit(iomin, attr->dma_attr_minxfer);
1207 iomin = maxbit(iomin, attr->dma_attr_align);
1208 iomin = i_ddi_iomin(dip, iomin, streaming);
1209 if (iomin == 0)
1210 return (DDI_FAILURE);
1211
1212 ASSERT((iomin & (iomin - 1)) == 0);
1213 ASSERT(iomin >= attr->dma_attr_minxfer);
1214 ASSERT(iomin >= attr->dma_attr_align);
1215
1216 length = P2ROUNDUP(length, iomin);
1217 align = iomin;
1218
1219 if (accattrp != NULL)
1220 endian_flags = accattrp->devacc_attr_endian_flags;
1221
1222 a = kalloca(length, align, cansleep, endian_flags);
1223 if ((*kaddrp = a) == 0) {
1224 return (DDI_FAILURE);
1225 } else {
1226 if (real_length) {
1227 *real_length = length;
1228 }
|