/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/machparam.h>
#include <vm/seg_kmem.h>
#ifdef __sparc
#include <sys/cpu_module.h>
#else
#endif
int bp_force_copy = 0;
typedef enum {
BP_COPYIN = 0,
} bp_copydir_t;
static void *
{
}
void
{
if (bp_align <= bp_max_cache)
}
/*
*/
void *
{
int color;
/* Fastpath single page IO to locked memory by using kpm. */
else
}
/*
* Allocate kernel virtual space for remapping.
*/
if (bp_map_arena != NULL) {
return (NULL);
} else {
return (NULL);
}
/*
* Map bp into the virtual space we just allocated.
*/
} else {
}
while (npages-- != 0) {
if (pp) {
if (pfnum == PFN_INVALID)
panic("bp_mapin_common: hat_getpfnum for"
" addr %p failed\n", (void *)addr);
} else {
pplist++;
}
}
}
/*
*/
void
{
}
/*
* Release all the resources associated with a previous bp_mapin() call.
*/
void
{
return;
else
return;
}
if (bp_map_arena != NULL) {
} else
}
/*
* copy data from a KVA into a buf_t which may not be mapped in. offset
* is relative to the buf_t only.
*/
int
{
}
/*
* copy data from a buf_t which may not be mapped in, into a KVA.. offset
* is relative to the buf_t only.
*/
int
{
}
static int
{
/* if the buf_t already has a KVA, just do a bcopy */
return (0);
}
/* if we don't have kpm enabled, we need to do the slow path */
if (!kpm_enable || bp_force_copy) {
return (0);
}
/*
* kpm is enabled, and we need to map in the buf_t for the copy
*/
/* setup pp, plist, and make sure 'as' is right */
} else {
}
}
/*
* locals for the address, the offset into the first page, and the
* size of the first page we are going to copy.
*/
/*
* we always start with a 0 offset into the driverbuf provided. The
* offset passed in only applies to the buf_t.
*/
voff = 0;
/* Loop until we've copied al the data */
while (size > 0) {
/*
* for a pp or pplist, get the pfn, then go to the next page_t
* for the next time around the loop.
*/
if (pp) {
pplist++;
/*
* We have a user VA. If we are going to copy this page, (e.g.
* the offset into the buf_t where we start to copy is
* within this page), get the pfn. Don't waste the cycles
* getting the pfn if we're not copying this page.
*/
if (pfn == PFN_INVALID) {
return (-1);
}
} else {
}
/*
* if we have an initial offset into the buf_t passed in,
* and it falls within the current page, account for it in
* the page size (how much we will copy) and the offset into the
* page (where we'll start copying from).
*/
offset = 0;
/*
* if we have an initial offset into the buf_t passed in,
* and it's not within the current page, skip this page.
* We don't have to worry about the first page offset and size
* anymore. psize will normally be PAGESIZE now unless we are
* on the last page.
*/
poff = 0;
continue;
}
/*
* page. update size left and offset into the driverbuf passed
* in for the next time around the loop.
*/
psize);
poff = 0;
}
return (0);
}