This commit is contained in:
Mark Murray 2013-08-24 13:42:20 +00:00
commit b2e0423c48
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/random_number_generator/; revision=254782
114 changed files with 6344 additions and 601 deletions

View File

@ -495,14 +495,10 @@ waitcmdloop(struct job *job)
in_waitcmd++;
do {
if (job != NULL) {
if (job->state) {
if (job->state == JOBDONE) {
status = job->ps[job->nprocs - 1].status;
if (WIFEXITED(status))
retval = WEXITSTATUS(status);
#if JOBS
else if (WIFSTOPPED(status))
retval = WSTOPSIG(status) + 128;
#endif
else
retval = WTERMSIG(status) + 128;
if (! iflag || ! job->changed)

View File

@ -25,6 +25,7 @@
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
*/
#include <solaris.h>
@ -2128,8 +2129,10 @@ zpool_do_import(int argc, char **argv)
errno = 0;
searchguid = strtoull(argv[0], &endptr, 10);
if (errno != 0 || *endptr != '\0')
if (errno != 0 || *endptr != '\0') {
searchname = argv[0];
searchguid = 0;
}
found_config = NULL;
/*

View File

@ -24,13 +24,15 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#include <sys/sysmacros.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <ctf_impl.h>
#include <sys/debug.h>
/*
* This static string is used as the template for initially populating a
@ -166,6 +168,51 @@ ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
return (s);
}
/*
* Only types of dyanmic CTF containers contain reference counts. These
* containers are marked RD/WR. Because of that we basically make this a no-op
* for compatability with non-dynamic CTF sections. This is also a no-op for
* types which are not dynamic types. It is the responsibility of the caller to
* make sure it is a valid type. We help that caller out on debug builds.
*
* Note that the reference counts are not maintained for types that are not
* within this container. In other words if we have a type in a parent, that
* will not have its reference count increased. On the flip side, the parent
* will not be allowed to remove dynamic types if it has children.
*/
static void
ctf_ref_inc(ctf_file_t *fp, ctf_id_t tid)
{
ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
if (dtd == NULL)
return;
if (!(fp->ctf_flags & LCTF_RDWR))
return;
dtd->dtd_ref++;
}
/*
* Just as with ctf_ref_inc, this is a no-op on non-writeable containers and the
* caller should ensure that this is already a valid type.
*/
static void
ctf_ref_dec(ctf_file_t *fp, ctf_id_t tid)
{
ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
if (dtd == NULL)
return;
if (!(fp->ctf_flags & LCTF_RDWR))
return;
ASSERT(dtd->dtd_ref >= 1);
dtd->dtd_ref--;
}
/*
* If the specified CTF container is writable and has been modified, reload
* this container with the updated type definitions. In order to make this
@ -180,6 +227,10 @@ ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
* ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
* constant for the caller, so after ctf_bufopen() returns, we use bcopy to
* swap the interior of the old and new ctf_file_t's, and then free the old.
*
* Note that the lists of dynamic types stays around and the resulting container
* is still writeable. Furthermore, the reference counts that are on the dtd's
* are still valid.
*/
int
ctf_update(ctf_file_t *fp)
@ -432,6 +483,7 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
ctf_dmdef_t *dmd, *nmd;
size_t len;
int kind, i;
for (p = *q; p != NULL; p = p->dtd_hash) {
if (p != dtd)
@ -443,7 +495,8 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
if (p != NULL)
*q = p->dtd_hash;
switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
switch (kind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
case CTF_K_ENUM:
@ -454,14 +507,33 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
ctf_free(dmd->dmd_name, len);
fp->ctf_dtstrlen -= len;
}
if (kind != CTF_K_ENUM)
ctf_ref_dec(fp, dmd->dmd_type);
nmd = ctf_list_next(dmd);
ctf_free(dmd, sizeof (ctf_dmdef_t));
}
break;
case CTF_K_FUNCTION:
ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
for (i = 0; i < CTF_INFO_VLEN(dtd->dtd_data.ctt_info); i++)
if (dtd->dtd_u.dtu_argv[i] != 0)
ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]);
ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
break;
case CTF_K_ARRAY:
ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
break;
case CTF_K_TYPEDEF:
ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
break;
case CTF_K_POINTER:
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
break;
}
if (dtd->dtd_name) {
@ -495,7 +567,9 @@ ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
* Discard all of the dynamic type definitions that have been added to the
* container since the last call to ctf_update(). We locate such types by
* scanning the list and deleting elements that have type IDs greater than
* ctf_dtoldid, which is set by ctf_update(), above.
* ctf_dtoldid, which is set by ctf_update(), above. Note that to work properly
* with our reference counting schemes, we must delete the dynamic list in
* reverse.
*/
int
ctf_discard(ctf_file_t *fp)
@ -508,11 +582,11 @@ ctf_discard(ctf_file_t *fp)
if (!(fp->ctf_flags & LCTF_DIRTY))
return (0); /* no update required */
for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
if (dtd->dtd_type <= fp->ctf_dtoldid)
continue; /* skip types that have been committed */
ntd = ctf_list_next(dtd);
ntd = ctf_list_prev(dtd);
ctf_dtd_delete(fp, dtd);
}
@ -614,6 +688,8 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
return (CTF_ERR); /* errno is set for us */
ctf_ref_inc(fp, ref);
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
dtd->dtd_data.ctt_type = (ushort_t)ref;
@ -645,16 +721,29 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
{
ctf_dtdef_t *dtd;
ctf_id_t type;
ctf_file_t *fpd;
if (arp == NULL)
return (ctf_set_errno(fp, EINVAL));
fpd = fp;
if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
fpd = fp;
if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
return (CTF_ERR); /* errno is set for us */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
dtd->dtd_data.ctt_size = 0;
dtd->dtd_u.dtu_arr = *arp;
ctf_ref_inc(fp, arp->ctr_contents);
ctf_ref_inc(fp, arp->ctr_index);
return (type);
}
@ -662,6 +751,7 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
int
ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
{
ctf_file_t *fpd;
ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
if (!(fp->ctf_flags & LCTF_RDWR))
@ -670,8 +760,22 @@ ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
return (ctf_set_errno(fp, ECTF_BADID));
fpd = fp;
if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
fpd = fp;
if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
fp->ctf_flags |= LCTF_DIRTY;
dtd->dtd_u.dtu_arr = *arp;
ctf_ref_inc(fp, arp->ctr_contents);
ctf_ref_inc(fp, arp->ctr_index);
return (0);
}
@ -683,7 +787,9 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
ctf_dtdef_t *dtd;
ctf_id_t type;
uint_t vlen;
int i;
ctf_id_t *vdat = NULL;
ctf_file_t *fpd;
if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
(ctc->ctc_argc != 0 && argv == NULL))
@ -696,6 +802,18 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
if (vlen > CTF_MAX_VLEN)
return (ctf_set_errno(fp, EOVERFLOW));
fpd = fp;
if (ctf_lookup_by_id(&fpd, ctc->ctc_return) == NULL &&
ctf_dtd_lookup(fp, ctc->ctc_return) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
for (i = 0; i < ctc->ctc_argc; i++) {
fpd = fp;
if (ctf_lookup_by_id(&fpd, argv[i]) == NULL &&
ctf_dtd_lookup(fp, argv[i]) == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
}
if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
return (ctf_set_errno(fp, EAGAIN));
@ -707,6 +825,10 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
ctf_ref_inc(fp, ctc->ctc_return);
for (i = 0; i < ctc->ctc_argc; i++)
ctf_ref_inc(fp, argv[i]);
bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
if (ctc->ctc_flags & CTF_FUNC_VARARG)
vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
@ -825,8 +947,11 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
{
ctf_dtdef_t *dtd;
ctf_id_t type;
ctf_file_t *fpd;
if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
fpd = fp;
if (ref == CTF_ERR || (ctf_lookup_by_id(&fpd, ref) == NULL &&
ctf_dtd_lookup(fp, ref) == NULL))
return (ctf_set_errno(fp, EINVAL));
if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
@ -834,6 +959,7 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
dtd->dtd_data.ctt_type = (ushort_t)ref;
ctf_ref_inc(fp, ref);
return (type);
}
@ -1008,6 +1134,45 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
if (s != NULL)
fp->ctf_dtstrlen += strlen(s) + 1;
ctf_ref_inc(fp, type);
fp->ctf_flags |= LCTF_DIRTY;
return (0);
}
/*
* This removes a type from the dynamic section. This will fail if the type is
* referenced by another type. Note that the CTF ID is never reused currently by
* CTF. Note that if this container is a parent container then we just outright
* refuse to remove the type. There currently is no notion of searching for the
* ctf_dtdef_t in parent containers. If there is, then this constraint could
* become finer grained.
*/
int
ctf_delete_type(ctf_file_t *fp, ctf_id_t type)
{
ctf_file_t *fpd;
ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
if (!(fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(fp, ECTF_RDONLY));
/*
* We want to give as useful an errno as possible. That means that we
* want to distinguish between a type which does not exist and one for
* which the type is not dynamic.
*/
fpd = fp;
if (ctf_lookup_by_id(&fpd, type) == NULL &&
ctf_dtd_lookup(fp, type) == NULL)
return (CTF_ERR); /* errno is set for us */
if (dtd == NULL)
return (ctf_set_errno(fp, ECTF_NOTDYN));
if (dtd->dtd_ref != 0 || fp->ctf_refcnt > 1)
return (ctf_set_errno(fp, ECTF_REFERENCED));
ctf_dtd_delete(fp, dtd);
fp->ctf_flags |= LCTF_DIRTY;
return (0);
}
@ -1103,6 +1268,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
ctf_hash_t *hp;
ctf_helem_t *hep;
if (dst_fp == src_fp)
return (src_type);
if (!(dst_fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(dst_fp, ECTF_RDONLY));
@ -1313,6 +1481,14 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
if (errs)
return (CTF_ERR); /* errno is set for us */
/*
* Now that we know that we can't fail, we go through and bump
* all the reference counts on the member types.
*/
for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
dmd != NULL; dmd = ctf_list_next(dmd))
ctf_ref_inc(dst_fp, dmd->dmd_type);
break;
}

View File

@ -23,8 +23,9 @@
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 2012, Joyent, Inc.
*/
#include <ctf_impl.h>
@ -73,6 +74,8 @@ static const char *const _ctf_errlist[] = {
"Limit on number of dynamic types reached", /* ECTF_FULL */
"Duplicate member name definition", /* ECTF_DUPMEMBER */
"Conflicting type is already defined", /* ECTF_CONFLICT */
"Type has outstanding references", /* ECTF_REFERENCED */
"Type is not a dynamic type" /* ECTF_NOTDYN */
};
static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]);

View File

@ -24,12 +24,13 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _CTF_IMPL_H
#define _CTF_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/sysmacros.h>
@ -149,6 +150,7 @@ typedef struct ctf_dtdef {
char *dtd_name; /* name associated with definition (if any) */
ctf_id_t dtd_type; /* type identifier for this definition */
ctf_type_t dtd_data; /* type node (see <sys/ctf.h>) */
int dtd_ref; /* recfount for dyanmic types */
union {
ctf_list_t dtu_members; /* struct, union, or enum */
ctf_arinfo_t dtu_arr; /* array */
@ -269,7 +271,9 @@ enum {
ECTF_DTFULL, /* CTF type is full (no more members allowed) */
ECTF_FULL, /* CTF container is full */
ECTF_DUPMEMBER, /* duplicate member name definition */
ECTF_CONFLICT /* conflicting type definition present */
ECTF_CONFLICT, /* conflicting type definition present */
ECTF_REFERENCED, /* type has outstanding references */
ECTF_NOTDYN /* type is not a dynamic type */
};
extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,

View File

@ -24,8 +24,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#include <ctf_impl.h>
#include <sys/mman.h>
@ -810,8 +811,12 @@ ctf_close(ctf_file_t *fp)
if (fp->ctf_parent != NULL)
ctf_close(fp->ctf_parent);
for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
ntd = ctf_list_next(dtd);
/*
* Note, to work properly with reference counting on the dynamic
* section, we must delete the list in reverse.
*/
for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
ntd = ctf_list_prev(dtd);
ctf_dtd_delete(fp, dtd);
}

View File

@ -216,6 +216,7 @@ ctf_fdopen(int fd, int *errp)
{
ctf_sect_t ctfsect, symsect, strsect;
ctf_file_t *fp = NULL;
size_t shstrndx, shnum;
struct stat64 st;
ssize_t nbytes;
@ -278,11 +279,10 @@ ctf_fdopen(int fd, int *errp)
#else
uchar_t order = ELFDATA2LSB;
#endif
GElf_Half i, n;
GElf_Shdr *sp;
void *strs_map;
size_t strs_mapsz;
size_t strs_mapsz, i;
char *strs;
if (hdr.e32.e_ident[EI_DATA] != order)
@ -298,11 +298,38 @@ ctf_fdopen(int fd, int *errp)
ehdr_to_gelf(&e32, &hdr.e64);
}
if (hdr.e64.e_shstrndx >= hdr.e64.e_shnum)
shnum = hdr.e64.e_shnum;
shstrndx = hdr.e64.e_shstrndx;
/* Extended ELF sections */
if ((shstrndx == SHN_XINDEX) || (shnum == 0)) {
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr x32;
if (pread64(fd, &x32, sizeof (x32),
hdr.e64.e_shoff) != sizeof (x32))
return (ctf_set_open_errno(errp,
errno));
shnum = x32.sh_size;
shstrndx = x32.sh_link;
} else {
Elf64_Shdr x64;
if (pread64(fd, &x64, sizeof (x64),
hdr.e64.e_shoff) != sizeof (x64))
return (ctf_set_open_errno(errp,
errno));
shnum = x64.sh_size;
shstrndx = x64.sh_link;
}
}
if (shstrndx >= shnum)
return (ctf_set_open_errno(errp, ECTF_CORRUPT));
n = hdr.e64.e_shnum;
nbytes = sizeof (GElf_Shdr) * n;
nbytes = sizeof (GElf_Shdr) * shnum;
if ((sp = malloc(nbytes)) == NULL)
return (ctf_set_open_errno(errp, errno));
@ -314,7 +341,7 @@ ctf_fdopen(int fd, int *errp)
if (hdr.e32.e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Shdr *sp32;
nbytes = sizeof (Elf32_Shdr) * n;
nbytes = sizeof (Elf32_Shdr) * shnum;
if ((sp32 = malloc(nbytes)) == NULL || pread64(fd,
sp32, nbytes, hdr.e64.e_shoff) != nbytes) {
@ -322,7 +349,7 @@ ctf_fdopen(int fd, int *errp)
return (ctf_set_open_errno(errp, errno));
}
for (i = 0; i < n; i++)
for (i = 0; i < shnum; i++)
shdr_to_gelf(&sp32[i], &sp[i]);
free(sp32);
@ -336,14 +363,14 @@ ctf_fdopen(int fd, int *errp)
* Now mmap the section header strings section so that we can
* perform string comparison on the section names.
*/
strs_mapsz = sp[hdr.e64.e_shstrndx].sh_size +
(sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
strs_mapsz = sp[shstrndx].sh_size +
(sp[shstrndx].sh_offset & ~_PAGEMASK);
strs_map = mmap64(NULL, strs_mapsz, PROT_READ, MAP_PRIVATE,
fd, sp[hdr.e64.e_shstrndx].sh_offset & _PAGEMASK);
fd, sp[shstrndx].sh_offset & _PAGEMASK);
strs = (char *)strs_map +
(sp[hdr.e64.e_shstrndx].sh_offset & ~_PAGEMASK);
(sp[shstrndx].sh_offset & ~_PAGEMASK);
if (strs_map == MAP_FAILED) {
free(sp);
@ -354,15 +381,15 @@ ctf_fdopen(int fd, int *errp)
* Iterate over the section header array looking for the CTF
* section and symbol table. The strtab is linked to symtab.
*/
for (i = 0; i < n; i++) {
for (i = 0; i < shnum; i++) {
const GElf_Shdr *shp = &sp[i];
const GElf_Shdr *lhp = &sp[shp->sh_link];
if (shp->sh_link >= hdr.e64.e_shnum)
if (shp->sh_link >= shnum)
continue; /* corrupt sh_link field */
if (shp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size ||
lhp->sh_name >= sp[hdr.e64.e_shstrndx].sh_size)
if (shp->sh_name >= sp[shstrndx].sh_size ||
lhp->sh_name >= sp[shstrndx].sh_size)
continue; /* corrupt sh_name field */
if (shp->sh_type == SHT_PROGBITS &&

View File

@ -21,10 +21,10 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdio.h>
@ -452,8 +452,12 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
}
ida->stack = isf.next;
}
if (!first && err == 0)
err = ida->func(zhp, ida->data);
else
zfs_close(zhp);
return (err);
}

View File

@ -336,19 +336,45 @@ class IRExecutionUnit : public IRMemoryMap
/// @return
/// True in case of failure, false in case of success.
//------------------------------------------------------------------
virtual bool finalizeMemory(std::string *ErrMsg) {
// TODO: Ensure that the instruction cache is flushed because
// relocations are updated by dy-load. See:
// sys::Memory::InvalidateInstructionCache
// llvm::SectionMemoryManager
return false;
}
bool applyPermissions(std::string *ErrMsg) { return false; }
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
virtual void deallocateFunctionBody(void *Body);
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
virtual uint8_t* startExceptionTable(const llvm::Function* F,
uintptr_t &ActualSize);
//------------------------------------------------------------------
/// Complete the exception table for a function, and add it to the
/// m_exception_tables map
///
/// @param[in] F
/// The function whose exception table is being written.
///
/// @param[in] TableStart
/// The first byte of the exception table.
///
/// @param[in] TableEnd
/// The last byte of the exception table.
///
/// @param[in] FrameRegister
/// I don't know what this does, but it's passed through.
//------------------------------------------------------------------
virtual void endExceptionTable(const llvm::Function *F,
uint8_t *TableStart,
uint8_t *TableEnd,
uint8_t* FrameRegister);
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
virtual void deallocateExceptionTable(void *ET);
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------

View File

@ -52,7 +52,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/PathV1.h"
#include "llvm/Support/TargetSelect.h"
#if defined(__FreeBSD__)
@ -81,16 +81,19 @@ using namespace lldb_private;
//===----------------------------------------------------------------------===//
std::string GetBuiltinIncludePath(const char *Argv0) {
SmallString<128> P(llvm::sys::fs::getMainExecutable(
Argv0, (void *)(intptr_t) GetBuiltinIncludePath));
if (!P.empty()) {
llvm::sys::path::remove_filename(P); // Remove /clang from foo/bin/clang
llvm::sys::path::remove_filename(P); // Remove /bin from foo/bin
llvm::sys::Path P =
llvm::sys::Path::GetMainExecutable(Argv0,
(void*)(intptr_t) GetBuiltinIncludePath);
if (!P.isEmpty()) {
P.eraseComponent(); // Remove /clang from foo/bin/clang
P.eraseComponent(); // Remove /bin from foo/bin
// Get foo/lib/clang/<version>/include
llvm::sys::path::append(P, "lib", "clang", CLANG_VERSION_STRING,
"include");
P.appendComponent("lib");
P.appendComponent("clang");
P.appendComponent(CLANG_VERSION_STRING);
P.appendComponent("include");
}
return P.str();

View File

@ -563,6 +563,28 @@ IRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body)
m_default_mm_ap->deallocateFunctionBody(Body);
}
uint8_t*
IRExecutionUnit::MemoryManager::startExceptionTable(const llvm::Function* F,
uintptr_t &ActualSize)
{
return m_default_mm_ap->startExceptionTable(F, ActualSize);
}
void
IRExecutionUnit::MemoryManager::endExceptionTable(const llvm::Function *F,
uint8_t *TableStart,
uint8_t *TableEnd,
uint8_t* FrameRegister)
{
m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
}
void
IRExecutionUnit::MemoryManager::deallocateExceptionTable(void *ET)
{
m_default_mm_ap->deallocateExceptionTable (ET);
}
lldb::addr_t
IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
{

View File

@ -553,8 +553,9 @@ FileSpec::ResolveExecutableLocation ()
if (file_cstr)
{
const std::string file_str (file_cstr);
std::string path = llvm::sys::FindProgramByName (file_str);
llvm::StringRef dir_ref = llvm::sys::path::parent_path(path);
llvm::sys::Path path = llvm::sys::Program::FindProgramByName (file_str);
const std::string &path_str = path.str();
llvm::StringRef dir_ref = llvm::sys::path::parent_path(path_str);
//llvm::StringRef dir_ref = path.getDirname();
if (! dir_ref.empty())
{

View File

@ -10,7 +10,6 @@
#include "DisassemblerLLVMC.h"
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
@ -18,7 +17,6 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryObject.h"
@ -442,30 +440,23 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns
m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
features_str));
m_asm_info_ap.reset(curr_target->createMCAsmInfo(*curr_target->createMCRegInfo(triple), triple));
m_asm_info_ap.reset(curr_target->createMCAsmInfo(triple));
if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
{
m_is_valid = false;
return;
}
m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
if (m_disasm_ap.get() && m_context_ap.get())
if (m_disasm_ap.get())
{
llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
if (!RelInfo)
{
m_is_valid = false;
return;
}
m_disasm_ap->setupForSymbolicDisassembly(NULL,
DisassemblerLLVMC::SymbolLookupCallback,
(void *) &owner,
m_context_ap.get(),
RelInfo);
DisassemblerLLVMC::SymbolLookupCallback,
(void *) &owner,
m_context_ap.get());
unsigned asm_printer_variant;
if (flavor == ~0U)

View File

@ -25,7 +25,7 @@
#include "Utility/ARM_DWARF_Registers.h"
#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
// and countTrailingZeros function
// and CountTrailingZeros_32 function
using namespace lldb;
using namespace lldb_private;
@ -47,7 +47,7 @@ using namespace lldb_private;
static uint32_t
CountITSize (uint32_t ITMask) {
// First count the trailing zeros of the IT mask.
uint32_t TZ = llvm::countTrailingZeros(ITMask);
uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
if (TZ > 3)
{
#ifdef LLDB_CONFIGURATION_DEBUG

View File

@ -661,9 +661,9 @@ ipv4_down()
for _inet in $inetList ; do
# get rid of extraneous line
case $_inet in
"") break ;;
inet\ *) ;;
*) continue ;;
"") break ;;
\ inet\ *|inet\ *) ;;
*) continue ;;
esac
[ -z "$_inet" ] && break

View File

@ -539,6 +539,7 @@ MAN= aac.4 \
${_virtio_scsi.4} \
vkbd.4 \
vlan.4 \
${_vmx.4} \
vpo.4 \
vr.4 \
vte.4 \
@ -706,6 +707,7 @@ MLINKS+=ural.4 if_ural.4
MLINKS+=${_urtw.4} ${_if_urtw.4}
MLINKS+=vge.4 if_vge.4
MLINKS+=vlan.4 if_vlan.4
MLINKS+=${_vmx.4} ${_if_vmx.4}
MLINKS+=vpo.4 imm.4
MLINKS+=vr.4 if_vr.4
MLINKS+=vte.4 if_vte.4
@ -758,6 +760,7 @@ _if_nfe.4= if_nfe.4
_if_nve.4= if_nve.4
_if_nxge.4= if_nxge.4
_if_urtw.4= if_urtw.4
_if_vmx.4= if_vmx.4
_if_vtnet.4= if_vtnet.4
_if_vxge.4= if_vxge.4
_if_wpi.4= if_wpi.4
@ -777,6 +780,7 @@ _virtio.4= virtio.4
_virtio_balloon.4=virtio_balloon.4
_virtio_blk.4= virtio_blk.4
_virtio_scsi.4= virtio_scsi.4
_vmx.4= vmx.4
_vtnet.4= vtnet.4
_vxge.4= vxge.4
_padlock.4= padlock.4

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 6, 1999
.Dd August 23, 2013
.Dt SA 4
.Os
.Sh NAME
@ -159,6 +159,70 @@ of 0.
(As above, if the file mark is never read, it remains for the next
process to read if in no-rewind mode.)
.El
.Sh BLOCK SIZES
By default, the driver will NOT accept reads or writes to a tape device that
are larger than may be written to or read from the mounted tape using a single
write or read request.
Because of this, the application author may have confidence that his wishes
are respected in terms of the block size written to tape.
For example, if the user tries to write a 256KB block to the tape, but the
controller can handle no more than 128KB, the write will fail.
The previous
.Fx
behavior, prior to
.Fx
10.0,
was to break up large reads or writes into smaller blocks when going to the
tape.
The problem with that behavior, though, is that it hides the actual on-tape
block size from the application writer, at least in variable block mode.
.Pp
If the user would like his large reads and writes broken up into separate
pieces, he may set the following loader tunables.
Note that these tunables WILL GO AWAY in
.Fx 11.0 .
They are provided for transition purposes only.
.Bl -tag -width 12
.It kern.cam.sa.allow_io_split
.Pp
This variable, when set to 1, will configure all
.Nm
devices to split large buffers into smaller pieces when needed.
.It kern.cam.sa.%d.allow_io_split
.Pp
This variable, when set to 1, will configure the given
.Nm
unit to split large buffers into multiple pieces.
This will override the global setting, if it exists.
.El
.Pp
There are several
.Xr sysctl 8
variables available to view block handling parameters:
.Bl -tag -width 12
.It kern.cam.sa.%d.allow_io_split
.Pp
This variable allows the user to see, but not modify, the current I/O split
setting.
The user is not permitted to modify this setting so that there is no chance
of behavior changing for the application while a tape is mounted.
.It kern.cam.sa.%d.maxio
.Pp
This variable shows the maximum I/O size in bytes that is allowed by the
combination of kernel tuning parameters (MAXPHYS, DFLTPHYS) and the
capabilities of the controller that is attached to the tape drive.
Applications may look at this value for a guide on how large an I/O may be
permitted, but should keep in mind that the actual maximum may be
restricted further by the tape drive via the
.Tn SCSI
READ BLOCK LIMITS command.
.It kern.cam.sa.%d.cpi_maxio
.Pp
This variable shows the maximum I/O size supported by the controller, in
bytes, that is reported via the CAM Path Inquiry CCB (XPT_PATH_INQ).
If this is 0, that means that the controller has not reported a maximum I/O
size.
.El
.Sh FILE MARK HANDLING
The handling of file marks on write is automatic.
If the user has

112
share/man/man4/vmx.4 Normal file
View File

@ -0,0 +1,112 @@
.\"
.\" Copyright (c) 2006,2013 Reyk Floeter <reyk@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\" $OpenBSD: src/share/man/man4/vmx.4,v 1.1 2013/05/31 20:18:44 reyk Exp $
.\"
.\" $FreeBSD$
.\"
.Dd August 4, 2013
.Dt VMX 4
.Os
.Sh NAME
.Nm vmx
.Nd VMware VMXNET3 Virtual Interface Controller device
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following line in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device vmx"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
if_vmx_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
driver provides support for the VMXNET3 virtual NIC available in virtual
machines by VMware.
It appears as a simple Ethernet device but is actually a virtual network
interface to the underlying host operating system.
.Pp
This driver supports the
.Ic VMXNET3
driver protocol, as an alternative to the emulated
.Xr pcn 4 ,
.Xr em 4
interfaces also available in the VMware environment.
The
.Nm
driver is optimized for the virtual machine, it can provide advanced
capabilities depending on the underlying host operating system and
the physical network interface controller of the host.
The
.Nm
driver supports features like multiqueue support, IPv6
checksum offloading, MSI/MSI-X support and hardware VLAN tagging in
VMware's VLAN Guest Tagging (VGT) mode.
.Pp
The
.Nm
driver supports VMXNET3 VMware virtual NICs provided by the virtual
machine hardware version 7 or newer, as provided by the following
products:
.Pp
.Bl -bullet -compact -offset indent
.It
VMware ESX/ESXi 4.0 and newer
.It
VMware Server 2.0 and newer
.It
VMware Workstation 6.5 and newer
.It
VMware Fusion 2.0 and newer
.El
.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh EXAMPLES
The following entry must be added to the VMware configuration file
to provide the
.Nm
device:
.Bd -literal -offset indent
ethernet0.virtualDev = "vmxnet3"
.Ed
.Sh SEE ALSO
.Xr altq 4 ,
.Xr arp 4 ,
.Xr em 4 ,
.Xr netintro 4 ,
.Xr ng_ether 4 ,
.Xr pcn 4 ,
.Xr vlan 4 ,
.Xr ifconfig 8
.Sh AUTHORS
.An -nosplit
The
.Nm
driver was ported from
.Ox
by
.An Bryan Venteicher Aq bryanv@freebsd.org .
The
.Ox
driver was written by
.An Tsubai Masanari .

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 22, 2012
.Dd August 23, 2013
.Dt PFIL 9
.Os
.Sh NAME
@ -36,7 +36,6 @@
.Nm pfil_head_register ,
.Nm pfil_head_unregister ,
.Nm pfil_head_get ,
.Nm pfil_hook_get ,
.Nm pfil_add_hook ,
.Nm pfil_remove_hook ,
.Nm pfil_run_hooks ,
@ -50,20 +49,18 @@
.In sys/mbuf.h
.In net/if.h
.In net/pfil.h
.Bd -literal
typedef int (*pfil_func_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb);
.Ft int
.Fn pfil_head_register "struct pfil_head *head"
.Ft int
.Fn pfil_head_unregister "struct pfil_head *head"
.Ft "struct pfil_head *"
.Fn pfil_head_get "int af" "u_long dlt"
.Ft "struct packet_filter_hook *"
.Fn pfil_hook_get "int dir" "struct pfil_head *head"
.Ft void
.Fn pfil_add_hook "int (*func)()" "void *arg" "int flags" "struct pfil_head *"
.Fn pfil_add_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *"
.Ft void
.Fn pfil_remove_hook "int (*func)()" "void *arg" "int flags" "struct pfil_head *"
.Ft int
.Fn (*func) "void *arg" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *"
.Fn pfil_remove_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *"
.Ft int
.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *"
.Ft void
@ -245,11 +242,7 @@ lock export was added in
.Fx 10.0 .
.Sh BUGS
The
.Fn pfil_hook_get
function
is only safe for internal use.
.Pp
When a
.Fn When a
.Vt pfil_head
is being modified, no traffic is diverted
(to avoid deadlock).

View File

@ -61,7 +61,7 @@ biosacpi_detect(void)
return;
/* export values from the RSDP */
sprintf(buf, "%u", VTOP(rsdp));
sprintf(buf, "0x%08x", VTOP(rsdp));
setenv("hint.acpi.0.rsdp", buf, 1);
revision = rsdp->Revision;
if (revision == 0)

View File

@ -1091,7 +1091,8 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
cdai.buftype = CDAI_TYPE_SERIAL_NUM;
else if (!strcmp(attr, "GEOM::physpath"))
cdai.buftype = CDAI_TYPE_PHYS_PATH;
else if (!strcmp(attr, "GEOM::lunid")) {
else if (strcmp(attr, "GEOM::lunid") == 0 ||
strcmp(attr, "GEOM::lunname") == 0) {
cdai.buftype = CDAI_TYPE_SCSI_DEVID;
cdai.bufsiz = CAM_SCSI_DEVID_MAXLEN;
} else
@ -1108,11 +1109,14 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
if (cdai.provsiz == 0)
goto out;
if (cdai.buftype == CDAI_TYPE_SCSI_DEVID) {
idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
cdai.provsiz, scsi_devid_is_lun_naa);
if (idd == NULL)
if (strcmp(attr, "GEOM::lunid") == 0) {
idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
cdai.provsiz, scsi_devid_is_lun_eui64);
cdai.provsiz, scsi_devid_is_lun_naa);
if (idd == NULL)
idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
cdai.provsiz, scsi_devid_is_lun_eui64);
} else
idd = NULL;
if (idd == NULL)
idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
cdai.provsiz, scsi_devid_is_lun_t10);

View File

@ -894,8 +894,13 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
struct ctl_lun *lun;
struct ctl_page_index *page_index;
struct copan_aps_subpage *current_sp;
uint32_t targ_lun;
lun = ctl_softc->ctl_luns[msg_info.hdr.nexus.targ_lun];
targ_lun = msg_info.hdr.nexus.targ_lun;
if (msg_info.hdr.nexus.lun_map_fn != NULL)
targ_lun = msg_info.hdr.nexus.lun_map_fn(msg_info.hdr.nexus.lun_map_arg, targ_lun);
lun = ctl_softc->ctl_luns[targ_lun];
page_index = &lun->mode_pages.index[index_to_aps_page];
current_sp = (struct copan_aps_subpage *)
(page_index->page_data +
@ -1098,7 +1103,8 @@ ctl_init(void)
mtx_unlock(&softc->ctl_lock);
return (error);
}
printf("ctl: CAM Target Layer loaded\n");
if (bootverbose)
printf("ctl: CAM Target Layer loaded\n");
/*
* Initialize the initiator and portname mappings
@ -1194,7 +1200,8 @@ ctl_shutdown(void)
free(control_softc, M_DEVBUF);
control_softc = NULL;
printf("ctl: CAM Target Layer unloaded\n");
if (bootverbose)
printf("ctl: CAM Target Layer unloaded\n");
}
static int
@ -1678,12 +1685,16 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio, int have_lock)
union ctl_ha_msg msg_info;
struct ctl_lun *lun;
int retval = 0;
uint32_t targ_lun;
ctl_softc = control_softc;
if (have_lock == 0)
mtx_lock(&ctl_softc->ctl_lock);
lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
targ_lun = ctsio->io_hdr.nexus.targ_lun;
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
lun = ctl_softc->ctl_luns[targ_lun];
if (lun==NULL)
{
/*
@ -2980,6 +2991,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct sbuf *sb;
struct ctl_lun *lun;
struct ctl_lun_list *list;
struct ctl_be_lun_option *opt;
list = (struct ctl_lun_list *)addr;
@ -3097,17 +3109,16 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
if (retval != 0)
break;
if (lun->backend->lun_info == NULL) {
retval = sbuf_printf(sb, "</lun>\n");
if (lun->backend->lun_info != NULL) {
retval = lun->backend->lun_info(lun->be_lun->be_lun, sb);
if (retval != 0)
break;
}
STAILQ_FOREACH(opt, &lun->be_lun->options, links) {
retval = sbuf_printf(sb, "<%s>%s</%s>", opt->name, opt->value, opt->name);
if (retval != 0)
break;
continue;
}
retval =lun->backend->lun_info(lun->be_lun->be_lun, sb);
if (retval != 0)
break;
retval = sbuf_printf(sb, "</lun>\n");
@ -4432,9 +4443,14 @@ ctl_free_lun(struct ctl_lun *lun)
*/
for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue); io != NULL;
io = next_io) {
uint32_t targ_lun;
next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links);
targ_lun = io->io_hdr.nexus.targ_lun;
if (io->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((io->io_hdr.nexus.targ_target.id == lun->target.id)
&& (io->io_hdr.nexus.targ_lun == lun->lun))
&& (targ_lun == lun->lun))
STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr,
ctl_io_hdr, links);
}
@ -8247,12 +8263,16 @@ ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
struct ctl_lun *lun;
struct ctl_softc *softc;
int i;
uint32_t targ_lun;
softc = control_softc;
mtx_lock(&softc->ctl_lock);
lun = softc->ctl_luns[msg->hdr.nexus.targ_lun];
targ_lun = msg->hdr.nexus.targ_lun;
if (msg->hdr.nexus.lun_map_fn != NULL)
targ_lun = msg->hdr.nexus.lun_map_fn(msg->hdr.nexus.lun_map_arg, targ_lun);
lun = softc->ctl_luns[targ_lun];
switch(msg->pr.pr_info.action) {
case CTL_PR_REG_KEY:
if (!lun->per_res[msg->pr.pr_info.residx].registered) {
@ -8601,7 +8621,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
int num_luns, retval;
uint32_t alloc_len, lun_datalen;
int num_filled, well_known;
uint32_t initidx;
uint32_t initidx, targ_lun_id, lun_id;
retval = CTL_RETVAL_COMPLETE;
well_known = 0;
@ -8662,63 +8682,47 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
lun_data = (struct scsi_report_luns_data *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
if (lun_datalen < alloc_len) {
ctsio->residual = alloc_len - lun_datalen;
ctsio->kern_data_len = lun_datalen;
ctsio->kern_total_len = lun_datalen;
} else {
ctsio->residual = 0;
ctsio->kern_data_len = alloc_len;
ctsio->kern_total_len = alloc_len;
}
ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
/*
* We set this to the actual data length, regardless of how much
* space we actually have to return results. If the user looks at
* this value, he'll know whether or not he allocated enough space
* and reissue the command if necessary. We don't support well
* known logical units, so if the user asks for that, return none.
*/
scsi_ulto4b(lun_datalen - 8, lun_data->length);
mtx_lock(&control_softc->ctl_lock);
for (num_filled = 0, lun = STAILQ_FIRST(&control_softc->lun_list);
(lun != NULL) && (num_filled < num_luns);
lun = STAILQ_NEXT(lun, links)) {
for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
lun_id = targ_lun_id;
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
lun_id = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, lun_id);
if (lun_id >= CTL_MAX_LUNS)
continue;
lun = control_softc->ctl_luns[lun_id];
if (lun == NULL)
continue;
if (lun->lun <= 0xff) {
if (targ_lun_id <= 0xff) {
/*
* Peripheral addressing method, bus number 0.
*/
lun_data->luns[num_filled].lundata[0] =
RPL_LUNDATA_ATYP_PERIPH;
lun_data->luns[num_filled].lundata[1] = lun->lun;
lun_data->luns[num_filled].lundata[1] = targ_lun_id;
num_filled++;
} else if (lun->lun <= 0x3fff) {
} else if (targ_lun_id <= 0x3fff) {
/*
* Flat addressing method.
*/
lun_data->luns[num_filled].lundata[0] =
RPL_LUNDATA_ATYP_FLAT |
(lun->lun & RPL_LUNDATA_FLAT_LUN_MASK);
(targ_lun_id & RPL_LUNDATA_FLAT_LUN_MASK);
#ifdef OLDCTLHEADERS
(SRLD_ADDR_FLAT << SRLD_ADDR_SHIFT) |
(lun->lun & SRLD_BUS_LUN_MASK);
(targ_lun_id & SRLD_BUS_LUN_MASK);
#endif
lun_data->luns[num_filled].lundata[1] =
#ifdef OLDCTLHEADERS
lun->lun >> SRLD_BUS_LUN_BITS;
targ_lun_id >> SRLD_BUS_LUN_BITS;
#endif
lun->lun >> RPL_LUNDATA_FLAT_LUN_BITS;
targ_lun_id >> RPL_LUNDATA_FLAT_LUN_BITS;
num_filled++;
} else {
printf("ctl_report_luns: bogus LUN number %jd, "
"skipping\n", (intmax_t)lun->lun);
"skipping\n", (intmax_t)targ_lun_id);
}
/*
* According to SPC-3, rev 14 section 6.21:
@ -8742,6 +8746,35 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
}
mtx_unlock(&control_softc->ctl_lock);
/*
* It's quite possible that we've returned fewer LUNs than we allocated
* space for. Trim it.
*/
lun_datalen = sizeof(*lun_data) +
(num_filled * sizeof(struct scsi_report_luns_lundata));
if (lun_datalen < alloc_len) {
ctsio->residual = alloc_len - lun_datalen;
ctsio->kern_data_len = lun_datalen;
ctsio->kern_total_len = lun_datalen;
} else {
ctsio->residual = 0;
ctsio->kern_data_len = alloc_len;
ctsio->kern_total_len = alloc_len;
}
ctsio->kern_data_resid = 0;
ctsio->kern_rel_offset = 0;
ctsio->kern_sg_entries = 0;
/*
* We set this to the actual data length, regardless of how much
* space we actually have to return results. If the user looks at
* this value, he'll know whether or not he allocated enough space
* and reissue the command if necessary. We don't support well
* known logical units, so if the user asks for that, return none.
*/
scsi_ulto4b(lun_datalen - 8, lun_data->length);
/*
* We can only return SCSI_STATUS_CHECK_COND when we can't satisfy
* this request.
@ -9077,6 +9110,14 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
int devid_len;
ctl_softc = control_softc;
mtx_lock(&ctl_softc->ctl_lock);
fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
mtx_unlock(&ctl_softc->ctl_lock);
if (fe->devid != NULL)
return ((fe->devid)(ctsio, alloc_len));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
devid_len = sizeof(struct scsi_vpd_device_id) +
@ -9130,8 +9171,6 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
mtx_lock(&ctl_softc->ctl_lock);
fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
/*
* For Fibre channel,
*/
@ -10350,7 +10389,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
struct ctl_lun *lun;
struct ctl_cmd_entry *entry;
uint8_t opcode;
uint32_t initidx;
uint32_t initidx, targ_lun;
int retval;
retval = 0;
@ -10361,9 +10400,12 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
mtx_lock(&ctl_softc->ctl_lock);
if ((ctsio->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun] != NULL)) {
lun = ctl_softc->ctl_luns[ctsio->io_hdr.nexus.targ_lun];
targ_lun = ctsio->io_hdr.nexus.targ_lun;
if (ctsio->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = ctsio->io_hdr.nexus.lun_map_fn(ctsio->io_hdr.nexus.lun_map_arg, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[targ_lun] != NULL)) {
lun = ctl_softc->ctl_luns[targ_lun];
/*
* If the LUN is invalid, pretend that it doesn't exist.
* It will go away as soon as all pending I/O has been
@ -10403,6 +10445,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
ctl_set_unsupported_lun(ctsio);
mtx_unlock(&ctl_softc->ctl_lock);
ctl_done((union ctl_io *)ctsio);
CTL_DEBUG_PRINT(("ctl_scsiio_precheck: bailing out due to invalid LUN\n"));
goto bailout;
} else {
/*
@ -10769,6 +10812,7 @@ ctl_abort_task(union ctl_io *io)
char printbuf[128];
#endif
int found;
uint32_t targ_lun;
ctl_softc = control_softc;
found = 0;
@ -10776,9 +10820,12 @@ ctl_abort_task(union ctl_io *io)
/*
* Look up the LUN.
*/
if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
targ_lun = io->io_hdr.nexus.targ_lun;
if (io->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
lun = ctl_softc->ctl_luns[targ_lun];
else
goto bailout;
@ -10968,6 +11015,8 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
int retval;
targ_lun = io->io_hdr.nexus.targ_lun;
if (io->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
@ -11042,7 +11091,7 @@ ctl_run_task_queue(struct ctl_softc *ctl_softc)
(uintmax_t)io->io_hdr.nexus.initid.id,
io->io_hdr.nexus.targ_port,
(uintmax_t)io->io_hdr.nexus.targ_target.id,
io->io_hdr.nexus.targ_lun,
io->io_hdr.nexus.targ_lun /* XXX */,
(io->io_hdr.io_type == CTL_IO_TASK) ?
io->taskio.tag_num : io->scsiio.tag_num);
STAILQ_REMOVE(&ctl_softc->task_queue, &io->io_hdr,
@ -11066,10 +11115,14 @@ ctl_handle_isc(union ctl_io *io)
int free_io;
struct ctl_lun *lun;
struct ctl_softc *ctl_softc;
uint32_t targ_lun;
ctl_softc = control_softc;
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
targ_lun = io->io_hdr.nexus.targ_lun;
if (io->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
lun = ctl_softc->ctl_luns[targ_lun];
switch (io->io_hdr.msg_type) {
case CTL_MSG_SERIALIZE:
@ -12625,7 +12678,7 @@ ctl_queue_sense(union ctl_io *io)
{
struct ctl_lun *lun;
struct ctl_softc *ctl_softc;
uint32_t initidx;
uint32_t initidx, targ_lun;
ctl_softc = control_softc;
@ -12644,9 +12697,12 @@ ctl_queue_sense(union ctl_io *io)
* If we don't have a LUN for this, just toss the sense
* information.
*/
if ((io->io_hdr.nexus.targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun] != NULL))
lun = ctl_softc->ctl_luns[io->io_hdr.nexus.targ_lun];
targ_lun = io->io_hdr.nexus.targ_lun;
if (io->io_hdr.nexus.lun_map_fn != NULL)
targ_lun = io->io_hdr.nexus.lun_map_fn(io->io_hdr.nexus.lun_map_arg, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
&& (ctl_softc->ctl_luns[targ_lun] != NULL))
lun = ctl_softc->ctl_luns[targ_lun];
else
goto bailout;
@ -13047,6 +13103,8 @@ ctl_isc_start(struct ctl_ha_component *c, ctl_ha_state state)
{
ctl_ha_comp_status ret = CTL_HA_COMP_STATUS_OK;
printf("%s: go\n", __func__);
// UNKNOWN->HA or UNKNOWN->SINGLE (bootstrap)
if (c->state == CTL_HA_STATE_UNKNOWN ) {
ctl_is_single = 0;

View File

@ -52,6 +52,7 @@ typedef enum {
CTL_PORT_SCSI = 0x02,
CTL_PORT_IOCTL = 0x04,
CTL_PORT_INTERNAL = 0x08,
CTL_PORT_ISCSI = 0x10,
CTL_PORT_ALL = 0xff,
CTL_PORT_ISC = 0x100 // FC port for inter-shelf communication
} ctl_port_type;

View File

@ -173,6 +173,12 @@ typedef void (*be_lun_config_t)(void *be_lun,
* The links field is for CTL internal use only, and should not be used by
* the backend.
*/
struct ctl_be_lun_option {
STAILQ_ENTRY(ctl_be_lun_option) links;
char *name;
char *value;
};
struct ctl_be_lun {
uint8_t lun_type; /* passed to CTL */
ctl_backend_lun_flags flags; /* passed to CTL */
@ -187,6 +193,7 @@ struct ctl_be_lun {
be_lun_config_t lun_config_status; /* passed to CTL */
struct ctl_backend_driver *be; /* passed to CTL */
void *ctl_lun; /* used by CTL */
STAILQ_HEAD(, ctl_be_lun_option) options; /* passed to CTL */
STAILQ_ENTRY(ctl_be_lun) links; /* used by CTL */
};

View File

@ -1639,6 +1639,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
STAILQ_INIT(&be_lun->input_queue);
STAILQ_INIT(&be_lun->config_write_queue);
STAILQ_INIT(&be_lun->datamove_queue);
STAILQ_INIT(&be_lun->ctl_be_lun.options);
sprintf(be_lun->lunname, "cblk%d", softc->num_luns);
mtx_init(&be_lun->lock, be_lun->lunname, NULL, MTX_DEF);
@ -1740,6 +1741,16 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
}
num_threads = tmp_num_threads;
} else if (strcmp(req->kern_be_args[i].kname, "file") != 0 &&
strcmp(req->kern_be_args[i].kname, "dev") != 0) {
struct ctl_be_lun_option *opt;
opt = malloc(sizeof(*opt), M_CTLBLK, M_WAITOK);
opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_CTLBLK, M_WAITOK);
strcpy(opt->name, req->kern_be_args[i].kname);
opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_CTLBLK, M_WAITOK);
strcpy(opt->value, req->kern_be_args[i].kvalue);
STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links);
}
}

View File

@ -491,7 +491,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
struct ctl_lun_create_params *params;
uint32_t blocksize;
char tmpstr[32];
int retval;
int i, retval;
retval = 0;
params = &req->reqdata.create;
@ -509,6 +509,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
sizeof(*be_lun));
goto bailout_error;
}
STAILQ_INIT(&be_lun->ctl_be_lun.options);
if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
be_lun->ctl_be_lun.lun_type = params->device_type;
@ -545,6 +546,17 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
be_lun->softc = softc;
for (i = 0; i < req->num_be_args; i++) {
struct ctl_be_lun_option *opt;
opt = malloc(sizeof(*opt), M_RAMDISK, M_WAITOK);
opt->name = malloc(strlen(req->kern_be_args[i].kname) + 1, M_RAMDISK, M_WAITOK);
strcpy(opt->name, req->kern_be_args[i].kname);
opt->value = malloc(strlen(req->kern_be_args[i].kvalue) + 1, M_RAMDISK, M_WAITOK);
strcpy(opt->value, req->kern_be_args[i].kvalue);
STAILQ_INSERT_TAIL(&be_lun->ctl_be_lun.options, opt, links);
}
be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
be_lun->ctl_be_lun.be_lun = be_lun;

View File

@ -49,6 +49,9 @@ typedef enum {
typedef void (*port_func_t)(void *onoff_arg);
typedef int (*targ_func_t)(void *arg, struct ctl_id targ_id);
typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id);
typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
typedef int (*fe_devid_t)(struct ctl_scsiio *ctsio, int alloc_len);
/*
* The ctl_frontend structure is the registration mechanism between a FETD
@ -213,6 +216,8 @@ struct ctl_frontend {
targ_func_t targ_disable; /* passed to CTL */
lun_func_t lun_enable; /* passed to CTL */
lun_func_t lun_disable; /* passed to CTL */
fe_ioctl_t ioctl; /* passed to CTL */
fe_devid_t devid; /* passed to CTL */
void *targ_lun_arg; /* passed to CTL */
void (*fe_datamove)(union ctl_io *io); /* passed to CTL */
void (*fe_done)(union ctl_io *io); /* passed to CTL */

View File

@ -204,6 +204,8 @@ struct ctl_nexus {
uint32_t targ_port; /* Target port, filled in by PORT */
struct ctl_id targ_target; /* Destination target */
uint32_t targ_lun; /* Destination lun */
uint32_t (*lun_map_fn)(void *arg, uint32_t lun);
void *lun_map_arg;
};
typedef enum {

View File

@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
#include <sys/mtio.h>
#ifdef _KERNEL
#include <sys/conf.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#endif
#include <sys/fcntl.h>
#include <sys/devicestat.h>
@ -223,6 +225,8 @@ struct sa_softc {
u_int32_t max_blk;
u_int32_t min_blk;
u_int32_t maxio;
u_int32_t cpi_maxio;
int allow_io_split;
u_int32_t comp_algorithm;
u_int32_t saved_comp_algorithm;
u_int32_t media_blksize;
@ -268,6 +272,10 @@ struct sa_softc {
open_rdonly : 1, /* open read-only */
open_pending_mount : 1, /* open pending mount */
ctrl_mode : 1; /* control device open */
struct task sysctl_task;
struct sysctl_ctx_list sysctl_ctx;
struct sysctl_oid *sysctl_tree;
};
struct sa_quirk_entry {
@ -426,6 +434,22 @@ static int sardpos(struct cam_periph *periph, int, u_int32_t *);
static int sasetpos(struct cam_periph *periph, int, u_int32_t *);
#ifndef SA_DEFAULT_IO_SPLIT
#define SA_DEFAULT_IO_SPLIT 0
#endif
static int sa_allow_io_split = SA_DEFAULT_IO_SPLIT;
/*
* Tunable to allow the user to set a global allow_io_split value. Note
* that this WILL GO AWAY in FreeBSD 11.0. Silently splitting the I/O up
* is bad behavior, because it hides the true tape block size from the
* application.
*/
TUNABLE_INT("kern.cam.sa.allow_io_split", &sa_allow_io_split);
static SYSCTL_NODE(_kern_cam, OID_AUTO, sa, CTLFLAG_RD, 0,
"CAM Sequential Access Tape Driver");
static struct periph_driver sadriver =
{
sainit, "sa",
@ -1448,6 +1472,49 @@ saasync(void *callback_arg, u_int32_t code,
}
}
static void
sasysctlinit(void *context, int pending)
{
struct cam_periph *periph;
struct sa_softc *softc;
char tmpstr[80], tmpstr2[80];
periph = (struct cam_periph *)context;
/*
* If the periph is invalid, no need to setup the sysctls.
*/
if (periph->flags & CAM_PERIPH_INVALID)
goto bailout;
softc = (struct sa_softc *)periph->softc;
snprintf(tmpstr, sizeof(tmpstr), "CAM SA unit %d", periph->unit_number);
snprintf(tmpstr2, sizeof(tmpstr2), "%u", periph->unit_number);
sysctl_ctx_init(&softc->sysctl_ctx);
softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2,
CTLFLAG_RD, 0, tmpstr);
if (softc->sysctl_tree == NULL)
goto bailout;
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "allow_io_split", CTLTYPE_INT | CTLFLAG_RDTUN,
&softc->allow_io_split, 0, "Allow Splitting I/O");
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "maxio", CTLTYPE_INT | CTLFLAG_RD,
&softc->maxio, 0, "Maximum I/O size");
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "cpi_maxio", CTLTYPE_INT | CTLFLAG_RD,
&softc->cpi_maxio, 0, "Maximum Controller I/O size");
bailout:
/*
* Release the reference that was held when this task was enqueued.
*/
cam_periph_release(periph);
}
static cam_status
saregister(struct cam_periph *periph, void *arg)
{
@ -1455,6 +1522,7 @@ saregister(struct cam_periph *periph, void *arg)
struct ccb_getdev *cgd;
struct ccb_pathinq cpi;
caddr_t match;
char tmpstr[80];
int i;
cgd = (struct ccb_getdev *)arg;
@ -1509,21 +1577,55 @@ saregister(struct cam_periph *periph, void *arg)
XPORT_DEVSTAT_TYPE(cpi.transport), DEVSTAT_PRIORITY_TAPE);
/*
* If maxio isn't set, we fall back to DFLTPHYS. If it is set, we
* take it whether or not it's larger than MAXPHYS. physio will
* break it down into pieces small enough to fit in a buffer.
* Load the default value that is either compiled in, or loaded
* in the global kern.cam.sa.allow_io_split tunable.
*/
softc->allow_io_split = sa_allow_io_split;
/*
* Load a per-instance tunable, if it exists. NOTE that this
* tunable WILL GO AWAY in FreeBSD 11.0.
*/
snprintf(tmpstr, sizeof(tmpstr), "kern.cam.sa.%u.allow_io_split",
periph->unit_number);
TUNABLE_INT_FETCH(tmpstr, &softc->allow_io_split);
/*
* If maxio isn't set, we fall back to DFLTPHYS. Otherwise we take
* the smaller of cpi.maxio or MAXPHYS.
*/
if (cpi.maxio == 0)
softc->maxio = DFLTPHYS;
else if (cpi.maxio > MAXPHYS)
softc->maxio = MAXPHYS;
else
softc->maxio = cpi.maxio;
/*
* Record the controller's maximum I/O size so we can report it to
* the user later.
*/
softc->cpi_maxio = cpi.maxio;
/*
* By default we tell physio that we do not want our I/O split.
* The user needs to have a 1:1 mapping between the size of his
* write to a tape character device and the size of the write
* that actually goes down to the drive.
*/
if (softc->allow_io_split == 0)
softc->si_flags = SI_NOSPLIT;
else
softc->si_flags = 0;
TASK_INIT(&softc->sysctl_task, 0, sasysctlinit, periph);
/*
* If the SIM supports unmapped I/O, let physio know that we can
* handle unmapped buffers.
*/
if (cpi.hba_misc & PIM_UNMAPPED)
softc->si_flags = SI_UNMAPPED;
softc->si_flags |= SI_UNMAPPED;
softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV,
0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR,
@ -1585,6 +1687,13 @@ saregister(struct cam_periph *periph, void *arg)
}
cam_periph_lock(periph);
/*
* Bump the peripheral refcount for the sysctl thread, in case we
* get invalidated before the thread has a chance to run.
*/
cam_periph_acquire(periph);
taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
/*
* Add an async callback so that we get
* notified if this device goes away.

View File

@ -40,6 +40,12 @@
#include <sys/sa.h>
#include <sys/sa_impl.h>
/*
* Number of times that zfs_free_range() took the slow path while doing
* a zfs receive. A nonzero value indicates a potential performance problem.
*/
uint64_t zfs_free_range_recv_miss;
static void dbuf_destroy(dmu_buf_impl_t *db);
static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
@ -819,20 +825,22 @@ dbuf_free_range(dnode_t *dn, uint64_t start, uint64_t end, dmu_tx_t *tx)
}
dprintf_dnode(dn, "start=%llu end=%llu\n", start, end);
if (dmu_objset_is_receiving(dn->dn_objset)) {
/*
* When processing a free record from a zfs receive,
* there should have been no previous modifications to the
* data in this range. Therefore there should be no dbufs
* in the range. Searching dn_dbufs for these non-existent
* dbufs can be very expensive, so simply ignore this.
*/
VERIFY3P(dbuf_find(dn, 0, start), ==, NULL);
VERIFY3P(dbuf_find(dn, 0, end), ==, NULL);
mutex_enter(&dn->dn_dbufs_mtx);
if (start >= dn->dn_unlisted_l0_blkid * dn->dn_datablksz) {
/* There can't be any dbufs in this range; no need to search. */
mutex_exit(&dn->dn_dbufs_mtx);
return;
} else if (dmu_objset_is_receiving(dn->dn_objset)) {
/*
* If we are receiving, we expect there to be no dbufs in
* the range to be freed, because receive modifies each
* block at most once, and in offset order. If this is
* not the case, it can lead to performance problems,
* so note that we unexpectedly took the slow path.
*/
atomic_inc_64(&zfs_free_range_recv_miss);
}
mutex_enter(&dn->dn_dbufs_mtx);
for (db = list_head(&dn->dn_dbufs); db; db = db_next) {
db_next = list_next(&dn->dn_dbufs, db);
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
@ -1720,6 +1728,9 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid,
return (odb);
}
list_insert_head(&dn->dn_dbufs, db);
if (db->db_level == 0 && db->db_blkid >=
dn->dn_unlisted_l0_blkid)
dn->dn_unlisted_l0_blkid = db->db_blkid + 1;
db->db_state = DB_UNCACHED;
mutex_exit(&dn->dn_dbufs_mtx);
arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER);

View File

@ -575,98 +575,93 @@ dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset, uint64_t len)
* the end so that the file gets shorter over time (if we crashes in the
* middle, this will leave us in a better state). We find allocated file
* data by simply searching the allocated level 1 indirects.
*
* On input, *start should be the first offset that does not need to be
* freed (e.g. "offset + length"). On return, *start will be the first
* offset that should be freed.
*/
static int
get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t limit)
get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum)
{
uint64_t len = *start - limit;
uint64_t blkcnt = 0;
uint64_t maxblks = DMU_MAX_ACCESS / (1ULL << (dn->dn_indblkshift + 1));
uint64_t maxblks = DMU_MAX_ACCESS >> (dn->dn_indblkshift + 1);
/* bytes of data covered by a level-1 indirect block */
uint64_t iblkrange =
dn->dn_datablksz * EPB(dn->dn_indblkshift, SPA_BLKPTRSHIFT);
ASSERT(limit <= *start);
ASSERT3U(minimum, <=, *start);
if (len <= iblkrange * maxblks) {
*start = limit;
if (*start - minimum <= iblkrange * maxblks) {
*start = minimum;
return (0);
}
ASSERT(ISP2(iblkrange));
while (*start > limit && blkcnt < maxblks) {
for (uint64_t blks = 0; *start > minimum && blks < maxblks; blks++) {
int err;
/* find next allocated L1 indirect */
/*
* dnode_next_offset(BACKWARDS) will find an allocated L1
* indirect block at or before the input offset. We must
* decrement *start so that it is at the end of the region
* to search.
*/
(*start)--;
err = dnode_next_offset(dn,
DNODE_FIND_BACKWARDS, start, 2, 1, 0);
/* if there are no more, then we are done */
/* if there are no indirect blocks before start, we are done */
if (err == ESRCH) {
*start = limit;
return (0);
} else if (err) {
*start = minimum;
break;
} else if (err != 0) {
return (err);
}
blkcnt += 1;
/* reset offset to end of "next" block back */
/* set start to the beginning of this L1 indirect */
*start = P2ALIGN(*start, iblkrange);
if (*start <= limit)
*start = limit;
else
*start -= 1;
}
if (*start < minimum)
*start = minimum;
return (0);
}
static int
dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset,
uint64_t length, boolean_t free_dnode)
uint64_t length)
{
dmu_tx_t *tx;
uint64_t object_size, start, end, len;
boolean_t trunc = (length == DMU_OBJECT_END);
int align, err;
uint64_t object_size = (dn->dn_maxblkid + 1) * dn->dn_datablksz;
int err;
align = 1 << dn->dn_datablkshift;
ASSERT(align > 0);
object_size = align == 1 ? dn->dn_datablksz :
(dn->dn_maxblkid + 1) << dn->dn_datablkshift;
end = offset + length;
if (trunc || end > object_size)
end = object_size;
if (end <= offset)
if (offset >= object_size)
return (0);
length = end - offset;
while (length) {
start = end;
/* assert(offset <= start) */
err = get_next_chunk(dn, &start, offset);
if (length == DMU_OBJECT_END || offset + length > object_size)
length = object_size - offset;
while (length != 0) {
uint64_t chunk_end, chunk_begin;
chunk_end = chunk_begin = offset + length;
/* move chunk_begin backwards to the beginning of this chunk */
err = get_next_chunk(dn, &chunk_begin, offset);
if (err)
return (err);
len = trunc ? DMU_OBJECT_END : end - start;
ASSERT3U(chunk_begin, >=, offset);
ASSERT3U(chunk_begin, <=, chunk_end);
tx = dmu_tx_create(os);
dmu_tx_hold_free(tx, dn->dn_object, start, len);
dmu_tx_t *tx = dmu_tx_create(os);
dmu_tx_hold_free(tx, dn->dn_object,
chunk_begin, chunk_end - chunk_begin);
err = dmu_tx_assign(tx, TXG_WAIT);
if (err) {
dmu_tx_abort(tx);
return (err);
}
dnode_free_range(dn, start, trunc ? -1 : len, tx);
if (start == 0 && free_dnode) {
ASSERT(trunc);
dnode_free(dn, tx);
}
length -= end - start;
dnode_free_range(dn, chunk_begin, chunk_end - chunk_begin, tx);
dmu_tx_commit(tx);
end = start;
length -= chunk_end - chunk_begin;
}
return (0);
}
@ -681,38 +676,32 @@ dmu_free_long_range(objset_t *os, uint64_t object,
err = dnode_hold(os, object, FTAG, &dn);
if (err != 0)
return (err);
err = dmu_free_long_range_impl(os, dn, offset, length, FALSE);
err = dmu_free_long_range_impl(os, dn, offset, length);
dnode_rele(dn, FTAG);
return (err);
}
int
dmu_free_object(objset_t *os, uint64_t object)
dmu_free_long_object(objset_t *os, uint64_t object)
{
dnode_t *dn;
dmu_tx_t *tx;
int err;
err = dnode_hold_impl(os, object, DNODE_MUST_BE_ALLOCATED,
FTAG, &dn);
err = dmu_free_long_range(os, object, 0, DMU_OBJECT_END);
if (err != 0)
return (err);
if (dn->dn_nlevels == 1) {
tx = dmu_tx_create(os);
dmu_tx_hold_bonus(tx, object);
dmu_tx_hold_free(tx, dn->dn_object, 0, DMU_OBJECT_END);
err = dmu_tx_assign(tx, TXG_WAIT);
if (err == 0) {
dnode_free_range(dn, 0, DMU_OBJECT_END, tx);
dnode_free(dn, tx);
dmu_tx_commit(tx);
} else {
dmu_tx_abort(tx);
}
tx = dmu_tx_create(os);
dmu_tx_hold_bonus(tx, object);
dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
err = dmu_tx_assign(tx, TXG_WAIT);
if (err == 0) {
err = dmu_object_free(os, object, tx);
dmu_tx_commit(tx);
} else {
err = dmu_free_long_range_impl(os, dn, 0, DMU_OBJECT_END, TRUE);
dmu_tx_abort(tx);
}
dnode_rele(dn, FTAG);
return (err);
}

View File

@ -1286,7 +1286,7 @@ restore_freeobjects(struct restorearg *ra, objset_t *os,
if (dmu_object_info(os, obj, NULL) != 0)
continue;
err = dmu_free_object(os, obj);
err = dmu_free_long_object(os, obj);
if (err != 0)
return (err);
}

View File

@ -615,7 +615,8 @@ dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
* if they are blocksize-aligned.
*/
if (dn->dn_datablkshift == 0) {
dmu_tx_count_write(txh, off, len);
if (off != 0 || len < dn->dn_datablksz)
dmu_tx_count_write(txh, off, len);
} else {
/* first block will be modified if it is not aligned */
if (!IS_P2ALIGNED(off, 1 << dn->dn_datablkshift))

View File

@ -117,6 +117,7 @@ dnode_cons(void *arg, void *unused, int kmflag)
dn->dn_id_flags = 0;
dn->dn_dbufs_count = 0;
dn->dn_unlisted_l0_blkid = 0;
list_create(&dn->dn_dbufs, sizeof (dmu_buf_impl_t),
offsetof(dmu_buf_impl_t, db_link));
@ -170,6 +171,7 @@ dnode_dest(void *arg, void *unused)
ASSERT0(dn->dn_id_flags);
ASSERT0(dn->dn_dbufs_count);
ASSERT0(dn->dn_unlisted_l0_blkid);
list_destroy(&dn->dn_dbufs);
}
@ -475,6 +477,7 @@ dnode_destroy(dnode_t *dn)
dn->dn_newuid = 0;
dn->dn_newgid = 0;
dn->dn_id_flags = 0;
dn->dn_unlisted_l0_blkid = 0;
dmu_zfetch_rele(&dn->dn_zfetch);
kmem_cache_free(dnode_cache, dn);
@ -705,6 +708,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
ASSERT(list_is_empty(&ndn->dn_dbufs));
list_move_tail(&ndn->dn_dbufs, &odn->dn_dbufs);
ndn->dn_dbufs_count = odn->dn_dbufs_count;
ndn->dn_unlisted_l0_blkid = odn->dn_unlisted_l0_blkid;
ndn->dn_bonus = odn->dn_bonus;
ndn->dn_have_spill = odn->dn_have_spill;
ndn->dn_zio = odn->dn_zio;
@ -739,6 +743,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
list_create(&odn->dn_dbufs, sizeof (dmu_buf_impl_t),
offsetof(dmu_buf_impl_t, db_link));
odn->dn_dbufs_count = 0;
odn->dn_unlisted_l0_blkid = 0;
odn->dn_bonus = NULL;
odn->dn_zfetch.zf_dnode = NULL;
@ -1528,7 +1533,7 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
blkshift = dn->dn_datablkshift;
epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
if (len == -1ULL) {
if (len == DMU_OBJECT_END) {
len = UINT64_MAX - off;
trunc = TRUE;
}

View File

@ -101,9 +101,8 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
used, compressed, uncompressed);
return;
}
dmu_buf_will_dirty(ds->ds_dbuf, tx);
mutex_enter(&ds->ds_dir->dd_lock);
dmu_buf_will_dirty(ds->ds_dbuf, tx);
mutex_enter(&ds->ds_lock);
delta = parent_delta(ds, used);
ds->ds_phys->ds_referenced_bytes += used;
@ -115,7 +114,6 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
compressed, uncompressed, tx);
dsl_dir_transfer_space(ds->ds_dir, used - delta,
DD_USED_REFRSRV, DD_USED_HEAD, tx);
mutex_exit(&ds->ds_dir->dd_lock);
}
int
@ -150,7 +148,6 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
dprintf_bp(bp, "freeing ds=%llu", ds->ds_object);
dsl_free(tx->tx_pool, tx->tx_txg, bp);
mutex_enter(&ds->ds_dir->dd_lock);
mutex_enter(&ds->ds_lock);
ASSERT(ds->ds_phys->ds_unique_bytes >= used ||
!DS_UNIQUE_IS_ACCURATE(ds));
@ -161,7 +158,6 @@ dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx,
delta, -compressed, -uncompressed, tx);
dsl_dir_transfer_space(ds->ds_dir, -used - delta,
DD_USED_REFRSRV, DD_USED_HEAD, tx);
mutex_exit(&ds->ds_dir->dd_lock);
} else {
dprintf_bp(bp, "putting on dead list: %s", "");
if (async) {
@ -596,31 +592,6 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name)
}
}
static int
dsl_dataset_namelen(dsl_dataset_t *ds)
{
int result;
if (ds == NULL) {
result = 3; /* "mos" */
} else {
result = dsl_dir_namelen(ds->ds_dir);
VERIFY0(dsl_dataset_get_snapname(ds));
if (ds->ds_snapname[0]) {
++result; /* adding one for the @-sign */
if (!MUTEX_HELD(&ds->ds_lock)) {
mutex_enter(&ds->ds_lock);
result += strlen(ds->ds_snapname);
mutex_exit(&ds->ds_lock);
} else {
result += strlen(ds->ds_snapname);
}
}
}
return (result);
}
void
dsl_dataset_rele(dsl_dataset_t *ds, void *tag)
{

View File

@ -896,7 +896,7 @@ dsl_destroy_head(const char *name)
for (uint64_t obj = 0; error == 0;
error = dmu_object_next(os, &obj, FALSE,
prev_snap_txg))
(void) dmu_free_object(os, obj);
(void) dmu_free_long_object(os, obj);
/* sync out all frees */
txg_wait_synced(dmu_objset_pool(os), 0);
dmu_objset_disown(os, FTAG);

View File

@ -845,11 +845,21 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
int64_t used, int64_t compressed, int64_t uncompressed, dmu_tx_t *tx)
{
int64_t accounted_delta;
/*
* dsl_dataset_set_refreservation_sync_impl() calls this with
* dd_lock held, so that it can atomically update
* ds->ds_reserved and the dsl_dir accounting, so that
* dsl_dataset_check_quota() can see dataset and dir accounting
* consistently.
*/
boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
ASSERT(dmu_tx_is_syncing(tx));
ASSERT(type < DD_USED_NUM);
dmu_buf_will_dirty(dd->dd_dbuf, tx);
if (needlock)
mutex_enter(&dd->dd_lock);
accounted_delta = parent_delta(dd, dd->dd_phys->dd_used_bytes, used);
@ -858,7 +868,6 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
dd->dd_phys->dd_compressed_bytes >= -compressed);
ASSERT(uncompressed >= 0 ||
dd->dd_phys->dd_uncompressed_bytes >= -uncompressed);
dmu_buf_will_dirty(dd->dd_dbuf, tx);
dd->dd_phys->dd_used_bytes += used;
dd->dd_phys->dd_uncompressed_bytes += uncompressed;
dd->dd_phys->dd_compressed_bytes += compressed;
@ -891,8 +900,6 @@ void
dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx)
{
boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
ASSERT(dmu_tx_is_syncing(tx));
ASSERT(oldtype < DD_USED_NUM);
ASSERT(newtype < DD_USED_NUM);
@ -900,17 +907,15 @@ dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
if (delta == 0 || !(dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN))
return;
if (needlock)
mutex_enter(&dd->dd_lock);
dmu_buf_will_dirty(dd->dd_dbuf, tx);
mutex_enter(&dd->dd_lock);
ASSERT(delta > 0 ?
dd->dd_phys->dd_used_breakdown[oldtype] >= delta :
dd->dd_phys->dd_used_breakdown[newtype] >= -delta);
ASSERT(dd->dd_phys->dd_used_bytes >= ABS(delta));
dmu_buf_will_dirty(dd->dd_dbuf, tx);
dd->dd_phys->dd_used_breakdown[oldtype] -= delta;
dd->dd_phys->dd_used_breakdown[newtype] += delta;
if (needlock)
mutex_exit(&dd->dd_lock);
mutex_exit(&dd->dd_lock);
}
typedef struct dsl_dir_set_qr_arg {

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
@ -583,7 +583,7 @@ int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
uint64_t size, dmu_tx_t *tx);
int dmu_free_long_range(objset_t *os, uint64_t object, uint64_t offset,
uint64_t size);
int dmu_free_object(objset_t *os, uint64_t object);
int dmu_free_long_object(objset_t *os, uint64_t object);
/*
* Convenience functions.

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
#ifndef _SYS_DNODE_H
@ -188,6 +188,8 @@ typedef struct dnode {
/* protected by dn_dbufs_mtx; declared here to fill 32-bit hole */
uint32_t dn_dbufs_count; /* count of dn_dbufs */
/* There are no level-0 blocks of this blkid or higher in dn_dbufs */
uint64_t dn_unlisted_l0_blkid;
/* protected by os_lock: */
list_node_t dn_dirty_link[TXG_SIZE]; /* next on dataset's dirty */

View File

@ -23,6 +23,9 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
/*
* This header file defines the interfaces available from the CTF debugger
@ -40,8 +43,6 @@
#ifndef _CTF_API_H
#define _CTF_API_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/elf.h>
@ -227,6 +228,8 @@ extern int ctf_add_member(ctf_file_t *, ctf_id_t, const char *, ctf_id_t);
extern int ctf_set_array(ctf_file_t *, ctf_id_t, const ctf_arinfo_t *);
extern int ctf_delete_type(ctf_file_t *, ctf_id_t);
extern int ctf_update(ctf_file_t *);
extern int ctf_discard(ctf_file_t *);
extern int ctf_write(ctf_file_t *, int);

View File

@ -304,6 +304,7 @@ dev/tpm/tpm_acpi.c optional tpm acpi
dev/tpm/tpm_isa.c optional tpm isa
dev/uart/uart_cpu_x86.c optional uart
dev/viawd/viawd.c optional viawd
dev/vmware/vmxnet3/if_vmx.c optional vmx
dev/wbwd/wbwd.c optional wbwd
dev/wpi/if_wpi.c optional wpi
dev/isci/isci.c optional isci

View File

@ -267,6 +267,7 @@ dev/tpm/tpm_acpi.c optional tpm acpi
dev/tpm/tpm_isa.c optional tpm isa
dev/uart/uart_cpu_x86.c optional uart
dev/viawd/viawd.c optional viawd
dev/vmware/vmxnet3/if_vmx.c optional vmx
dev/acpica/acpi_if.m standard
dev/acpi_support/acpi_wmi_if.m standard
dev/wbwd/wbwd.c optional wbwd

View File

@ -21,7 +21,7 @@ stripdirs="generate libraries tests tools"
stripfiles="Makefile README accygwin.h acefi.h achaiku.h acintel.h \
aclinux.h acmacosx.h acmsvc.h acnetbsd.h acos2.h acwin.h \
acwin64.h new_table.txt osfreebsdtbl.c oslinuxtbl.c osunixdir.c \
oswindir.c oswintbl.c oswinxf.c readme.txt utclib.c"
osunixmap.c oswindir.c oswintbl.c oswinxf.c readme.txt utclib.c"
# include files to canonify
src_headers="acapps.h acbuffer.h accommon.h acconfig.h acdebug.h \

View File

@ -1,3 +1,87 @@
----------------------------------------
23 August 2013. Summary of changes for version 20130823:
1) ACPICA kernel-resident subsystem:
Implemented support for host-installed System Control Interrupt (SCI)
handlers. Certain ACPI functionality requires the host to handle raw
SCIs. For example, the "SCI Doorbell" that is defined for memory power
state support requires the host device driver to handle SCIs to examine
if the doorbell has been activated. Multiple SCI handlers can be
installed to allow for future expansion. New external interfaces are
AcpiInstallSciHandler, AcpiRemoveSciHandler; see the ACPICA reference for
details. Lv Zheng, Bob Moore. ACPICA BZ 1032.
Operation region support: Never locally free the handler "context"
pointer. This change removes some dangerous code that attempts to free
the handler context pointer in some (rare) circumstances. The owner of
the handler owns this pointer and the ACPICA code should never touch it.
Although not seen to be an issue in any kernel, it did show up as a
problem (fault) under AcpiExec. Also, set the internal storage field for
the context pointer to zero when the region is deactivated, simply for
sanity. David Box. ACPICA BZ 1039.
AcpiRead: On error, do not modify the return value target location. If an
error happens in the middle of a split 32/32 64-bit I/O operation, do not
modify the target of the return value pointer. Makes the code consistent
with the rest of ACPICA. Bjorn Helgaas.
Example Code and Data Size: These are the sizes for the OS-independent
acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The
debug version of the code includes the debug output trace mechanism and
has a much larger code and data size.
Current Release:
Non-Debug Version: 96.7K Code, 27.1K Data, 123.9K Total
Debug Version: 184.4K Code, 76.8K Data, 261.2K Total
Previous Release:
Non-Debug Version: 96.2K Code, 27.1K Data, 123.3K Total
Debug Version: 185.4K Code, 77.1K Data, 262.5K Total
2) iASL Compiler/Disassembler and Tools:
AcpiDump: Implemented several new features and fixed some problems:
1) Added support to dump the RSDP, RSDT, and XSDT tables.
2) Added support for multiple table instances (SSDT, UEFI).
3) Added option to dump "customized" (overridden) tables (-c).
4) Fixed a problem where some table filenames were improperly
constructed.
5) Improved some error messages, removed some unnecessary messages.
iASL: Implemented additional support for disassembly of ACPI tables that
contain invocations of external control methods. The -fe<file> option
allows the import of a file that specifies the external methods along
with the required number of arguments for each -- allowing for the
correct disassembly of the table. This is a workaround for a limitation
of AML code where the disassembler often cannot determine the number of
arguments required for an external control method and generates incorrect
ASL code. See the iASL reference for details. ACPICA BZ 1030.
Debugger: Implemented a new command (paths) that displays the full
pathnames (namepaths) and object types of all objects in the namespace.
This is an alternative to the namespace command.
Debugger: Implemented a new command (sci) that invokes the SCI dispatch
mechanism and any installed handlers.
iASL: Fixed a possible segfault for "too many parent prefixes" condition.
This can occur if there are too many parent prefixes in a namepath (for
example, ^^^^^^PCI0.ECRD). ACPICA BZ 1035.
Application OSLs: Set the return value for the PCI read functions. These
functions simply return AE_OK, but should set the return value to zero
also. This change implements this. ACPICA BZ 1038.
Debugger: Prevent possible command line buffer overflow. Increase the
size of a couple of the debugger line buffers, and ensure that overflow
cannot happen. ACPICA BZ 1037.
iASL: Changed to abort immediately on serious errors during the parsing
phase. Due to the nature of ASL, there is no point in attempting to
compile these types of errors, and they typically end up causing a
cascade of hundreds of errors which obscure the original problem.
----------------------------------------
25 July 2013. Summary of changes for version 20130725:

View File

@ -341,6 +341,10 @@ AdAmlDisassemble (
{
AcpiDmClearExternalList ();
}
/* Load any externals defined in the optional external ref file */
AcpiDmGetExternalsFromFile ();
}
else
{

View File

@ -373,10 +373,18 @@ AcpiDmDumpDescending (
switch (Op->Common.AmlOpcode)
{
case AML_BYTE_OP:
AcpiOsPrintf ("%2.2X", (UINT32) Op->Common.Value.Integer);
break;
case AML_WORD_OP:
AcpiOsPrintf ("%4.4X", (UINT32) Op->Common.Value.Integer);
break;
case AML_DWORD_OP:
AcpiOsPrintf ("%X", (UINT32) Op->Common.Value.Integer);
AcpiOsPrintf ("%8.8X", (UINT32) Op->Common.Value.Integer);
break;
case AML_QWORD_OP:

View File

@ -46,7 +46,9 @@
#include <contrib/dev/acpica/include/amlcode.h>
#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/acdisasm.h>
#include <contrib/dev/acpica/compiler/aslcompiler.h>
#include <stdio.h>
#include <errno.h>
/*
@ -87,6 +89,8 @@ static const char *AcpiGbl_DmTypeNames[] =
/* 19 */ ", FieldUnitObj"
};
#define METHOD_SEPARATORS " \t,()\n"
/* Local prototypes */
@ -99,6 +103,12 @@ AcpiDmNormalizeParentPrefix (
ACPI_PARSE_OBJECT *Op,
char *Path);
static void
AcpiDmAddToExternalListFromFile (
char *Path,
UINT8 Type,
UINT32 Value);
/*******************************************************************************
*
@ -444,7 +454,7 @@ AcpiDmAddToExternalList (
(NextExternal->Value != Value))
{
ACPI_ERROR ((AE_INFO,
"Argument count mismatch for method %s %u %u",
"External method arg count mismatch %s: Current %u, attempted %u",
NextExternal->Path, NextExternal->Value, Value));
}
@ -534,6 +544,275 @@ AcpiDmAddToExternalList (
}
/*******************************************************************************
*
* FUNCTION: AcpiDmGetExternalsFromFile
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Process the optional external reference file.
*
* Each line in the file should be of the form:
* External (<Method namepath>, MethodObj, <ArgCount>)
*
* Example:
* External (_SB_.PCI0.XHC_.PS0X, MethodObj, 4)
*
******************************************************************************/
void
AcpiDmGetExternalsFromFile (
void)
{
FILE *ExternalRefFile;
char *Token;
char *MethodName;
UINT32 ArgCount;
UINT32 ImportCount = 0;
if (!Gbl_ExternalRefFilename)
{
return;
}
/* Open the file */
ExternalRefFile = fopen (Gbl_ExternalRefFilename, "r");
if (!ExternalRefFile)
{
fprintf (stderr, "Could not open external reference file \"%s\"\n",
Gbl_ExternalRefFilename);
return;
}
/* Each line defines a method */
while (fgets (StringBuffer, ASL_MSG_BUFFER_SIZE, ExternalRefFile))
{
Token = strtok (StringBuffer, METHOD_SEPARATORS); /* "External" */
if (!Token) continue;
if (strcmp (Token, "External")) continue;
MethodName = strtok (NULL, METHOD_SEPARATORS); /* Method namepath */
if (!MethodName) continue;
Token = strtok (NULL, METHOD_SEPARATORS); /* "MethodObj" */
if (!Token) continue;
if (strcmp (Token, "MethodObj")) continue;
Token = strtok (NULL, METHOD_SEPARATORS); /* Arg count */
if (!Token) continue;
/* Convert arg count string to an integer */
errno = 0;
ArgCount = strtoul (Token, NULL, 0);
if (errno)
{
fprintf (stderr, "Invalid argument count (%s)\n", Token);
continue;
}
if (ArgCount > 7)
{
fprintf (stderr, "Invalid argument count (%u)\n", ArgCount);
continue;
}
/* Add this external to the global list */
AcpiOsPrintf ("%s: Importing method external (%u arguments) %s\n",
Gbl_ExternalRefFilename, ArgCount, MethodName);
AcpiDmAddToExternalListFromFile (MethodName, ACPI_TYPE_METHOD, ArgCount | 0x80);
ImportCount++;
}
if (!ImportCount)
{
fprintf (stderr, "Did not find any external methods in reference file \"%s\"\n",
Gbl_ExternalRefFilename);
}
else
{
/* Add the external(s) to the namespace */
AcpiDmAddExternalsToNamespace ();
AcpiOsPrintf ("%s: Imported %u external method definitions\n",
Gbl_ExternalRefFilename, ImportCount);
}
fclose (ExternalRefFile);
}
/*******************************************************************************
*
* FUNCTION: AcpiDmAddToExternalListFromFile
*
* PARAMETERS: Path - Internal (AML) path to the object
* Type - ACPI object type to be added
* Value - Arg count if adding a Method object
*
* RETURN: None
*
* DESCRIPTION: Insert a new name into the global list of Externals which
* will in turn be later emitted as an External() declaration
* in the disassembled output.
*
******************************************************************************/
static void
AcpiDmAddToExternalListFromFile (
char *Path,
UINT8 Type,
UINT32 Value)
{
char *InternalPath;
char *ExternalPath;
ACPI_EXTERNAL_LIST *NewExternal;
ACPI_EXTERNAL_LIST *NextExternal;
ACPI_EXTERNAL_LIST *PrevExternal = NULL;
ACPI_STATUS Status;
BOOLEAN Resolved = FALSE;
if (!Path)
{
return;
}
/* TBD: Add a flags parameter */
if (Type == ACPI_TYPE_METHOD)
{
if (Value & 0x80)
{
Resolved = TRUE;
}
Value &= 0x07;
}
/*
* We don't want External() statements to contain a leading '\'.
* This prevents duplicate external statements of the form:
*
* External (\ABCD)
* External (ABCD)
*
* This would cause a compile time error when the disassembled
* output file is recompiled.
*/
if ((*Path == AML_ROOT_PREFIX) && (Path[1]))
{
Path++;
}
/* Check all existing externals to ensure no duplicates */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (!ACPI_STRCMP (Path, NextExternal->Path))
{
/* Duplicate method, check that the Value (ArgCount) is the same */
if ((NextExternal->Type == ACPI_TYPE_METHOD) &&
(NextExternal->Value != Value))
{
ACPI_ERROR ((AE_INFO,
"(File) External method arg count mismatch %s: Current %u, override to %u",
NextExternal->Path, NextExternal->Value, Value));
/* Override, since new value came from external reference file */
NextExternal->Value = Value;
}
/* Allow upgrade of type from ANY */
else if (NextExternal->Type == ACPI_TYPE_ANY)
{
NextExternal->Type = Type;
NextExternal->Value = Value;
}
return;
}
NextExternal = NextExternal->Next;
}
/* Get the internal pathname (AML format) */
Status = AcpiNsInternalizeName (Path, &InternalPath);
if (ACPI_FAILURE (Status))
{
return;
}
/* Allocate and init a new External() descriptor */
NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST));
if (!NewExternal)
{
ACPI_FREE (InternalPath);
return;
}
/* Must copy and normalize the input path */
AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath, NULL, &ExternalPath);
NewExternal->Path = ExternalPath;
NewExternal->Type = Type;
NewExternal->Value = Value;
NewExternal->Resolved = Resolved;
NewExternal->Length = (UINT16) ACPI_STRLEN (Path);
NewExternal->InternalPath = InternalPath;
/* Set flag to indicate External->InternalPath needs to be freed */
NewExternal->Flags |= ACPI_IPATH_ALLOCATED | ACPI_FROM_REFERENCE_FILE;
/* Link the new descriptor into the global list, alphabetically ordered */
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0)
{
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
NewExternal->Next = NextExternal;
return;
}
PrevExternal = NextExternal;
NextExternal = NextExternal->Next;
}
if (PrevExternal)
{
PrevExternal->Next = NewExternal;
}
else
{
AcpiGbl_ExternalList = NewExternal;
}
}
/*******************************************************************************
*
* FUNCTION: AcpiDmAddExternalsToNamespace
@ -563,7 +842,7 @@ AcpiDmAddExternalsToNamespace (
Status = AcpiNsLookup (NULL, External->InternalPath, External->Type,
ACPI_IMODE_LOAD_PASS1,
ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
ACPI_NS_ERROR_IF_FOUND | ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE,
NULL, &Node);
if (ACPI_FAILURE (Status))
@ -731,7 +1010,8 @@ AcpiDmEmitExternals (
NextExternal->Path,
AcpiDmGetObjectTypeName (NextExternal->Type));
AcpiOsPrintf (") // Warning: Unresolved Method, "
AcpiOsPrintf (
") // Warning: Unresolved Method, "
"guessing %u arguments (may be incorrect, see warning above)\n",
NextExternal->Value);
@ -743,9 +1023,45 @@ AcpiDmEmitExternals (
AcpiOsPrintf ("\n");
/* Emit externals that were imported from a file */
if (Gbl_ExternalRefFilename)
{
AcpiOsPrintf (
" /*\n * External declarations that were imported from\n"
" * the reference file [%s]\n */\n",
Gbl_ExternalRefFilename);
NextExternal = AcpiGbl_ExternalList;
while (NextExternal)
{
if (!NextExternal->Emitted && (NextExternal->Flags & ACPI_FROM_REFERENCE_FILE))
{
AcpiOsPrintf (" External (%s%s",
NextExternal->Path,
AcpiDmGetObjectTypeName (NextExternal->Type));
if (NextExternal->Type == ACPI_TYPE_METHOD)
{
AcpiOsPrintf (") // %u Arguments\n",
NextExternal->Value);
}
else
{
AcpiOsPrintf (")\n");
}
NextExternal->Emitted = TRUE;
}
NextExternal = NextExternal->Next;
}
AcpiOsPrintf ("\n");
}
/*
* Walk the list of externals (unresolved references)
* found during the AML parsing
* Walk the list of externals found during the AML parsing
*/
while (AcpiGbl_ExternalList)
{

View File

@ -446,7 +446,7 @@ AcpiDmDumpDataTable (
Length = Table->Length;
AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoFacs);
}
else if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_RSDP))
else if (ACPI_VALIDATE_RSDP_SIG (Table->Signature))
{
Length = AcpiDmDumpRsdp (Table);
}

View File

@ -593,10 +593,15 @@ CmDoCompile (
AslCompilerparse();
UtEndEvent (Event);
/* Flush out any remaining source after parse tree is complete */
/* Check for parse errors */
Event = UtBeginEvent ("Flush source input");
CmFlushSourceCode ();
Status = AslCheckForErrorExit ();
if (ACPI_FAILURE (Status))
{
fprintf (stderr, "Compiler aborting due to parser-detected syntax error(s)\n");
LsDumpParseTree ();
goto ErrorExit;
}
/* Did the parse tree get successfully constructed? */
@ -606,16 +611,18 @@ CmDoCompile (
* If there are no errors, then we have some sort of
* internal problem.
*/
Status = AslCheckForErrorExit ();
if (Status == AE_OK)
{
AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
NULL, "- Could not resolve parse tree root node");
}
AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
NULL, "- Could not resolve parse tree root node");
goto ErrorExit;
}
/* Flush out any remaining source after parse tree is complete */
Event = UtBeginEvent ("Flush source input");
CmFlushSourceCode ();
/* Optional parse tree dump, compiler debug output only */
LsDumpParseTree ();

View File

@ -186,6 +186,7 @@ ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_IncludeFilename, NULL)
ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_OutputFilenamePrefix, NULL);
ASL_EXTERN ASL_INCLUDE_DIR ASL_INIT_GLOBAL (*Gbl_IncludeDirList, NULL);
ASL_EXTERN char *Gbl_CurrentInputFilename;
ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_ExternalRefFilename, NULL);
ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HasIncludeFiles, FALSE);

View File

@ -487,6 +487,10 @@ LdNamespace1Begin (
ACPI_TYPE_LOCAL_SCOPE,
ACPI_IMODE_LOAD_PASS1, Flags,
WalkState, &(Node));
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/*
* However, this is an error -- primarily because the MS

View File

@ -138,6 +138,7 @@ Usage (
ACPI_OPTION ("-dc <f1,f2>", "Disassemble AML and immediately compile it");
ACPI_OPTION ("", " (Obtain DSDT from current system if no input file)");
ACPI_OPTION ("-e <f1,f2>", "Include ACPI table(s) for external symbol resolution");
ACPI_OPTION ("-fe <file>", "Specify external symbol declaration file");
ACPI_OPTION ("-g", "Get ACPI tables and write to files (*.dat)");
ACPI_OPTION ("-in", "Ignore NoOp opcodes");
ACPI_OPTION ("-vt", "Dump binary table data in hex format within output file");

View File

@ -68,7 +68,7 @@ AslDoResponseFile (
#define ASL_TOKEN_SEPARATORS " \t\n"
#define ASL_SUPPORTED_OPTIONS "@:b|c|d^D:e:fgh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z"
#define ASL_SUPPORTED_OPTIONS "@:b|c|d^D:e:f^gh^i|I:l^m:no|p:P^r:s|t|T+G^v^w|x:z"
/*******************************************************************************
@ -136,8 +136,7 @@ AslCommandLine (
if (BadCommandLine)
{
printf ("\n");
Usage ();
printf ("Use -h option for help information\n");
exit (1);
}
@ -276,9 +275,30 @@ AslDoOptions (
}
break;
case 'f': /* Ignore errors and force creation of aml file */
case 'f':
Gbl_IgnoreErrors = TRUE;
switch (AcpiGbl_Optarg[0])
{
case '^': /* Ignore errors and force creation of aml file */
Gbl_IgnoreErrors = TRUE;
break;
case 'e': /* Disassembler: Get external declaration file */
if (AcpiGetoptArgument (argc, argv))
{
return (-1);
}
Gbl_ExternalRefFilename = AcpiGbl_Optarg;
break;
default:
printf ("Unknown option: -f%s\n", AcpiGbl_Optarg);
return (-1);
}
break;
case 'G':

View File

@ -317,7 +317,7 @@ DtCompileDataTable (
DtSetTableLength ();
return (Status);
}
else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP))
else if (ACPI_VALIDATE_RSDP_SIG (Signature))
{
Status = DtCompileRsdp (FieldList);
return (Status);

View File

@ -1211,6 +1211,14 @@ AcpiDbGenerateGpe (
(void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
}
void
AcpiDbGenerateSci (
void)
{
AcpiEvSciDispatch ();
}
#endif /* !ACPI_REDUCED_HARDWARE */
#endif /* ACPI_DEBUGGER */

View File

@ -142,7 +142,8 @@ AcpiDbOpenDebugFile (
}
AcpiOsPrintf ("Debug output file %s opened\n", Name);
ACPI_STRCPY (AcpiGbl_DbDebugFilename, Name);
ACPI_STRNCPY (AcpiGbl_DbDebugFilename, Name,
sizeof (AcpiGbl_DbDebugFilename));
AcpiGbl_DbOutputToFile = TRUE;
#endif
@ -274,11 +275,9 @@ AcpiDbReadTable (
fseek (fp, 0, SEEK_SET);
/* The RSDT, FACS and S3PT tables do not have standard ACPI headers */
/* The RSDP table does not have standard ACPI header */
if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD ") ||
ACPI_COMPARE_NAME (TableHeader.Signature, "FACS") ||
ACPI_COMPARE_NAME (TableHeader.Signature, "S3PT"))
if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD "))
{
*TableLength = FileSize;
StandardHeader = FALSE;

View File

@ -132,12 +132,14 @@ enum AcpiExDebuggerCommands
CMD_OPEN,
CMD_OSI,
CMD_OWNER,
CMD_PATHS,
CMD_PREDEFINED,
CMD_PREFIX,
CMD_QUIT,
CMD_REFERENCES,
CMD_RESOURCES,
CMD_RESULTS,
CMD_SCI,
CMD_SET,
CMD_SLEEP,
CMD_STATS,
@ -203,12 +205,14 @@ static const ACPI_DB_COMMAND_INFO AcpiGbl_DbCommands[] =
{"OPEN", 1},
{"OSI", 0},
{"OWNER", 1},
{"PATHS", 0},
{"PREDEFINED", 0},
{"PREFIX", 0},
{"QUIT", 0},
{"REFERENCES", 1},
{"RESOURCES", 0},
{"RESULTS", 0},
{"SCI", 0},
{"SET", 3},
{"SLEEP", 0},
{"STATS", 1},
@ -259,22 +263,19 @@ static const ACPI_DB_COMMAND_HELP AcpiGbl_DbCommandHelp[] =
{0, "\nNamespace Access Commands:", "\n"},
{1, " Businfo", "Display system bus info\n"},
{1, " Disassemble <Method>", "Disassemble a control method\n"},
{1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
{1, " Find <AcpiName> (? is wildcard)", "Find ACPI name(s) with wildcards\n"},
{1, " Gpe <GpeNum> <GpeBlock>", "Simulate a GPE\n"},
{1, " Gpes", "Display info on all GPEs\n"},
{1, " Integrity", "Validate namespace integrity\n"},
{1, " Methods", "Display list of loaded control methods\n"},
{1, " Namespace [Object] [Depth]", "Display loaded namespace tree/subtree\n"},
{1, " Notify <Object> <Value>", "Send a notification on Object\n"},
{1, " Objects <ObjectType>", "Display all objects of the given type\n"},
{1, " Owner <OwnerId> [Depth]", "Display loaded namespace by object owner\n"},
{1, " Paths", "Display full pathnames of namespace objects\n"},
{1, " Predefined", "Check all predefined names\n"},
{1, " Prefix [<NamePath>]", "Set or Get current execution prefix\n"},
{1, " References <Addr>", "Find all references to object at addr\n"},
{1, " Resources [DeviceName]", "Display Device resources (no arg = all devices)\n"},
{1, " Set N <NamedObject> <Value>", "Set value for named integer\n"},
{1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
{1, " Template <Object>", "Format/dump a Buffer/ResourceTemplate\n"},
{1, " Terminate", "Delete namespace and all internal objects\n"},
{1, " Type <Object>", "Display object type\n"},
@ -288,7 +289,7 @@ static const ACPI_DB_COMMAND_HELP AcpiGbl_DbCommandHelp[] =
{5, " Execute <Namepath> [Arguments]", "Execute control method\n"},
{1, " Hex Integer", "Integer method argument\n"},
{1, " \"Ascii String\"", "String method argument\n"},
{1, " (Byte List)", "Buffer method argument\n"},
{1, " (Hex Byte List)", "Buffer method argument\n"},
{1, " [Package Element List]", "Package method argument\n"},
{1, " Go", "Allow method to run to completion\n"},
{1, " Information", "Display info about the current method\n"},
@ -303,6 +304,13 @@ static const ACPI_DB_COMMAND_HELP AcpiGbl_DbCommandHelp[] =
{1, " Tree", "Display control method calling tree\n"},
{1, " <Enter>", "Single step next AML opcode (over calls)\n"},
{0, "\nHardware Related Commands:", "\n"},
{1, " Event <F|G> <Value>", "Generate AcpiEvent (Fixed/GPE)\n"},
{1, " Gpe <GpeNum> <GpeBlock>", "Simulate a GPE\n"},
{1, " Gpes", "Display info on all GPEs\n"},
{1, " Sci", "Generate an SCI\n"},
{1, " Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
{0, "\nFile I/O Commands:", "\n"},
{1, " Close", "Close debug output file\n"},
{1, " Load <Input Filename>", "Load ACPI table from a file\n"},
@ -1002,6 +1010,11 @@ AcpiDbCommandDispatch (
AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
break;
case CMD_PATHS:
AcpiDbDumpNamespacePaths ();
break;
case CMD_PREDEFINED:
AcpiDbCheckPredefinedNames ();
@ -1027,6 +1040,11 @@ AcpiDbCommandDispatch (
AcpiDbDisplayResults ();
break;
case CMD_SCI:
AcpiDbGenerateSci ();
break;
case CMD_SET:
AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],

View File

@ -254,6 +254,37 @@ AcpiDbDumpNamespace (
}
/*******************************************************************************
*
* FUNCTION: AcpiDbDumpNamespacePaths
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Dump entire namespace with full object pathnames and object
* type information. Alternative to "namespace" command.
*
******************************************************************************/
void
AcpiDbDumpNamespacePaths (
void)
{
AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
AcpiOsPrintf ("ACPI Namespace (from root):\n");
/* Display the entire namespace */
AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
AcpiNsDumpObjectPaths (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode);
AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
}
/*******************************************************************************
*
* FUNCTION: AcpiDbDumpNamespaceByOwner

View File

@ -216,7 +216,7 @@ AcpiEvGetGpeDevice (
*
* FUNCTION: AcpiEvGetGpeXruptBlock
*
* PARAMETERS: InterruptNumber - Interrupt for a GPE block
* PARAMETERS: InterruptNumber - Interrupt for a GPE block
*
* RETURN: A GPE interrupt block
*

View File

@ -292,15 +292,6 @@ AcpiEvTerminate (
Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
/* Remove SCI handler */
Status = AcpiEvRemoveSciHandler ();
if (ACPI_FAILURE(Status))
{
ACPI_ERROR ((AE_INFO,
"Could not remove SCI handler"));
}
Status = AcpiEvRemoveGlobalLockHandler ();
if (ACPI_FAILURE(Status))
{
@ -311,6 +302,15 @@ AcpiEvTerminate (
AcpiGbl_EventsInitialized = FALSE;
}
/* Remove SCI handlers */
Status = AcpiEvRemoveAllSciHandlers ();
if (ACPI_FAILURE(Status))
{
ACPI_ERROR ((AE_INFO,
"Could not remove SCI handler"));
}
/* Deallocate all handler objects installed within GPE info structs */
Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);

View File

@ -234,18 +234,12 @@ AcpiEvAddressSpaceDispatch (
{
RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE;
if (RegionObj2->Extra.RegionContext)
/*
* Save the returned context for use in all accesses to
* the handler for this particular region
*/
if (!(RegionObj2->Extra.RegionContext))
{
/* The handler for this region was already installed */
ACPI_FREE (RegionContext);
}
else
{
/*
* Save the returned context for use in all accesses to
* this particular region
*/
RegionObj2->Extra.RegionContext = RegionContext;
}
}
@ -261,7 +255,6 @@ AcpiEvAddressSpaceDispatch (
ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset),
AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
/*
* Special handling for GenericSerialBus and GeneralPurposeIo:
* There are three extra parameters that must be passed to the
@ -424,6 +417,15 @@ AcpiEvDetachRegion(
Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
HandlerObj->AddressSpace.Context, RegionContext);
/*
* RegionContext should have been released by the deactivate
* operation. We don't need access to it anymore here.
*/
if (RegionContext)
{
*RegionContext = NULL;
}
/* Init routine may fail, Just ignore errors */
if (ACPI_FAILURE (Status))

View File

@ -59,6 +59,57 @@ AcpiEvSciXruptHandler (
void *Context);
/*******************************************************************************
*
* FUNCTION: AcpiEvSciDispatch
*
* PARAMETERS: None
*
* RETURN: Status code indicates whether interrupt was handled.
*
* DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers.
*
******************************************************************************/
UINT32
AcpiEvSciDispatch (
void)
{
ACPI_SCI_HANDLER_INFO *SciHandler;
ACPI_CPU_FLAGS Flags;
UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
ACPI_FUNCTION_NAME (EvSciDispatch);
/* Are there any host-installed SCI handlers? */
if (!AcpiGbl_SciHandlerList)
{
return (IntStatus);
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Invoke all host-installed SCI handlers */
SciHandler = AcpiGbl_SciHandlerList;
while (SciHandler)
{
/* Invoke the installed handler (at interrupt level) */
IntStatus |= SciHandler->Address (
SciHandler->Context);
SciHandler = SciHandler->Next;
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return (IntStatus);
}
/*******************************************************************************
*
* FUNCTION: AcpiEvSciXruptHandler
@ -100,6 +151,10 @@ AcpiEvSciXruptHandler (
*/
InterruptHandled |= AcpiEvGpeDetect (GpeXruptList);
/* Invoke all host-installed SCI handlers */
InterruptHandled |= AcpiEvSciDispatch ();
AcpiSciCount++;
return_UINT32 (InterruptHandled);
}
@ -129,14 +184,13 @@ AcpiEvGpeXruptHandler (
/*
* We are guaranteed by the ACPI CA initialization/shutdown code that
* We are guaranteed by the ACPICA initialization/shutdown code that
* if this interrupt handler is installed, ACPI is enabled.
*/
/* GPEs: Check for and dispatch any GPEs that have occurred */
InterruptHandled |= AcpiEvGpeDetect (GpeXruptList);
return_UINT32 (InterruptHandled);
}
@ -171,15 +225,15 @@ AcpiEvInstallSciHandler (
/******************************************************************************
*
* FUNCTION: AcpiEvRemoveSciHandler
* FUNCTION: AcpiEvRemoveAllSciHandlers
*
* PARAMETERS: none
*
* RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not
* RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not
* installed to begin with
*
* DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be
* taken.
* taken. Remove all host-installed SCI handlers.
*
* Note: It doesn't seem important to disable all events or set the event
* enable registers to their original values. The OS should disable
@ -189,13 +243,15 @@ AcpiEvInstallSciHandler (
******************************************************************************/
ACPI_STATUS
AcpiEvRemoveSciHandler (
AcpiEvRemoveAllSciHandlers (
void)
{
ACPI_SCI_HANDLER_INFO *SciHandler;
ACPI_CPU_FLAGS Flags;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (EvRemoveSciHandler);
ACPI_FUNCTION_TRACE (EvRemoveAllSciHandlers);
/* Just let the OS remove the handler and disable the level */
@ -203,6 +259,23 @@ AcpiEvRemoveSciHandler (
Status = AcpiOsRemoveInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt,
AcpiEvSciXruptHandler);
if (!AcpiGbl_SciHandlerList)
{
return (Status);
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Free all host-installed SCI handlers */
while (AcpiGbl_SciHandlerList)
{
SciHandler = AcpiGbl_SciHandlerList;
AcpiGbl_SciHandlerList = SciHandler->Next;
ACPI_FREE (SciHandler);
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}

View File

@ -433,6 +433,169 @@ ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
#if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
*
* FUNCTION: AcpiInstallSciHandler
*
* PARAMETERS: Address - Address of the handler
* Context - Value passed to the handler on each SCI
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for a System Control Interrupt.
*
******************************************************************************/
ACPI_STATUS
AcpiInstallSciHandler (
ACPI_SCI_HANDLER Address,
void *Context)
{
ACPI_SCI_HANDLER_INFO *NewSciHandler;
ACPI_SCI_HANDLER_INFO *SciHandler;
ACPI_CPU_FLAGS Flags;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
if (!Address)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Allocate and init a handler object */
NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
if (!NewSciHandler)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
NewSciHandler->Address = Address;
NewSciHandler->Context = Context;
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
goto Exit;
}
/* Lock list during installation */
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
SciHandler = AcpiGbl_SciHandlerList;
/* Ensure handler does not already exist */
while (SciHandler)
{
if (Address == SciHandler->Address)
{
Status = AE_ALREADY_EXISTS;
goto UnlockAndExit;
}
SciHandler = SciHandler->Next;
}
/* Install the new handler into the global list (at head) */
NewSciHandler->Next = AcpiGbl_SciHandlerList;
AcpiGbl_SciHandlerList = NewSciHandler;
UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
Exit:
if (ACPI_FAILURE (Status))
{
ACPI_FREE (NewSciHandler);
}
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiRemoveSciHandler
*
* PARAMETERS: Address - Address of the handler
*
* RETURN: Status
*
* DESCRIPTION: Remove a handler for a System Control Interrupt.
*
******************************************************************************/
ACPI_STATUS
AcpiRemoveSciHandler (
ACPI_SCI_HANDLER Address)
{
ACPI_SCI_HANDLER_INFO *PrevSciHandler;
ACPI_SCI_HANDLER_INFO *NextSciHandler;
ACPI_CPU_FLAGS Flags;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
if (!Address)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Remove the SCI handler with lock */
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
PrevSciHandler = NULL;
NextSciHandler = AcpiGbl_SciHandlerList;
while (NextSciHandler)
{
if (NextSciHandler->Address == Address)
{
/* Unlink and free the SCI handler info block */
if (PrevSciHandler)
{
PrevSciHandler->Next = NextSciHandler->Next;
}
else
{
AcpiGbl_SciHandlerList = NextSciHandler->Next;
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
ACPI_FREE (NextSciHandler);
goto UnlockAndExit;
}
PrevSciHandler = NextSciHandler;
NextSciHandler = NextSciHandler->Next;
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
Status = AE_NOT_EXIST;
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiInstallGlobalEventHandler

View File

@ -131,7 +131,8 @@ AcpiRead (
UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
UINT32 Value;
UINT32 ValueLo;
UINT32 ValueHi;
UINT32 Width;
UINT64 Address;
ACPI_STATUS Status;
@ -153,13 +154,8 @@ AcpiRead (
return (Status);
}
/* Initialize entire 64-bit return value to zero */
*ReturnValue = 0;
Value = 0;
/*
* Two address spaces supported: Memory or IO. PCI_Config is
* Two address spaces supported: Memory or I/O. PCI_Config is
* not supported here because the GAS structure is insufficient
*/
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
@ -173,6 +169,9 @@ AcpiRead (
}
else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
{
ValueLo = 0;
ValueHi = 0;
Width = Reg->BitWidth;
if (Width == 64)
{
@ -180,25 +179,27 @@ AcpiRead (
}
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
Address, &Value, Width);
Address, &ValueLo, Width);
if (ACPI_FAILURE (Status))
{
return (Status);
}
*ReturnValue = Value;
if (Reg->BitWidth == 64)
{
/* Read the top 32 bits */
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
(Address + 4), &Value, 32);
(Address + 4), &ValueHi, 32);
if (ACPI_FAILURE (Status))
{
return (Status);
}
*ReturnValue |= ((UINT64) Value << 32);
}
/* Set the return value only if status is AE_OK */
*ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
@ -207,7 +208,7 @@ AcpiRead (
ACPI_FORMAT_UINT64 (Address),
AcpiUtGetRegionName (Reg->SpaceId)));
return (Status);
return (AE_OK);
}
ACPI_EXPORT_SYMBOL (AcpiRead)

View File

@ -448,8 +448,8 @@ AcpiNsLookup (
/* Current scope has no parent scope */
ACPI_ERROR ((AE_INFO,
"ACPI path has too many parent prefixes (^) "
"- reached beyond root node"));
"%s: Path has too many parent prefixes (^) "
"- reached beyond root node", Pathname));
return_ACPI_STATUS (AE_NOT_FOUND);
}
}

View File

@ -69,6 +69,22 @@ AcpiNsDumpOneDevice (
#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
static ACPI_STATUS
AcpiNsDumpOneObjectPath (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue);
static ACPI_STATUS
AcpiNsGetMaxDepth (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue);
/*******************************************************************************
*
* FUNCTION: AcpiNsPrintPathname
@ -695,6 +711,142 @@ AcpiNsDumpObjects (
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDumpOneObjectPath, AcpiNsGetMaxDepth
*
* PARAMETERS: ObjHandle - Node to be dumped
* Level - Nesting level of the handle
* Context - Passed into WalkNamespace
* ReturnValue - Not used
*
* RETURN: Status
*
* DESCRIPTION: Dump the full pathname to a namespace object. AcpNsGetMaxDepth
* computes the maximum nesting depth in the namespace tree, in
* order to simplify formatting in AcpiNsDumpOneObjectPath.
* These procedures are UserFunctions called by AcpiNsWalkNamespace.
*
******************************************************************************/
static ACPI_STATUS
AcpiNsDumpOneObjectPath (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue)
{
UINT32 MaxLevel = *((UINT32 *) Context);
char *Pathname;
ACPI_NAMESPACE_NODE *Node;
int PathIndent;
if (!ObjHandle)
{
return (AE_OK);
}
Node = AcpiNsValidateHandle (ObjHandle);
Pathname = AcpiNsGetExternalPathname (Node);
PathIndent = 1;
if (Level <= MaxLevel)
{
PathIndent = MaxLevel - Level + 1;
}
AcpiOsPrintf ("%2d%*s%-12s%*s",
Level, Level, " ", AcpiUtGetTypeName (Node->Type),
PathIndent, " ");
AcpiOsPrintf ("%s\n", &Pathname[1]);
ACPI_FREE (Pathname);
return (AE_OK);
}
static ACPI_STATUS
AcpiNsGetMaxDepth (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue)
{
UINT32 *MaxLevel = (UINT32 *) Context;
if (Level > *MaxLevel)
{
*MaxLevel = Level;
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDumpObjectPaths
*
* PARAMETERS: Type - Object type to be dumped
* DisplayType - 0 or ACPI_DISPLAY_SUMMARY
* MaxDepth - Maximum depth of dump. Use ACPI_UINT32_MAX
* for an effectively unlimited depth.
* OwnerId - Dump only objects owned by this ID. Use
* ACPI_UINT32_MAX to match all owners.
* StartHandle - Where in namespace to start/end search
*
* RETURN: None
*
* DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses
* AcpiNsWalkNamespace in conjunction with AcpiNsDumpOneObjectPath.
*
******************************************************************************/
void
AcpiNsDumpObjectPaths (
ACPI_OBJECT_TYPE Type,
UINT8 DisplayType,
UINT32 MaxDepth,
ACPI_OWNER_ID OwnerId,
ACPI_HANDLE StartHandle)
{
ACPI_STATUS Status;
UINT32 MaxLevel = 0;
ACPI_FUNCTION_ENTRY ();
/*
* Just lock the entire namespace for the duration of the dump.
* We don't want any changes to the namespace during this time,
* especially the temporary nodes since we are going to display
* them also.
*/
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
AcpiOsPrintf ("Could not acquire namespace mutex\n");
return;
}
/* Get the max depth of the namespace tree, for formatting later */
(void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
AcpiNsGetMaxDepth, NULL, (void *) &MaxLevel, NULL);
/* Now dump the entire namespace */
(void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
AcpiNsDumpOneObjectPath, NULL, (void *) &MaxLevel, NULL);
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
}
/*******************************************************************************
*
* FUNCTION: AcpiNsDumpEntry

View File

@ -654,10 +654,19 @@ AcpiWalkNamespace (
goto UnlockAndExit;
}
/* Now we can validate the starting node */
if (!AcpiNsValidateHandle (StartObject))
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit2;
}
Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
ACPI_NS_WALK_UNLOCK, DescendingCallback,
AscendingCallback, Context, ReturnValue);
UnlockAndExit2:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
UnlockAndExit:

View File

@ -93,14 +93,9 @@ AcpiTbVerifyTable (
}
}
/* FACS is the odd table, has no standard ACPI header and no checksum */
/* Always calculate checksum, ignore bad checksum if requested */
if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
{
/* Always calculate checksum, ignore bad checksum if requested */
Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
}
Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
return_ACPI_STATUS (Status);
}

View File

@ -158,7 +158,7 @@ AcpiTbPrintTableHeader (
Header->Signature, ACPI_CAST_PTR (void, Address),
Header->Length));
}
else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP))
else if (ACPI_VALIDATE_RSDP_SIG (Header->Signature))
{
/* RSDP has no common fields */
@ -211,6 +211,17 @@ AcpiTbVerifyChecksum (
UINT8 Checksum;
/*
* FACS/S3PT:
* They are the odd tables, have no standard ACPI header and no checksum
*/
if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT) ||
ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS))
{
return (AE_OK);
}
/* Compute the checksum on the table */
Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length);

View File

@ -75,8 +75,7 @@ AcpiTbValidateRsdp (
* Note: Sometimes there exists more than one RSDP in memory; the valid
* RSDP has a valid checksum, all others have an invalid checksum.
*/
if (ACPI_STRNCMP ((char *) Rsdp->Signature, ACPI_SIG_RSDP,
sizeof (ACPI_SIG_RSDP)-1) != 0)
if (!ACPI_VALIDATE_RSDP_SIG (Rsdp->Signature))
{
/* Nope, BAD Signature */

View File

@ -216,7 +216,7 @@ AcpiDebugPrint (
* Display the module name, current line number, thread ID (if requested),
* current procedure nesting level, and the current procedure name
*/
AcpiOsPrintf ("%8s-%04ld ", ModuleName, LineNumber);
AcpiOsPrintf ("%9s-%04ld ", ModuleName, LineNumber);
if (ACPI_LV_THREADS & AcpiDbgLevel)
{

View File

@ -274,7 +274,7 @@ AcpiUtInitGlobals (
#if (!ACPI_REDUCED_HARDWARE)
/* GPE support */
/* GPE/SCI support */
AcpiGbl_AllGpesInitialized = FALSE;
AcpiGbl_GpeXruptListHead = NULL;
@ -283,6 +283,7 @@ AcpiUtInitGlobals (
AcpiCurrentGpeCount = 0;
AcpiGbl_GlobalEventHandler = NULL;
AcpiGbl_SciHandlerList = NULL;
#endif /* !ACPI_REDUCED_HARDWARE */

View File

@ -159,6 +159,10 @@ AcpiDbGenerateGpe (
char *GpeArg,
char *BlockArg))
ACPI_HW_DEPENDENT_RETURN_VOID (
void
AcpiDbGenerateSci (
void))
/*
* dbconvert - miscellaneous conversion routines
@ -233,6 +237,10 @@ AcpiDbDumpNamespace (
char *StartArg,
char *DepthArg);
void
AcpiDbDumpNamespacePaths (
void);
void
AcpiDbDumpNamespaceByOwner (
char *OwnerArg,

View File

@ -694,6 +694,9 @@ void
AcpiDmUnresolvedWarning (
UINT8 Type);
void
AcpiDmGetExternalsFromFile (
void);
/*
* dmresrc

View File

@ -338,18 +338,18 @@ UINT32 ACPI_SYSTEM_XFACE
AcpiEvGpeXruptHandler (
void *Context);
UINT32
AcpiEvSciDispatch (
void);
UINT32
AcpiEvInstallSciHandler (
void);
ACPI_STATUS
AcpiEvRemoveSciHandler (
AcpiEvRemoveAllSciHandlers (
void);
UINT32
AcpiEvInitializeSCI (
UINT32 ProgramSCI);
ACPI_HW_DEPENDENT_RETURN_VOID (
void
AcpiEvTerminate (

View File

@ -127,8 +127,9 @@ typedef struct acpi_exception_info
#define AE_NO_HANDLER EXCEP_ENV (0x001A)
#define AE_OWNER_ID_LIMIT EXCEP_ENV (0x001B)
#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
#define AE_ACCESS EXCEP_ENV (0x001D)
#define AE_CODE_ENV_MAX 0x001C
#define AE_CODE_ENV_MAX 0x001D
/*
@ -235,7 +236,7 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Env[] =
EXCEP_TXT ("AE_NO_ACPI_TABLES", "ACPI tables could not be found"),
EXCEP_TXT ("AE_NO_NAMESPACE", "A namespace has not been loaded"),
EXCEP_TXT ("AE_NO_MEMORY", "Insufficient dynamic memory"),
EXCEP_TXT ("AE_NOT_FOUND", "The name was not found in the namespace"),
EXCEP_TXT ("AE_NOT_FOUND", "A requested entity is not found"),
EXCEP_TXT ("AE_NOT_EXIST", "A required entity does not exist"),
EXCEP_TXT ("AE_ALREADY_EXISTS", "An entity already exists"),
EXCEP_TXT ("AE_TYPE", "The object type is incorrect"),
@ -258,7 +259,8 @@ static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Env[] =
EXCEP_TXT ("AE_SAME_HANDLER", "Attempt was made to install the same handler that is already installed"),
EXCEP_TXT ("AE_NO_HANDLER", "A handler for the operation is not installed"),
EXCEP_TXT ("AE_OWNER_ID_LIMIT", "There are no more Owner IDs available for ACPI tables or control methods"),
EXCEP_TXT ("AE_NOT_CONFIGURED", "The interface is not part of the current subsystem configuration")
EXCEP_TXT ("AE_NOT_CONFIGURED", "The interface is not part of the current subsystem configuration"),
EXCEP_TXT ("AE_ACCESS", "Permission denied for the requested operation")
};
static const ACPI_EXCEPTION_INFO AcpiGbl_ExceptionNames_Pgm[] =

View File

@ -274,6 +274,7 @@ ACPI_EXTERN ACPI_TABLE_HANDLER AcpiGbl_TableHandler;
ACPI_EXTERN void *AcpiGbl_TableHandlerContext;
ACPI_EXTERN ACPI_WALK_STATE *AcpiGbl_BreakpointWalk;
ACPI_EXTERN ACPI_INTERFACE_HANDLER AcpiGbl_InterfaceHandler;
ACPI_EXTERN ACPI_SCI_HANDLER_INFO *AcpiGbl_SciHandlerList;
/* Owner ID support */
@ -453,13 +454,6 @@ ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_tables;
ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_stats;
ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_ini_methods;
ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_NoRegionSupport;
ACPI_EXTERN char *AcpiGbl_DbArgs[ACPI_DEBUGGER_MAX_ARGS];
ACPI_EXTERN ACPI_OBJECT_TYPE AcpiGbl_DbArgTypes[ACPI_DEBUGGER_MAX_ARGS];
ACPI_EXTERN char AcpiGbl_DbLineBuf[ACPI_DB_LINE_BUFFER_SIZE];
ACPI_EXTERN char AcpiGbl_DbParsedBuf[ACPI_DB_LINE_BUFFER_SIZE];
ACPI_EXTERN char AcpiGbl_DbScopeBuf[80];
ACPI_EXTERN char AcpiGbl_DbDebugFilename[80];
ACPI_EXTERN BOOLEAN AcpiGbl_DbOutputToFile;
ACPI_EXTERN char *AcpiGbl_DbBuffer;
ACPI_EXTERN char *AcpiGbl_DbFilename;
@ -467,6 +461,16 @@ ACPI_EXTERN UINT32 AcpiGbl_DbDebugLevel;
ACPI_EXTERN UINT32 AcpiGbl_DbConsoleDebugLevel;
ACPI_EXTERN ACPI_NAMESPACE_NODE *AcpiGbl_DbScopeNode;
ACPI_EXTERN char *AcpiGbl_DbArgs[ACPI_DEBUGGER_MAX_ARGS];
ACPI_EXTERN ACPI_OBJECT_TYPE AcpiGbl_DbArgTypes[ACPI_DEBUGGER_MAX_ARGS];
/* These buffers should all be the same size */
ACPI_EXTERN char AcpiGbl_DbLineBuf[ACPI_DB_LINE_BUFFER_SIZE];
ACPI_EXTERN char AcpiGbl_DbParsedBuf[ACPI_DB_LINE_BUFFER_SIZE];
ACPI_EXTERN char AcpiGbl_DbScopeBuf[ACPI_DB_LINE_BUFFER_SIZE];
ACPI_EXTERN char AcpiGbl_DbDebugFilename[ACPI_DB_LINE_BUFFER_SIZE];
/*
* Statistic globals
*/

View File

@ -453,6 +453,16 @@ typedef struct acpi_simple_repair_info
*
****************************************************************************/
/* Dispatch info for each host-installed SCI handler */
typedef struct acpi_sci_handler_info
{
struct acpi_sci_handler_info *Next;
ACPI_SCI_HANDLER Address; /* Address of handler */
void *Context; /* Context to be passed to handler */
} ACPI_SCI_HANDLER_INFO;
/* Dispatch info for each GPE -- either a method or handler, cannot be both */
typedef struct acpi_gpe_handler_info
@ -1217,7 +1227,8 @@ typedef struct acpi_external_list
/* Values for Flags field above */
#define ACPI_IPATH_ALLOCATED 0x01
#define ACPI_IPATH_ALLOCATED 0x01
#define ACPI_FROM_REFERENCE_FILE 0x02
typedef struct acpi_external_file

View File

@ -272,6 +272,14 @@ AcpiNsDumpObjects (
ACPI_OWNER_ID OwnerId,
ACPI_HANDLE StartHandle);
void
AcpiNsDumpObjectPaths (
ACPI_OBJECT_TYPE Type,
UINT8 DisplayType,
UINT32 MaxDepth,
ACPI_OWNER_ID OwnerId,
ACPI_HANDLE StartHandle);
/*
* nseval - Namespace evaluation functions

View File

@ -404,6 +404,7 @@ ACPI_STATUS
AcpiOsGetTableByIndex (
UINT32 Index,
ACPI_TABLE_HEADER **Table,
UINT32 *Instance,
ACPI_PHYSICAL_ADDRESS *Address);
ACPI_STATUS

View File

@ -47,7 +47,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20130725
#define ACPI_CA_VERSION 0x20130823
#include <contrib/dev/acpica/include/acconfig.h>
#include <contrib/dev/acpica/include/actypes.h>
@ -375,6 +375,17 @@ AcpiInstallInitializationHandler (
ACPI_INIT_HANDLER Handler,
UINT32 Function);
ACPI_HW_DEPENDENT_RETURN_STATUS (
ACPI_STATUS
AcpiInstallSciHandler (
ACPI_SCI_HANDLER Address,
void *Context))
ACPI_HW_DEPENDENT_RETURN_STATUS (
ACPI_STATUS
AcpiRemoveSciHandler (
ACPI_SCI_HANDLER Address))
ACPI_HW_DEPENDENT_RETURN_STATUS (
ACPI_STATUS
AcpiInstallGlobalEventHandler (

View File

@ -488,6 +488,11 @@ typedef UINT64 ACPI_INTEGER;
#define ACPI_MOVE_NAME(dest,src) (ACPI_STRNCPY (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
#endif
/* Support for the special RSDP signature (8 characters) */
#define ACPI_VALIDATE_RSDP_SIG(a) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
#define ACPI_MAKE_RSDP_SIG(dest) (ACPI_MEMCPY (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
/*******************************************************************************
*
@ -1006,6 +1011,10 @@ typedef void
* Various handlers and callback procedures
*/
typedef
UINT32 (*ACPI_SCI_HANDLER) (
void *Context);
typedef
void (*ACPI_GBL_EVENT_HANDLER) (
UINT32 EventType,
ACPI_HANDLE Device,

View File

@ -1023,6 +1023,7 @@ AcpiOsReadPciConfiguration (
UINT32 Width)
{
*Value = 0;
return (AE_OK);
}

View File

@ -119,7 +119,7 @@ static void krping_wait(struct krping_cb *cb, int state)
int rc;
mtx_lock(&cb->lock);
while (cb->state < state) {
rc = msleep(cb, &cb->lock, 0, "krping", 0);
rc = msleep(cb, &cb->lock, PCATCH, "krping", 0);
if (rc && rc != ERESTART) {
cb->state = ERROR;
break;
@ -188,7 +188,12 @@ static int krping_cma_event_handler(struct rdma_cm_id *cma_id,
case RDMA_CM_EVENT_DEVICE_REMOVAL:
DEBUG_LOG(PFX "cma detected device removal!!!!\n");
break;
cb->state = ERROR;
wakeup(cb);
mtx_unlock(&cb->lock);
krping_wait(cb, CLEANUP);
tsleep(cb, 0, "krping", 5000);
return 0;
default:
log(LOG_ERR, "oof bad type!\n");
@ -603,6 +608,8 @@ static int krping_setup_qp(struct krping_cb *cb, struct rdma_cm_id *cm_id)
}
DEBUG_LOG(PFX "created pd %p\n", cb->pd);
strlcpy(cb->name, cb->pd->device->name, sizeof(cb->name));
cb->cq = ib_create_cq(cm_id->device, krping_cq_event_handler, NULL,
cb, cb->txdepth * 2, 0);
if (IS_ERR(cb->cq)) {
@ -1164,7 +1171,7 @@ static void krping_wlat_test_server(struct krping_cb *cb)
}
wlat_test(cb);
krping_wait(cb, ERROR);
}
static void krping_bw_test_server(struct krping_cb *cb)
@ -1776,6 +1783,12 @@ int krping_doit(char *cmd)
else
krping_run_client(cb);
DEBUG_LOG(PFX "destroy cm_id %p\n", cb->cm_id);
mtx_lock(&cb->lock);
cb->state = CLEANUP;
wakeup(cb);
mtx_unlock(&cb->lock);
rdma_destroy_id(cb->cm_id);
out:
mtx_lock(&krping_mutex);

View File

@ -37,7 +37,8 @@ enum test_state {
RDMA_READ_COMPLETE,
RDMA_WRITE_ADV,
RDMA_WRITE_COMPLETE,
ERROR
ERROR,
CLEANUP
};
struct krping_rdma_info {
@ -100,13 +101,15 @@ struct krping_cb {
/* listener on service side. */
struct rdma_cm_id *child_cm_id; /* connection on server side */
TAILQ_ENTRY(krping_cb) list;
int rlat; /* run read latency test */
int wlat; /* run write latency test */
int bw; /* run write bw test */
int duplex; /* run write bw full duplex test */
int poll; /* poll vs block in rlat */
int txdepth;
char name[16];
};
static __inline uint64_t

View File

@ -112,12 +112,11 @@ krping_read(struct cdev *dev, struct uio *uio, int ioflag)
mtx_unlock(&krping_mutex);
while (!TAILQ_EMPTY(&copy_cbs)) {
cb = TAILQ_FIRST(&copy_cbs);
TAILQ_REMOVE(&copy_cbs, cb, list);
if (cb->pd) {
uprintf("krping: %4d %10s %10u %10u %10u %10u %10u %10u %10u %10u\n",
num++, cb->pd->device->name, cb->stats.send_bytes,
num++, cb->name, cb->stats.send_bytes,
cb->stats.send_msgs, cb->stats.recv_bytes,
cb->stats.recv_msgs, cb->stats.write_bytes,
cb->stats.write_msgs,

View File

@ -308,17 +308,16 @@ mfip_cam_rescan(struct mfi_softc *sc, uint32_t tid)
return;
}
camsc->state = MFIP_STATE_RESCAN;
mtx_unlock(&sc->mfi_io_lock);
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
mtx_unlock(&sc->mfi_io_lock);
device_printf(sc->mfi_dev,
"Cannot allocate ccb for bus rescan.\n");
return;
}
sim = camsc->sim;
mtx_lock(&sc->mfi_io_lock);
if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sim),
tid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_free_ccb(ccb);
@ -327,11 +326,8 @@ mfip_cam_rescan(struct mfi_softc *sc, uint32_t tid)
"Cannot create path for bus rescan.\n");
return;
}
mtx_unlock(&sc->mfi_io_lock);
xpt_rescan(ccb);
mtx_lock(&sc->mfi_io_lock);
camsc->state = MFIP_STATE_NONE;
mtx_unlock(&sc->mfi_io_lock);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
/*-
* Copyright (c) 2013 Tsubai Masanari
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $OpenBSD: src/sys/dev/pci/if_vmxreg.h,v 1.2 2013/06/12 01:07:33 uebayasi Exp $
*
* $FreeBSD$
*/
#ifndef _IF_VMXREG_H
#define _IF_VMXREG_H
struct UPT1_TxStats {
uint64_t TSO_packets;
uint64_t TSO_bytes;
uint64_t ucast_packets;
uint64_t ucast_bytes;
uint64_t mcast_packets;
uint64_t mcast_bytes;
uint64_t bcast_packets;
uint64_t bcast_bytes;
uint64_t error;
uint64_t discard;
} __packed;
struct UPT1_RxStats {
uint64_t LRO_packets;
uint64_t LRO_bytes;
uint64_t ucast_packets;
uint64_t ucast_bytes;
uint64_t mcast_packets;
uint64_t mcast_bytes;
uint64_t bcast_packets;
uint64_t bcast_bytes;
uint64_t nobuffer;
uint64_t error;
} __packed;
/* Interrupt moderation levels */
#define UPT1_IMOD_NONE 0 /* No moderation */
#define UPT1_IMOD_HIGHEST 7 /* Least interrupts */
#define UPT1_IMOD_ADAPTIVE 8 /* Adaptive interrupt moderation */
/* Hardware features */
#define UPT1_F_CSUM 0x0001 /* Rx checksum verification */
#define UPT1_F_RSS 0x0002 /* Receive side scaling */
#define UPT1_F_VLAN 0x0004 /* VLAN tag stripping */
#define UPT1_F_LRO 0x0008 /* Large receive offloading */
#define VMXNET3_BAR0_IMASK(irq) (0x000 + (irq) * 8) /* Interrupt mask */
#define VMXNET3_BAR0_TXH(q) (0x600 + (q) * 8) /* Tx head */
#define VMXNET3_BAR0_RXH1(q) (0x800 + (q) * 8) /* Ring1 Rx head */
#define VMXNET3_BAR0_RXH2(q) (0xA00 + (q) * 8) /* Ring2 Rx head */
#define VMXNET3_BAR1_VRRS 0x000 /* VMXNET3 revision report selection */
#define VMXNET3_BAR1_UVRS 0x008 /* UPT version report selection */
#define VMXNET3_BAR1_DSL 0x010 /* Driver shared address low */
#define VMXNET3_BAR1_DSH 0x018 /* Driver shared address high */
#define VMXNET3_BAR1_CMD 0x020 /* Command */
#define VMXNET3_BAR1_MACL 0x028 /* MAC address low */
#define VMXNET3_BAR1_MACH 0x030 /* MAC address high */
#define VMXNET3_BAR1_INTR 0x038 /* Interrupt status */
#define VMXNET3_BAR1_EVENT 0x040 /* Event status */
#define VMXNET3_CMD_ENABLE 0xCAFE0000 /* Enable VMXNET3 */
#define VMXNET3_CMD_DISABLE 0xCAFE0001 /* Disable VMXNET3 */
#define VMXNET3_CMD_RESET 0xCAFE0002 /* Reset device */
#define VMXNET3_CMD_SET_RXMODE 0xCAFE0003 /* Set interface flags */
#define VMXNET3_CMD_SET_FILTER 0xCAFE0004 /* Set address filter */
#define VMXNET3_CMD_VLAN_FILTER 0xCAFE0005 /* Set VLAN filter */
#define VMXNET3_CMD_GET_STATUS 0xF00D0000 /* Get queue errors */
#define VMXNET3_CMD_GET_STATS 0xF00D0001 /* Get queue statistics */
#define VMXNET3_CMD_GET_LINK 0xF00D0002 /* Get link status */
#define VMXNET3_CMD_GET_MACL 0xF00D0003 /* Get MAC address low */
#define VMXNET3_CMD_GET_MACH 0xF00D0004 /* Get MAC address high */
#define VMXNET3_CMD_GET_INTRCFG 0xF00D0008 /* Get interrupt config */
#define VMXNET3_DMADESC_ALIGN 128
#define VMXNET3_INIT_GEN 1
struct vmxnet3_txdesc {
uint64_t addr;
uint32_t len:14;
uint32_t gen:1; /* Generation */
uint32_t pad1:1;
uint32_t dtype:1; /* Descriptor type */
uint32_t pad2:1;
uint32_t offload_pos:14; /* Offloading position */
uint32_t hlen:10; /* Header len */
uint32_t offload_mode:2; /* Offloading mode */
uint32_t eop:1; /* End of packet */
uint32_t compreq:1; /* Completion request */
uint32_t pad3:1;
uint32_t vtag_mode:1; /* VLAN tag insertion mode */
uint32_t vtag:16; /* VLAN tag */
} __packed;
/* Offloading modes */
#define VMXNET3_OM_NONE 0
#define VMXNET3_OM_CSUM 2
#define VMXNET3_OM_TSO 3
struct vmxnet3_txcompdesc {
uint32_t eop_idx:12; /* EOP index in Tx ring */
uint32_t pad1:20;
uint32_t pad2:32;
uint32_t pad3:32;
uint32_t rsvd:24;
uint32_t type:7;
uint32_t gen:1;
} __packed;
struct vmxnet3_rxdesc {
uint64_t addr;
uint32_t len:14;
uint32_t btype:1; /* Buffer type */
uint32_t dtype:1; /* Descriptor type */
uint32_t rsvd:15;
uint32_t gen:1;
uint32_t pad1:32;
} __packed;
/* Buffer types */
#define VMXNET3_BTYPE_HEAD 0 /* Head only */
#define VMXNET3_BTYPE_BODY 1 /* Body only */
struct vmxnet3_rxcompdesc {
uint32_t rxd_idx:12; /* Rx descriptor index */
uint32_t pad1:2;
uint32_t eop:1; /* End of packet */
uint32_t sop:1; /* Start of packet */
uint32_t qid:10;
uint32_t rss_type:4;
uint32_t no_csum:1; /* No checksum calculated */
uint32_t pad2:1;
uint32_t rss_hash:32; /* RSS hash value */
uint32_t len:14;
uint32_t error:1;
uint32_t vlan:1; /* 802.1Q VLAN frame */
uint32_t vtag:16; /* VLAN tag */
uint32_t csum:16;
uint32_t csum_ok:1; /* TCP/UDP checksum ok */
uint32_t udp:1;
uint32_t tcp:1;
uint32_t ipcsum_ok:1; /* IP checksum OK */
uint32_t ipv6:1;
uint32_t ipv4:1;
uint32_t fragment:1; /* IP fragment */
uint32_t fcs:1; /* Frame CRC correct */
uint32_t type:7;
uint32_t gen:1;
} __packed;
#define VMXNET3_REV1_MAGIC 0XBABEFEE1
#define VMXNET3_GOS_UNKNOWN 0x00
#define VMXNET3_GOS_LINUX 0x04
#define VMXNET3_GOS_WINDOWS 0x08
#define VMXNET3_GOS_SOLARIS 0x0C
#define VMXNET3_GOS_FREEBSD 0x10
#define VMXNET3_GOS_PXE 0x14
#define VMXNET3_GOS_32BIT 0x01
#define VMXNET3_GOS_64BIT 0x02
#define VMXNET3_MAX_TX_QUEUES 8
#define VMXNET3_MAX_RX_QUEUES 16
#define VMXNET3_MAX_INTRS \
(VMXNET3_MAX_TX_QUEUES + VMXNET3_MAX_RX_QUEUES + 1)
#define VMXNET3_ICTRL_DISABLE_ALL 0x01
#define VMXNET3_RXMODE_UCAST 0x01
#define VMXNET3_RXMODE_MCAST 0x02
#define VMXNET3_RXMODE_BCAST 0x04
#define VMXNET3_RXMODE_ALLMULTI 0x08
#define VMXNET3_RXMODE_PROMISC 0x10
#define VMXNET3_EVENT_RQERROR 0x01
#define VMXNET3_EVENT_TQERROR 0x02
#define VMXNET3_EVENT_LINK 0x04
#define VMXNET3_EVENT_DIC 0x08
#define VMXNET3_EVENT_DEBUG 0x10
#define VMXNET3_MIN_MTU 60
#define VMXNET3_MAX_MTU 9000
/* Interrupt mask mode. */
#define VMXNET3_IMM_AUTO 0x00
#define VMXNET3_IMM_ACTIVE 0x01
#define VMXNET3_IMM_LAZY 0x02
/* Interrupt type. */
#define VMXNET3_IT_AUTO 0x00
#define VMXNET3_IT_LEGACY 0x01
#define VMXNET3_IT_MSI 0x02
#define VMXNET3_IT_MSIX 0x03
struct vmxnet3_driver_shared {
uint32_t magic;
uint32_t pad1;
/* Misc. control */
uint32_t version; /* Driver version */
uint32_t guest; /* Guest OS */
uint32_t vmxnet3_revision; /* Supported VMXNET3 revision */
uint32_t upt_version; /* Supported UPT version */
uint64_t upt_features;
uint64_t driver_data;
uint64_t queue_shared;
uint32_t driver_data_len;
uint32_t queue_shared_len;
uint32_t mtu;
uint16_t nrxsg_max;
uint8_t ntxqueue;
uint8_t nrxqueue;
uint32_t reserved1[4];
/* Interrupt control */
uint8_t automask;
uint8_t nintr;
uint8_t evintr;
uint8_t modlevel[VMXNET3_MAX_INTRS];
uint32_t ictrl;
uint32_t reserved2[2];
/* Receive filter parameters */
uint32_t rxmode;
uint16_t mcast_tablelen;
uint16_t pad2;
uint64_t mcast_table;
uint32_t vlan_filter[4096 / 32];
struct {
uint32_t version;
uint32_t len;
uint64_t paddr;
} rss, pm, plugin;
uint32_t event;
uint32_t reserved3[5];
} __packed;
struct vmxnet3_txq_shared {
/* Control */
uint32_t npending;
uint32_t intr_threshold;
uint64_t reserved1;
/* Config */
uint64_t cmd_ring;
uint64_t data_ring;
uint64_t comp_ring;
uint64_t driver_data;
uint64_t reserved2;
uint32_t cmd_ring_len;
uint32_t data_ring_len;
uint32_t comp_ring_len;
uint32_t driver_data_len;
uint8_t intr_idx;
uint8_t pad1[7];
/* Queue status */
uint8_t stopped;
uint8_t pad2[3];
uint32_t error;
struct UPT1_TxStats stats;
uint8_t pad3[88];
} __packed;
struct vmxnet3_rxq_shared {
uint8_t update_rxhead;
uint8_t pad1[7];
uint64_t reserved1;
uint64_t cmd_ring[2];
uint64_t comp_ring;
uint64_t driver_data;
uint64_t reserved2;
uint32_t cmd_ring_len[2];
uint32_t comp_ring_len;
uint32_t driver_data_len;
uint8_t intr_idx;
uint8_t pad2[7];
uint8_t stopped;
uint8_t pad3[3];
uint32_t error;
struct UPT1_RxStats stats;
uint8_t pad4[88];
} __packed;
#endif /* _IF_VMXREG_H */

View File

@ -0,0 +1,319 @@
/*-
* Copyright (c) 2013 Tsubai Masanari
* Copyright (c) 2013 Bryan Venteicher <bryanv@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $FreeBSD$
*/
#ifndef _IF_VMXVAR_H
#define _IF_VMXVAR_H
struct vmxnet3_softc;
struct vmxnet3_dma_alloc {
bus_addr_t dma_paddr;
caddr_t dma_vaddr;
bus_dma_tag_t dma_tag;
bus_dmamap_t dma_map;
bus_size_t dma_size;
};
/*
* The number of Rx/Tx queues this driver supports.
*/
#define VMXNET3_RX_QUEUES 1
#define VMXNET3_TX_QUEUES 1
/*
* The number of Rx rings in each Rx queue.
*/
#define VMXNET3_RXRINGS_PERQ 2
/*
* The maximum number of descriptors in each Rx/Tx ring.
*/
#define VMXNET3_MAX_TX_NDESC 512
#define VMXNET3_MAX_RX_NDESC 256
#define VMXNET3_MAX_TX_NCOMPDESC VMXNET3_MAX_TX_NDESC
#define VMXNET3_MAX_RX_NCOMPDESC \
(VMXNET3_MAX_RX_NDESC * VMXNET3_RXRINGS_PERQ)
/*
* The maximum number of Rx segments we accept. When LRO is enabled,
* this allows us to receive the maximum sized frame with one MCLBYTES
* cluster followed by 16 MJUMPAGESIZE clusters.
*/
#define VMXNET3_MAX_RX_SEGS 17
struct vmxnet3_txbuf {
bus_dmamap_t vtxb_dmamap;
struct mbuf *vtxb_m;
};
struct vmxnet3_txring {
struct vmxnet3_txbuf *vxtxr_txbuf;
u_int vxtxr_head;
u_int vxtxr_next;
u_int vxtxr_ndesc;
int vxtxr_gen;
bus_dma_tag_t vxtxr_txtag;
struct vmxnet3_txdesc *vxtxr_txd;
struct vmxnet3_dma_alloc vxtxr_dma;
};
static inline int
VMXNET3_TXRING_AVAIL(struct vmxnet3_txring *txr)
{
int avail = txr->vxtxr_next - txr->vxtxr_head - 1;
return (avail < 0 ? txr->vxtxr_ndesc + avail : avail);
}
struct vmxnet3_rxbuf {
bus_dmamap_t vrxb_dmamap;
struct mbuf *vrxb_m;
};
struct vmxnet3_rxring {
struct vmxnet3_rxbuf *vxrxr_rxbuf;
struct vmxnet3_rxdesc *vxrxr_rxd;
u_int vxrxr_fill;
u_int vxrxr_ndesc;
int vxrxr_gen;
int vxrxr_rid;
bus_dma_tag_t vxrxr_rxtag;
struct vmxnet3_dma_alloc vxrxr_dma;
bus_dmamap_t vxrxr_spare_dmap;
};
static inline void
vmxnet3_rxr_increment_fill(struct vmxnet3_rxring *rxr)
{
if (++rxr->vxrxr_fill == rxr->vxrxr_ndesc) {
rxr->vxrxr_fill = 0;
rxr->vxrxr_gen ^= 1;
}
}
struct vmxnet3_comp_ring {
union {
struct vmxnet3_txcompdesc *txcd;
struct vmxnet3_rxcompdesc *rxcd;
} vxcr_u;
u_int vxcr_next;
u_int vxcr_ndesc;
int vxcr_gen;
struct vmxnet3_dma_alloc vxcr_dma;
};
struct vmxnet3_txq_stats {
uint64_t vtxrs_full;
uint64_t vtxrs_offload_failed;
};
struct vmxnet3_txqueue {
struct mtx vxtxq_mtx;
struct vmxnet3_softc *vxtxq_sc;
int vxtxq_id;
int vxtxq_intr_idx;
int vxtxq_watchdog;
struct vmxnet3_txring vxtxq_cmd_ring;
struct vmxnet3_comp_ring vxtxq_comp_ring;
struct vmxnet3_txq_stats vxtxq_stats;
struct vmxnet3_txq_shared *vxtxq_ts;
struct sysctl_oid_list *vxtxq_sysctl;
char vxtxq_name[16];
};
#define VMXNET3_TXQ_LOCK(_txq) mtx_lock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_TRYLOCK(_txq) mtx_trylock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_UNLOCK(_txq) mtx_unlock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_LOCK_ASSERT(_txq) \
mtx_assert(&(_txq)->vxtxq_mtx, MA_OWNED)
#define VMXNET3_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \
mtx_assert(&(_txq)->vxtxq_mtx, MA_NOTOWNED)
struct vmxnet3_rxq_stats {
};
struct vmxnet3_rxqueue {
struct mtx vxrxq_mtx;
struct vmxnet3_softc *vxrxq_sc;
int vxrxq_id;
int vxrxq_intr_idx;
struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ];
struct vmxnet3_comp_ring vxrxq_comp_ring;
struct vmxnet3_rxq_stats vxrxq_stats;
struct vmxnet3_rxq_shared *vxrxq_rs;
struct sysctl_oid_list *vxrxq_sysctl;
char vxrxq_name[16];
};
#define VMXNET3_RXQ_LOCK(_rxq) mtx_lock(&(_rxq)->vxrxq_mtx)
#define VMXNET3_RXQ_UNLOCK(_rxq) mtx_unlock(&(_rxq)->vxrxq_mtx)
#define VMXNET3_RXQ_LOCK_ASSERT(_rxq) \
mtx_assert(&(_rxq)->vxrxq_mtx, MA_OWNED)
#define VMXNET3_RXQ_LOCK_ASSERT_NOTOWNED(_rxq) \
mtx_assert(&(_rxq)->vxrxq_mtx, MA_NOTOWNED)
struct vmxnet3_statistics {
uint32_t vmst_collapsed;
uint32_t vmst_mgetcl_failed;
uint32_t vmst_mbuf_load_failed;
};
struct vmxnet3_interrupt {
struct resource *vmxi_irq;
int vmxi_rid;
void *vmxi_handler;
};
struct vmxnet3_softc {
device_t vmx_dev;
struct ifnet *vmx_ifp;
struct vmxnet3_driver_shared *vmx_ds;
uint32_t vmx_flags;
#define VMXNET3_FLAG_NO_MSIX 0x0001
struct vmxnet3_rxqueue *vmx_rxq;
struct vmxnet3_txqueue *vmx_txq;
struct resource *vmx_res0;
bus_space_tag_t vmx_iot0;
bus_space_handle_t vmx_ioh0;
struct resource *vmx_res1;
bus_space_tag_t vmx_iot1;
bus_space_handle_t vmx_ioh1;
struct resource *vmx_msix_res;
int vmx_link_active;
int vmx_link_speed;
int vmx_if_flags;
int vmx_ntxqueues;
int vmx_nrxqueues;
int vmx_ntxdescs;
int vmx_nrxdescs;
int vmx_max_rxsegs;
int vmx_rx_max_chain;
struct vmxnet3_statistics vmx_stats;
int vmx_intr_type;
int vmx_intr_mask_mode;
int vmx_event_intr_idx;
int vmx_nintrs;
struct vmxnet3_interrupt vmx_intrs[VMXNET3_MAX_INTRS];
struct mtx vmx_mtx;
uint8_t *vmx_mcast;
void *vmx_qs;
struct callout vmx_tick;
struct vmxnet3_dma_alloc vmx_ds_dma;
struct vmxnet3_dma_alloc vmx_qs_dma;
struct vmxnet3_dma_alloc vmx_mcast_dma;
struct ifmedia vmx_media;
eventhandler_tag vmx_vlan_attach;
eventhandler_tag vmx_vlan_detach;
uint8_t vmx_vlan_filter[4096/32];
uint8_t vmx_lladdr[ETHER_ADDR_LEN];
};
#define VMXNET3_CORE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->vmx_mtx, _name, "VMXNET3 Lock", MTX_DEF)
#define VMXNET3_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_LOCK(_sc) mtx_lock(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vmx_mtx, MA_OWNED)
#define VMXNET3_CORE_LOCK_ASSERT_NOTOWNED(_sc) \
mtx_assert(&(_sc)->vmx_mtx, MA_NOTOWNED)
/*
* Our driver version we report to the hypervisor; we just keep
* this value constant.
*/
#define VMXNET3_DRIVER_VERSION 0x00010000
/*
* Convert the FreeBSD version in to something the hypervisor
* understands. This is apparently what VMware's driver reports
* so mimic it even though it probably is not required.
*/
#define VMXNET3_GUEST_OS_VERSION \
(((__FreeBSD_version / 100000) << 14) | \
(((__FreeBSD_version / 1000) % 100) << 6 ) | \
(((__FreeBSD_version / 100) % 10) << 30) | \
((__FreeBSD_version % 100) << 22))
/*
* Max descriptors per Tx packet. We must limit the size of the
* any TSO packets based on the number of segments.
*/
#define VMXNET3_TX_MAXSEGS 32
#define VMXNET3_TSO_MAXSIZE 65550
/*
* Maximum support Tx segments size. The length field in the
* Tx descriptor is 14 bits.
*/
#define VMXNET3_TX_MAXSEGSIZE (1 << 14)
/*
* Predetermined size of the multicast MACs filter table. If the
* number of multicast addresses exceeds this size, then the
* ALL_MULTI mode is use instead.
*/
#define VMXNET3_MULTICAST_MAX 32
/*
* Our Tx watchdog timeout.
*/
#define VMXNET3_WATCHDOG_TIMEOUT 5
/*
* IP protocols that we can perform Tx checksum offloading of.
*/
#define VMXNET3_CSUM_OFFLOAD (CSUM_TCP | CSUM_UDP)
#define VMXNET3_CSUM_OFFLOAD_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
#define VMXNET3_CSUM_ALL_OFFLOAD \
(VMXNET3_CSUM_OFFLOAD | VMXNET3_CSUM_OFFLOAD_IPV6 | CSUM_TSO)
/*
* Compat macros to keep this driver compiling on old releases.
*/
#if !defined(SYSCTL_ADD_UQUAD)
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
#endif
#if !defined(IFCAP_TXCSUM_IPV6)
#define IFCAP_TXCSUM_IPV6 0
#endif
#if !defined(IFCAP_RXCSUM_IPV6)
#define IFCAP_RXCSUM_IPV6 0
#endif
#if !defined(CSUM_TCP_IPV6)
#define CSUM_TCP_IPV6 0
#endif
#if !defined(CSUM_UDP_IPV6)
#define CSUM_UDP_IPV6 0
#endif
#endif /* _IF_VMXVAR_H */

View File

@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/stat.h>
#include <sys/systm.h>
@ -138,6 +140,7 @@ tmpfs_mount(struct mount *mp)
sizeof(struct tmpfs_dirent) + sizeof(struct tmpfs_node));
struct tmpfs_mount *tmp;
struct tmpfs_node *root;
struct thread *td = curthread;
int error;
/* Size counters. */
u_quad_t pages;
@ -150,6 +153,9 @@ tmpfs_mount(struct mount *mp)
struct vattr va;
if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_TMPFS))
return (EPERM);
if (vfs_filteropt(mp->mnt_optnew, tmpfs_opts))
return (EINVAL);
@ -420,4 +426,4 @@ struct vfsops tmpfs_vfsops = {
.vfs_statfs = tmpfs_statfs,
.vfs_fhtovp = tmpfs_fhtovp,
};
VFS_SET(tmpfs_vfsops, tmpfs, 0);
VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL);

View File

@ -460,6 +460,12 @@ g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g
if (dp->d_getattr(bp) == 0)
sbuf_printf(sb, "%s<lunid>%s</lunid>\n",
indent, buf);
bp->bio_attribute = "GEOM::lunname";
bp->bio_length = DISK_IDENT_SIZE;
bp->bio_data = buf;
if (dp->d_getattr(bp) == 0)
sbuf_printf(sb, "%s<lunname>%s</lunname>\n",
indent, buf);
g_destroy_bio(bp);
g_free(buf);
} else

View File

@ -206,6 +206,7 @@ static char *pr_allow_names[] = {
"allow.mount.nullfs",
"allow.mount.zfs",
"allow.mount.procfs",
"allow.mount.tmpfs",
};
const size_t pr_allow_names_size = sizeof(pr_allow_names);
@ -221,6 +222,7 @@ static char *pr_allow_nonames[] = {
"allow.mount.nonullfs",
"allow.mount.nozfs",
"allow.mount.noprocfs",
"allow.mount.notmpfs",
};
const size_t pr_allow_nonames_size = sizeof(pr_allow_nonames);
@ -4228,6 +4230,10 @@ SYSCTL_PROC(_security_jail, OID_AUTO, mount_procfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_PROCFS, sysctl_jail_default_allow, "I",
"Processes in jail can mount the procfs file system");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_tmpfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_TMPFS, sysctl_jail_default_allow, "I",
"Processes in jail can mount the tmpfs file system");
SYSCTL_PROC(_security_jail, OID_AUTO, mount_zfs_allowed,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
NULL, PR_ALLOW_MOUNT_ZFS, sysctl_jail_default_allow, "I",
@ -4380,6 +4386,8 @@ SYSCTL_JAIL_PARAM(_allow_mount, nullfs, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may mount the nullfs file system");
SYSCTL_JAIL_PARAM(_allow_mount, procfs, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may mount the procfs file system");
SYSCTL_JAIL_PARAM(_allow_mount, tmpfs, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may mount the tmpfs file system");
SYSCTL_JAIL_PARAM(_allow_mount, zfs, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may mount the zfs file system");

View File

@ -410,18 +410,14 @@ mb_ctor_mbuf(void *mem, int size, void *arg, int how)
{
struct mbuf *m;
struct mb_args *args;
#ifdef MAC
int error;
#endif
int flags;
short type;
#ifdef INVARIANTS
trash_ctor(mem, size, arg, how);
#endif
m = (struct mbuf *)mem;
args = (struct mb_args *)arg;
flags = args->flags;
type = args->type;
/*
@ -431,32 +427,12 @@ mb_ctor_mbuf(void *mem, int size, void *arg, int how)
if (type == MT_NOINIT)
return (0);
m->m_next = NULL;
m->m_nextpkt = NULL;
m->m_len = 0;
m->m_flags = flags;
m->m_type = type;
if (flags & M_PKTHDR) {
m->m_data = m->m_pktdat;
m->m_pkthdr.rcvif = NULL;
m->m_pkthdr.header = NULL;
m->m_pkthdr.len = 0;
m->m_pkthdr.csum_flags = 0;
m->m_pkthdr.csum_data = 0;
m->m_pkthdr.tso_segsz = 0;
m->m_pkthdr.ether_vtag = 0;
m->m_pkthdr.flowid = 0;
m->m_pkthdr.fibnum = 0;
SLIST_INIT(&m->m_pkthdr.tags);
#ifdef MAC
/* If the label init fails, fail the alloc */
error = mac_mbuf_init(m, how);
if (error)
return (error);
#endif
} else
m->m_data = m->m_dat;
return (0);
m = (struct mbuf *)mem;
flags = args->flags;
error = m_init(m, NULL, size, how, type, flags);
return (error);
}
/*
@ -571,6 +547,7 @@ mb_ctor_clust(void *mem, int size, void *arg, int how)
m->m_ext.ext_arg2 = NULL;
m->m_ext.ext_size = size;
m->m_ext.ext_type = type;
m->m_ext.ext_flags = 0;
m->m_ext.ref_cnt = refcnt;
}
@ -656,34 +633,14 @@ mb_ctor_pack(void *mem, int size, void *arg, int how)
#ifdef INVARIANTS
trash_ctor(m->m_ext.ext_buf, MCLBYTES, arg, how);
#endif
m->m_next = NULL;
m->m_nextpkt = NULL;
m->m_data = m->m_ext.ext_buf;
m->m_len = 0;
m->m_flags = (flags | M_EXT);
m->m_type = type;
if (flags & M_PKTHDR) {
m->m_pkthdr.rcvif = NULL;
m->m_pkthdr.len = 0;
m->m_pkthdr.header = NULL;
m->m_pkthdr.csum_flags = 0;
m->m_pkthdr.csum_data = 0;
m->m_pkthdr.tso_segsz = 0;
m->m_pkthdr.ether_vtag = 0;
m->m_pkthdr.flowid = 0;
m->m_pkthdr.fibnum = 0;
SLIST_INIT(&m->m_pkthdr.tags);
#ifdef MAC
/* If the label init fails, fail the alloc */
error = mac_mbuf_init(m, how);
if (error)
return (error);
#endif
}
error = m_init(m, NULL, size, how, type, flags);
/* m_ext is already initialized. */
m->m_data = m->m_ext.ext_buf;
m->m_flags = (flags | M_EXT);
return (0);
return (error);
}
int

View File

@ -54,6 +54,36 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
dev->si_iosize_max = DFLTPHYS;
}
/*
* If the driver does not want I/O to be split, that means that we
* need to reject any requests that will not fit into one buffer.
*/
if ((dev->si_flags & SI_NOSPLIT) &&
((uio->uio_resid > dev->si_iosize_max) ||
(uio->uio_resid > MAXPHYS) ||
(uio->uio_iovcnt > 1))) {
/*
* Tell the user why his I/O was rejected.
*/
if (uio->uio_resid > dev->si_iosize_max)
printf("%s: request size %zd > si_iosize_max=%d, "
"cannot split request\n", devtoname(dev),
uio->uio_resid, dev->si_iosize_max);
if (uio->uio_resid > MAXPHYS)
printf("%s: request size %zd > MAXPHYS=%d, "
"cannot split request\n", devtoname(dev),
uio->uio_resid, MAXPHYS);
if (uio->uio_iovcnt > 1)
printf("%s: request vectors=%d > 1, "
"cannot split request\n", devtoname(dev),
uio->uio_iovcnt);
error = EFBIG;
goto doerror;
}
for (i = 0; i < uio->uio_iovcnt; i++) {
while (uio->uio_iov[i].iov_len) {
bp->b_flags = 0;
@ -83,6 +113,17 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
*/
iolen = ((vm_offset_t) bp->b_data) & PAGE_MASK;
if ((bp->b_bcount + iolen) > bp->b_kvasize) {
/*
* This device does not want I/O to be split.
*/
if (dev->si_flags & SI_NOSPLIT) {
printf("%s: request ptr %#jx is not "
"on a page boundary, cannot split "
"request\n", devtoname(dev),
(uintmax_t)bp->b_data);
error = EFBIG;
goto doerror;
}
bp->b_bcount = bp->b_kvasize;
if (iolen != 0)
bp->b_bcount -= PAGE_SIZE;

View File

@ -267,6 +267,7 @@ m_extadd(struct mbuf *mb, caddr_t buf, u_int size,
mb->m_ext.ext_arg1 = arg1;
mb->m_ext.ext_arg2 = arg2;
mb->m_ext.ext_type = type;
mb->m_ext.ext_flags = 0;
return (0);
}
@ -342,6 +343,7 @@ mb_free_ext(struct mbuf *m)
m->m_ext.ref_cnt = NULL;
m->m_ext.ext_size = 0;
m->m_ext.ext_type = 0;
m->m_ext.ext_flags = 0;
m->m_flags &= ~M_EXT;
uma_zfree(zone_mbuf, m);
}
@ -368,6 +370,7 @@ mb_dupcl(struct mbuf *n, struct mbuf *m)
n->m_ext.ext_size = m->m_ext.ext_size;
n->m_ext.ref_cnt = m->m_ext.ref_cnt;
n->m_ext.ext_type = m->m_ext.ext_type;
n->m_ext.ext_flags = m->m_ext.ext_flags;
n->m_flags |= M_EXT;
n->m_flags |= m->m_flags & M_RDONLY;
}

View File

@ -342,6 +342,7 @@ SUBDIR= \
${_viawd} \
vkbd \
${_vmm} \
${_vmware} \
${_vpo} \
vr \
vte \
@ -368,6 +369,7 @@ SUBDIR= \
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
_filemon= filemon
_vmware= vmware
.endif
.if ${MACHINE_CPUARCH} != "powerpc" && ${MACHINE_CPUARCH} != "arm" && \

View File

@ -1,9 +1,9 @@
# $FreeBSD$
SUBDIR= addr
SUBDIR+= cma
SUBDIR+= iwcm
SUBDIR+= core
#SUBDIR= addr
#SUBDIR+= cma
#SUBDIR+= iwcm
#SUBDIR+= core
SUBDIR+= krping
.include <bsd.subdir.mk>

View File

@ -0,0 +1,28 @@
#
# $FreeBSD$
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
SUBDIR= vmxnet3
.include <bsd.subdir.mk>

View File

@ -0,0 +1,44 @@
#
# $FreeBSD$
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
.PATH: ${.CURDIR}/../../../dev/vmware/vmxnet3
KMOD= if_vmx
SRCS= if_vmx.c
SRCS+= bus_if.h device_if.h pci_if.h opt_inet.h opt_inet6.h
.if !defined(KERNBUILDDIR)
.if ${MK_INET_SUPPORT} != "no"
opt_inet.h:
@echo "#define INET 1" > ${.TARGET}
.endif
.if ${MK_INET6_SUPPORT} != "no"
opt_inet6.h:
@echo "#define INET6 1" > ${.TARGET}
.endif
.endif
.include <bsd.kmod.mk>

Some files were not shown because too many files have changed in this diff Show More