o make sure the boundary is a power of 2, when not zero.

o   don't convert 0 to ~0 just so that we can use MIN. ~0 is not a
    valid boundary. Introduce BNDRY_MIN that deals with 0 values
    that mean no boundary.
This commit is contained in:
Marcel Moolenaar 2015-07-26 16:39:37 +00:00
parent dfded4478d
commit b2ce196ca1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=285892

View File

@ -51,6 +51,9 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_PROTO_BUSDMA, "proto_busdma", "DMA management data");
#define BNDRY_MIN(a, b) \
(((a) == 0) ? (b) : (((b) == 0) ? (a) : MIN((a), (b))))
struct proto_callback_bundle {
struct proto_busdma *busdma;
struct proto_md *md;
@ -63,6 +66,11 @@ proto_busdma_tag_create(struct proto_busdma *busdma, struct proto_tag *parent,
{
struct proto_tag *tag;
/* Make sure that when a boundary is specified, it's a power of 2 */
if (ioc->u.tag.bndry != 0 &&
(ioc->u.tag.bndry & (ioc->u.tag.bndry - 1)) != 0)
return (EINVAL);
/*
* If nsegs is 1, ignore maxsegsz. What this means is that if we have
* just 1 segment, then maxsz should be equal to maxsegsz. To keep it
@ -71,16 +79,12 @@ proto_busdma_tag_create(struct proto_busdma *busdma, struct proto_tag *parent,
if (ioc->u.tag.maxsegsz > ioc->u.tag.maxsz || ioc->u.tag.nsegs == 1)
ioc->u.tag.maxsegsz = ioc->u.tag.maxsz;
/* A bndry of 0 really means ~0, or no boundary. */
if (ioc->u.tag.bndry == 0)
ioc->u.tag.bndry = ~0U;
tag = malloc(sizeof(*tag), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
if (parent != NULL) {
tag->parent = parent;
LIST_INSERT_HEAD(&parent->children, tag, peers);
tag->align = MAX(ioc->u.tag.align, parent->align);
tag->bndry = MIN(ioc->u.tag.bndry, parent->bndry);
tag->bndry = BNDRY_MIN(ioc->u.tag.bndry, parent->bndry);
tag->maxaddr = MIN(ioc->u.tag.maxaddr, parent->maxaddr);
tag->maxsz = MIN(ioc->u.tag.maxsz, parent->maxsz);
tag->maxsegsz = MIN(ioc->u.tag.maxsegsz, parent->maxsegsz);