Deleted Added
full compact
busdma_machdep-v6.c (274538) busdma_machdep-v6.c (274545)
1/*-
1/*-
2 * Copyright (c) 2012 Ian Lepore
2 * Copyright (c) 2012-2014 Ian Lepore
3 * Copyright (c) 2010 Mark Tinguely
4 * Copyright (c) 2004 Olivier Houchard
5 * Copyright (c) 2002 Peter Grehan
6 * Copyright (c) 1997, 1998 Justin T. Gibbs.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 15 unchanged lines hidden (view full) ---

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb
31 */
32
33#include <sys/cdefs.h>
3 * Copyright (c) 2010 Mark Tinguely
4 * Copyright (c) 2004 Olivier Houchard
5 * Copyright (c) 2002 Peter Grehan
6 * Copyright (c) 1997, 1998 Justin T. Gibbs.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 15 unchanged lines hidden (view full) ---

26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep-v6.c 274538 2014-11-15 03:39:58Z ian $");
34__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep-v6.c 274545 2014-11-15 05:40:20Z ian $");
35
36#define _ARM32_BUS_DMA_PRIVATE
37#include <sys/param.h>
38#include <sys/kdb.h>
39#include <ddb/ddb.h>
40#include <ddb/db_output.h>
41#include <sys/systm.h>
42#include <sys/malloc.h>

--- 298 unchanged lines hidden (view full) ---

341 * Note that the addr argument might be either virtual or physical. It doesn't
342 * matter because we only look at the low-order bits, which are the same in both
343 * address spaces.
344 */
345static __inline int
346might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
347 bus_size_t size)
348{
35
36#define _ARM32_BUS_DMA_PRIVATE
37#include <sys/param.h>
38#include <sys/kdb.h>
39#include <ddb/ddb.h>
40#include <ddb/db_output.h>
41#include <sys/systm.h>
42#include <sys/malloc.h>

--- 298 unchanged lines hidden (view full) ---

341 * Note that the addr argument might be either virtual or physical. It doesn't
342 * matter because we only look at the low-order bits, which are the same in both
343 * address spaces.
344 */
345static __inline int
346might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
347 bus_size_t size)
348{
349
349 return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) ||
350 alignment_bounce(dmat, addr) ||
351 cacheline_bounce(map, addr, size));
352}
353
354/*
355 * Return true if we must bounce the DMA described by paddr and size.
356 *

--- 82 unchanged lines hidden (view full) ---

439 * dflt_lock should never get called. It gets put into the dma tag when
440 * lockfunc == NULL, which is only valid if the maps that are associated
441 * with the tag are meant to never be defered.
442 * XXX Should have a way to identify which driver is responsible here.
443 */
444static void
445dflt_lock(void *arg, bus_dma_lock_op_t op)
446{
350 return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) ||
351 alignment_bounce(dmat, addr) ||
352 cacheline_bounce(map, addr, size));
353}
354
355/*
356 * Return true if we must bounce the DMA described by paddr and size.
357 *

--- 82 unchanged lines hidden (view full) ---

440 * dflt_lock should never get called. It gets put into the dma tag when
441 * lockfunc == NULL, which is only valid if the maps that are associated
442 * with the tag are meant to never be defered.
443 * XXX Should have a way to identify which driver is responsible here.
444 */
445static void
446dflt_lock(void *arg, bus_dma_lock_op_t op)
447{
448
447 panic("driver error: busdma dflt_lock called");
448}
449
450/*
451 * Allocate a device specific dma_tag.
452 */
453int
454bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,

--- 165 unchanged lines hidden (view full) ---

620 }
621out:
622 CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
623 return (error);
624}
625
626static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
627{
449 panic("driver error: busdma dflt_lock called");
450}
451
452/*
453 * Allocate a device specific dma_tag.
454 */
455int
456bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,

--- 165 unchanged lines hidden (view full) ---

622 }
623out:
624 CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
625 return (error);
626}
627
628static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
629{
628 struct bounce_zone *bz;
630 struct bounce_zone *bz;
629 int maxpages;
630 int error;
631
632 if (dmat->bounce_zone == NULL)
633 if ((error = alloc_bounce_zone(dmat)) != 0)
634 return (error);
635 bz = dmat->bounce_zone;
636 /* Initialize the new map */

--- 610 unchanged lines hidden (view full) ---

1247 map->pagesreserved = 0;
1248 map->pagesneeded = 0;
1249 }
1250 map->sync_count = 0;
1251 map->flags &= ~DMAMAP_MBUF;
1252}
1253
1254#ifdef notyetbounceuser
631 int maxpages;
632 int error;
633
634 if (dmat->bounce_zone == NULL)
635 if ((error = alloc_bounce_zone(dmat)) != 0)
636 return (error);
637 bz = dmat->bounce_zone;
638 /* Initialize the new map */

--- 610 unchanged lines hidden (view full) ---

1249 map->pagesreserved = 0;
1250 map->pagesneeded = 0;
1251 }
1252 map->sync_count = 0;
1253 map->flags &= ~DMAMAP_MBUF;
1254}
1255
1256#ifdef notyetbounceuser
1255 /* If busdma uses user pages, then the interrupt handler could
1256 * be use the kernel vm mapping. Both bounce pages and sync list
1257 * do not cross page boundaries.
1258 * Below is a rough sequence that a person would do to fix the
1259 * user page reference in the kernel vmspace. This would be
1260 * done in the dma post routine.
1261 */
1257/* If busdma uses user pages, then the interrupt handler could
1258 * be use the kernel vm mapping. Both bounce pages and sync list
1259 * do not cross page boundaries.
1260 * Below is a rough sequence that a person would do to fix the
1261 * user page reference in the kernel vmspace. This would be
1262 * done in the dma post routine.
1263 */
1262void
1263_bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len,
1264 pmap_t pmap, int op)
1265{
1266 bus_size_t sgsize;
1267 bus_addr_t curaddr;
1268 vm_offset_t va;
1269
1264void
1265_bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len,
1266 pmap_t pmap, int op)
1267{
1268 bus_size_t sgsize;
1269 bus_addr_t curaddr;
1270 vm_offset_t va;
1271
1270 /* each synclist entry is contained within a single page.
1271 *
1272 * this would be needed if BUS_DMASYNC_POSTxxxx was implemented
1273 */
1272 /*
1273 * each synclist entry is contained within a single page.
1274 * this would be needed if BUS_DMASYNC_POSTxxxx was implemented
1275 */
1274 curaddr = pmap_extract(pmap, buf);
1275 va = pmap_dma_map(curaddr);
1276 switch (op) {
1277 case SYNC_USER_INV:
1278 cpu_dcache_wb_range(va, sgsize);
1279 break;
1280
1281 case SYNC_USER_COPYTO:

--- 124 unchanged lines hidden (view full) ---

1406 sl = &map->slist[0];
1407 end = &map->slist[map->sync_count];
1408 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
1409 "performing sync", __func__, dmat, dmat->flags, op);
1410
1411 switch (op) {
1412 case BUS_DMASYNC_PREWRITE:
1413 while (sl != end) {
1276 curaddr = pmap_extract(pmap, buf);
1277 va = pmap_dma_map(curaddr);
1278 switch (op) {
1279 case SYNC_USER_INV:
1280 cpu_dcache_wb_range(va, sgsize);
1281 break;
1282
1283 case SYNC_USER_COPYTO:

--- 124 unchanged lines hidden (view full) ---

1408 sl = &map->slist[0];
1409 end = &map->slist[map->sync_count];
1410 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
1411 "performing sync", __func__, dmat, dmat->flags, op);
1412
1413 switch (op) {
1414 case BUS_DMASYNC_PREWRITE:
1415 while (sl != end) {
1414 cpu_dcache_wb_range(sl->vaddr, sl->datacount);
1415 l2cache_wb_range(sl->vaddr, sl->busaddr,
1416 sl->datacount);
1417 sl++;
1416 cpu_dcache_wb_range(sl->vaddr, sl->datacount);
1417 l2cache_wb_range(sl->vaddr, sl->busaddr,
1418 sl->datacount);
1419 sl++;
1418 }
1419 break;
1420
1421 case BUS_DMASYNC_PREREAD:
1422 while (sl != end) {
1423 cpu_dcache_inv_range(sl->vaddr, sl->datacount);
1424 l2cache_inv_range(sl->vaddr, sl->busaddr,
1425 sl->datacount);

--- 31 unchanged lines hidden (view full) ---

1457 STAILQ_INIT(&bounce_map_callbacklist);
1458 mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
1459}
1460SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
1461
1462static struct sysctl_ctx_list *
1463busdma_sysctl_tree(struct bounce_zone *bz)
1464{
1420 }
1421 break;
1422
1423 case BUS_DMASYNC_PREREAD:
1424 while (sl != end) {
1425 cpu_dcache_inv_range(sl->vaddr, sl->datacount);
1426 l2cache_inv_range(sl->vaddr, sl->busaddr,
1427 sl->datacount);

--- 31 unchanged lines hidden (view full) ---

1459 STAILQ_INIT(&bounce_map_callbacklist);
1460 mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
1461}
1462SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
1463
1464static struct sysctl_ctx_list *
1465busdma_sysctl_tree(struct bounce_zone *bz)
1466{
1467
1465 return (&bz->sysctl_tree);
1466}
1467
1468static struct sysctl_oid *
1469busdma_sysctl_tree_top(struct bounce_zone *bz)
1470{
1468 return (&bz->sysctl_tree);
1469}
1470
1471static struct sysctl_oid *
1472busdma_sysctl_tree_top(struct bounce_zone *bz)
1473{
1474
1471 return (bz->sysctl_tree_top);
1472}
1473
1474static int
1475alloc_bounce_zone(bus_dma_tag_t dmat)
1476{
1477 struct bounce_zone *bz;
1478

--- 220 unchanged lines hidden ---
1475 return (bz->sysctl_tree_top);
1476}
1477
1478static int
1479alloc_bounce_zone(bus_dma_tag_t dmat)
1480{
1481 struct bounce_zone *bz;
1482

--- 220 unchanged lines hidden ---