Merge ^/head r279163 through r279308.

This commit is contained in:
Dimitry Andric 2015-02-26 07:26:56 +00:00
commit 0d56a8cba1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang360-import/; revision=279309
170 changed files with 10178 additions and 2536 deletions

View File

@ -1222,6 +1222,8 @@ legacy:
#
# bootstrap-tools: Build tools needed for compatibility
#
_bt= _bootstrap-tools
.if ${MK_GAMES} != "no"
_strfile= games/fortune/strfile
.endif
@ -1245,6 +1247,8 @@ _sed= usr.bin/sed
.if ${BOOTSTRAPPING} < 1000002
_m4= lib/libohash \
usr.bin/m4
${_bt}-usr.bin/m4: ${_bt}-lib/libohash
.endif
.if ${BOOTSTRAPPING} < 1000014
@ -1254,6 +1258,8 @@ _crunch= usr.sbin/crunch
.if ${BOOTSTRAPPING} < 1000026
_nmtree= lib/libnetbsd \
usr.sbin/nmtree
${_bt}-usr.sbin/nmtree: ${_bt}-lib/libnetbsd
.endif
.if ${BOOTSTRAPPING} < 1000027
@ -1271,6 +1277,8 @@ _awk= usr.bin/awk
.if ${BOOTSTRAPPING} < 1001506
_yacc= lib/liby \
usr.bin/yacc
${_bt}-usr.bin/yacc: ${_bt}-lib/liby
.endif
.if ${MK_BSNMP} != "no"
@ -1285,6 +1293,9 @@ _clang_tblgen= \
lib/clang/libllvmtablegen \
usr.bin/clang/tblgen \
usr.bin/clang/clang-tblgen
${_bt}-usr.bin/clang/clang-tblgen: ${_bt}-lib/clang/libllvmtablegen ${_bt}-lib/clang/libllvmsupport
${_bt}-usr.bin/clang/tblgen: ${_bt}-lib/clang/libllvmtablegen ${_bt}-lib/clang/libllvmsupport
.endif
# ELF Tool Chain libraries are needed for ELF tools and dtrace tools.
@ -1296,6 +1307,9 @@ _elftoolchain_libs= lib/libelf lib/libdwarf
.if ${MK_CDDL} != "no"
_dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf cddl/usr.bin/ctfconvert \
cddl/usr.bin/ctfmerge
${_bt}-cddl/usr.bin/ctfconvert: ${_bt}-lib/libelf ${_bt}-lib/libdwarf ${_bt}-cddl/lib/libctf
${_bt}-cddl/usr.bin/ctfmerge: ${_bt}-lib/libelf ${_bt}-lib/libdwarf ${_bt}-cddl/lib/libctf
.endif
.endif
@ -1314,12 +1328,16 @@ _kerberos5_bootstrap_tools= \
kerberos5/tools/asn1_compile \
kerberos5/tools/slc \
usr.bin/compile_et
${_bt}-kerberos5/tools/slc: ${_bt}-kerberos5/lib/libroken
${_bt}-kerberos5/tools/asn1_compile: ${_bt}-kerberos5/lib/libroken
.endif
bootstrap-tools: .PHONY
# Please document (add comment) why something is in 'bootstrap-tools'.
# Try to bound the building of the bootstrap-tool to just the
# FreeBSD versions that need the tool built at this stage of the build.
bootstrap-tools: .MAKE
.for _tool in \
${_clang_tblgen} \
${_kerberos5_bootstrap_tools} \
@ -1345,12 +1363,15 @@ bootstrap-tools: .MAKE
${_crunch} \
${_nmtree} \
${_vtfontcvt}
${_bt}-${_tool}: .PHONY .MAKE
${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
cd ${.CURDIR}/${_tool} && \
${MAKE} DIRPRFX=${_tool}/ obj && \
${MAKE} DIRPRFX=${_tool}/ depend && \
${MAKE} DIRPRFX=${_tool}/ all && \
${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install
bootstrap-tools: ${_bt}-${_tool}
.endfor
#

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd November 14, 2014
.Dd February 22, 2015
.Dt SH 1
.Os
.Sh NAME
@ -1196,17 +1196,18 @@ command is implemented as a special built-in command.
.Ss Variables and Parameters
The shell maintains a set of parameters.
A parameter
denoted by a name is called a variable.
denoted by a name
(consisting solely
of alphabetics, numerics, and underscores,
and starting with an alphabetic or an underscore)
is called a variable.
When starting up,
the shell turns all the environment variables into shell
the shell turns all environment variables with valid names into shell
variables.
New variables can be set using the form
.Pp
.D1 Ar name Ns = Ns Ar value
.Pp
Variables set by the user must have a name consisting solely
of alphabetics, numerics, and underscores.
The first letter of a variable name must not be numeric.
A parameter can also be denoted by a number
or a special character as explained below.
.Pp
@ -1369,6 +1370,10 @@ This variable overrides the
.Va MAIL
setting.
There is a maximum of 10 mailboxes that can be monitored at once.
.It Va OPTIND
The index of the next argument to be processed by
.Ic getopts .
This is initialized to 1 at startup.
.It Va PATH
The default search path for executables.
See the
@ -2297,6 +2302,8 @@ If an invalid option is encountered,
is set to
.Ql \&? .
It returns a false value (1) when it encounters the end of the options.
A new set of arguments may be parsed by assigning
.Li OPTIND=1 .
.It Ic hash Oo Fl rv Oc Op Ar command ...
The shell maintains a hash table which remembers the locations of commands.
With no arguments whatsoever, the
@ -2771,7 +2778,7 @@ This is inherited by children of the shell, and is used in the history
editing modes.
.El
.Pp
Additionally, all environment variables are turned into shell variables
Additionally, environment variables are turned into shell variables
at startup,
which may affect the shell as described under
.Sx Special Variables .

View File

@ -2382,7 +2382,8 @@ find_line (bfd *abfd,
else
addr += section->vma;
*filename_ptr = NULL;
*functionname_ptr = NULL;
if (!do_line)
*functionname_ptr = NULL;
*linenumber_ptr = 0;
if (! *pinfo)

View File

@ -4268,6 +4268,11 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "stvx", X(31, 231), X_MASK, PPCVEC, { VS, RA, RB } },
{ "stvxl", X(31, 487), X_MASK, PPCVEC, { VS, RA, RB } },
/* New VSX opcodes in POWER ISA 2.06 */
/* XXX: only enough opcodes for FreeBSD kernel, remove and replace with real info */
{ "stxvw4x", X(31, 908), X_MASK, PPCVEC, { FRS, RA0, RB } },
{ "lxvw4x", X(31, 780), X_MASK, PPCVEC, { FRT, RA0, RB } },
/* New load/store left/right index vector instructions that are in the Cell only. */
{ "lvlx", X(31, 519), X_MASK, CELL, { VD, RA0, RB } },
{ "lvlxl", X(31, 775), X_MASK, CELL, { VD, RA0, RB } },

View File

@ -1525,7 +1525,8 @@ print_lineno(struct sym_entry *ep, struct func_info_head *func_info,
/* For function symbol, search the function line information list. */
if ((ep->sym->st_info & 0xf) == STT_FUNC && func_info != NULL) {
SLIST_FOREACH(func, func_info, entries) {
if (!strcmp(ep->name, func->name) &&
if (func->name != NULL &&
!strcmp(ep->name, func->name) &&
ep->sym->st_value >= func->lowpc &&
ep->sym->st_value < func->highpc) {
printf("\t%s:%" PRIu64, func->file, func->line);

View File

@ -796,6 +796,7 @@
.ds doc-str-Lb-libmd Message Digest (MD4, MD5, etc.) Support Library (libmd, \-lmd)
.ds doc-str-Lb-libmemstat Kernel Memory Allocator Statistics Library (libmemstat, \-lmemstat)
.ds doc-str-Lb-libmenu Curses Menu Library (libmenu, \-lmenu)
.ds doc-str-Lb-libmt Magnetic Tape Library (libmt, \-lmt)
.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph)
.ds doc-str-Lb-libnetpgp Netpgp signing, verification, encryption and decryption (libnetpgp, \-lnetpgp)
.ds doc-str-Lb-libossaudio OSS Audio Emulation Library (libossaudio, \-lossaudio)

View File

@ -218,15 +218,17 @@ static int64_t read_sleb128(dw_eh_ptr_t *data)
static uint64_t read_value(char encoding, dw_eh_ptr_t *data)
{
enum dwarf_data_encoding type = get_encoding(encoding);
uint64_t v;
switch (type)
{
// Read fixed-length types
#define READ(dwarf, type) \
case dwarf:\
v = static_cast<uint64_t>(*reinterpret_cast<type*>(*data));\
*data += sizeof(type);\
break;
{\
type t;\
memcpy(&t, *data, sizeof t);\
*data += sizeof t;\
return static_cast<uint64_t>(t);\
}
READ(DW_EH_PE_udata2, uint16_t)
READ(DW_EH_PE_udata4, uint32_t)
READ(DW_EH_PE_udata8, uint64_t)
@ -237,15 +239,11 @@ static uint64_t read_value(char encoding, dw_eh_ptr_t *data)
#undef READ
// Read variable-length types
case DW_EH_PE_sleb128:
v = read_sleb128(data);
break;
return read_sleb128(data);
case DW_EH_PE_uleb128:
v = read_uleb128(data);
break;
return read_uleb128(data);
default: abort();
}
return v;
}
/**

View File

@ -158,16 +158,13 @@ BIN1+= regdomain.xml
# -rwxr-xr-x root:wheel, for the new cron root:wheel
BIN2= netstart pccard_ether rc.suspend rc.resume
MTREE= BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist
MTREE= BSD.debug.dist BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist
.if ${MK_TESTS} != "no"
MTREE+= BSD.tests.dist
.endif
.if ${MK_SENDMAIL} != "no"
MTREE+= BSD.sendmail.dist
.endif
.if ${MK_DEBUG_FILES} != "no"
MTREE+= BSD.debug.dist
.endif
PPPCNF= ppp.conf
@ -346,10 +343,8 @@ MTREE_CMD?= mtree
MTREES= mtree/BSD.root.dist / \
mtree/BSD.var.dist /var \
mtree/BSD.usr.dist /usr \
mtree/BSD.include.dist /usr/include
.if ${MK_DEBUG_FILES} != "no"
MTREES+= mtree/BSD.debug.dist /usr/lib
.endif
mtree/BSD.include.dist /usr/include \
mtree/BSD.debug.dist /usr/lib
.if ${MK_GROFF} != "no"
MTREES+= mtree/BSD.groff.dist /usr
.endif

View File

@ -70,6 +70,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
libmd \
${_libmilter} \
${_libmp} \
libmt \
${_libnandfs} \
libnetbsd \
${_libnetgraph} \

View File

@ -28,7 +28,7 @@
.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
.Dd April 28, 1995
.Dd February 22, 2015
.Dt SETMODE 3
.Os
.Sh NAME
@ -99,7 +99,20 @@ The
function
may fail and set errno for any of the errors specified for the library
routine
.Xr malloc 3 .
.Xr malloc 3
or
.Xr strtol 3 .
In addition,
.Fn setmode
will fail and set
.Va errno
to:
.Bl -tag -width Er
.It Bq Er EINVAL
The
.Fa mode
argument does not represent a valid mode.
.El
.Sh SEE ALSO
.Xr chmod 1 ,
.Xr stat 2 ,

View File

@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
@ -66,7 +68,7 @@ typedef struct bitcmd {
#define CMD2_OBITS 0x08
#define CMD2_UBITS 0x10
static BITCMD *addcmd(BITCMD *, int, int, int, u_int);
static BITCMD *addcmd(BITCMD *, mode_t, mode_t, mode_t, mode_t);
static void compress_mode(BITCMD *);
#ifdef SETMODE_DEBUG
static void dumpmode(BITCMD *);
@ -151,33 +153,32 @@ common: if (set->cmd2 & CMD2_CLR) {
BITCMD *newset; \
setlen += SET_LEN_INCR; \
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
if (!newset) { \
if (saveset) \
free(saveset); \
saveset = NULL; \
return (NULL); \
} \
if (newset == NULL) \
goto out; \
set = newset + (set - saveset); \
saveset = newset; \
endset = newset + (setlen - 2); \
} \
set = addcmd(set, (a), (b), (c), (d))
set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d))
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
void *
setmode(const char *p)
{
int perm, who;
int serrno;
char op, *ep;
BITCMD *set, *saveset, *endset;
sigset_t sigset, sigoset;
mode_t mask;
int equalopdone=0, permXbits, setlen;
mode_t mask, perm, permXbits, who;
long perml;
int equalopdone;
int setlen;
if (!*p)
if (!*p) {
errno = EINVAL;
return (NULL);
}
/*
* Get a copy of the mask for the permissions that are mask relative.
@ -203,10 +204,17 @@ setmode(const char *p)
* or illegal bits.
*/
if (isdigit((unsigned char)*p)) {
errno = 0;
perml = strtol(p, &ep, 8);
if (*ep || perml < 0 || perml & ~(STANDARD_BITS|S_ISTXT)) {
free(saveset);
return (NULL);
if (*ep) {
errno = EINVAL;
goto out;
}
if (errno == ERANGE && (perml == LONG_MAX || perml == LONG_MIN))
goto out;
if (perml & ~(STANDARD_BITS|S_ISTXT)) {
errno = EINVAL;
goto out;
}
perm = (mode_t)perml;
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
@ -218,6 +226,7 @@ setmode(const char *p)
* Build list of structures to set/clear/copy bits as described by
* each clause of the symbolic mode.
*/
equalopdone = 0;
for (;;) {
/* First, find out which bits might be modified. */
for (who = 0;; ++p) {
@ -240,8 +249,8 @@ setmode(const char *p)
}
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
free(saveset);
return (NULL);
errno = EINVAL;
goto out;
}
if (op == '=')
equalopdone = 0;
@ -330,10 +339,15 @@ apply: if (!*p)
dumpmode(saveset);
#endif
return (saveset);
out:
serrno = errno;
free(saveset);
errno = serrno;
return NULL;
}
static BITCMD *
addcmd(BITCMD *set, int op, int who, int oparg, u_int mask)
addcmd(BITCMD *set, mode_t op, mode_t who, mode_t oparg, mode_t mask)
{
switch (op) {
case '=':

View File

@ -54,9 +54,8 @@
.Fn setstate "char *state"
.Sh DESCRIPTION
.Bf -symbolic
The functions described in this manual page are not cryptographically
secure.
Cryptographic applications should use
The functions described in this manual page are not secure.
Applications which require unpredictable random numbers should use
.Xr arc4random 3
instead.
.Ef

13
lib/libmt/Makefile Normal file
View File

@ -0,0 +1,13 @@
# $FreeBSD$
LIB= mt
SHLIBDIR?= /lib
SRCS= mtlib.c
INCS= mtlib.h
DPADD= ${LIBSBUF}
LDADD= -lsbuf
MAN= mt.3
.include <bsd.lib.mk>

455
lib/libmt/mt.3 Normal file
View File

@ -0,0 +1,455 @@
.\"
.\" Copyright (c) 2013, 2015 Spectra Logic Corporation
.\" All rights reserved.
.\"
.\" 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,
.\" without modification.
.\" 2. Redistributions in binary form must reproduce at minimum a disclaimer
.\" substantially similar to the "NO WARRANTY" disclaimer below
.\" ("Disclaimer") and any redistribution must be conditioned upon
.\" including a substantially similar Disclaimer requirement for further
.\" binary redistribution.
.\"
.\" NO WARRANTY
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
.\" HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
.\"
.\" Authors: Ken Merry (Spectra Logic Corporation)
.\"
.\" $FreeBSD$
.\"
.Dd February 13, 2015
.Dt MT 3
.Os
.Sh NAME
.Nm
.Nm mt_start_element ,
.Nm mt_end_element ,
.Nm mt_char_handler ,
.Nm mt_status_tree_sbuf ,
.Nm mt_status_tree_print ,
.Nm mt_status_entry_free ,
.Nm mt_status_free ,
.Nm mt_entry_sbuf ,
.Nm mt_param_parent_print ,
.Nm mt_param_entry_print ,
.Nm mt_protect_print ,
.Nm mt_param_list ,
.Nm mt_density_name ,
.Nm mt_density_bp ,
.Nm mt_density_num ,
.Nm mt_get_xml_str ,
.Nm mt_get_status
.Nd Magnetic Tape library
.Sh LIBRARY
.Lb libmt
.Sh SYNOPSIS
.In sys/sbuf.h
.In bsdxml.h
.In mtlib.h
.Ft void
.Fo mt_start_element
.Fa "void *user_data"
.Fa "const char *name"
.Fa "const char **attr"
.Fc
.Ft void
.Fo mt_end_element
.Fa "void *user_data"
.Fa "const char *name"
.Fc
.Ft void
.Fo mt_char_handler
.Fa "void *user_data"
.Fa "const XML_Char *str"
.Fa "int len"
.Fc
.Ft void
.Fo mt_status_tree_sbuf
.Fa "struct sbuf *sb"
.Fa "struct mt_status_entry *entry"
.Fa "int indent"
.Fa "void (*sbuf_func)(struct sbuf *sb, struct mt_status_entry *entry, void *arg)"
.Fa "void *arg"
.Fc
.Ft void
.Fo mt_status_tree_print
.Fa "struct mt_status_entry *entry"
.Fa "int indent"
.Fa "void (*print_func)(struct mt_status_entry *entry, void *arg)"
.Fa "void *arg"
.Fc
.Ft "struct mt_status_entry *"
.Fo mt_entry_find
.Fa "struct mt_status_entry *entry"
.Fa "char *name"
.Fc
.Ft "struct mt_status_entry *"
.Fo mt_status_entry_find
.Fa "struct mt_status_data *status_data"
.Fa "char *name"
.Fc
.Ft void
.Fo mt_status_entry_free
.Fa "struct mt_status_entry *entry)"
.Fc
.Ft void
.Fo mt_status_free
.Fa "struct mt_status_data *status_data"
.Fc
.Ft void
.Fo mt_entry_sbuf
.Fa "struct sbuf *sb"
.Fa "struct mt_status_entry *entry"
.Fa "char *fmt"
.Fc
.Ft void
.Fo mt_param_parent_sbuf
.Fa "struct sbuf *sb"
.Fa "struct mt_status_entry *entry"
.Fa "struct mt_print_params *print_params"
.Fc
.Ft void
.Fo mt_param_parent_print
.Fa "struct mt_status_entry *entry"
.Fa "struct mt_print_params *print_params"
.Fc
.Ft void
.Fo mt_param_entry_sbuf
.Fa "struct sbuf *sb"
.Fa "struct mt_status_entry *entry"
.Fa "void *arg"
.Fc
.Ft void
.Fo mt_param_entry_print
.Fa "struct mt_status_entry *entry"
.Fa "void *arg"
.Fc
.Ft int
.Fo mt_protect_print
.Fa "struct mt_status_data *status_data"
.Fa "int verbose"
.Fc
.Ft int
.Fo mt_param_list
.Fa "struct mt_status_data *status_data"
.Fa "char *param_name"
.Fa "int quiet"
.Fc
.Ft "const char *"
.Fo mt_density_name
.Fa "int density_num"
.Fc
.Ft int
.Fo mt_density_bp
.Fa "int density_num"
.Fa "int bpi"
.Fc
.Ft int
.Fo mt_density_num
.Fa "const char *density_name"
.Fc
.Ft int
.Fo mt_get_status
.Fa "char *xml_str"
.Fa "struct mt_status_data *status_data"
.Fc
.Sh DESCRIPTION
The MT library consists of a number of functions designed to aid in
interacting with the
.Xr sa 4
driver.
The
.Xr sa 4
driver returns some status data as XML-formatted strings, and
the primary purpose of this library is to make it easier for the
software developer to parse those strings and extract the status values.
.Pp
The
.Fn mt_start_element ,
.Fn mt_end_element ,
and
.Fn mt_char_handler
functions are designed to work with the
.Xr libbbsdxml 3
library, which is an XML parsing library.
The user data for the XML parser should be set with
.Fn XML_SetUserData
to a zeroed struct
mt_status_data with the entries list initialized.
The element handlers for the XML parser should be set to
.Fn mt_start_element
and
.Fn mt_end_element
with
.Fn XML_SetElementHandler .
The character data handler should be set to
.Fn mt_char_handler
with the
.Fn XML_SetCharacterDataHandler
function.
The error member of the status_data structure will be set to 0 if parsing
is successful, and non-zero if parsing failed.
In the event of a failure, the error_str member will contain an error
message describing the failure.
These functions will build a tree of tape driver status data that can be
searched and printed using the other functions in this library.
.Pp
.Fn mt_status_tree_sbuf
takes the root node of a tree of
.Xr sa 4
driver status information, and displays it in an
.Xr sbuf 9 .
The
.Ar sb
argument is the destination sbuf.
The
.Ar entry
argument is the root of the tree.
The
.Ar indent
argument is the number of characters to indent the output.
Each recursive call to
.Fn mt_status_tree_sbuf
will have the indent level incremented by 2.
The
.Ar sbuf_func
argument is for a user-supplied alternate printing function.
If it is non-NULL, it will be called instead of the default output printing
code.
The
.Ar arg
argument is an argument for the
.Ar sbuf_func
function.
.Pp
The
.Fn mt_status_tree_print
function is the same as the
.Fn mt_status_tree_sbuf
function, except that the tree is printed to standard out instead of to a
sbuf.
.Pp
The
.Fn mt_entry_find
function returns the first entry in the tree starting at
.Ar entry
that matches
.Ar name .
The supplied node name can be a single level name like "foo", or it can
specify mulitple node names that must be matched, for instance "foo.bar.baz".
In the case of a single level name, it will match any node beneath
.Ar entry
that matches
.Ar name .
In the case of a multi-level name like "foo.bar.baz", it will return the
first entry named "baz" whose immediate parent is "bar" and where the
parent of "bar" is named "foo".
.Pp
The
.Fn mt_status_entry_find
is the same as
.Fn mt_entry_find ,
except that it operates on the top level mt_status_data and all
mt_status_entry nodes below it instead of just an mt_status_entry
structure.
.Pp
The
.Fn mt_status_entry_free
function frees the tree of status data underneath
.Ar entry .
.Pp
The
.Fn mt_status_free
function frees the tree of status data underneath
.Ar status_data .
.Pp
The
.Fn mt_entry_sbuf
function prints
.Ar entry
to the supplied sbuf
.Ar sb ,
optionally using the
.Xr printf 3
format
.Ar fmt .
If
.Ar fmt
is NULL, then
.Fn mt_entry_sbuf
will render integer types in base 10 without special formatting and all
other types as they were rendered in the XML.
.Pp
.Fn mt_param_parent_sbuf
prints the parents of the given
.Ar entry
to the supplied sbuf
.Ar sb
subject to the print parameters
.Ar print_params .
The result will be formatted with a period between each level, like
"foo.bar.baz".
.Pp
.Fn mt_param_parent_print
is like
.Fn mt_param_parent_sbuf
except that it prints the results to standard output instead of an sbuf.
.Pp
.Fn mt_param_entry_sbuf
prints the
.Ar entry
to the given sbuf
.Ar sb .
The argument
.Ar arg
is a pointer to struct mt_print_params, which allows the caller to control
the printing output.
This function is intended to be supplied as an argument to
.Fn mt_status_tree_sbuf .
.Pp
.Fn mt_param_entry_print
is like
.Fn mt_param_entry_sbuf
except that it prints to standard output instead of an sbuf.
It is intended to be used as an argument to
.Fn mt_status_tree_print .
.Pp
.Fn mt_protect_print
prints tape drive protection information from the supplied
.Ar status_data
beginning at the node name defined as the root node for protection data.
If the
.Ar verbose
argument is non-zero, protection entry descriptions will be printed.
If it is zero, protection entry descriptions will not be printed.
.Pp
.Fn mt_param_list
prints tape driver parameters information from the supplied
.Ar status_data .
If the
.Ar param_name
is non-NULL, only the named parameter will be printed.
If
.Ar quiet
is non-zero, parameter descriptions will be omitted in the output.
.Pp
.Fn mt_density_name
Returns a text identifier for the supplied numeric
.Ar density_num .
The
.Ar density_num
should currently be a value between 0 and 255 inclusive, since that is the
valid range for
.Tn SCSI
density code values.
See below for notes on the return values.
.Pp
.Fn mt_density_bp
Returns the bits per inch or bits per mm values for a given density entry
specified by the
.Ar density_num .
If the
.Ar bpi
argument is non-zero, the bits per inch value is returned.
Otherwise, the bits per mm value is returned.
.Pp
.Fn mt_density_num
returns a numeric value for a text density description.
It does a case-insensitive comparison of density names in the density table
to the supplied density name.
.Pp
.Fn mt_get_xml_str
gets the current XML status / parameter string from the sa(4) driver
instance referenced by the open file descriptor
.Ar mtfd .
The
.Xr mtio 4
.Xr ioctl 2
to be used is supplied as the
.Ar cmd
argument.
Currently the
.Fn mt_get_xml_str
function will work with the
.Dv MTIOCEXTGET
and
.Dv MTIOCPARAMGET
ioctls.
The supplied
.Ar xml_str
will be filled in with a pointer to the complete XML status string.
Multiple calls to the given
.Xr ioctl 2
are made and more space is malloced until all of the XML string is fetched.
The string returned in the
.Ar xml_str
argument should be freed when it is no longer in use.
.Sh RETURN VALUES
.Fn mt_entry_find
returns the first matching entry, or NULL if it fails to find a match.
.Pp
.Fn mt_status_entry_find
returns the first matching entry, or NULL if it fails to find a match.
.Pp
.Fn mt_protect_print
Returns 0 for success, and non-zero for failure.
.Fn mt_protect_print
can only fail if it cannot find protection information in the supplied
status data.
.Pp
.Fn mt_param_list
Returns 0 for success and non-zero for failure.
.Fn mt_param_list
can only fail if it cannot find parameter information in the supplied
status data.
.Pp
.Fn mt_density_name
returns a text description of a numeric density.
The special density value 0 is decoded as "default".
The special density value 0x7f is decoded as "same".
If the density is not known,
.Fn mt_density_name
will return "UNKNOWN".
.Pp
.Fn mt_density_bp
returns the bits per inch value for the given density (if the
.Ar bpi
field is non-zero), the bits per mm value otherwise, or 0 if the supplied
.Ar density_num
is not in the density table or the table entry does not include bpi / bpmm
values.
.Pp
.Fn mt_density_num
returns a numeric density value between 0 and 255 for the supplied density
name.
It returns 0 if the density name is not recognized.
.Pp
.Fn mt_get_xml_str
returns 0 for success, and -1 for failure.
.Sh SEE ALSO
.Xr mt 1 ,
.Xr mtio 4 ,
.Xr sa 4
.Sh HISTORY
The MT library first appeared in
.Fx 10.1 .
.Sh AUTHORS
.An Ken Merry Aq ken@FreeBSD.org
.Sh BUGS
The library interface is not complete, and may change in the future.
Application authors should not rely on the library interface to be
consistent in the immediate future.

756
lib/libmt/mtlib.c Normal file
View File

@ -0,0 +1,756 @@
/*-
* Copyright (c) 2013, 2014, 2015 Spectra Logic Corporation
* All rights reserved.
*
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* Authors: Ken Merry (Spectra Logic Corporation)
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/queue.h>
#include <sys/sbuf.h>
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <bsdxml.h>
#include <mtlib.h>
/*
* Called at the start of each XML element, and includes the list of
* attributes for the element.
*/
void
mt_start_element(void *user_data, const char *name, const char **attr)
{
int i;
struct mt_status_data *mtinfo;
struct mt_status_entry *entry;
mtinfo = (struct mt_status_data *)user_data;
if (mtinfo->error != 0)
return;
mtinfo->level++;
if ((u_int)mtinfo->level >= (sizeof(mtinfo->cur_sb) /
sizeof(mtinfo->cur_sb[0]))) {
mtinfo->error = 1;
snprintf(mtinfo->error_str, sizeof(mtinfo->error_str),
"%s: too many nesting levels, %zd max", __func__,
sizeof(mtinfo->cur_sb) / sizeof(mtinfo->cur_sb[0]));
return;
}
mtinfo->cur_sb[mtinfo->level] = sbuf_new_auto();
if (mtinfo->cur_sb[mtinfo->level] == NULL) {
mtinfo->error = 1;
snprintf(mtinfo->error_str, sizeof(mtinfo->error_str),
"%s: Unable to allocate sbuf", __func__);
return;
}
entry = malloc(sizeof(*entry));
if (entry == NULL) {
mtinfo->error = 1;
snprintf(mtinfo->error_str, sizeof(mtinfo->error_str),
"%s: unable to allocate %zd bytes", __func__,
sizeof(*entry));
return;
}
bzero(entry, sizeof(*entry));
STAILQ_INIT(&entry->nv_list);
STAILQ_INIT(&entry->child_entries);
entry->entry_name = strdup(name);
mtinfo->cur_entry[mtinfo->level] = entry;
if (mtinfo->cur_entry[mtinfo->level - 1] == NULL) {
STAILQ_INSERT_TAIL(&mtinfo->entries, entry, links);
} else {
STAILQ_INSERT_TAIL(
&mtinfo->cur_entry[mtinfo->level - 1]->child_entries,
entry, links);
entry->parent = mtinfo->cur_entry[mtinfo->level - 1];
}
for (i = 0; attr[i] != NULL; i+=2) {
struct mt_status_nv *nv;
int need_nv;
need_nv = 0;
if (strcmp(attr[i], "size") == 0) {
entry->size = strtoull(attr[i+1], NULL, 0);
} else if (strcmp(attr[i], "type") == 0) {
if (strcmp(attr[i+1], "int") == 0) {
entry->var_type = MT_TYPE_INT;
} else if (strcmp(attr[i+1], "uint") == 0) {
entry->var_type = MT_TYPE_UINT;
} else if (strcmp(attr[i+1], "str") == 0) {
entry->var_type = MT_TYPE_STRING;
} else if (strcmp(attr[i+1], "node") == 0) {
entry->var_type = MT_TYPE_NODE;
} else {
need_nv = 1;
}
} else if (strcmp(attr[i], "fmt") == 0) {
entry->fmt = strdup(attr[i+1]);
} else if (strcmp(attr[i], "desc") == 0) {
entry->desc = strdup(attr[i+1]);
} else {
need_nv = 1;
}
if (need_nv != 0) {
nv = malloc(sizeof(*nv));
if (nv == NULL) {
mtinfo->error = 1;
snprintf(mtinfo->error_str,
sizeof(mtinfo->error_str),
"%s: error allocating %zd bytes",
__func__, sizeof(*nv));
}
bzero(nv, sizeof(*nv));
nv->name = strdup(attr[i]);
nv->value = strdup(attr[i+1]);
STAILQ_INSERT_TAIL(&entry->nv_list, nv, links);
}
}
}
/*
* Called on XML element close.
*/
void
mt_end_element(void *user_data, const char *name)
{
struct mt_status_data *mtinfo;
char *str;
mtinfo = (struct mt_status_data *)user_data;
if (mtinfo->error != 0)
return;
if (mtinfo->cur_sb[mtinfo->level] == NULL) {
mtinfo->error = 1;
snprintf(mtinfo->error_str, sizeof(mtinfo->error_str),
"%s: no valid sbuf at level %d (name %s)", __func__,
mtinfo->level, name);
return;
}
sbuf_finish(mtinfo->cur_sb[mtinfo->level]);
str = strdup(sbuf_data(mtinfo->cur_sb[mtinfo->level]));
if (str == NULL) {
mtinfo->error = 1;
snprintf(mtinfo->error_str, sizeof(mtinfo->error_str),
"%s can't allocate %zd bytes for string", __func__,
sbuf_len(mtinfo->cur_sb[mtinfo->level]));
return;
}
if (strlen(str) == 0) {
free(str);
str = NULL;
}
if (str != NULL) {
struct mt_status_entry *entry;
entry = mtinfo->cur_entry[mtinfo->level];
switch(entry->var_type) {
case MT_TYPE_INT:
entry->value_signed = strtoll(str, NULL, 0);
break;
case MT_TYPE_UINT:
entry->value_unsigned = strtoull(str, NULL, 0);
break;
default:
break;
}
}
mtinfo->cur_entry[mtinfo->level]->value = str;
sbuf_delete(mtinfo->cur_sb[mtinfo->level]);
mtinfo->cur_sb[mtinfo->level] = NULL;
mtinfo->cur_entry[mtinfo->level] = NULL;
mtinfo->level--;
}
/*
* Called to handle character strings in the current element.
*/
void
mt_char_handler(void *user_data, const XML_Char *str, int len)
{
struct mt_status_data *mtinfo;
mtinfo = (struct mt_status_data *)user_data;
if (mtinfo->error != 0)
return;
sbuf_bcat(mtinfo->cur_sb[mtinfo->level], str, len);
}
void
mt_status_tree_sbuf(struct sbuf *sb, struct mt_status_entry *entry, int indent,
void (*sbuf_func)(struct sbuf *sb, struct mt_status_entry *entry,
void *arg), void *arg)
{
struct mt_status_nv *nv;
struct mt_status_entry *entry2;
if (sbuf_func != NULL) {
sbuf_func(sb, entry, arg);
} else {
sbuf_printf(sb, "%*sname: %s, value: %s, fmt: %s, size: %zd, "
"type: %d, desc: %s\n", indent, "", entry->entry_name,
entry->value, entry->fmt, entry->size, entry->var_type,
entry->desc);
STAILQ_FOREACH(nv, &entry->nv_list, links) {
sbuf_printf(sb, "%*snv: name: %s, value: %s\n",
indent + 1, "", nv->name, nv->value);
}
}
STAILQ_FOREACH(entry2, &entry->child_entries, links)
mt_status_tree_sbuf(sb, entry2, indent + 2, sbuf_func, arg);
}
void
mt_status_tree_print(struct mt_status_entry *entry, int indent,
void (*print_func)(struct mt_status_entry *entry, void *arg), void *arg)
{
if (print_func != NULL) {
struct mt_status_entry *entry2;
print_func(entry, arg);
STAILQ_FOREACH(entry2, &entry->child_entries, links)
mt_status_tree_print(entry2, indent + 2, print_func,
arg);
} else {
struct sbuf *sb;
sb = sbuf_new_auto();
if (sb == NULL)
return;
mt_status_tree_sbuf(sb, entry, indent, NULL, NULL);
sbuf_finish(sb);
printf("%s", sbuf_data(sb));
sbuf_delete(sb);
}
}
/*
* Given a parameter name in the form "foo" or "foo.bar.baz", traverse the
* tree looking for the parameter (the first case) or series of parameters
* (second case).
*/
struct mt_status_entry *
mt_entry_find(struct mt_status_entry *entry, char *name)
{
struct mt_status_entry *entry2;
char *tmpname = NULL, *tmpname2 = NULL, *tmpstr = NULL;
tmpname = strdup(name);
if (tmpname == NULL)
goto bailout;
/* Save a pointer so we can free this later */
tmpname2 = tmpname;
tmpstr = strsep(&tmpname, ".");
/*
* Is this the entry we're looking for? Or do we have further
* child entries that we need to grab?
*/
if (strcmp(entry->entry_name, tmpstr) == 0) {
if (tmpname == NULL) {
/*
* There are no further child entries to find. We
* have a complete match.
*/
free(tmpname2);
return (entry);
} else {
/*
* There are more child entries that we need to find.
* Fall through to the recursive search off of this
* entry, below. Use tmpname, which will contain
* everything after the first period.
*/
name = tmpname;
}
}
/*
* Recursively look for further entries.
*/
STAILQ_FOREACH(entry2, &entry->child_entries, links) {
struct mt_status_entry *entry3;
entry3 = mt_entry_find(entry2, name);
if (entry3 != NULL) {
free(tmpname2);
return (entry3);
}
}
bailout:
free(tmpname2);
return (NULL);
}
struct mt_status_entry *
mt_status_entry_find(struct mt_status_data *status_data, char *name)
{
struct mt_status_entry *entry, *entry2;
STAILQ_FOREACH(entry, &status_data->entries, links) {
entry2 = mt_entry_find(entry, name);
if (entry2 != NULL)
return (entry2);
}
return (NULL);
}
void
mt_status_entry_free(struct mt_status_entry *entry)
{
struct mt_status_entry *entry2, *entry3;
struct mt_status_nv *nv, *nv2;
STAILQ_FOREACH_SAFE(entry2, &entry->child_entries, links, entry3) {
STAILQ_REMOVE(&entry->child_entries, entry2, mt_status_entry,
links);
mt_status_entry_free(entry2);
}
free(entry->entry_name);
free(entry->value);
free(entry->fmt);
free(entry->desc);
STAILQ_FOREACH_SAFE(nv, &entry->nv_list, links, nv2) {
STAILQ_REMOVE(&entry->nv_list, nv, mt_status_nv, links);
free(nv->name);
free(nv->value);
free(nv);
}
free(entry);
}
void
mt_status_free(struct mt_status_data *status_data)
{
struct mt_status_entry *entry, *entry2;
STAILQ_FOREACH_SAFE(entry, &status_data->entries, links, entry2) {
STAILQ_REMOVE(&status_data->entries, entry, mt_status_entry,
links);
mt_status_entry_free(entry);
}
}
void
mt_entry_sbuf(struct sbuf *sb, struct mt_status_entry *entry, char *fmt)
{
switch(entry->var_type) {
case MT_TYPE_INT:
if (fmt != NULL)
sbuf_printf(sb, fmt, (intmax_t)entry->value_signed);
else
sbuf_printf(sb, "%jd",
(intmax_t)entry->value_signed);
break;
case MT_TYPE_UINT:
if (fmt != NULL)
sbuf_printf(sb, fmt, (uintmax_t)entry->value_unsigned);
else
sbuf_printf(sb, "%ju",
(uintmax_t)entry->value_unsigned);
break;
default:
if (fmt != NULL)
sbuf_printf(sb, fmt, entry->value);
else
sbuf_printf(sb, "%s", entry->value);
break;
}
}
void
mt_param_parent_print(struct mt_status_entry *entry,
struct mt_print_params *print_params)
{
if (entry->parent != NULL)
mt_param_parent_print(entry->parent, print_params);
if (((print_params->flags & MT_PF_INCLUDE_ROOT) == 0)
&& (strcmp(entry->entry_name, print_params->root_name) == 0))
return;
printf("%s.", entry->entry_name);
}
void
mt_param_parent_sbuf(struct sbuf *sb, struct mt_status_entry *entry,
struct mt_print_params *print_params)
{
if (entry->parent != NULL)
mt_param_parent_sbuf(sb, entry->parent, print_params);
if (((print_params->flags & MT_PF_INCLUDE_ROOT) == 0)
&& (strcmp(entry->entry_name, print_params->root_name) == 0))
return;
sbuf_printf(sb, "%s.", entry->entry_name);
}
void
mt_param_entry_sbuf(struct sbuf *sb, struct mt_status_entry *entry, void *arg)
{
struct mt_print_params *print_params;
print_params = (struct mt_print_params *)arg;
/*
* We don't want to print nodes.
*/
if (entry->var_type == MT_TYPE_NODE)
return;
if ((print_params->flags & MT_PF_FULL_PATH)
&& (entry->parent != NULL))
mt_param_parent_sbuf(sb, entry->parent, print_params);
sbuf_printf(sb, "%s: %s", entry->entry_name, entry->value);
if ((print_params->flags & MT_PF_VERBOSE)
&& (entry->desc != NULL)
&& (strlen(entry->desc) > 0))
sbuf_printf(sb, " (%s)", entry->desc);
sbuf_printf(sb, "\n");
}
void
mt_param_entry_print(struct mt_status_entry *entry, void *arg)
{
struct mt_print_params *print_params;
print_params = (struct mt_print_params *)arg;
/*
* We don't want to print nodes.
*/
if (entry->var_type == MT_TYPE_NODE)
return;
if ((print_params->flags & MT_PF_FULL_PATH)
&& (entry->parent != NULL))
mt_param_parent_print(entry->parent, print_params);
printf("%s: %s", entry->entry_name, entry->value);
if ((print_params->flags & MT_PF_VERBOSE)
&& (entry->desc != NULL)
&& (strlen(entry->desc) > 0))
printf(" (%s)", entry->desc);
printf("\n");
}
int
mt_protect_print(struct mt_status_data *status_data, int verbose)
{
struct mt_status_entry *entry;
const char *prot_name = MT_PROTECTION_NAME;
struct mt_print_params print_params;
snprintf(print_params.root_name, sizeof(print_params.root_name),
MT_PARAM_ROOT_NAME);
print_params.flags = MT_PF_FULL_PATH;
if (verbose != 0)
print_params.flags |= MT_PF_VERBOSE;
entry = mt_status_entry_find(status_data, __DECONST(char *,prot_name));
if (entry == NULL)
return (1);
mt_status_tree_print(entry, 0, mt_param_entry_print, &print_params);
return (0);
}
int
mt_param_list(struct mt_status_data *status_data, char *param_name, int quiet)
{
struct mt_status_entry *entry;
struct mt_print_params print_params;
char root_name[20];
snprintf(root_name, sizeof(root_name), "mtparamget");
strlcpy(print_params.root_name, root_name,
sizeof(print_params.root_name));
print_params.flags = MT_PF_FULL_PATH;
if (quiet == 0)
print_params.flags |= MT_PF_VERBOSE;
if (param_name != NULL) {
entry = mt_status_entry_find(status_data, param_name);
if (entry == NULL)
return (1);
mt_param_entry_print(entry, &print_params);
return (0);
} else {
entry = mt_status_entry_find(status_data, root_name);
STAILQ_FOREACH(entry, &status_data->entries, links)
mt_status_tree_print(entry, 0, mt_param_entry_print,
&print_params);
}
return (0);
}
static struct densities {
int dens;
int bpmm;
int bpi;
const char *name;
} dens[] = {
/*
* Taken from T10 Project 997D
* SCSI-3 Stream Device Commands (SSC)
* Revision 11, 4-Nov-97
*
* LTO 1-6 definitions obtained from the eighth edition of the
* IBM TotalStorage LTO Ultrium Tape Drive SCSI Reference
* (July 2007) and the second edition of the IBM System Storage LTO
* Tape Drive SCSI Reference (February 13, 2013).
*
* IBM 3592 definitions obtained from second edition of the IBM
* System Storage Tape Drive 3592 SCSI Reference (May 25, 2012).
*/
/*Num. bpmm bpi Reference */
{ 0x1, 32, 800, "X3.22-1983" },
{ 0x2, 63, 1600, "X3.39-1986" },
{ 0x3, 246, 6250, "X3.54-1986" },
{ 0x5, 315, 8000, "X3.136-1986" },
{ 0x6, 126, 3200, "X3.157-1987" },
{ 0x7, 252, 6400, "X3.116-1986" },
{ 0x8, 315, 8000, "X3.158-1987" },
{ 0x9, 491, 37871, "X3.180" },
{ 0xA, 262, 6667, "X3B5/86-199" },
{ 0xB, 63, 1600, "X3.56-1986" },
{ 0xC, 500, 12690, "HI-TC1" },
{ 0xD, 999, 25380, "HI-TC2" },
{ 0xF, 394, 10000, "QIC-120" },
{ 0x10, 394, 10000, "QIC-150" },
{ 0x11, 630, 16000, "QIC-320" },
{ 0x12, 2034, 51667, "QIC-1350" },
{ 0x13, 2400, 61000, "X3B5/88-185A" },
{ 0x14, 1703, 43245, "X3.202-1991" },
{ 0x15, 1789, 45434, "ECMA TC17" },
{ 0x16, 394, 10000, "X3.193-1990" },
{ 0x17, 1673, 42500, "X3B5/91-174" },
{ 0x18, 1673, 42500, "X3B5/92-50" },
{ 0x19, 2460, 62500, "DLTapeIII" },
{ 0x1A, 3214, 81633, "DLTapeIV(20GB)" },
{ 0x1B, 3383, 85937, "DLTapeIV(35GB)" },
{ 0x1C, 1654, 42000, "QIC-385M" },
{ 0x1D, 1512, 38400, "QIC-410M" },
{ 0x1E, 1385, 36000, "QIC-1000C" },
{ 0x1F, 2666, 67733, "QIC-2100C" },
{ 0x20, 2666, 67733, "QIC-6GB(M)" },
{ 0x21, 2666, 67733, "QIC-20GB(C)" },
{ 0x22, 1600, 40640, "QIC-2GB(C)" },
{ 0x23, 2666, 67733, "QIC-875M" },
{ 0x24, 2400, 61000, "DDS-2" },
{ 0x25, 3816, 97000, "DDS-3" },
{ 0x26, 3816, 97000, "DDS-4" },
{ 0x27, 3056, 77611, "Mammoth" },
{ 0x28, 1491, 37871, "X3.224" },
{ 0x40, 4880, 123952, "LTO-1" },
{ 0x41, 3868, 98250, "DLTapeIV(40GB)" },
{ 0x42, 7398, 187909, "LTO-2" },
{ 0x44, 9638, 244805, "LTO-3" },
{ 0x46, 12725, 323215, "LTO-4" },
{ 0x48, 5236, 133000, "SDLTapeI(110)" },
{ 0x49, 7598, 193000, "SDLTapeI(160)" },
{ 0x4a, 0, 0, "T10000A" },
{ 0x4b, 0, 0, "T10000B" },
{ 0x4c, 0, 0, "T10000C" },
{ 0x4d, 0, 0, "T10000D" },
{ 0x51, 11800, 299720, "3592A1 (unencrypted)" },
{ 0x52, 11800, 299720, "3592A2 (unencrypted)" },
{ 0x53, 13452, 341681, "3592A3 (unencrypted)" },
{ 0x54, 19686, 500024, "3592A4 (unencrypted)" },
{ 0x55, 20670, 525018, "3592A5 (unencrypted)" },
{ 0x58, 15142, 384607, "LTO-5" },
{ 0x5A, 15142, 384607, "LTO-6" },
{ 0x71, 11800, 299720, "3592A1 (encrypted)" },
{ 0x72, 11800, 299720, "3592A2 (encrypted)" },
{ 0x73, 13452, 341681, "3592A3 (encrypted)" },
{ 0x74, 19686, 500024, "3592A4 (encrypted)" },
{ 0x75, 20670, 525018, "3592A5 (encrypted)" },
{ 0x8c, 1789, 45434, "EXB-8500c" },
{ 0x90, 1703, 43245, "EXB-8200c" },
{ 0, 0, 0, NULL }
};
const char *
mt_density_name(int density_num)
{
struct densities *sd;
/* densities 0 and 0x7f are handled as special cases */
if (density_num == 0)
return ("default");
if (density_num == 0x7f)
return ("same");
for (sd = dens; sd->dens != 0; sd++)
if (sd->dens == density_num)
break;
if (sd->dens == 0)
return ("UNKNOWN");
return (sd->name);
}
/*
* Given a specific density number, return either the bits per inch or bits
* per millimeter for the given density.
*/
int
mt_density_bp(int density_num, int bpi)
{
struct densities *sd;
for (sd = dens; sd->dens; sd++)
if (sd->dens == density_num)
break;
if (sd->dens == 0)
return (0);
if (bpi)
return (sd->bpi);
else
return (sd->bpmm);
}
int
mt_density_num(const char *density_name)
{
struct densities *sd;
size_t l = strlen(density_name);
for (sd = dens; sd->dens; sd++)
if (strncasecmp(sd->name, density_name, l) == 0)
break;
return (sd->dens);
}
/*
* Get the current status XML string.
* Returns 0 on success, -1 on failure (with errno set, and *xml_str == NULL).
*/
int
mt_get_xml_str(int mtfd, unsigned long cmd, char **xml_str)
{
size_t alloc_len = 32768;
struct mtextget extget;
int error;
*xml_str = NULL;
for (;;) {
bzero(&extget, sizeof(extget));
*xml_str = malloc(alloc_len);
if (*xml_str == NULL)
return (-1);
extget.status_xml = *xml_str;
extget.alloc_len = alloc_len;
error = ioctl(mtfd, cmd, (caddr_t)&extget);
if (error == 0 && extget.status == MT_EXT_GET_OK)
break;
free(*xml_str);
*xml_str = NULL;
if (error != 0 || extget.status != MT_EXT_GET_NEED_MORE_SPACE)
return (-1);
/* The driver needs more space, so double and try again. */
alloc_len *= 2;
}
return (0);
}
/*
* Populate a struct mt_status_data from the XML string via mt_get_xml_str().
*
* Returns XML_STATUS_OK on success.
* If XML_STATUS_ERROR is returned, errno may be set to indicate the reason.
* The caller must check status_data->error.
*/
int
mt_get_status(char *xml_str, struct mt_status_data *status_data)
{
XML_Parser parser;
int retval;
bzero(status_data, sizeof(*status_data));
STAILQ_INIT(&status_data->entries);
parser = XML_ParserCreate(NULL);
if (parser == NULL) {
errno = ENOMEM;
return (XML_STATUS_ERROR);
}
XML_SetUserData(parser, status_data);
XML_SetElementHandler(parser, mt_start_element, mt_end_element);
XML_SetCharacterDataHandler(parser, mt_char_handler);
retval = XML_Parse(parser, xml_str, strlen(xml_str), 1);
XML_ParserFree(parser);
return (retval);
}

122
lib/libmt/mtlib.h Normal file
View File

@ -0,0 +1,122 @@
/*-
* Copyright (c) 2013, 2014 Spectra Logic Corporation
* All rights reserved.
*
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* Authors: Ken Merry (Spectra Logic Corporation)
*
* $FreeBSD$
*/
#ifndef _MTLIB_H
#define _MTLIB_H
typedef enum {
MT_TYPE_NONE,
MT_TYPE_STRING,
MT_TYPE_INT,
MT_TYPE_UINT,
MT_TYPE_NODE
} mt_variable_type;
struct mt_status_nv {
char *name;
char *value;
STAILQ_ENTRY(mt_status_nv) links;
};
struct mt_status_entry {
char *entry_name;
char *value;
uint64_t value_unsigned;
int64_t value_signed;
char *fmt;
char *desc;
size_t size;
mt_variable_type var_type;
struct mt_status_entry *parent;
STAILQ_HEAD(, mt_status_nv) nv_list;
STAILQ_HEAD(, mt_status_entry) child_entries;
STAILQ_ENTRY(mt_status_entry) links;
};
struct mt_status_data {
int level;
struct sbuf *cur_sb[32];
struct mt_status_entry *cur_entry[32];
int error;
char error_str[128];
STAILQ_HEAD(, mt_status_entry) entries;
};
typedef enum {
MT_PF_NONE = 0x00,
MT_PF_VERBOSE = 0x01,
MT_PF_FULL_PATH = 0x02,
MT_PF_INCLUDE_ROOT = 0x04
} mt_print_flags;
struct mt_print_params {
mt_print_flags flags;
char root_name[64];
};
__BEGIN_DECLS
void mt_start_element(void *user_data, const char *name, const char **attr);
void mt_end_element(void *user_data, const char *name);
void mt_char_handler(void *user_data, const XML_Char *str, int len);
void mt_status_tree_sbuf(struct sbuf *sb, struct mt_status_entry *entry,
int indent, void (*sbuf_func)(struct sbuf *sb,
struct mt_status_entry *entry, void *arg), void *arg);
void mt_status_tree_print(struct mt_status_entry *entry, int indent,
void (*print_func)(struct mt_status_entry *entry,
void *arg), void *arg);
struct mt_status_entry *mt_entry_find(struct mt_status_entry *entry,
char *name);
struct mt_status_entry *mt_status_entry_find(struct mt_status_data *status_data,
char *name);
void mt_status_entry_free(struct mt_status_entry *entry);
void mt_status_free(struct mt_status_data *status_data);
void mt_entry_sbuf(struct sbuf *sb, struct mt_status_entry *entry, char *fmt);
void mt_param_parent_print(struct mt_status_entry *entry,
struct mt_print_params *print_params);
void mt_param_parent_sbuf(struct sbuf *sb, struct mt_status_entry *entry,
struct mt_print_params *print_params);
void mt_param_entry_sbuf(struct sbuf *sb, struct mt_status_entry *entry,
void *arg);
void mt_param_entry_print(struct mt_status_entry *entry, void *arg);
int mt_protect_print(struct mt_status_data *status_data, int verbose);
int mt_param_list(struct mt_status_data *status_data, char *param_name,
int quiet);
const char *mt_density_name(int density_num);
int mt_density_bp(int density_num, int bpi);
int mt_density_num(const char *density_name);
int mt_get_xml_str(int mtfd, unsigned long cmd, char **xml_str);
int mt_get_status(char *xml_str, struct mt_status_data *status_data);
__END_DECLS
#endif /* _MTLIB_H */

View File

@ -633,7 +633,7 @@ mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer)
{
struct pthread *curthread = _get_curthread();
uint32_t id;
int defered;
int defered, error;
if (__predict_false(m <= THR_MUTEX_DESTROYED)) {
if (m == THR_MUTEX_DESTROYED)
@ -647,6 +647,7 @@ mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer)
if (__predict_false(m->m_owner != curthread))
return (EPERM);
error = 0;
id = TID(curthread);
if (__predict_false(
PMUTEX_TYPE(m->m_flags) == PTHREAD_MUTEX_RECURSIVE &&
@ -660,7 +661,7 @@ mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer)
defered = 0;
DEQUEUE_MUTEX(curthread, m);
_thr_umutex_unlock2(&m->m_lock, id, mtx_defer);
error = _thr_umutex_unlock2(&m->m_lock, id, mtx_defer);
if (mtx_defer == NULL && defered) {
_thr_wake_all(curthread->defer_waiters,
@ -670,7 +671,7 @@ mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer)
}
if (!cv && m->m_flags & PMUTEX_FLAG_PRIVATE)
THR_CRITICAL_LEAVE(curthread);
return (0);
return (error);
}
int

View File

@ -373,7 +373,7 @@ static const double qS2[6] = {
if(ix>=0x40200000) {p = qR8; q= qS8;}
else if(ix>=0x40122E8B){p = qR5; q= qS5;}
else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
else if(ix>=0x40000000){p = qR2; q= qS2;}
else {p = qR2; q= qS2;} /* ix>=0x40000000 */
z = one/(x*x);
r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));

View File

@ -329,7 +329,7 @@ static const float qS2[6] = {
if(ix>=0x41000000) {p = qR8; q= qS8;}
else if(ix>=0x40f71c58){p = qR5; q= qS5;}
else if(ix>=0x4036db68){p = qR3; q= qS3;}
else if(ix>=0x40000000){p = qR2; q= qS2;}
else {p = qR2; q= qS2;} /* ix>=0x40000000 */
z = one/(x*x);
r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));

View File

@ -368,7 +368,7 @@ static const double qs2[6] = {
if(ix>=0x40200000) {p = qr8; q= qs8;}
else if(ix>=0x40122E8B){p = qr5; q= qs5;}
else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
else if(ix>=0x40000000){p = qr2; q= qs2;}
else {p = qr2; q= qs2;} /* ix>=0x40000000 */
z = one/(x*x);
r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));

View File

@ -325,7 +325,7 @@ static const float qs2[6] = {
if(ix>=0x40200000) {p = qr8; q= qs8;}
else if(ix>=0x40f71c58){p = qr5; q= qs5;}
else if(ix>=0x4036db68){p = qr3; q= qs3;}
else if(ix>=0x40000000){p = qr2; q= qs2;}
else {p = qr2; q= qs2;} /* ix>=0x40000000 */
z = one/(x*x);
r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));

View File

@ -286,7 +286,7 @@ real-release:
${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} obj
${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${RELEASE_TARGETS}
install: release-install vm-install
install: release-install vm-install cloudware-install
release-install:
.if defined(DESTDIR) && !empty(DESTDIR)

View File

@ -20,24 +20,30 @@ CLOUDWARE?= AZURE \
OPENSTACK
AZURE_FORMAT= vhdf
AZURE_DESC= Microsoft Azure platform image
AZURE_DISK= ${OSRELEASE}.${AZURE_FORMAT}
GCE_FORMAT= raw
GCE_DESC= Google Compute Engine image
GCE_DISK= disk.${GCE_FORMAT}
OPENSTACK_FORMAT=qcow2
OPENSTACK_DESC= OpenStack platform image
OPENSTACK_DISK= ${OSRELEASE}.${OPENSTACK_FORMAT}
.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
. for _CW in ${CLOUDWARE}
CLOUDTARGETS+= vm-${_CW:tl}
CLEANDIRS+= vm-${_CW:tl}
CLOUDTARGETS+= cw-${_CW:tl}
CLEANDIRS+= cw-${_CW:tl}
CLEANFILES+= ${_CW:tl}.img \
${_CW:tl}.${${_CW:tu}_FORMAT} \
${_CW:tl}.${${_CW:tu}_FORMAT}.raw
${_CW:tl}.${${_CW:tu}_FORMAT}.raw \
cw${_CW:tl}-package
CLOUDINSTALL+= cw${_CW:tl}-install
CLOUDPACKAGE+= cw${_CW:tl}-package
${_CW:tu}IMAGE= ${_CW:tl}.${${_CW:tu}_FORMAT}
. if exists(${.CURDIR}/tools/${_CW:tl}.conf) && !defined(${_CW:tu}CONF)
${_CW:tu}CONF?= ${.CURDIR}/tools/${_CW:tl}.conf
. endif
vm-${_CW:tl}:
cw-${_CW:tl}:
mkdir -p ${.OBJDIR}/${.TARGET}
env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
${.CURDIR}/scripts/mk-vmimage.sh \
@ -45,6 +51,26 @@ vm-${_CW:tl}:
-i ${.OBJDIR}/${_CW:tl}.img -s ${VMSIZE} -f ${${_CW}_FORMAT} \
-S ${WORLDDIR} -o ${.OBJDIR}/${${_CW}IMAGE} -c ${${_CW}CONF}
touch ${.TARGET}
cw${_CW:tl}-install:
mkdir -p ${DESTDIR}/${_CW:tl}
cp -p ${${_CW}IMAGE} \
${DESTDIR}/${_CW:tl}/${${_CW}_DISK}
cd ${DESTDIR}/${_CW:tl} && sha256 ${${_CW}_DISK}* > \
${DESTDIR}/${_CW:tl}/CHECKSUM.SHA256
cd ${DESTDIR}/${_CW:tl} && md5 ${${_CW}_DISK}* > \
${DESTDIR}/${_CW:tl}/CHECKSUM.MD5
cw${_CW:tl}-package:
@# Special target to handle packaging cloud images in the formats
@# specific to each hosting provider.
.if exists(${.CURDIR}/tools/${_CW:tl}-package.sh)
env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
${.CURDIR}/tools/${_CW:tl}-package.sh \
-D ${DESTDIR} -I ${${_CW}_DISK} -S ${WORLDDIR}
.endif
touch ${.TARGET}
. endfor
.endif
@ -97,8 +123,6 @@ vm-install:
${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT}
. endfor
. if defined(WITH_COMPRESSED_VMIMAGES) && !empty(WITH_COMPRESSED_VMIMAGES)
# This is very time consuming, so defer it after the images are moved to
# the DESTDIR.
. for FORMAT in ${VMFORMATS}
# Don't keep the originals. There is a copy in ${.OBJDIR} if needed.
${XZ_CMD} ${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT}
@ -119,3 +143,8 @@ cloudware-release:
.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDTARGETS}
.endif
cloudware-install:
.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDINSTALL}
.endif

47
release/tools/gce-package.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
#
# $FreeBSD$
#
# Script to handle packaging cloud images for GCE.
#
# XXX:
# This script only exists to help in automating image creation,
# and reimplementing this is intended (in other words, this is
# temporary).
usage() {
echo "Usage:"
echo "$(basename ${0}) -D <destdir> -I <input_file> -S <src_tree>"
exit 1
}
main() {
while getopts "D:I:W:" opt; do
case ${opt} in
D)
DESTDIR="${OPTARG}"
;;
I)
INFILE="${OPTARG}"
;;
S)
WORLDDIR="${OPTARG}"
;;
*)
usage
;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [ -z "${DESTDIR}" -o -z "${INFILE}" -o -z "${WORLDDIR}" ]; then
usage
fi
OUTFILE="$(make -C ${WORLDDIR}/release -V OSRELEASE).tar.gz"
cd ${DESTDIR} && tar --format=gnutar -zcf ${OUTFILE} ${INFILE}
}
main "$@"

View File

@ -131,7 +131,7 @@ CRUNCH_LIBS+= -lgeom -lbsdxml -lkiconv
.if ${MK_OPENSSL} == "no"
CRUNCH_LIBS+= -lmd
.endif
CRUNCH_LIBS+= -lsbuf -lufs -lz
CRUNCH_LIBS+= -lmt -lsbuf -lufs -lz
.if ${MACHINE_CPUARCH} == "i386"
CRUNCH_PROGS_sbin+= bsdlabel sconfig fdisk

View File

@ -31,7 +31,7 @@
.\" @(#)mtio.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd November 11, 2011
.Dd February 12, 2015
.Dt MTIO 4
.Os
.Sh NAME
@ -40,10 +40,10 @@
.Sh DESCRIPTION
The special files
named
.Pa /dev/[n]sa*
.Pa /dev/[en]sa*
refer to SCSI tape drives,
which may be attached to the system.
.Pa /dev/[n]sa*.ctl
.Pa /dev/sa*.ctl
are control devices that can be used to issue ioctls to the SCSI
tape driver to set parameters that are required to last beyond the
unmounting of a tape.
@ -53,16 +53,19 @@ when the last requested read, write or seek has finished, or the end of the tape
has been reached.
The letter
.Ql n
is usually prepended to
is prepended to
the name of the no-rewind devices.
The letter
.Ql e
is prepended to the name of the eject devices.
.Pp
Tapes can be written with either fixed length records or variable length
records.
See
.Xr sa 4
for more information.
Two end-of-file markers mark the end of a tape, and
one end-of-file marker marks the end of a tape file.
Two filemarks mark the end of a tape, and
one filemark marks the end of a tape file.
If the tape is not to be rewound it is positioned with the
head in between the two tape marks, where the next write
will over write the second end-of-file marker.
@ -128,6 +131,8 @@ struct mtop {
#define MTWSS 16 /* write setmark(s) */
#define MTFSS 17 /* forward space setmark */
#define MTBSS 18 /* backward space setmark */
#define MTLOAD 19 /* load tape in drive */
#define MTWEOFI 20 /* write an end-of-file record without waiting*/
#define MT_COMP_ENABLE 0xffffffff
#define MT_COMP_DISABLED 0xfffffffe
@ -224,6 +229,112 @@ union mterrstat {
char _reserved_padding[256];
};
struct mtrblim {
uint32_t granularity;
uint32_t min_block_length;
uint32_t max_block_length;
};
typedef enum {
MT_LOCATE_DEST_OBJECT = 0x00,
MT_LOCATE_DEST_FILE = 0x01,
MT_LOCATE_DEST_SET = 0x02,
MT_LOCATE_DEST_EOD = 0x03
} mt_locate_dest_type;
typedef enum {
MT_LOCATE_BAM_IMPLICIT = 0x00,
MT_LOCATE_BAM_EXPLICIT = 0x01
} mt_locate_bam;
typedef enum {
MT_LOCATE_FLAG_IMMED = 0x01,
MT_LOCATE_FLAG_CHANGE_PART = 0x02
} mt_locate_flags;
struct mtlocate {
mt_locate_flags flags;
mt_locate_dest_type dest_type;
mt_locate_bam block_address_mode;
int64_t partition;
uint64_t logical_id;
uint8_t reserved[64];
};
typedef enum {
MT_EXT_GET_NONE,
MT_EXT_GET_OK,
MT_EXT_GET_NEED_MORE_SPACE,
MT_EXT_GET_ERROR
} mt_ext_get_status;
struct mtextget {
uint32_t alloc_len;
char *status_xml;
uint32_t fill_len;
mt_ext_get_status status;
char error_str[128];
uint8_t reserved[64];
};
#define MT_EXT_GET_ROOT_NAME "mtextget"
#define MT_DENSITY_ROOT_NAME "mtdensity"
#define MT_MEDIA_DENSITY_NAME "media_density"
#define MT_DENSITY_REPORT_NAME "density_report"
#define MT_MEDIUM_TYPE_REPORT_NAME "medium_type_report"
#define MT_MEDIA_REPORT_NAME "media_report"
#define MT_DENSITY_ENTRY_NAME "density_entry"
#define MT_DENS_WRITE_OK 0x80
#define MT_DENS_DUP 0x40
#define MT_DENS_DEFLT 0x20
#define MT_PARAM_FIXED_STR_LEN 32
union mt_param_value {
int64_t value_signed;
uint64_t value_unsigned;
char *value_var_str;
char value_fixed_str[MT_PARAM_FIXED_STR_LEN];
uint8_t reserved[64];
};
typedef enum {
MT_PARAM_SET_NONE,
MT_PARAM_SET_SIGNED,
MT_PARAM_SET_UNSIGNED,
MT_PARAM_SET_VAR_STR,
MT_PARAM_SET_FIXED_STR
} mt_param_set_type;
typedef enum {
MT_PARAM_STATUS_NONE,
MT_PARAM_STATUS_OK,
MT_PARAM_STATUS_ERROR
} mt_param_set_status;
#define MT_PARAM_VALUE_NAME_LEN 64
struct mtparamset {
char value_name[MT_PARAM_VALUE_NAME_LEN];
mt_param_set_type value_type;
int value_len;
union mt_param_value value;
mt_param_set_status status;
char error_str[128];
};
#define MT_PARAM_ROOT_NAME "mtparamget"
#define MT_PROTECTION_NAME "protection"
/*
* Set a list of parameters.
*/
struct mtsetlist {
int num_params;
int param_len;
struct mtparamset *params;
};
/*
* Constants for mt_type byte. These are the same
* for controllers compatible with the types listed.
@ -273,6 +384,12 @@ union mterrstat {
#define MTIOCSETEOTMODEL _IOW('m', 8, uint32_t)
/* Get current EOT model */
#define MTIOCGETEOTMODEL _IOR('m', 8, uint32_t)
#define MTIOCRBLIM _IOR('m', 9, struct mtrblim) /* get block limits */
#define MTIOCEXTLOCATE _IOW('m', 10, struct mtlocate) /* seek to position */
#define MTIOCEXTGET _IOWR('m', 11, struct mtextget) /* get tape status */
#define MTIOCPARAMGET _IOWR('m', 12, struct mtextget) /* get tape params */
#define MTIOCPARAMSET _IOWR('m', 13, struct mtparamset) /* set tape params */
#define MTIOCSETLIST _IOWR('m', 14, struct mtsetlist) /* set N params */
#ifndef _KERNEL
#define DEFTAPE "/dev/nsa0"
@ -281,13 +398,12 @@ union mterrstat {
#endif /* !_SYS_MTIO_H_ */
.Ed
.Sh FILES
.Bl -tag -width /dev/[n]sa* -compact
.It Pa /dev/[n]sa*
.Bl -tag -width /dev/[en]sa* -compact
.It Pa /dev/[en]sa*
.El
.Sh SEE ALSO
.Xr mt 1 ,
.Xr tar 1 ,
.Xr ast 4 ,
.Xr sa 4
.Sh HISTORY
The
@ -296,8 +412,3 @@ manual appeared in
.Bx 4.2 .
An i386 version first appeared in
.Fx 2.2 .
.Sh BUGS
The status should be returned in a device independent format.
.Pp
The special file naming should be redone in a more consistent and
understandable manner.

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 23, 2013
.Dd February 12, 2015
.Dt SA 4
.Os
.Sh NAME
@ -285,10 +285,10 @@ device driver written and ported from
by
.An Julian Elischer .
.Pp
The current owner of record is
.An Matthew Jacob
who has suffered too many
years of breaking tape drivers.
The owner of record for many years was
.An Matthew Jacob .
The current maintainer is
.An Kenneth Merry
.Sh BUGS
This driver lacks many of the hacks required to deal with older devices.
Many older
@ -305,7 +305,5 @@ for your device in order to read tapes written under
.Fx
2.X.
.Pp
Fine grained density and compression mode support that is bound to specific
device names needs to be added.
.Pp
Support for fast indexing by use of partitions is missing.
Partitions are only supported for status information and location.
It would be nice to add support for creating and editing tape partitions.

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 30, 2014
.Dd February 22, 2015
.Dt SFXGE 4
.Os
.Sh NAME
@ -103,7 +103,7 @@ The value must be greater than 0.
The maximum number of non-TCP packets in the deferred packet
.Dq get-list
, used only if the transmit queue lock can be acquired.
If packet is dropped, the
If a packet is dropped, the
.Va tx_get_non_tcp_overflow
counter is incremented and the local sender receives ENOBUFS.
The value must be greater than 0.

View File

@ -591,15 +591,15 @@ This would usually be set to
.It Va weekly_status_security_enable
.Pq Vt bool
Weekly counterpart of
.Va daily_status_securiy_enable .
.Va daily_status_security_enable .
.It Va weekly_status_security_inline
.Pq Vt bool
Weekly counterpart of
.Va daily_status_securiy_inline .
.Va daily_status_security_inline .
.It Va weekly_status_security_output
.Pq Vt str
Weekly counterpart of
.Va daily_status_securiy_output .
.Va daily_status_security_output .
.It Va weekly_status_pkg_enable
.Pq Vt bool
Set to
@ -670,15 +670,15 @@ command.
.It Va monthly_status_security_enable
.Pq Vt bool
Monthly counterpart of
.Va daily_status_securiy_enable .
.Va daily_status_security_enable .
.It Va monthly_status_security_inline
.Pq Vt bool
Monthly counterpart of
.Va daily_status_securiy_inline .
.Va daily_status_security_inline .
.It Va monthly_status_security_output
.Pq Vt str
Monthly counterpart of
.Va daily_status_securiy_output .
.Va daily_status_security_output .
.It Va monthly_local
.Pq Vt str
Set to a list of extra scripts that should be run after all other

View File

@ -85,6 +85,7 @@ LIBMEMSTAT?= ${DESTDIR}${LIBDIR}/libmemstat.a
LIBMENU?= ${DESTDIR}${LIBDIR}/libmenu.a
LIBMILTER?= ${DESTDIR}${LIBDIR}/libmilter.a
LIBMP?= ${DESTDIR}${LIBDIR}/libmp.a
LIBMT?= ${DESTDIR}${LIBDIR}/libmt.a
LIBNCURSES?= ${DESTDIR}${LIBDIR}/libncurses.a
LIBNCURSESW?= ${DESTDIR}${LIBDIR}/libncursesw.a
LIBNETGRAPH?= ${DESTDIR}${LIBDIR}/libnetgraph.a

View File

@ -11,3 +11,13 @@ SRCCONF?= /etc/src.conf
.include "${SRCCONF}"
_srcconf_included_: .NOTMAIN
.endif
# If we were found via .../share/mk we need to replace that in
# with ${.PARSEDIR:tA} so that we can be found by
# sub-makes launched from objdir.
.if ${.MAKEFLAGS:M.../share/mk} != ""
.MAKEFLAGS:= ${.MAKEFLAGS:S,.../share/mk,${.PARSEDIR:tA},}
.endif
.if ${MAKESYSPATH:Uno:M*.../*} != ""
MAKESYSPATH:= ${MAKESYSPATH:S,.../share/mk,${.PARSEDIR:tA},}
.export MAKESYSPATH
.endif

View File

@ -342,18 +342,6 @@ vmcs_init(struct vmcs *vmcs)
*/
VMPTRLD(vmcs);
/* Initialize guest IA32_PAT MSR with the default value */
pat = PAT_VALUE(0, PAT_WRITE_BACK) |
PAT_VALUE(1, PAT_WRITE_THROUGH) |
PAT_VALUE(2, PAT_UNCACHED) |
PAT_VALUE(3, PAT_UNCACHEABLE) |
PAT_VALUE(4, PAT_WRITE_BACK) |
PAT_VALUE(5, PAT_WRITE_THROUGH) |
PAT_VALUE(6, PAT_UNCACHED) |
PAT_VALUE(7, PAT_UNCACHEABLE);
if ((error = vmwrite(VMCS_GUEST_IA32_PAT, pat)) != 0)
goto done;
/* Host state */
/* Initialize host IA32_PAT MSR */

View File

@ -100,13 +100,11 @@ __FBSDID("$FreeBSD$");
(VM_EXIT_HOST_LMA | \
VM_EXIT_SAVE_EFER | \
VM_EXIT_LOAD_EFER | \
VM_EXIT_ACKNOWLEDGE_INTERRUPT | \
VM_EXIT_SAVE_PAT | \
VM_EXIT_LOAD_PAT)
VM_EXIT_ACKNOWLEDGE_INTERRUPT)
#define VM_EXIT_CTLS_ZERO_SETTING VM_EXIT_SAVE_DEBUG_CONTROLS
#define VM_ENTRY_CTLS_ONE_SETTING (VM_ENTRY_LOAD_EFER | VM_ENTRY_LOAD_PAT)
#define VM_ENTRY_CTLS_ONE_SETTING (VM_ENTRY_LOAD_EFER)
#define VM_ENTRY_CTLS_ZERO_SETTING \
(VM_ENTRY_LOAD_DEBUG_CONTROLS | \
@ -859,10 +857,6 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
* VM exit and entry respectively. It is also restored from the
* host VMCS area on a VM exit.
*
* MSR_PAT is saved and restored in the guest VMCS are on a VM exit
* and entry respectively. It is also restored from the host VMCS
* area on a VM exit.
*
* The TSC MSR is exposed read-only. Writes are disallowed as that
* will impact the host TSC.
* XXX Writes would be implemented with a wrmsr trap, and
@ -874,7 +868,6 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
guest_msr_rw(vmx, MSR_SYSENTER_ESP_MSR) ||
guest_msr_rw(vmx, MSR_SYSENTER_EIP_MSR) ||
guest_msr_rw(vmx, MSR_EFER) ||
guest_msr_rw(vmx, MSR_PAT) ||
guest_msr_ro(vmx, MSR_TSC))
panic("vmx_vminit: error setting guest msr access");

View File

@ -103,6 +103,7 @@ enum {
IDX_MSR_STAR,
IDX_MSR_SF_MASK,
IDX_MSR_KGSBASE,
IDX_MSR_PAT,
GUEST_MSR_NUM /* must be the last enumeration */
};

View File

@ -230,6 +230,25 @@ westmere_cpu(void)
return (false);
}
static bool
pat_valid(uint64_t val)
{
int i, pa;
/*
* From Intel SDM: Table "Memory Types That Can Be Encoded With PAT"
*
* Extract PA0 through PA7 and validate that each one encodes a
* valid memory type.
*/
for (i = 0; i < 8; i++) {
pa = (val >> (i * 8)) & 0xff;
if (pa == 2 || pa == 3 || pa >= 8)
return (false);
}
return (true);
}
void
vmx_msr_init(void)
{
@ -302,6 +321,10 @@ vmx_msr_init(void)
void
vmx_msr_guest_init(struct vmx *vmx, int vcpuid)
{
uint64_t *guest_msrs;
guest_msrs = vmx->guest_msrs[vcpuid];
/*
* The permissions bitmap is shared between all vcpus so initialize it
* once when initializing the vBSP.
@ -313,6 +336,19 @@ vmx_msr_guest_init(struct vmx *vmx, int vcpuid)
guest_msr_rw(vmx, MSR_SF_MASK);
guest_msr_rw(vmx, MSR_KGSBASE);
}
/*
* Initialize guest IA32_PAT MSR with default value after reset.
*/
guest_msrs[IDX_MSR_PAT] = PAT_VALUE(0, PAT_WRITE_BACK) |
PAT_VALUE(1, PAT_WRITE_THROUGH) |
PAT_VALUE(2, PAT_UNCACHED) |
PAT_VALUE(3, PAT_UNCACHEABLE) |
PAT_VALUE(4, PAT_WRITE_BACK) |
PAT_VALUE(5, PAT_WRITE_THROUGH) |
PAT_VALUE(6, PAT_UNCACHED) |
PAT_VALUE(7, PAT_UNCACHEABLE);
return;
}
@ -353,7 +389,11 @@ vmx_msr_guest_exit(struct vmx *vmx, int vcpuid)
int
vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
{
int error = 0;
const uint64_t *guest_msrs;
int error;
guest_msrs = vmx->guest_msrs[vcpuid];
error = 0;
switch (num) {
case MSR_IA32_MISC_ENABLE:
@ -366,6 +406,9 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
case MSR_TURBO_RATIO_LIMIT1:
*val = turbo_ratio_limit;
break;
case MSR_PAT:
*val = guest_msrs[IDX_MSR_PAT];
break;
default:
error = EINVAL;
break;
@ -376,10 +419,13 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
int
vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
{
uint64_t *guest_msrs;
uint64_t changed;
int error;
guest_msrs = vmx->guest_msrs[vcpuid];
error = 0;
switch (num) {
case MSR_IA32_MISC_ENABLE:
changed = val ^ misc_enable;
@ -401,6 +447,12 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
error = EINVAL;
break;
case MSR_PAT:
if (pat_valid(val))
guest_msrs[IDX_MSR_PAT] = val;
else
vm_inject_gp(vmx->vm, vcpuid);
break;
default:
error = EINVAL;
break;

View File

@ -72,11 +72,7 @@ __FBSDID("$FreeBSD$");
#endif
ENTRY(armv7_setttb)
stmdb sp!, {r0, lr}
bl _C_LABEL(armv7_idcache_wbinv_all) /* clean the D cache */
ldmia sp!, {r0, lr}
dsb
orr r0, r0, #PT_ATTR
mcr CP15_TTBR0(r0)
isb

View File

@ -205,7 +205,7 @@ gic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
} else {
if (intr[0] == 0)
if (fdt32_to_cpu(intr[0]) == 0)
*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI;
else
*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI;
@ -217,13 +217,13 @@ gic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
* 8 = active low level-sensitive
* The hardware only supports active-high-level or rising-edge.
*/
if (intr[2] & 0x0a) {
if (fdt32_to_cpu(intr[2]) & 0x0a) {
printf("unsupported trigger/polarity configuration "
"0x%2x\n", intr[2] & 0x0f);
"0x%2x\n", fdt32_to_cpu(intr[2]) & 0x0f);
return (ENOTSUP);
}
*pol = INTR_POLARITY_CONFORM;
if (intr[2] & 0x01)
if (fdt32_to_cpu(intr[2]) & 0x01)
*trig = INTR_TRIGGER_EDGE;
else
*trig = INTR_TRIGGER_LEVEL;

View File

@ -47,13 +47,22 @@
ranges = <0x0 0x18000000 0x04000000>;
bus-frequency = <0>;
pic: pic@4000 {
compatible = "netlogic,xlp-pic";
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0x4000 0x200>;
};
serial0: serial@30100 {
compatible = "ns16550";
reg = <0x30100 0x200>;
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <133000000>;
interrupts = <9>;
interrupt-parent = <&pic>;
interrupts = <17>;
};
};

View File

@ -1299,13 +1299,12 @@ fdt_merge_strings(int argc, char *argv[], int start, char **buffer)
sz += argc - start;
buf = (char *)malloc(sizeof(char) * sz);
bzero(buf, sizeof(char) * sz);
if (buf == NULL) {
sprintf(command_errbuf, "could not allocate space "
"for string");
return (1);
}
bzero(buf, sizeof(char) * sz);
idx = 0;
for (i = start, idx = 0; i < argc; i++) {

View File

@ -32,19 +32,63 @@ __FBSDID("$FreeBSD$");
*/
#include <stand.h>
#include <machine/pc/bios.h>
#include "bootstrap.h"
#include "libi386.h"
#include "btxv86.h"
vm_offset_t memtop, memtop_copyin, high_heap_base;
uint32_t bios_basemem, bios_extmem, high_heap_size;
static struct bios_smap smap;
static struct bios_smap_xattr smap;
/*
* Used to track which method was used to set BIOS memory
* regions.
*/
static uint8_t b_bios_probed;
#define B_BASEMEM_E820 0x1
#define B_BASEMEM_12 0x2
#define B_EXTMEM_E820 0x4
#define B_EXTMEM_E801 0x8
#define B_EXTMEM_8800 0x10
/*
* The minimum amount of memory to reserve in bios_extmem for the heap.
*/
#define HEAP_MIN (3 * 1024 * 1024)
/*
* Products in this list need quirks to detect
* memory correctly. You need both maker and product as
* reported by smbios.
*/
#define BQ_DISTRUST_E820_EXTMEM 0x1 /* e820 might not return useful
extended memory */
struct bios_getmem_quirks {
const char* bios_vendor;
const char* maker;
const char* product;
int quirk;
};
static struct bios_getmem_quirks quirks[] = {
{"coreboot", "Acer", "Peppy", BQ_DISTRUST_E820_EXTMEM},
{NULL, NULL, NULL, 0}
};
static int
bios_getquirks(void)
{
int i;
for (i=0; quirks[i].quirk != 0; ++i)
if (smbios_match(quirks[i].bios_vendor, quirks[i].maker,
quirks[i].product))
return (quirks[i].quirk);
return (0);
}
void
bios_getmem(void)
{
@ -56,7 +100,7 @@ bios_getmem(void)
v86.ctl = V86_FLAGS;
v86.addr = 0x15; /* int 0x15 function 0xe820*/
v86.eax = 0xe820;
v86.ecx = sizeof(struct bios_smap);
v86.ecx = sizeof(struct bios_smap_xattr);
v86.edx = SMAP_SIG;
v86.es = VTOPSEG(&smap);
v86.edi = VTOPOFF(&smap);
@ -65,11 +109,16 @@ bios_getmem(void)
break;
/* look for a low-memory segment that's large enough */
if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0) &&
(smap.length >= (512 * 1024)))
(smap.length >= (512 * 1024))) {
bios_basemem = smap.length;
b_bios_probed |= B_BASEMEM_E820;
}
/* look for the first segment in 'extended' memory */
if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) {
if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000) &&
!(bios_getquirks() & BQ_DISTRUST_E820_EXTMEM)) {
bios_extmem = smap.length;
b_bios_probed |= B_EXTMEM_E820;
}
/*
@ -100,6 +149,7 @@ bios_getmem(void)
v86int();
bios_basemem = (v86.eax & 0xffff) * 1024;
b_bios_probed |= B_BASEMEM_12;
}
/* Fall back through several compatibility functions for extended memory */
@ -109,7 +159,30 @@ bios_getmem(void)
v86.eax = 0xe801;
v86int();
if (!(V86_CY(v86.efl))) {
bios_extmem = ((v86.ecx & 0xffff) + ((v86.edx & 0xffff) * 64)) * 1024;
/*
* Clear high_heap; it may end up overlapping
* with the segment we're determining here.
* Let the default "steal stuff from top of
* bios_extmem" code below pick up on it.
*/
high_heap_size = 0;
high_heap_base = 0;
/*
* %cx is the number of 1KiB blocks between 1..16MiB.
* It can only be up to 0x3c00; if it's smaller then
* there's a PC AT memory hole so we can't treat
* it as contiguous.
*/
bios_extmem = (v86.ecx & 0xffff) * 1024;
if (bios_extmem == (1024 * 0x3c00))
bios_extmem += (v86.edx & 0xffff) * 64 * 1024;
/* truncate bios_extmem */
if (bios_extmem > 0x3ff00000)
bios_extmem = 0x3ff00000;
b_bios_probed |= B_EXTMEM_E801;
}
}
if (bios_extmem == 0) {
@ -118,6 +191,7 @@ bios_getmem(void)
v86.eax = 0x8800;
v86int();
bios_extmem = (v86.eax & 0xffff) * 1024;
b_bios_probed |= B_EXTMEM_8800;
}
/* Set memtop to actual top of memory */
@ -132,4 +206,36 @@ bios_getmem(void)
high_heap_size = HEAP_MIN;
high_heap_base = memtop - HEAP_MIN;
}
}
}
static int
command_biosmem(int argc, char *argv[])
{
int bq = bios_getquirks();
printf("bios_basemem: 0x%llx\n", (unsigned long long) bios_basemem);
printf("bios_extmem: 0x%llx\n", (unsigned long long) bios_extmem);
printf("memtop: 0x%llx\n", (unsigned long long) memtop);
printf("high_heap_base: 0x%llx\n", (unsigned long long) high_heap_base);
printf("high_heap_size: 0x%llx\n", (unsigned long long) high_heap_size);
printf("bios_quirks: 0x%02x", bq);
if (bq & BQ_DISTRUST_E820_EXTMEM)
printf(" BQ_DISTRUST_E820_EXTMEM");
printf("\n");
printf("b_bios_probed: 0x%02x", (int) b_bios_probed);
if (b_bios_probed & B_BASEMEM_E820)
printf(" B_BASEMEM_E820");
if (b_bios_probed & B_BASEMEM_12)
printf(" B_BASEMEM_12");
if (b_bios_probed & B_EXTMEM_E820)
printf(" B_EXTMEM_E820");
if (b_bios_probed & B_EXTMEM_E801)
printf(" B_EXTMEM_E801");
if (b_bios_probed & B_EXTMEM_8800)
printf(" B_EXTMEM_8800");
printf("\n");
return (CMD_OK);
}
COMMAND_SET(biosmem, "biosmem", "show BIOS memory setup", command_biosmem);

View File

@ -7442,6 +7442,71 @@ scsi_persistent_reserve_out(struct ccb_scsiio *csio, uint32_t retries,
scsi_cmd->opcode = PERSISTENT_RES_OUT;
scsi_cmd->action = service_action;
scsi_cmd->scope_type = scope | res_type;
cam_fill_csio(csio,
retries,
cbfcnp,
/*flags*/CAM_DIR_OUT,
tag_action,
/*data_ptr*/data_ptr,
/*dxfer_len*/dxfer_len,
sense_len,
sizeof(*scsi_cmd),
timeout);
}
void
scsi_security_protocol_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint32_t security_protocol,
uint32_t security_protocol_specific, int byte4,
uint8_t *data_ptr, uint32_t dxfer_len, int sense_len,
int timeout)
{
struct scsi_security_protocol_in *scsi_cmd;
scsi_cmd = (struct scsi_security_protocol_in *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = SECURITY_PROTOCOL_IN;
scsi_cmd->security_protocol = security_protocol;
scsi_ulto2b(security_protocol_specific,
scsi_cmd->security_protocol_specific);
scsi_cmd->byte4 = byte4;
scsi_ulto4b(dxfer_len, scsi_cmd->length);
cam_fill_csio(csio,
retries,
cbfcnp,
/*flags*/CAM_DIR_IN,
tag_action,
data_ptr,
dxfer_len,
sense_len,
sizeof(*scsi_cmd),
timeout);
}
void
scsi_security_protocol_out(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint32_t security_protocol,
uint32_t security_protocol_specific, int byte4,
uint8_t *data_ptr, uint32_t dxfer_len, int sense_len,
int timeout)
{
struct scsi_security_protocol_out *scsi_cmd;
scsi_cmd = (struct scsi_security_protocol_out *)&csio->cdb_io.cdb_bytes;
bzero(scsi_cmd, sizeof(*scsi_cmd));
scsi_cmd->opcode = SECURITY_PROTOCOL_OUT;
scsi_cmd->security_protocol = security_protocol;
scsi_ulto2b(security_protocol_specific,
scsi_cmd->security_protocol_specific);
scsi_cmd->byte4 = byte4;
scsi_ulto4b(dxfer_len, scsi_cmd->length);
cam_fill_csio(csio,

View File

@ -1758,6 +1758,7 @@ struct ata_pass_16 {
#define SERVICE_ACTION_IN 0x9E
#define REPORT_LUNS 0xA0
#define ATA_PASS_12 0xA1
#define SECURITY_PROTOCOL_IN 0xA2
#define MAINTENANCE_IN 0xA3
#define MAINTENANCE_OUT 0xA4
#define MOVE_MEDIUM 0xA5
@ -1765,6 +1766,7 @@ struct ata_pass_16 {
#define WRITE_12 0xAA
#define WRITE_VERIFY_12 0xAE
#define VERIFY_12 0xAF
#define SECURITY_PROTOCOL_OUT 0xB5
#define READ_ELEMENT_STATUS 0xB8
#define READ_CD 0xBE
@ -2702,6 +2704,41 @@ struct scsi_target_group_data_extended {
struct scsi_target_port_group_descriptor groups[];
};
struct scsi_security_protocol_in
{
uint8_t opcode;
uint8_t security_protocol;
#define SPI_PROT_INFORMATION 0x00
#define SPI_PROT_CBCS 0x07
#define SPI_PROT_TAPE_DATA_ENC 0x20
#define SPI_PROT_DATA_ENC_CONFIG 0x21
#define SPI_PROT_SA_CREATE_CAP 0x40
#define SPI_PROT_IKEV2_SCSI 0x41
#define SPI_PROT_JEDEC_UFS 0xEC
#define SPI_PROT_SDCARD_TFSSS 0xED
#define SPI_PROT_AUTH_HOST_TRANSIENT 0xEE
#define SPI_PROT_ATA_DEVICE_PASSWORD 0xEF
uint8_t security_protocol_specific[2];
uint8_t byte4;
#define SPI_INC_512 0x80
uint8_t reserved1;
uint8_t length[4];
uint8_t reserved2;
uint8_t control;
};
struct scsi_security_protocol_out
{
uint8_t opcode;
uint8_t security_protocol;
uint8_t security_protocol_specific[2];
uint8_t byte4;
#define SPO_INC_512 0x80
uint8_t reserved1;
uint8_t length[4];
uint8_t reserved2;
uint8_t control;
};
typedef enum {
SSD_TYPE_NONE,
@ -3623,6 +3660,20 @@ void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
u_int8_t tag_action, int start, int load_eject,
int immediate, u_int8_t sense_len, u_int32_t timeout);
void scsi_security_protocol_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
uint8_t tag_action, uint32_t security_protocol,
uint32_t security_protocol_specific, int byte4,
uint8_t *data_ptr, uint32_t dxfer_len,
int sense_len, int timeout);
void scsi_security_protocol_out(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *,union ccb *),
uint8_t tag_action, uint32_t security_protocol,
uint32_t security_protocol_specific, int byte4,
uint8_t *data_ptr, uint32_t dxfer_len,
int sense_len, int timeout);
void scsi_persistent_reserve_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *,union ccb *),
uint8_t tag_action, int service_action,

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
* SCSI Sequential Access Peripheral driver for CAM.
*
* Copyright (c) 1999, 2000 Matthew Jacob
* Copyright (c) 2013, 2014, 2015 Spectra Logic Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -141,6 +142,53 @@ struct scsi_erase
u_int8_t control;
};
/*
* Set tape capacity.
*/
struct scsi_set_capacity
{
u_int8_t opcode;
u_int8_t byte1;
#define SA_SSC_IMMED 0x01
u_int8_t reserved;
u_int8_t cap_proportion[2];
u_int8_t control;
};
/*
* Format tape media. The CDB opcode is the same as the disk-specific
* FORMAT UNIT command, but the fields are different inside the CDB. Thus
* the reason for a separate definition here.
*/
struct scsi_format_medium
{
u_int8_t opcode;
u_int8_t byte1;
#define SFM_IMMED 0x01
#define SFM_VERIFY 0x02
u_int8_t byte2;
#define SFM_FORMAT_DEFAULT 0x00
#define SFM_FORMAT_PARTITION 0x01
#define SFM_FORMAT_DEF_PART 0x02
#define SFM_FORMAT_MASK 0x0f
u_int8_t length[2];
u_int8_t control;
};
struct scsi_allow_overwrite
{
u_int8_t opcode;
u_int8_t reserved1;
u_int8_t allow_overwrite;
#define SAO_ALLOW_OVERWRITE_DISABLED 0x00
#define SAO_ALLOW_OVERWRITE_CUR_POS 0x01
#define SAO_ALLOW_OVERWRITE_FORMAT 0x02
u_int8_t partition;
u_int8_t logical_id[8];
u_int8_t reserved2[3];
u_int8_t control;
};
/*
* Dev specific mode page masks.
*/
@ -180,11 +228,18 @@ struct scsi_dev_conf_page {
#define SA_BIS 0x40 /* block identifiers supported */
#define SA_RSMK 0x20 /* report setmarks */
#define SA_AVC 0x10 /* automatic velocity control */
#define SA_SOCF_MASK 0xc0 /* stop on consecutive formats */
#define SA_RBO 0x20 /* recover buffer order */
#define SA_REW 0x10 /* report early warning */
#define SA_SOCF_MASK 0x0c /* stop on consecutive formats */
#define SA_RBO 0x02 /* recover buffer order */
#define SA_REW 0x01 /* report early warning */
u_int8_t gap_size;
u_int8_t byte10;
/* from SCSI-3: SSC-4 Working draft (2/14) 8.3.3 */
#define SA_EOD_DEF_MASK 0xe0 /* EOD defined */
#define SA_EEG 0x10 /* Enable EOD Generation */
#define SA_SEW 0x08 /* Synchronize at Early Warning */
#define SA_SOFT_WP 0x04 /* Software Write Protect */
#define SA_BAML 0x02 /* Block Address Mode Lock */
#define SA_BAM 0x01 /* Block Address Mode */
u_int8_t ew_bufsize[3];
u_int8_t sel_comp_alg;
#define SA_COMP_NONE 0x00
@ -221,10 +276,78 @@ typedef union {
struct scsi_data_compression_page dcomp;
} sa_comp_t;
/*
* Control Data Protection subpage. This is as defined in SSC3r03.
*/
struct scsi_control_data_prot_subpage {
uint8_t page_code;
#define SA_CTRL_DP_PAGE_CODE 0x0a
uint8_t subpage_code;
#define SA_CTRL_DP_SUBPAGE_CODE 0xf0
uint8_t length[2];
uint8_t prot_method;
#define SA_CTRL_DP_NO_LBP 0x00
#define SA_CTRL_DP_REED_SOLOMON 0x01
#define SA_CTRL_DP_METHOD_MAX 0xff
uint8_t pi_length;
#define SA_CTRL_DP_PI_LENGTH_MASK 0x3f
#define SA_CTRL_DP_RS_LENGTH 4
uint8_t prot_bits;
#define SA_CTRL_DP_LBP_W 0x80
#define SA_CTRL_DP_LBP_R 0x40
#define SA_CTRL_DP_RBDP 0x20
uint8_t reserved[];
};
/*
* This is the Read/Write Control mode page used on IBM Enterprise Tape
* Drives. They are known as 3592, TS, or Jaguar drives. The SCSI inquiry
* data will show a Product ID "03592XXX", where XXX is 'J1A', 'E05' (TS1120),
* 'E06' (TS1130), 'E07' (TS1140) or 'E08' (TS1150).
*
* This page definition is current as of the 3592 SCSI Reference v6,
* released on December 16th, 2014.
*/
struct scsi_tape_ibm_rw_control {
uint8_t page_code;
#define SA_IBM_RW_CTRL_PAGE_CODE 0x25
uint8_t page_length;
uint8_t ignore_seq_checks;
#define SA_IBM_RW_CTRL_LOC_IGNORE_SEQ 0x04
#define SA_IBM_RW_CTRL_SPC_BLK_IGNORE_SEQ 0x02
#define SA_IBM_RW_CTRL_SPC_FM_IGNORE_SEQ 0x01
uint8_t ignore_data_checks;
#define SA_IBM_RW_CTRL_LOC_IGNORE_DATA 0x04
#define SA_IBM_RW_CTRL_SPC_BLK_IGNORE_DATA 0x02
#define SA_IBM_RW_CTRL_SPC_FM_IGNORE_DATA 0x01
uint8_t reserved1;
uint8_t leop_method;
#define SA_IBM_RW_CTRL_LEOP_DEFAULT 0x00
#define SA_IBM_RW_CTRL_LEOP_MAX_CAP 0x01
#define SA_IBM_RW_CTRL_LEOP_CONST_CAP 0x02
uint8_t leop_ew[2];
uint8_t byte8;
#define SA_IBM_RW_CTRL_DISABLE_FASTSYNC 0x80
#define SA_IBM_RW_CTRL_DISABLE_SKIPSYNC 0x40
#define SA_IBM_RW_CTRL_DISABLE_CROSS_EOD 0x08
#define SA_IBM_RW_CTRL_DISABLE_CROSS_PERM_ERR 0x04
#define SA_IBM_RW_CTRL_REPORT_SEG_EW 0x02
#define SA_IBM_RW_CTRL_REPORT_HOUSEKEEPING_ERR 0x01
uint8_t default_write_dens_bop_0;
uint8_t pending_write_dens_bop_0;
uint8_t reserved2[21];
};
struct scsi_tape_read_position {
u_int8_t opcode; /* READ_POSITION */
u_int8_t byte1; /* set LSB to read hardware block pos */
u_int8_t reserved[8];
#define SA_RPOS_SHORT_FORM 0x00
#define SA_RPOS_SHORT_VENDOR 0x01
#define SA_RPOS_LONG_FORM 0x06
#define SA_RPOS_EXTENDED_FORM 0x08
u_int8_t reserved[5];
u_int8_t length[2];
u_int8_t control;
};
struct scsi_tape_position_data { /* Short Form */
@ -235,6 +358,7 @@ struct scsi_tape_position_data { /* Short Form */
#define SA_RPOS_BYCU 0x10 /* Byte Count Unknown (SCSI3) */
#define SA_RPOS_BPU 0x04 /* Block Position Unknown */
#define SA_RPOS_PERR 0x02 /* Position Error (SCSI3) */
#define SA_RPOS_BPEW 0x01 /* Beyond Programmable Early Warning */
#define SA_RPOS_UNCERTAIN SA_RPOS_BPU
u_int8_t partition;
u_int8_t reserved[2];
@ -245,6 +369,38 @@ struct scsi_tape_position_data { /* Short Form */
u_int8_t nbufbyte[4];
};
struct scsi_tape_position_long_data {
u_int8_t flags;
#define SA_RPOS_LONG_BOP 0x80 /* Beginning of Partition */
#define SA_RPOS_LONG_EOP 0x40 /* End of Partition */
#define SA_RPOS_LONG_MPU 0x08 /* Mark Position Unknown */
#define SA_RPOS_LONG_LONU 0x04 /* Logical Object Number Unknown */
#define SA_RPOS_LONG_BPEW 0x01 /* Beyond Programmable Early Warning */
u_int8_t reserved[3];
u_int8_t partition[4];
u_int8_t logical_object_num[8];
u_int8_t logical_file_num[8];
u_int8_t set_id[8];
};
struct scsi_tape_position_ext_data {
u_int8_t flags;
#define SA_RPOS_EXT_BOP 0x80 /* Beginning of Partition */
#define SA_RPOS_EXT_EOP 0x40 /* End of Partition */
#define SA_RPOS_EXT_LOCU 0x20 /* Logical Object Count Unknown */
#define SA_RPOS_EXT_BYCU 0x10 /* Byte Count Unknown */
#define SA_RPOS_EXT_LOLU 0x04 /* Logical Object Location Unknown */
#define SA_RPOS_EXT_PERR 0x02 /* Position Error */
#define SA_RPOS_EXT_BPEW 0x01 /* Beyond Programmable Early Warning */
u_int8_t partition;
u_int8_t length[2];
u_int8_t reserved;
u_int8_t num_objects[3];
u_int8_t first_object[8];
u_int8_t last_object[8];
u_int8_t bytes_in_buffer[8];
};
struct scsi_tape_locate {
u_int8_t opcode;
u_int8_t byte1;
@ -253,18 +409,521 @@ struct scsi_tape_locate {
#define SA_SPOS_BT 0x04
u_int8_t reserved1;
u_int8_t blkaddr[4];
#define SA_SPOS_MAX_BLK 0xffffffff
u_int8_t reserved2;
u_int8_t partition;
u_int8_t control;
};
struct scsi_locate_16 {
u_int8_t opcode;
u_int8_t byte1;
#define SA_LC_IMMEDIATE 0x01
#define SA_LC_CP 0x02
#define SA_LC_DEST_TYPE_MASK 0x38
#define SA_LC_DEST_TYPE_SHIFT 3
#define SA_LC_DEST_OBJECT 0x00
#define SA_LC_DEST_FILE 0x01
#define SA_LC_DEST_SET 0x02
#define SA_LC_DEST_EOD 0x03
u_int8_t byte2;
#define SA_LC_BAM_IMPLICIT 0x00
#define SA_LC_BAM_EXPLICIT 0x01
u_int8_t partition;
u_int8_t logical_id[8];
u_int8_t reserved[3];
u_int8_t control;
};
struct scsi_report_density_support {
u_int8_t opcode;
u_int8_t byte1;
#define SRDS_MEDIA 0x01
#define SRDS_MEDIUM_TYPE 0x02
u_int8_t reserved[5];
u_int8_t length[2];
#define SRDS_MAX_LENGTH 0xffff
u_int8_t control;
};
struct scsi_density_hdr {
u_int8_t length[2];
u_int8_t reserved[2];
u_int8_t descriptor[];
};
struct scsi_density_data {
u_int8_t primary_density_code;
u_int8_t secondary_density_code;
u_int8_t byte2;
#define SDD_DLV 0x01
#define SDD_DEFLT 0x20
#define SDD_DUP 0x40
#define SDD_WRTOK 0x80
u_int8_t length[2];
#define SDD_DEFAULT_LENGTH 52
u_int8_t bits_per_mm[3];
u_int8_t media_width[2];
u_int8_t tracks[2];
u_int8_t capacity[4];
u_int8_t assigning_org[8];
u_int8_t density_name[8];
u_int8_t description[20];
};
struct scsi_medium_type_data {
u_int8_t medium_type;
u_int8_t reserved1;
u_int8_t length[2];
#define SMTD_DEFAULT_LENGTH 52
u_int8_t num_density_codes;
u_int8_t primary_density_codes[8];
u_int8_t media_width[2];
u_int8_t medium_length[2];
u_int8_t reserved2[2];
u_int8_t assigning_org[8];
u_int8_t medium_type_name[8];
u_int8_t description[20];
};
/*
* Security Protocol Specific values for the Tape Data Encryption protocol
* (0x20) used with SECURITY PROTOCOL IN. See below for values used with
* SECURITY PROTOCOL OUT. Current as of SSC4r03.
*/
#define TDE_IN_SUPPORT_PAGE 0x0000
#define TDE_OUT_SUPPORT_PAGE 0x0001
#define TDE_DATA_ENC_CAP_PAGE 0x0010
#define TDE_SUPPORTED_KEY_FORMATS_PAGE 0x0011
#define TDE_DATA_ENC_MAN_CAP_PAGE 0x0012
#define TDE_DATA_ENC_STATUS_PAGE 0x0020
#define TDE_NEXT_BLOCK_ENC_STATUS_PAGE 0x0021
#define TDE_GET_ENC_MAN_ATTR_PAGE 0x0022
#define TDE_RANDOM_NUM_PAGE 0x0030
#define TDE_KEY_WRAP_PK_PAGE 0x0031
/*
* Tape Data Encryption protocol pages used with SECURITY PROTOCOL IN and
* SECURITY PROTOCOL OUT.
*/
/*
* Tape Data Encryption In Support page (0x0000).
*/
struct tde_in_support_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t page_codes[];
};
/*
* Tape Data Encryption Out Support page (0x0001).
*/
struct tde_out_support_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t page_codes[];
};
/*
* Logical block encryption algorithm descriptor. This is reported in the
* Data Encryption Capabilities page.
*/
struct tde_block_enc_alg_desc {
uint8_t alg_index;
uint8_t reserved1;
uint8_t desc_length[2];
uint8_t byte4;
#define TDE_BEA_AVFMV 0x80
#define TDE_BEA_SDK_C 0x40
#define TDE_BEA_MAC_C 0x20
#define TDE_BEA_DELB_C 0x10
#define TDE_BEA_DECRYPT_C_MASK 0x0c
#define TDE_BEA_DECRYPT_C_EXT 0x0c
#define TDE_BEA_DECRYPT_C_HARD 0x08
#define TDE_BEA_DECRYPT_C_SOFT 0x04
#define TDE_BEA_DECRYPT_C_NO_CAP 0x00
#define TDE_BEA_ENCRYPT_C_MASK 0x03
#define TDE_BEA_ENCRYPT_C_EXT 0x03
#define TDE_BEA_ENCRYPT_C_HARD 0x02
#define TDE_BEA_ENCRYPT_C_SOFT 0x01
#define TDE_BEA_ENCRYPT_C_NO_CAP 0x00
uint8_t byte5;
#define TDE_BEA_AVFCLP_MASK 0xc0
#define TDE_BEA_AVFCLP_VALID 0x80
#define TDE_BEA_AVFCLP_NOT_VALID 0x40
#define TDE_BEA_AVFCLP_NOT_APP 0x00
#define TDE_BEA_NONCE_C_MASK 0x30
#define TDE_BEA_NONCE_C_SUPPORTED 0x30
#define TDE_BEA_NONCE_C_PROVIDED 0x20
#define TDE_BEA_NONCE_C_GENERATED 0x10
#define TDE_BEA_NONCE_C_NOT_REQUIRED 0x00
#define TDE_BEA_KADF_C 0x08
#define TDE_BEA_VCELB_C 0x04
#define TDE_BEA_UKADF 0x02
#define TDE_BEA_AKADF 0x01
uint8_t max_unauth_key_bytes[2];
uint8_t max_auth_key_bytes[2];
uint8_t lbe_key_size[2];
uint8_t byte12;
#define TDE_BEA_DKAD_C_MASK 0xc0
#define TDE_BEA_DKAD_C_CAPABLE 0xc0
#define TDE_BEA_DKAD_C_NOT_ALLOWED 0x80
#define TDE_BEA_DKAD_C_REQUIRED 0x40
#define TDE_BEA_EEMC_C_MASK 0x30
#define TDE_BEA_EEMC_C_ALLOWED 0x20
#define TDE_BEA_EEMC_C_NOT_ALLOWED 0x10
#define TDE_BEA_EEMC_C_NOT_SPECIFIED 0x00
/*
* Raw Decryption Mode Control Capabilities (RDMC_C) field. The
* descriptions are too complex to represent as a simple name.
*/
#define TDE_BEA_RDMC_C_MASK 0x0e
#define TDE_BEA_RDMC_C_MODE_7 0x0e
#define TDE_BEA_RDMC_C_MODE_6 0x0c
#define TDE_BEA_RDMC_C_MODE_5 0x0a
#define TDE_BEA_RDMC_C_MODE_4 0x08
#define TDE_BEA_RDMC_C_MODE_1 0x02
#define TDE_BEA_EAREM 0x01
uint8_t byte13;
#define TDE_BEA_MAX_EEDKS_MASK 0x0f
uint8_t msdk_count[2];
uint8_t max_eedk_size[2];
uint8_t reserved2[2];
uint8_t security_algo_code[4];
};
/*
* Data Encryption Capabilities page (0x0010).
*/
struct tde_data_enc_cap_page {
uint8_t page_code[2];
uint8_t page_length;
uint8_t byte4;
#define DATA_ENC_CAP_EXTDECC_MASK 0x0c
#define DATA_ENC_CAP_EXTDECC_NOT_REPORTED 0x00
#define DATA_ENC_CAP_EXTDECC_NOT_CAPABLE 0x04
#define DATA_ENC_CAP_EXTDECC_CAPABLE 0x08
#define DATA_ENC_CAP_CFG_P_MASK 0x03
#define DATA_ENC_CAP_CFG_P_NOT_REPORTED 0x00
#define DATA_ENC_CAP_CFG_P_ALLOWED 0x01
#define DATA_ENC_CAP_CFG_P_NOT_ALLOWED 0x02
uint8_t reserved[15];
struct tde_block_enc_alg_desc alg_descs[];
};
/*
* Tape Data Encryption Supported Key Formats page (0x0011).
*/
struct tde_supported_key_formats_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t key_formats_list[];
};
/*
* Tape Data Encryption Management Capabilities page (0x0012).
*/
struct tde_data_enc_man_cap_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t byte4;
#define TDE_DEMC_LOCK_C 0x01
uint8_t byte5;
#define TDE_DEMC_CKOD_C 0x04
#define TDE_DEMC_CKORP_C 0x02
#define TDE_DEMC_CKORL_C 0x01
uint8_t reserved1;
uint8_t byte7;
#define TDE_DEMC_AITN_C 0x04
#define TDE_DEMC_LOCAL_C 0x02
#define TDE_DEMC_PUBLIC_C 0x01
uint8_t reserved2[8];
};
/*
* Tape Data Encryption Status Page (0x0020).
*/
struct tde_data_enc_status_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t scope;
#define TDE_DES_IT_NEXUS_SCOPE_MASK 0xe0
#define TDE_DES_LBE_SCOPE_MASK 0x07
uint8_t encryption_mode;
uint8_t decryption_mode;
uint8_t algo_index;
uint8_t key_instance_counter[4];
uint8_t byte12;
#define TDE_DES_PARAM_CTRL_MASK 0x70
#define TDE_DES_PARAM_CTRL_MGMT 0x40
#define TDE_DES_PARAM_CTRL_CHANGER 0x30
#define TDE_DES_PARAM_CTRL_DRIVE 0x20
#define TDE_DES_PARAM_CTRL_EXT 0x10
#define TDE_DES_PARAM_CTRL_NOT_REPORTED 0x00
#define TDE_DES_VCELB 0x08
#define TDE_DES_CEEMS_MASK 0x06
#define TDE_DES_RDMD 0x01
uint8_t enc_params_kad_format;
uint8_t asdk_count[2];
uint8_t reserved[8];
uint8_t key_assoc_data_desc[];
};
/*
* Tape Data Encryption Next Block Encryption Status page (0x0021).
*/
struct tde_next_block_enc_status_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t logical_obj_number[8];
uint8_t status;
#define TDE_NBES_COMP_STATUS_MASK 0xf0
#define TDE_NBES_COMP_INCAPABLE 0x00
#define TDE_NBES_COMP_NOT_YET 0x10
#define TDE_NBES_COMP_NOT_A_BLOCK 0x20
#define TDE_NBES_COMP_NOT_COMPRESSED 0x30
#define TDE_NBES_COMP_COMPRESSED 0x40
#define TDE_NBES_ENC_STATUS_MASK 0x0f
#define TDE_NBES_ENC_INCAPABLE 0x00
#define TDE_NBES_ENC_NOT_YET 0x01
#define TDE_NBES_ENC_NOT_A_BLOCK 0x02
#define TDE_NBES_ENC_NOT_ENCRYPTED 0x03
#define TDE_NBES_ENC_ALG_NOT_SUPPORTED 0x04
#define TDE_NBES_ENC_SUPPORTED_ALG 0x05
#define TDE_NBES_ENC_NO_KEY 0x06
uint8_t algo_index;
uint8_t byte14;
#define TDE_NBES_EMES 0x02
#define TDE_NBES_RDMDS 0x01
uint8_t next_block_kad_format;
uint8_t key_assoc_data_desc[];
};
/*
* Tape Data Encryption Get Encryption Management Attributes page (0x0022).
*/
struct tde_get_enc_man_attr_page {
uint8_t page_code[2];
uint8_t reserved[3];
uint8_t byte5;
#define TDE_GEMA_CAOD 0x01
uint8_t page_length[2];
uint8_t enc_mgmt_attr_desc[];
};
/*
* Tape Data Encryption Random Number page (0x0030).
*/
struct tde_random_num_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t random_number[32];
};
/*
* Tape Data Encryption Device Server Key Wrapping Public Key page (0x0031).
*/
struct tde_key_wrap_pk_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t public_key_type[4];
uint8_t public_key_format[4];
uint8_t public_key_length[2];
uint8_t public_key[];
};
/*
* Security Protocol Specific values for the Tape Data Encryption protocol
* (0x20) used with SECURITY PROTOCOL OUT. See above for values used with
* SECURITY PROTOCOL IN. Current as of SSCr03.
*/
#define TDE_SET_DATA_ENC_PAGE 0x0010
#define TDE_SA_ENCAP_PAGE 0x0011
#define TDE_SET_ENC_MGMT_ATTR_PAGE 0x0022
/*
* Tape Data Encryption Set Data Encryption page (0x0010).
*/
struct tde_set_data_enc_page {
uint8_t page_code[2];
uint8_t page_length[2];
uint8_t byte4;
#define TDE_SDE_SCOPE_MASK 0xe0
#define TDE_SDE_SCOPE_ALL_IT_NEXUS 0x80
#define TDE_SDE_SCOPE_LOCAL 0x40
#define TDE_SDE_SCOPE_PUBLIC 0x00
#define TDE_SDE_LOCK 0x01
uint8_t byte5;
#define TDE_SDE_CEEM_MASK 0xc0
#define TDE_SDE_CEEM_ENCRYPT 0xc0
#define TDE_SDE_CEEM_EXTERNAL 0x80
#define TDE_SDE_CEEM_NO_CHECK 0x40
#define TDE_SDE_RDMC_MASK 0x30
#define TDE_SDE_RDMC_DISABLED 0x30
#define TDE_SDE_RDMC_ENABLED 0x20
#define TDE_SDE_RDMC_DEFAULT 0x00
#define TDE_SDE_SDK 0x08
#define TDE_SDE_CKOD 0x04
#define TDE_SDE_CKORP 0x02
#define TDE_SDE_CKORL 0x01
uint8_t encryption_mode;
#define TDE_SDE_ENC_MODE_DISABLE 0x00
#define TDE_SDE_ENC_MODE_EXTERNAL 0x01
#define TDE_SDE_ENC_MODE_ENCRYPT 0x02
uint8_t decryption_mode;
#define TDE_SDE_DEC_MODE_DISABLE 0x00
#define TDE_SDE_DEC_MODE_RAW 0x01
#define TDE_SDE_DEC_MODE_DECRYPT 0x02
#define TDE_SDE_DEC_MODE_MIXED 0x03
uint8_t algo_index;
uint8_t lbe_key_format;
#define TDE_SDE_KEY_PLAINTEXT 0x00
#define TDE_SDE_KEY_VENDOR_SPEC 0x01
#define TDE_SDE_KEY_PUBLIC_WRAP 0x02
#define TDE_SDE_KEY_ESP_SCSI 0x03
uint8_t kad_format;
#define TDE_SDE_KAD_ASCII 0x02
#define TDE_SDE_KAD_BINARY 0x01
#define TDE_SDE_KAD_UNSPECIFIED 0x00
uint8_t reserved[7];
uint8_t lbe_key_length[2];
uint8_t lbe_key[];
};
/*
* Used for the Vendor Specific key format (0x01).
*/
struct tde_key_format_vendor {
uint8_t t10_vendor_id[8];
uint8_t vendor_key[];
};
/*
* Used for the public key wrapped format (0x02).
*/
struct tde_key_format_public_wrap {
uint8_t parameter_set[2];
#define TDE_PARAM_SET_RSA2048 0x0000
#define TDE_PARAM_SET_ECC521 0x0010
uint8_t label_length[2];
uint8_t label[];
};
/*
* Tape Data Encryption SA Encapsulation page (0x0011).
*/
struct tde_sa_encap_page {
uint8_t page_code[2];
uint8_t data_desc[];
};
/*
* Tape Data Encryption Set Encryption Management Attributes page (0x0022).
*/
struct tde_set_enc_mgmt_attr_page {
uint8_t page_code[2];
uint8_t reserved[3];
uint8_t byte5;
#define TDE_SEMA_CAOD 0x01
uint8_t page_length[2];
uint8_t attr_desc[];
};
/*
* Tape Data Encryption descriptor format.
* SSC4r03 Section 8.5.4.2.1 Table 197
*/
struct tde_data_enc_desc {
uint8_t key_desc_type;
#define TDE_KEY_DESC_WK_KAD 0x04
#define TDE_KEY_DESC_M_KAD 0x03
#define TDE_KEY_DESC_NONCE_VALUE 0x02
#define TDE_KEY_DESC_A_KAD 0x01
#define TDE_KEY_DESC_U_KAD 0x00
uint8_t byte2;
#define TDE_KEY_DESC_AUTH_MASK 0x07
#define TDE_KEY_DESC_AUTH_FAILED 0x04
#define TDE_KEY_DESC_AUTH_SUCCESS 0x03
#define TDE_KEY_DESC_AUTH_NO_ATTEMPT 0x02
#define TDE_KEY_DESC_AUTH_U_KAD 0x01
uint8_t key_desc_length[2];
uint8_t key_desc[];
};
/*
* Wrapped Key descriptor format.
* SSC4r03 Section 8.5.4.3.1 Table 200
*/
struct tde_wrapped_key_desc {
uint8_t wrapped_key_type;
#define TDE_WRAP_KEY_DESC_LENGTH 0x04
#define TDE_WRAP_KEY_DESC_IDENT 0x03
#define TDE_WRAP_KEY_DESC_INFO 0x02
#define TDE_WRAP_KEY_DESC_ENTITY_ID 0x01
#define TDE_WRAP_KEY_DESC_DEVICE_ID 0x00
uint8_t reserved;
uint8_t wrapped_desc_length[2];
uint8_t wrapped_desc[];
};
/*
* Encryption management attributes descriptor format.
* SSC4r03 Section 8.5.4.4.1 Table 202
*/
struct tde_enc_mgmt_attr_desc {
uint8_t enc_mgmt_attr_type[2];
#define TDE_EMAD_DESIRED_KEY_MGR_OP 0x0000
#define TDE_EMAD_LOG_BLOCK_ENC_KEY_CRIT 0x0001
#define TDE_EMAD_LOG_BLOCK_ENC_KEY_WRAP 0x0002
uint8_t reserved;
uint8_t byte2;
#define TDE_EMAD_CRIT 0x80
uint8_t attr_length[2];
uint8_t attributes[];
#define TDE_EMAD_DESIRED_KEY_CREATE 0x0001
#define TDE_EMAD_DESIRED_KEY_RESOLVE 0x0002
};
/*
* Logical block encryption key selection criteria descriptor format.
* SSC4r03 Section 8.5.4.4.3.1 Table 206
*/
struct tde_lb_enc_key_sel_desc {
uint8_t lbe_key_sel_crit_type[2];
/*
* The CRIT bit is the top bit of the first byte of the type.
*/
#define TDE_LBE_KEY_SEL_CRIT 0x80
#define TDE_LBE_KEY_SEL_ALGO 0x0001
#define TDE_LBE_KEY_SEL_ID 0x0002
uint8_t lbe_key_sel_crit_length[2];
uint8_t lbe_key_sel_crit[];
};
/*
* Logical block encryption key wrapping attribute descriptor format.
* SSC4r03 Section 8.5.4.4.4.1 Table 209
*/
struct tde_lb_enc_key_wrap_desc {
uint8_t lbe_key_wrap_type[2];
/*
* The CRIT bit is the top bit of the first byte of the type.
*/
#define TDE_LBE_KEY_WRAP_CRIT 0x80
#define TDE_LBE_KEY_WRAP_KEKS 0x0001
uint8_t lbe_key_wrap_length[2];
uint8_t lbe_key_wrap_attr[];
};
/*
* Opcodes
*/
#define REWIND 0x01
#define FORMAT_MEDIUM 0x04
#define READ_BLOCK_LIMITS 0x05
#define SA_READ 0x08
#define SA_WRITE 0x0A
#define SET_CAPACITY 0x0B
#define WRITE_FILEMARKS 0x10
#define SPACE 0x11
#define RESERVE_UNIT 0x16
@ -273,6 +932,9 @@ struct scsi_tape_locate {
#define LOAD_UNLOAD 0x1B
#define LOCATE 0x2B
#define READ_POSITION 0x34
#define REPORT_DENSITY_SUPPORT 0x44
#define ALLOW_OVERWRITE 0x82
#define LOCATE_16 0x92
/*
* Tape specific density codes- only enough of them here to recognize
@ -352,11 +1014,55 @@ void scsi_read_position(struct ccb_scsiio *csio, u_int32_t retries,
u_int8_t tag_action, int hardsoft,
struct scsi_tape_position_data *sbp,
u_int8_t sense_len, u_int32_t timeout);
void scsi_read_position_10(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int service_action,
u_int8_t *data_ptr, u_int32_t length,
u_int32_t sense_len, u_int32_t timeout);
void scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int hardsoft, u_int32_t blkno,
u_int8_t sense_len, u_int32_t timeout);
void scsi_locate_10(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immed, int cp, int hard,
int64_t partition, u_int32_t block_address,
int sense_len, u_int32_t timeout);
void scsi_locate_16(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int immed, int cp,
u_int8_t dest_type, int bam, int64_t partition,
u_int64_t logical_id, int sense_len,
u_int32_t timeout);
void scsi_report_density_support(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
union ccb *),
u_int8_t tag_action, int media,
int medium_type, u_int8_t *data_ptr,
u_int32_t length, u_int32_t sense_len,
u_int32_t timeout);
void scsi_set_capacity(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int byte1, u_int32_t proportion,
u_int32_t sense_len, u_int32_t timeout);
void scsi_format_medium(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int byte1, int byte2,
u_int8_t *data_ptr, u_int32_t length,
u_int32_t sense_len, u_int32_t timeout);
void scsi_allow_overwrite(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int allow_overwrite,
int partition, u_int64_t logical_id,
u_int32_t sense_len, u_int32_t timeout);
__END_DECLS
#endif /* _SCSI_SCSI_SA_H */

View File

@ -2161,6 +2161,37 @@ dev/sdhci/sdhci.c optional sdhci
dev/sdhci/sdhci_if.m optional sdhci
dev/sdhci/sdhci_pci.c optional sdhci pci
dev/sf/if_sf.c optional sf pci
dev/sfxge/common/efx_bootcfg.c optional sfxge pci
dev/sfxge/common/efx_ev.c optional sfxge pci
dev/sfxge/common/efx_filter.c optional sfxge pci
dev/sfxge/common/efx_intr.c optional sfxge pci
dev/sfxge/common/efx_mac.c optional sfxge pci
dev/sfxge/common/efx_mcdi.c optional sfxge pci
dev/sfxge/common/efx_mon.c optional sfxge pci
dev/sfxge/common/efx_nic.c optional sfxge pci
dev/sfxge/common/efx_nvram.c optional sfxge pci
dev/sfxge/common/efx_phy.c optional sfxge pci
dev/sfxge/common/efx_port.c optional sfxge pci
dev/sfxge/common/efx_rx.c optional sfxge pci
dev/sfxge/common/efx_sram.c optional sfxge pci
dev/sfxge/common/efx_tx.c optional sfxge pci
dev/sfxge/common/efx_vpd.c optional sfxge pci
dev/sfxge/common/efx_wol.c optional sfxge pci
dev/sfxge/common/siena_mac.c optional sfxge pci
dev/sfxge/common/siena_mon.c optional sfxge pci
dev/sfxge/common/siena_nic.c optional sfxge pci
dev/sfxge/common/siena_nvram.c optional sfxge pci
dev/sfxge/common/siena_phy.c optional sfxge pci
dev/sfxge/common/siena_sram.c optional sfxge pci
dev/sfxge/common/siena_vpd.c optional sfxge pci
dev/sfxge/sfxge.c optional sfxge pci
dev/sfxge/sfxge_dma.c optional sfxge pci
dev/sfxge/sfxge_ev.c optional sfxge pci
dev/sfxge/sfxge_intr.c optional sfxge pci
dev/sfxge/sfxge_mcdi.c optional sfxge pci
dev/sfxge/sfxge_port.c optional sfxge pci
dev/sfxge/sfxge_rx.c optional sfxge pci
dev/sfxge/sfxge_tx.c optional sfxge pci
dev/sge/if_sge.c optional sge pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si

View File

@ -419,7 +419,7 @@
/* Returns FALSE in "defects" per 2^31 - 1 calls, otherwise returns TRUE. */
#define DB_RANDOMFALSE(defects) (random() > defects)
#define DB_OR_RANDOMFALSE(defects) || (random() > defects)
#define DB_AND_RANDOMFALSE(defects) && (random() > ddfects)
#define DB_AND_RANDOMFALSE(defects) && (random() > defects)
/* Returns TRUE in "defects" per 2^31 - 1 calls, otherwise returns FALSE. */
#define DB_RANDOMTRUE(defects) (random() < defects)

View File

@ -1030,6 +1030,7 @@ void t4_update_fl_bufsize(struct ifnet *);
int parse_pkt(struct mbuf **);
void *start_wrq_wr(struct sge_wrq *, int, struct wrq_cookie *);
void commit_wrq_wr(struct sge_wrq *, void *, struct wrq_cookie *);
int tnl_cong(struct port_info *);
/* t4_tracer.c */
struct t4_tracer;

View File

@ -226,9 +226,9 @@ cxgbe_nm_qflush(struct ifnet *ifp)
}
static int
alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq, int cong)
{
int rc, cntxt_id;
int rc, cntxt_id, i;
__be32 v;
struct adapter *sc = pi->adapter;
struct netmap_adapter *na = NA(pi->nm_ifp);
@ -267,6 +267,11 @@ alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
V_FW_IQ_CMD_IQESIZE(ilog2(IQ_ESIZE) - 4));
c.iqsize = htobe16(pi->qsize_rxq);
c.iqaddr = htobe64(nm_rxq->iq_ba);
if (cong >= 0) {
c.iqns_to_fl0congen = htobe32(F_FW_IQ_CMD_IQFLINTCONGEN |
V_FW_IQ_CMD_FL0CNGCHMAP(cong) | F_FW_IQ_CMD_FL0CONGCIF |
F_FW_IQ_CMD_FL0CONGEN);
}
c.iqns_to_fl0congen |=
htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
F_FW_IQ_CMD_FL0FETCHRO | F_FW_IQ_CMD_FL0DATARO |
@ -310,7 +315,36 @@ alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
if (is_t5(sc))
nm_rxq->fl_db_val |= F_DBTYPE;
t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(F_QINTR_CNT_EN) |
if (is_t5(sc) && cong >= 0) {
uint32_t param, val;
param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
V_FW_PARAMS_PARAM_YZ(nm_rxq->iq_cntxt_id);
param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
V_FW_PARAMS_PARAM_YZ(nm_rxq->iq_cntxt_id);
if (cong == 0)
val = 1 << 19;
else {
val = 2 << 19;
for (i = 0; i < 4; i++) {
if (cong & (1 << i))
val |= 1 << (i << 2);
}
}
rc = -t4_set_params(sc, sc->mbox, sc->pf, 0, 1, &param, &val);
if (rc != 0) {
/* report error but carry on */
device_printf(sc->dev,
"failed to set congestion manager context for "
"ingress queue %d: %d\n", nm_rxq->iq_cntxt_id, rc);
}
}
t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
V_SEINTARM(V_QINTR_TIMER_IDX(1)) |
V_INGRESSQID(nm_rxq->iq_cntxt_id));
return (rc);
@ -351,7 +385,8 @@ alloc_nm_txq_hwq(struct port_info *pi, struct sge_nm_txq *nm_txq)
V_FW_EQ_ETH_CMD_VFN(0));
c.alloc_to_len16 = htobe32(F_FW_EQ_ETH_CMD_ALLOC |
F_FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c));
c.autoequiqe_to_viid = htobe32(V_FW_EQ_ETH_CMD_VIID(pi->nm_viid));
c.autoequiqe_to_viid = htobe32(F_FW_EQ_ETH_CMD_AUTOEQUEQE |
V_FW_EQ_ETH_CMD_VIID(pi->nm_viid));
c.fetchszm_to_iqid =
htobe32(V_FW_EQ_ETH_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) |
V_FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | F_FW_EQ_ETH_CMD_FETCHRO |
@ -448,7 +483,7 @@ cxgbe_netmap_on(struct adapter *sc, struct port_info *pi, struct ifnet *ifp,
nm_set_native_flags(na);
for_each_nm_rxq(pi, i, nm_rxq) {
alloc_nm_rxq_hwq(pi, nm_rxq);
alloc_nm_rxq_hwq(pi, nm_rxq, tnl_cong(pi));
nm_rxq->fl_hwidx = hwidx;
slot = netmap_reset(na, NR_RX, i, 0);
MPASS(slot != NULL); /* XXXNM: error check, not assert */
@ -513,12 +548,17 @@ cxgbe_netmap_off(struct adapter *sc, struct port_info *pi, struct ifnet *ifp,
if_printf(ifp, "netmap disable_vi failed: %d\n", rc);
nm_clear_native_flags(na);
/*
* XXXNM: We need to make sure that the tx queues are quiet and won't
* request any more SGE_EGR_UPDATEs.
*/
for_each_nm_txq(pi, i, nm_txq) {
struct sge_qstat *spg = (void *)&nm_txq->desc[nm_txq->sidx];
/* Wait for hw pidx to catch up ... */
while (be16toh(nm_txq->pidx) != spg->pidx)
pause("nmpidx", 1);
/* ... and then for the cidx. */
while (spg->pidx != spg->cidx)
pause("nmcidx", 1);
free_nm_txq_hwq(pi, nm_txq);
}
for_each_nm_rxq(pi, i, nm_rxq) {
@ -641,7 +681,7 @@ int lazy_tx_credit_flush = 1;
*/
static void
cxgbe_nm_tx(struct adapter *sc, struct sge_nm_txq *nm_txq,
struct netmap_kring *kring, int npkt, int npkt_remaining)
struct netmap_kring *kring, int npkt, int npkt_remaining, int txcsum)
{
struct netmap_ring *ring = kring->ring;
struct netmap_slot *slot;
@ -677,10 +717,12 @@ cxgbe_nm_tx(struct adapter *sc, struct sge_nm_txq *nm_txq,
* checksum offloading, TCP segmentation offloading,
* encryption, VLAN encapsulation/decapsulation, etc."
*
* XXXNM: it makes sense to enable checksum offload.
* So the ncxl interfaces have tx hardware checksumming
* disabled by default. But you can override netmap by
* enabling IFCAP_TXCSUM on the interface manully.
*/
cpl->ctrl1 = htobe64(F_TXPKT_IPCSUM_DIS |
F_TXPKT_L4CSUM_DIS);
cpl->ctrl1 = txcsum ? 0 :
htobe64(F_TXPKT_IPCSUM_DIS | F_TXPKT_L4CSUM_DIS);
usgl = (void *)(cpl + 1);
usgl->cmd_nsge = htobe32(V_ULPTX_CMD(ULP_TX_SC_DSGL) |
@ -793,7 +835,7 @@ cxgbe_netmap_txsync(struct netmap_kring *kring, int flags)
struct sge_nm_txq *nm_txq = &sc->sge.nm_txq[pi->first_nm_txq + kring->ring_id];
const u_int head = kring->rhead;
u_int reclaimed = 0;
int n, d, npkt_remaining, ndesc_remaining;
int n, d, npkt_remaining, ndesc_remaining, txcsum;
/*
* Tx was at kring->nr_hwcur last time around and now we need to advance
@ -804,6 +846,7 @@ cxgbe_netmap_txsync(struct netmap_kring *kring, int flags)
npkt_remaining = head >= kring->nr_hwcur ? head - kring->nr_hwcur :
kring->nkr_num_slots - kring->nr_hwcur + head;
txcsum = ifp->if_capenable & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6);
while (npkt_remaining) {
reclaimed += reclaim_nm_tx_desc(nm_txq);
ndesc_remaining = contiguous_ndesc_available(nm_txq);
@ -827,7 +870,7 @@ cxgbe_netmap_txsync(struct netmap_kring *kring, int flags)
/* Send n packets and update nm_txq->pidx and kring->nr_hwcur */
npkt_remaining -= n;
cxgbe_nm_tx(sc, nm_txq, kring, n, npkt_remaining);
cxgbe_nm_tx(sc, nm_txq, kring, n, npkt_remaining, txcsum);
}
MPASS(npkt_remaining == 0);
MPASS(kring->nr_hwcur == head);
@ -1133,6 +1176,7 @@ t4_nm_intr(void *arg)
netmap_rx_irq(ifp, nm_rxq->nid, &processed);
}
t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(n) |
V_INGRESSQID((u32)nm_rxq->iq_cntxt_id) | V_SEINTARM(F_QINTR_CNT_EN));
V_INGRESSQID((u32)nm_rxq->iq_cntxt_id) |
V_SEINTARM(V_QINTR_TIMER_IDX(1)));
}
#endif

View File

@ -2912,7 +2912,7 @@ free_mgmtq(struct adapter *sc)
return free_wrq(sc, &sc->sge.mgmtq);
}
static inline int
int
tnl_cong(struct port_info *pi)
{

View File

@ -2460,6 +2460,9 @@ igb_allocate_msix(struct adapter *adapter)
struct igb_queue *que = adapter->queues;
int error, rid, vector = 0;
int cpu_id = 0;
#ifdef RSS
cpuset_t cpu_mask;
#endif
/* Be sure to start with all interrupts disabled */
E1000_WRITE_REG(&adapter->hw, E1000_IMC, ~0);
@ -2566,8 +2569,9 @@ igb_allocate_msix(struct adapter *adapter)
* round-robin bucket -> queue -> CPU allocation.
*/
#ifdef RSS
taskqueue_start_threads_pinned(&que->tq, 1, PI_NET,
cpu_id,
CPU_SETOF(cpu_id, &cpu_mask);
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
&cpu_mask,
"%s que (bucket %d)",
device_get_nameunit(adapter->dev),
cpu_id);

View File

@ -2373,6 +2373,9 @@ ixgbe_allocate_msix(struct adapter *adapter)
struct tx_ring *txr = adapter->tx_rings;
int error, rid, vector = 0;
int cpu_id = 0;
#ifdef RSS
cpuset_t cpu_mask;
#endif
#ifdef RSS
/*
@ -2460,8 +2463,9 @@ ixgbe_allocate_msix(struct adapter *adapter)
que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT,
taskqueue_thread_enqueue, &que->tq);
#ifdef RSS
taskqueue_start_threads_pinned(&que->tq, 1, PI_NET,
cpu_id,
CPU_SETOF(cpu_id, &cpu_mask);
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
&cpu_mask,
"%s (bucket %d)",
device_get_nameunit(adapter->dev),
cpu_id);

View File

@ -213,6 +213,9 @@ DRIVER_MODULE(ixl, pci, ixl_driver, ixl_devclass, 0, 0);
MODULE_DEPEND(ixl, pci, 1, 1, 1);
MODULE_DEPEND(ixl, ether, 1, 1, 1);
#ifdef DEV_NETMAP
MODULE_DEPEND(ixl, netmap, 1, 1, 1);
#endif /* DEV_NETMAP */
/*
** Global reset mutex
@ -287,6 +290,10 @@ int ixl_atr_rate = 20;
TUNABLE_INT("hw.ixl.atr_rate", &ixl_atr_rate);
#endif
#ifdef DEV_NETMAP
#define NETMAP_IXL_MAIN /* only bring in one part of the netmap code */
#include <dev/netmap/if_ixl_netmap.h>
#endif /* DEV_NETMAP */
static char *ixl_fc_string[6] = {
"None",
@ -647,6 +654,9 @@ ixl_attach(device_t dev)
ixl_unregister_vlan, vsi, EVENTHANDLER_PRI_FIRST);
#ifdef DEV_NETMAP
ixl_netmap_attach(vsi);
#endif /* DEV_NETMAP */
INIT_DEBUGOUT("ixl_attach: end");
return (0);
@ -725,6 +735,9 @@ ixl_detach(device_t dev)
EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach);
callout_drain(&pf->timer);
#ifdef DEV_NETMAP
netmap_detach(vsi->ifp);
#endif /* DEV_NETMAP */
ixl_free_pci_resources(pf);
@ -1867,6 +1880,9 @@ ixl_assign_vsi_msix(struct ixl_pf *pf)
struct ixl_queue *que = vsi->queues;
struct tx_ring *txr;
int error, rid, vector = 0;
#ifdef RSS
cpuset_t cpu_mask;
#endif
/* Admin Que is vector 0*/
rid = vector + 1;
@ -1929,8 +1945,9 @@ ixl_assign_vsi_msix(struct ixl_pf *pf)
que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT,
taskqueue_thread_enqueue, &que->tq);
#ifdef RSS
taskqueue_start_threads_pinned(&que->tq, 1, PI_NET,
cpu_id, "%s (bucket %d)",
CPU_SETOF(cpu_id, &cpu_mask);
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
&cpu_mask, "%s (bucket %d)",
device_get_nameunit(dev), cpu_id);
#else
taskqueue_start_threads(&que->tq, 1, PI_NET,
@ -2662,6 +2679,15 @@ ixl_initialize_vsi(struct ixl_vsi *vsi)
break;
}
wr32(vsi->hw, I40E_QRX_TAIL(que->me), 0);
#ifdef DEV_NETMAP
/* preserve queue */
if (vsi->ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(vsi->ifp);
struct netmap_kring *kring = &na->rx_rings[i];
int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
wr32(vsi->hw, I40E_QRX_TAIL(que->me), t);
} else
#endif /* DEV_NETMAP */
wr32(vsi->hw, I40E_QRX_TAIL(que->me), que->num_desc - 1);
}
return (err);

View File

@ -1382,6 +1382,9 @@ ixlv_assign_msix(struct ixlv_sc *sc)
struct ixl_queue *que = vsi->queues;
struct tx_ring *txr;
int error, rid, vector = 1;
#ifdef RSS
cpuset_t cpu_mask;
#endif
for (int i = 0; i < vsi->num_queues; i++, vector++, que++) {
int cpu_id = i;
@ -1416,8 +1419,9 @@ ixlv_assign_msix(struct ixlv_sc *sc)
que->tq = taskqueue_create_fast("ixlv_que", M_NOWAIT,
taskqueue_thread_enqueue, &que->tq);
#ifdef RSS
taskqueue_start_threads_pinned(&que->tq, 1, PI_NET,
cpu_id, "%s (bucket %d)",
CPU_SETOF(cpu_id, &cpu_mask);
taskqueue_start_threads_cpuset(&que->tq, 1, PI_NET,
&cpu_mask, "%s (bucket %d)",
device_get_nameunit(dev), cpu_id);
#else
taskqueue_start_threads(&que->tq, 1, PI_NET,

View File

@ -62,6 +62,10 @@ static __inline void ixl_rx_discard(struct rx_ring *, int);
static __inline void ixl_rx_input(struct rx_ring *, struct ifnet *,
struct mbuf *, u8);
#ifdef DEV_NETMAP
#include <dev/netmap/if_ixl_netmap.h>
#endif /* DEV_NETMAP */
/*
** Multiqueue Transmit driver
**
@ -486,9 +490,21 @@ ixl_init_tx_ring(struct ixl_queue *que)
{
struct tx_ring *txr = &que->txr;
struct ixl_tx_buf *buf;
#ifdef DEV_NETMAP
struct netmap_adapter *na = NA(que->vsi->ifp);
struct netmap_slot *slot;
#endif /* DEV_NETMAP */
/* Clear the old ring contents */
IXL_TX_LOCK(txr);
#ifdef DEV_NETMAP
/*
* (under lock): if in netmap mode, do some consistency
* checks and set slot to entry 0 of the netmap ring.
*/
slot = netmap_reset(na, NR_TX, que->me, 0);
#endif /* DEV_NETMAP */
bzero((void *)txr->base,
(sizeof(struct i40e_tx_desc)) * que->num_desc);
@ -512,6 +528,19 @@ ixl_init_tx_ring(struct ixl_queue *que)
m_freem(buf->m_head);
buf->m_head = NULL;
}
#ifdef DEV_NETMAP
/*
* In netmap mode, set the map for the packet buffer.
* NOTE: Some drivers (not this one) also need to set
* the physical buffer address in the NIC ring.
* netmap_idx_n2k() maps a nic index, i, into the corresponding
* netmap slot index, si
*/
if (slot) {
int si = netmap_idx_n2k(&na->tx_rings[que->me], i);
netmap_load_map(na, buf->tag, buf->map, NMB(na, slot + si));
}
#endif /* DEV_NETMAP */
/* Clear the EOP index */
buf->eop_index = -1;
}
@ -823,6 +852,11 @@ ixl_txeof(struct ixl_queue *que)
mtx_assert(&txr->mtx, MA_OWNED);
#ifdef DEV_NETMAP
// XXX todo: implement moderation
if (netmap_tx_irq(que->vsi->ifp, que->me))
return FALSE;
#endif /* DEF_NETMAP */
/* These are not the descriptors you seek, move along :) */
if (txr->avail == que->num_desc) {
@ -1124,8 +1158,16 @@ ixl_init_rx_ring(struct ixl_queue *que)
struct ixl_rx_buf *buf;
bus_dma_segment_t pseg[1], hseg[1];
int rsize, nsegs, error = 0;
#ifdef DEV_NETMAP
struct netmap_adapter *na = NA(que->vsi->ifp);
struct netmap_slot *slot;
#endif /* DEV_NETMAP */
IXL_RX_LOCK(rxr);
#ifdef DEV_NETMAP
/* same as in ixl_init_tx_ring() */
slot = netmap_reset(na, NR_RX, que->me, 0);
#endif /* DEV_NETMAP */
/* Clear the ring contents */
rsize = roundup2(que->num_desc *
sizeof(union i40e_rx_desc), DBA_ALIGN);
@ -1159,6 +1201,28 @@ ixl_init_rx_ring(struct ixl_queue *que)
struct mbuf *mh, *mp;
buf = &rxr->buffers[j];
#ifdef DEV_NETMAP
/*
* In netmap mode, fill the map and set the buffer
* address in the NIC ring, considering the offset
* between the netmap and NIC rings (see comment in
* ixgbe_setup_transmit_ring() ). No need to allocate
* an mbuf, so end the block with a continue;
*/
if (slot) {
int sj = netmap_idx_n2k(&na->rx_rings[que->me], j);
uint64_t paddr;
void *addr;
addr = PNMB(na, slot + sj, &paddr);
netmap_load_map(na, rxr->dma.tag, buf->pmap, addr);
/* Update descriptor and the cached value */
rxr->base[j].read.pkt_addr = htole64(paddr);
rxr->base[j].read.hdr_addr = 0;
continue;
}
#endif /* DEV_NETMAP */
/*
** Don't allocate mbufs if not
** doing header split, its wasteful
@ -1458,6 +1522,12 @@ ixl_rxeof(struct ixl_queue *que, int count)
IXL_RX_LOCK(rxr);
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, que->me, &count)) {
IXL_RX_UNLOCK(rxr);
return (FALSE);
}
#endif /* DEV_NETMAP */
for (i = rxr->next_check; count != 0;) {
struct mbuf *sendmp, *mh, *mp;

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_cnfg.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2009-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2009-2012 LSI Corporation.
* Copyright (c) 2009-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_hbd.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2000-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -32,7 +33,8 @@
Fusion-MPT MPI 2.0 Header File Change History
==============================
Copyright (c) 2000-2012 LSI Corporation.
Copyright (c) 2000-2015 LSI Corporation.
Copyright (c) 2013-2015 Avago Technologies
---------------------------------------
Header Set Release Version: 02.00.18

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_init.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_ioc.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2009-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2012 LSI Corporation.
* Copyright (c) 2009-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_ra.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2007-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2007-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_raid.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2007-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2007-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_sas.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_targ.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2007-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2007-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_tool.h

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2006-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2006-2015 LSI Corporation.
* Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_type.h

View File

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -32,7 +33,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* Communications core for LSI MPT2 */
/* Communications core for Avago Technologies (LSI) MPT2 */
/* TODO Move headers to mpsvar */
#include <sys/types.h>
@ -1349,6 +1350,8 @@ mps_get_tunables(struct mps_softc *sc)
sc->disable_msix = 0;
sc->disable_msi = 0;
sc->max_chains = MPS_CHAIN_FRAMES;
sc->enable_ssu = MPS_SSU_ENABLE_SSD_DISABLE_HDD;
sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
/*
* Grab the global variables.
@ -1357,6 +1360,8 @@ mps_get_tunables(struct mps_softc *sc)
TUNABLE_INT_FETCH("hw.mps.disable_msix", &sc->disable_msix);
TUNABLE_INT_FETCH("hw.mps.disable_msi", &sc->disable_msi);
TUNABLE_INT_FETCH("hw.mps.max_chains", &sc->max_chains);
TUNABLE_INT_FETCH("hw.mps.enable_ssu", &sc->enable_ssu);
TUNABLE_INT_FETCH("hw.mps.spinup_wait_time", &sc->spinup_wait_time);
/* Grab the unit-instance variables */
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.debug_level",
@ -1379,6 +1384,14 @@ mps_get_tunables(struct mps_softc *sc)
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.exclude_ids",
device_get_unit(sc->mps_dev));
TUNABLE_STR_FETCH(tmpstr, sc->exclude_ids, sizeof(sc->exclude_ids));
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.enable_ssu",
device_get_unit(sc->mps_dev));
TUNABLE_INT_FETCH(tmpstr, &sc->enable_ssu);
snprintf(tmpstr, sizeof(tmpstr), "dev.mps.%d.spinup_wait_time",
device_get_unit(sc->mps_dev));
TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
}
static void
@ -1451,11 +1464,20 @@ mps_setup_sysctl(struct mps_softc *sc)
OID_AUTO, "max_chains", CTLFLAG_RD,
&sc->max_chains, 0,"maximum chain frames that will be allocated");
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, "enable_ssu", CTLFLAG_RW, &sc->enable_ssu, 0,
"enable SSU to SATA SSD/HDD at shutdown");
#if __FreeBSD_version >= 900030
SYSCTL_ADD_UQUAD(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, "chain_alloc_fail", CTLFLAG_RD,
&sc->chain_alloc_fail, "chain allocation failures");
#endif //FreeBSD_version >= 900030
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
&sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
"spinup after SATA ID error");
}
int

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>

View File

@ -27,12 +27,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD userland interface
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
*
* $FreeBSD$
*/
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -56,7 +57,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>
@ -889,14 +890,14 @@ _mapping_get_dev_info(struct mps_softc *sc,
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
u8 entry, enc_idx, phy_idx;
u8 entry, enc_idx, phy_idx, sata_end_device;
u32 map_idx, index, device_info;
struct _map_phy_change *phy_change, *tmp_phy_change;
uint64_t sas_address;
struct enc_mapping_table *et_entry;
struct dev_mapping_table *mt_entry;
u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED;
int rc;
int rc = 1;
for (entry = 0; entry < topo_change->num_entries; entry++) {
phy_change = &topo_change->phy_details[entry];
@ -910,42 +911,36 @@ _mapping_get_dev_info(struct mps_softc *sc,
continue;
}
/*
* Always get SATA Identify information because this is used
* to determine if Start/Stop Unit should be sent to the drive
* when the system is shutdown.
*/
device_info = le32toh(sas_device_pg0.DeviceInfo);
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
(device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) {
rc = mpssas_get_sas_address_for_sata_disk(sc,
&sas_address, phy_change->dev_handle,
device_info);
if (rc) {
printf("%s: failed to compute the "
"hashed SAS Address for SATA "
"device with handle 0x%04x\n",
__func__, phy_change->dev_handle);
sas_address =
sas_device_pg0.SASAddress.High;
sas_address = (sas_address << 32) |
sas_device_pg0.SASAddress.Low;
}
mps_dprint(sc, MPS_MAPPING,
"SAS Address for SATA device = %jx\n",
sas_address);
sas_address = sas_device_pg0.SASAddress.High;
sas_address = (sas_address << 32) |
sas_device_pg0.SASAddress.Low;
sata_end_device = 0;
if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
(device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) {
sata_end_device = 1;
rc = mpssas_get_sas_address_for_sata_disk(sc,
&sas_address, phy_change->dev_handle, device_info,
&phy_change->is_SATA_SSD);
if (rc) {
mps_dprint(sc, MPS_ERROR, "%s: failed to get "
"disk type (SSD or HDD) and SAS Address "
"for SATA device with handle 0x%04x\n",
__func__, phy_change->dev_handle);
} else {
sas_address =
sas_device_pg0.SASAddress.High;
sas_address = (sas_address << 32) |
sas_device_pg0.SASAddress.Low;
mps_dprint(sc, MPS_INFO, "SAS Address for SATA "
"device = %jx\n", sas_address);
}
} else {
sas_address = sas_device_pg0.SASAddress.High;
sas_address = (sas_address << 32) |
sas_device_pg0.SASAddress.Low;
}
phy_change->physical_id = sas_address;
phy_change->slot = le16toh(sas_device_pg0.Slot);
phy_change->device_info =
le32toh(sas_device_pg0.DeviceInfo);
phy_change->device_info = le32toh(sas_device_pg0.DeviceInfo);
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
@ -953,10 +948,10 @@ _mapping_get_dev_info(struct mps_softc *sc,
topo_change->enc_handle);
if (enc_idx == MPS_ENCTABLE_BAD_IDX) {
phy_change->is_processed = 1;
printf("%s: failed to add the device with "
"handle 0x%04x because the enclosure is "
"not in the mapping table\n", __func__,
phy_change->dev_handle);
mps_dprint(sc, MPS_MAPPING, "%s: failed to add "
"the device with handle 0x%04x because the "
"enclosure is not in the mapping table\n",
__func__, phy_change->dev_handle);
continue;
}
if (!((phy_change->device_info &

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -38,6 +39,7 @@
* @dev_handle: device handle for the device pointed by this entry
* @slot: slot ID
* @is_processed: Flag to indicate whether this entry is processed or not
* @is_SATA_SSD: 1 if this is a SATA device AND an SSD, 0 otherwise
*/
struct _map_phy_change {
uint64_t physical_id;
@ -46,6 +48,8 @@ struct _map_phy_change {
uint16_t slot;
uint8_t reason;
uint8_t is_processed;
uint8_t is_SATA_SSD;
uint8_t reserved;
};
/**
@ -66,6 +70,6 @@ struct _map_topology_change {
extern int
mpssas_get_sas_address_for_sata_disk(struct mps_softc *ioc,
u64 *sas_address, u16 handle, u32 device_info);
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
#endif

View File

@ -27,7 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* PCI/PCI-X/PCIe bus interface for the LSI MPT2 controllers */
/* PCI/PCI-X/PCIe bus interface for the Avago Tech (LSI) MPT2 controllers */
/* TODO Move headers to mpsvar */
#include <sys/types.h>
@ -98,33 +98,33 @@ struct mps_ident {
const char *desc;
} mps_identifiers[] = {
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2004,
0xffff, 0xffff, 0, "LSI SAS2004" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2004" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2008,
0xffff, 0xffff, 0, "LSI SAS2008" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2008" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_1,
0xffff, 0xffff, 0, "LSI SAS2108" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2108" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_2,
0xffff, 0xffff, 0, "LSI SAS2108" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2108" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2108_3,
0xffff, 0xffff, 0, "LSI SAS2108" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2108" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_1,
0xffff, 0xffff, 0, "LSI SAS2116" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2116" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2116_2,
0xffff, 0xffff, 0, "LSI SAS2116" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2116" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_1,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_2,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_3,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_4,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_5,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2208_6,
0xffff, 0xffff, 0, "LSI SAS2208" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2208" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_1,
0xffff, 0xffff, 0, "LSI SAS2308" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2308" },
// Add Customer specific vender/subdevice id before generic
// (0xffff) vender/subdevice id.
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
@ -136,11 +136,11 @@ struct mps_ident {
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
0x8086, 0x3519, 0, "Intel(R) Integrated RAID Module RMS25KB040" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_2,
0xffff, 0xffff, 0, "LSI SAS2308" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2308" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
0xffff, 0xffff, 0, "LSI SAS2308" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS2308" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
0xffff, 0xffff, MPS_FLAGS_WD_AVAILABLE, "LSI SSS6200" },
0xffff, 0xffff, 0, "Avago Technologies (LSI) SSS6200" },
{ 0, 0, 0, 0, 0, NULL }
};

View File

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -32,7 +33,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* Communications core for LSI MPT2 */
/* Communications core for Avago Technologies (LSI) MPT2 */
/* TODO Move headers to mpsvar */
#include <sys/types.h>
@ -119,6 +120,8 @@ static void mpssas_remove_device(struct mps_softc *, struct mps_command *);
static void mpssas_remove_complete(struct mps_softc *, struct mps_command *);
static void mpssas_action(struct cam_sim *sim, union ccb *ccb);
static void mpssas_poll(struct cam_sim *sim);
static int mpssas_send_abort(struct mps_softc *sc, struct mps_command *tm,
struct mps_command *cm);
static void mpssas_scsiio_timeout(void *data);
static void mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm);
static void mpssas_direct_drive_io(struct mpssas_softc *sassc,
@ -133,8 +136,6 @@ static void mpssas_send_smpcmd(struct mpssas_softc *sassc, union ccb *ccb,
static void mpssas_action_smpio(struct mpssas_softc *sassc, union ccb *ccb);
#endif //FreeBSD_version >= 900026
static void mpssas_resetdev_complete(struct mps_softc *, struct mps_command *);
static int mpssas_send_abort(struct mps_softc *sc, struct mps_command *tm, struct mps_command *cm);
static int mpssas_send_reset(struct mps_softc *sc, struct mps_command *tm, uint8_t type);
static void mpssas_async(void *callback_arg, uint32_t code,
struct cam_path *path, void *arg);
#if (__FreeBSD_version < 901503) || \
@ -224,7 +225,7 @@ mpssas_startup_decrement(struct mpssas_softc *sassc)
}
}
/* LSI's firmware requires us to stop sending commands when we're doing task
/* The firmware requires us to stop sending commands when we're doing task
* management, so refcount the TMs and keep the simq frozen when any are in
* use.
*/
@ -233,37 +234,31 @@ mpssas_alloc_tm(struct mps_softc *sc)
{
struct mps_command *tm;
MPS_FUNCTRACE(sc);
tm = mps_alloc_high_priority_command(sc);
if (tm != NULL) {
if (sc->sassc->tm_count++ == 0) {
mps_dprint(sc, MPS_RECOVERY,
"%s freezing simq\n", __func__);
xpt_freeze_simq(sc->sassc->sim, 1);
}
mps_dprint(sc, MPS_RECOVERY, "%s tm_count %u\n", __func__,
sc->sassc->tm_count);
}
return tm;
}
void
mpssas_free_tm(struct mps_softc *sc, struct mps_command *tm)
{
mps_dprint(sc, MPS_TRACE, "%s", __func__);
if (tm == NULL)
return;
/* if there are no TMs in use, we can release the simq. We use our
* own refcount so that it's easier for a diag reset to cleanup and
* release the simq.
/*
* For TM's the devq is frozen for the device. Unfreeze it here and
* free the resources used for freezing the devq. Must clear the
* INRESET flag as well or scsi I/O will not work.
*/
if (--sc->sassc->tm_count == 0) {
mps_dprint(sc, MPS_RECOVERY, "%s releasing simq\n", __func__);
xpt_release_simq(sc->sassc->sim, 1);
if (tm->cm_targ != NULL) {
tm->cm_targ->flags &= ~MPSSAS_TARGET_INRESET;
}
if (tm->cm_ccb) {
mps_dprint(sc, MPS_INFO, "Unfreezing devq for target ID %d\n",
tm->cm_targ->tid);
xpt_release_devq(tm->cm_ccb->ccb_h.path, 1, TRUE);
xpt_free_path(tm->cm_ccb->ccb_h.path);
xpt_free_ccb(tm->cm_ccb);
}
mps_dprint(sc, MPS_RECOVERY, "%s tm_count %u\n", __func__,
sc->sassc->tm_count);
mps_free_high_priority_command(sc, tm);
}
@ -371,7 +366,8 @@ mpssas_remove_volume(struct mps_softc *sc, struct mps_command *tm)
if (reply == NULL) {
/* XXX retry the remove after the diag reset completes? */
mps_dprint(sc, MPS_FAULT,
"%s NULL reply reseting device 0x%04x\n", __func__, handle);
"%s NULL reply resetting device 0x%04x\n", __func__,
handle);
mpssas_free_tm(sc, tm);
return;
}
@ -475,6 +471,11 @@ mpssas_prepare_volume_remove(struct mpssas_softc *sassc, uint16_t handle)
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = mpssas_remove_volume;
cm->cm_complete_data = (void *)(uintptr_t)handle;
mps_dprint(sc, MPS_INFO, "%s: Sending reset for target ID %d\n",
__func__, targ->tid);
mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
mps_map_command(sc, cm);
}
@ -533,6 +534,11 @@ mpssas_prepare_remove(struct mpssas_softc *sassc, uint16_t handle)
cm->cm_desc.HighPriority.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = mpssas_remove_device;
cm->cm_complete_data = (void *)(uintptr_t)handle;
mps_dprint(sc, MPS_INFO, "%s: Sending reset for target ID %d\n",
__func__, targ->tid);
mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
mps_map_command(sc, cm);
}
@ -785,9 +791,6 @@ mps_attach_sas(struct mps_softc *sc)
mpssas_startup_increment(sassc);
callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
sassc->discovery_timeouts = 0;
sassc->tm_count = 0;
/*
* Register for async events so we can determine the EEDP
@ -938,7 +941,7 @@ mpssas_action(struct cam_sim *sim, union ccb *ccb)
cpi->max_lun = 255;
cpi->initiator_id = sassc->maxtargets - 1;
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
strncpy(cpi->hba_vid, "Avago Tech (LSI)", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
cpi->bus_id = cam_sim_bus(sim);
@ -1134,8 +1137,8 @@ mpssas_handle_reinit(struct mps_softc *sc)
mpssas_complete_all_commands(sc);
mps_dprint(sc, MPS_INIT,
"%s startup %u tm %u after command completion\n",
__func__, sc->sassc->startup_refcount, sc->sassc->tm_count);
"%s startup %u after command completion\n", __func__,
sc->sassc->startup_refcount);
/* zero all the target handles, since they may change after the
* reset, and we have to rediscover all the targets and use the new
@ -1198,7 +1201,6 @@ mpssas_logical_unit_reset_complete(struct mps_softc *sc, struct mps_command *tm)
"NULL reset reply for tm %p\n", tm);
if ((sc->mps_flags & MPS_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->flags &= ~MPSSAS_TARGET_INRESET;
targ->tm = NULL;
mpssas_free_tm(sc, tm);
}
@ -1287,7 +1289,6 @@ mpssas_target_reset_complete(struct mps_softc *sc, struct mps_command *tm)
"NULL reset reply for tm %p\n", tm);
if ((sc->mps_flags & MPS_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->flags &= ~MPSSAS_TARGET_INRESET;
targ->tm = NULL;
mpssas_free_tm(sc, tm);
}
@ -1303,8 +1304,6 @@ mpssas_target_reset_complete(struct mps_softc *sc, struct mps_command *tm)
le16toh(reply->IOCStatus), le32toh(reply->ResponseCode),
le32toh(reply->TerminationCount));
targ->flags &= ~MPSSAS_TARGET_INRESET;
if (targ->outstanding == 0) {
/* we've finished recovery for this target and all
* of its logical units.
@ -1332,7 +1331,7 @@ mpssas_target_reset_complete(struct mps_softc *sc, struct mps_command *tm)
#define MPS_RESET_TIMEOUT 30
static int
int
mpssas_send_reset(struct mps_softc *sc, struct mps_command *tm, uint8_t type)
{
MPI2_SCSI_TASK_MANAGE_REQUEST *req;
@ -1358,15 +1357,19 @@ mpssas_send_reset(struct mps_softc *sc, struct mps_command *tm, uint8_t type)
mpssas_log_command(tm, MPS_RECOVERY|MPS_INFO,
"sending logical unit reset\n");
tm->cm_complete = mpssas_logical_unit_reset_complete;
mpssas_prepare_for_tm(sc, tm, target, tm->cm_lun);
}
else if (type == MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
/* Target reset method = SAS Hard Link Reset / SATA Link Reset */
/*
* Target reset method =
* SAS Hard Link Reset / SATA Link Reset
*/
req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
tm->cm_targ->target_resets++;
tm->cm_targ->flags |= MPSSAS_TARGET_INRESET;
mpssas_log_command(tm, MPS_RECOVERY|MPS_INFO,
"sending target reset\n");
tm->cm_complete = mpssas_target_reset_complete;
mpssas_prepare_for_tm(sc, tm, target, CAM_LUN_WILDCARD);
}
else {
mps_dprint(sc, MPS_ERROR, "unexpected reset type 0x%x\n", type);
@ -1513,6 +1516,10 @@ mpssas_send_abort(struct mps_softc *sc, struct mps_command *tm, struct mps_comma
targ->aborts++;
mps_dprint(sc, MPS_INFO, "Sending reset from %s for target ID %d\n",
__func__, targ->tid);
mpssas_prepare_for_tm(sc, tm, targ, tm->cm_lun);
err = mps_map_command(sc, tm);
if (err)
mpssas_log_command(tm, MPS_RECOVERY,
@ -1521,7 +1528,6 @@ mpssas_send_abort(struct mps_softc *sc, struct mps_command *tm, struct mps_comma
return err;
}
static void
mpssas_scsiio_timeout(void *data)
{
@ -1667,6 +1673,19 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
return;
}
/*
* If target has a reset in progress, freeze the devq and return. The
* devq will be released when the TM reset is finished.
*/
if (targ->flags & MPSSAS_TARGET_INRESET) {
ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN;
mps_dprint(sc, MPS_INFO, "%s: Freezing devq for target ID %d\n",
__func__, targ->tid);
xpt_freeze_devq(ccb->ccb_h.path, 1);
xpt_done(ccb);
return;
}
cm = mps_alloc_command(sc);
if (cm == NULL || (sc->mps_flags & MPS_FLAGS_DIAGRESET)) {
if (cm != NULL) {
@ -2056,6 +2075,8 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
u8 *TLR_bits, TLR_on;
int dir = 0, i;
u16 alloc_len;
struct mpssas_target *target;
target_id_t target_id;
MPS_FUNCTRACE(sc);
mps_dprint(sc, MPS_TRACE,
@ -2069,6 +2090,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
sassc = sc->sassc;
ccb = cm->cm_complete_data;
csio = &ccb->csio;
target_id = csio->ccb_h.target_id;
rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply;
/*
* XXX KDM if the chain allocation fails, does it matter if we do
@ -2250,9 +2272,10 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
* TLR_bits for the target.
*/
if ((rep->SCSIState & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) &&
((le32toh(rep->ResponseInfo) & MPI2_SCSI_RI_MASK_REASONCODE) ==
((le32toh(rep->ResponseInfo) &
MPI2_SCSI_RI_MASK_REASONCODE) ==
MPS_SCSI_RI_INVALID_FRAME)) {
sc->mapping_table[csio->ccb_h.target_id].TLR_bits =
sc->mapping_table[target_id].TLR_bits =
(u8)MPI2_SCSIIO_CONTROL_NO_TLR;
}
@ -2309,12 +2332,11 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
(csio->data_ptr != NULL) &&
((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) &&
(sc->control_TLR) &&
(sc->mapping_table[csio->ccb_h.target_id].device_info &
(sc->mapping_table[target_id].device_info &
MPI2_SAS_DEVICE_INFO_SSP_TARGET)) {
vpd_list = (struct scsi_vpd_supported_page_list *)
csio->data_ptr;
TLR_bits = &sc->mapping_table[csio->ccb_h.target_id].
TLR_bits;
TLR_bits = &sc->mapping_table[target_id].TLR_bits;
*TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR;
TLR_on = (u8)MPI2_SCSIIO_CONTROL_TLR_ON;
alloc_len = ((u16)csio->cdb_io.cdb_bytes[3] << 8) +
@ -2327,6 +2349,24 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
}
}
}
/*
* If this is a SATA direct-access end device, mark it so that
* a SCSI StartStopUnit command will be sent to it when the
* driver is being shutdown.
*/
if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) &&
((csio->data_ptr[0] & 0x1f) == T_DIRECT) &&
(sc->mapping_table[target_id].device_info &
MPI2_SAS_DEVICE_INFO_SATA_DEVICE) &&
((sc->mapping_table[target_id].device_info &
MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_END_DEVICE)) {
target = &sassc->targets[target_id];
target->supports_SSU = TRUE;
mps_dprint(sc, MPS_XINFO, "Target %d supports SSU\n",
target_id);
}
break;
case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
@ -3098,6 +3138,8 @@ mpssas_action_resetdev(struct mpssas_softc *sassc, union ccb *ccb)
tm->cm_complete = mpssas_resetdev_complete;
tm->cm_complete_data = ccb;
tm->cm_targ = targ;
targ->flags |= MPSSAS_TARGET_INRESET;
mps_map_command(sc, tm);
}
@ -3370,9 +3412,9 @@ mpssas_check_eedp(struct mps_softc *sc, struct cam_path *path,
* shutdown.
*/
if ((cgd.inq_data.device == T_DIRECT) &&
(target->devinfo & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) &&
((target->devinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_END_DEVICE)) {
(target->devinfo & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) &&
((target->devinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
MPI2_SAS_DEVICE_INFO_END_DEVICE)) {
lun->stop_at_shutdown = TRUE;
}
@ -3489,6 +3531,34 @@ mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
#endif /* (__FreeBSD_version < 901503) || \
((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) */
void
mpssas_prepare_for_tm(struct mps_softc *sc, struct mps_command *tm,
struct mpssas_target *target, lun_id_t lun_id)
{
union ccb *ccb;
path_id_t path_id;
/*
* Set the INRESET flag for this target so that no I/O will be sent to
* the target until the reset has completed. If an I/O request does
* happen, the devq will be frozen. The CCB holds the path which is
* used to release the devq. The devq is released and the CCB is freed
* when the TM completes.
*/
ccb = xpt_alloc_ccb_nowait();
if (ccb) {
path_id = cam_sim_path(sc->sassc->sim);
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, path_id,
target->tid, lun_id) != CAM_REQ_CMP) {
xpt_free_ccb(ccb);
} else {
tm->cm_ccb = ccb;
tm->cm_targ = target;
target->flags |= MPSSAS_TARGET_INRESET;
}
}
}
int
mpssas_startup(struct mps_softc *sc)
{

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -35,7 +36,6 @@ struct mpssas_lun {
lun_id_t lun_id;
uint8_t eedp_formatted;
uint32_t eedp_block_size;
uint8_t stop_at_shutdown;
};
struct mpssas_target {
@ -52,11 +52,10 @@ struct mpssas_target {
#define MPSSAS_TARGET_INREMOVAL (1 << 3)
#define MPS_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
#define MPS_TARGET_FLAGS_VOLUME (1 << 5)
#define MPS_TARGET_IS_SATA_SSD (1 << 6)
#define MPSSAS_TARGET_INRECOVERY (MPSSAS_TARGET_INABORT | \
MPSSAS_TARGET_INRESET | MPSSAS_TARGET_INCHIPRESET)
#define MPSSAS_TARGET_ADD (1 << 29)
#define MPSSAS_TARGET_REMOVE (1 << 30)
uint16_t tid;
SLIST_HEAD(, mpssas_lun) luns;
TAILQ_HEAD(, mps_command) commands;
@ -78,6 +77,8 @@ struct mpssas_target {
unsigned int aborts;
unsigned int logical_unit_resets;
unsigned int target_resets;
uint8_t stop_at_shutdown;
uint8_t supports_SSU;
};
struct mpssas_softc {
@ -95,11 +96,9 @@ struct mpssas_softc {
struct cam_path *path;
struct intr_config_hook sas_ich;
struct callout discovery_callout;
u_int discovery_timeouts;
struct mps_event_handle *mpssas_eh;
u_int startup_refcount;
u_int tm_count;
struct proc *sysctl_proc;
struct taskqueue *ev_tq;
@ -167,6 +166,8 @@ do { \
void mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ);
void mpssas_discovery_end(struct mpssas_softc *sassc);
void mpssas_prepare_for_tm(struct mps_softc *sc, struct mps_command *tm,
struct mpssas_target *target, lun_id_t lun_id);
void mpssas_startup_increment(struct mpssas_softc *sassc);
void mpssas_startup_decrement(struct mpssas_softc *sassc);

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -23,13 +24,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* Communications core for LSI MPT2 */
/* Communications core for Avago Technologies (LSI) MPT2 */
/* TODO Move headers to mpsvar */
#include <sys/types.h>
@ -105,7 +106,9 @@ struct _ata_identify_device_data {
u16 serial_number[10]; /* 10-19 */
u16 reserved2[7]; /* 20-26 */
u16 model_number[20]; /* 27-46*/
u16 reserved3[209]; /* 47-255*/
u16 reserved3[170]; /* 47-216 */
u16 rotational_speed; /* 217 */
u16 reserved4[38]; /* 218-255 */
};
static u32 event_count;
static void mpssas_fw_work(struct mps_softc *sc,
@ -116,8 +119,9 @@ static int mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate);
static int mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz,
u32 devinfo);
static void mpssas_ata_id_timeout(void *data);
int mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
u64 *sas_address, u16 handle, u32 device_info);
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
static int mpssas_volume_add(struct mps_softc *sc,
u16 handle);
static void mpssas_SSU_to_SATA_devices(struct mps_softc *sc);
@ -606,14 +610,14 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
struct mpssas_target *targ;
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t config_page;
uint64_t sas_address, sata_sas_address;
uint64_t sas_address;
uint64_t parent_sas_address = 0;
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
u32 device_info, parent_devinfo = 0;
unsigned int id;
int ret;
int error = 0;
int ret = 1, error = 0, i;
struct mpssas_lun *lun;
u8 is_SATA_SSD = 0;
struct mps_command *cm;
sassc = sc->sassc;
mpssas_startup_increment(sassc);
@ -645,26 +649,27 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
}
/* TODO Check proper endianess */
sas_address = config_page.SASAddress.High;
sas_address = (sas_address << 32) |
config_page.SASAddress.Low;
sas_address = (sas_address << 32) | config_page.SASAddress.Low;
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE)
== MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
ret = mpssas_get_sas_address_for_sata_disk(sc,
&sata_sas_address, handle, device_info);
if (!ret)
id = mps_mapping_get_sas_id(sc,
sata_sas_address, handle);
else
id = mps_mapping_get_sas_id(sc,
sas_address, handle);
} else
id = mps_mapping_get_sas_id(sc, sas_address,
handle);
} else
id = mps_mapping_get_sas_id(sc, sas_address, handle);
/*
* Always get SATA Identify information because this is used to
* determine if Start/Stop Unit should be sent to the drive when the
* system is shutdown.
*/
if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
ret = mpssas_get_sas_address_for_sata_disk(sc, &sas_address,
handle, device_info, &is_SATA_SSD);
if (ret) {
mps_dprint(sc, MPS_INFO, "%s: failed to get disk type "
"(SSD or HDD) for SATA device with handle 0x%04x\n",
__func__, handle);
} else {
mps_dprint(sc, MPS_INFO, "SAS Address from SATA "
"device = %jx\n", sas_address);
}
}
id = mps_mapping_get_sas_id(sc, sas_address, handle);
if (id == MPS_MAP_BAD_ID) {
printf("failure at %s:%d/%s()! Could not get ID for device "
"with handle 0x%04x\n", __FILE__, __LINE__, __func__,
@ -696,6 +701,9 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
targ->tid = id;
targ->linkrate = (linkrate>>4);
targ->flags = 0;
if (is_SATA_SSD) {
targ->flags = MPS_TARGET_IS_SATA_SSD;
}
TAILQ_INIT(&targ->commands);
TAILQ_INIT(&targ->timedout_commands);
while(!SLIST_EMPTY(&targ->luns)) {
@ -706,8 +714,8 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
SLIST_INIT(&targ->luns);
mps_describe_devinfo(targ->devinfo, devstring, 80);
mps_dprint(sc, MPS_MAPPING, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
mps_describe_table(mps_linkrate_names, targ->linkrate),
mps_dprint(sc, MPS_MAPPING, "Found device <%s> <%s> <0x%04x> <%d/%d>\n",
devstring, mps_describe_table(mps_linkrate_names, targ->linkrate),
targ->handle, targ->encl_handle, targ->encl_slot);
#if __FreeBSD_version < 1000039
@ -715,7 +723,50 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
#endif
mpssas_rescan_target(sc, targ);
mps_dprint(sc, MPS_MAPPING, "Target id 0x%x added\n", targ->tid);
/*
* Check all commands to see if the SATA_ID_TIMEOUT flag has been set.
* If so, send a Target Reset TM to the target that was just created.
* An Abort Task TM should be used instead of a Target Reset, but that
* would be much more difficult because targets have not been fully
* discovered yet, and LUN's haven't been setup. So, just reset the
* target instead of the LUN.
*/
for (i = 1; i < sc->num_reqs; i++) {
cm = &sc->commands[i];
if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
targ->timeouts++;
cm->cm_state = MPS_CM_STATE_TIMEDOUT;
if ((targ->tm = mpssas_alloc_tm(sc)) != NULL) {
mps_dprint(sc, MPS_INFO, "%s: sending Target "
"Reset for stuck SATA identify command "
"(cm = %p)\n", __func__, cm);
targ->tm->cm_targ = targ;
mpssas_send_reset(sc, targ->tm,
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
} else {
mps_dprint(sc, MPS_ERROR, "Failed to allocate "
"tm for Target Reset after SATA ID command "
"timed out (cm %p)\n", cm);
}
/*
* No need to check for more since the target is
* already being reset.
*/
break;
}
}
out:
/*
* Free the commands that may not have been freed from the SATA ID call
*/
for (i = 1; i < sc->num_reqs; i++) {
cm = &sc->commands[i];
if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
mps_free_command(sc, cm);
}
}
mpssas_startup_decrement(sassc);
return (error);
@ -723,7 +774,7 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
int
mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
u64 *sas_address, u16 handle, u32 device_info)
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD)
{
Mpi2SataPassthroughReply_t mpi_reply;
int i, rc, try_count;
@ -743,16 +794,25 @@ mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
ioc_status = le16toh(mpi_reply.IOCStatus)
& MPI2_IOCSTATUS_MASK;
sas_status = mpi_reply.SASStatus;
} while ((rc == -EAGAIN || ioc_status || sas_status) &&
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
if (sc->spinup_wait_time > 0) {
mps_dprint(sc, MPS_INFO, "Sleeping %d seconds "
"after SATA ID error to wait for spinup\n",
sc->spinup_wait_time);
msleep(&sc->msleep_fake_chan, &sc->mps_mtx, 0,
"mpsid", sc->spinup_wait_time * hz);
}
}
} while (((rc && (rc != EWOULDBLOCK)) || ioc_status || sas_status) &&
(try_count < 5));
if (rc == 0 && !ioc_status && !sas_status) {
mps_dprint(sc, MPS_MAPPING, "%s: got SATA identify successfully "
"for handle = 0x%x with try_count = %d\n",
__func__, handle, try_count);
mps_dprint(sc, MPS_MAPPING, "%s: got SATA identify "
"successfully for handle = 0x%x with try_count = %d\n",
__func__, handle, try_count);
} else {
mps_dprint(sc, MPS_MAPPING, "%s: handle = 0x%x failed\n",
__func__, handle);
__func__, handle);
return -1;
}
/* Copy & byteswap the 40 byte model number to a buffer */
@ -763,9 +823,9 @@ mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
/* Copy & byteswap the 20 byte serial number to a buffer */
for (i = 0; i < MPT2SAS_SN_LEN; i += 2) {
buffer[MPT2SAS_MN_LEN + i] =
((u8 *)ata_identify.serial_number)[i + 1];
((u8 *)ata_identify.serial_number)[i + 1];
buffer[MPT2SAS_MN_LEN + i + 1] =
((u8 *)ata_identify.serial_number)[i];
((u8 *)ata_identify.serial_number)[i];
}
bufferptr = (u32 *)buffer;
/* There are 60 bytes to hash down to 8. 60 isn't divisible by 8,
@ -792,6 +852,10 @@ mpssas_get_sas_address_for_sata_disk(struct mps_softc *sc,
(u64)hash_address.wwid[3] << 32 | (u64)hash_address.wwid[4] << 24 |
(u64)hash_address.wwid[5] << 16 | (u64)hash_address.wwid[6] << 8 |
(u64)hash_address.wwid[7];
if (ata_identify.rotational_speed == 1) {
*is_SATA_SSD = 1;
}
return 0;
}
@ -831,7 +895,22 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = buffer;
cm->cm_length = htole32(sz);
error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
/*
* Start a timeout counter specifically for the SATA ID command. This
* is used to fix a problem where the FW does not send a reply sometimes
* when a bad disk is in the topology. So, this is used to timeout the
* command so that processing can continue normally.
*/
mps_dprint(sc, MPS_XINFO, "%s start timeout counter for SATA ID "
"command\n", __func__);
callout_reset(&cm->cm_callout, MPS_ATA_ID_TIMEOUT * hz,
mpssas_ata_id_timeout, cm);
error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
mps_dprint(sc, MPS_XINFO, "%s stop timeout counter for SATA ID "
"command\n", __func__);
callout_stop(&cm->cm_callout);
reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
@ -854,11 +933,66 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
goto out;
}
out:
mps_free_command(sc, cm);
free(buffer, M_MPT2);
/*
* If the SATA_ID_TIMEOUT flag has been set for this command, don't free
* it. The command will be freed after sending a target reset TM. If
* the command did timeout, use EWOULDBLOCK.
*/
if ((cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
mps_free_command(sc, cm);
else if (error == 0)
error = EWOULDBLOCK;
free(buffer, M_MPT2);
return (error);
}
static void
mpssas_ata_id_timeout(void *data)
{
struct mps_softc *sc;
struct mps_command *cm;
cm = (struct mps_command *)data;
sc = cm->cm_sc;
mtx_assert(&sc->mps_mtx, MA_OWNED);
mps_dprint(sc, MPS_INFO, "%s checking ATA ID command %p sc %p\n",
__func__, cm, sc);
if ((callout_pending(&cm->cm_callout)) ||
(!callout_active(&cm->cm_callout))) {
mps_dprint(sc, MPS_INFO, "%s ATA ID command almost timed out\n",
__func__);
return;
}
callout_deactivate(&cm->cm_callout);
/*
* Run the interrupt handler to make sure it's not pending. This
* isn't perfect because the command could have already completed
* and been re-used, though this is unlikely.
*/
mps_intr_locked(sc);
if (cm->cm_state == MPS_CM_STATE_FREE) {
mps_dprint(sc, MPS_INFO, "%s ATA ID command almost timed out\n",
__func__);
return;
}
mps_dprint(sc, MPS_INFO, "ATA ID command timeout cm %p\n", cm);
/*
* Send wakeup() to the sleeping thread that issued this ATA ID command.
* wakeup() will cause msleep to return a 0 (not EWOULDBLOCK), and this
* will keep reinit() from being called. This way, an Abort Task TM can
* be issued so that the timed out command can be cleared. The Abort
* Task cannot be sent from here because the driver has not completed
* setting up targets. Instead, the command is flagged so that special
* handling will be used to send the abort.
*/
cm->cm_flags |= MPS_CM_FLAGS_SATA_ID_TIMEOUT;
wakeup(cm);
}
static int
mpssas_volume_add(struct mps_softc *sc, u16 handle)
{
@ -931,13 +1065,11 @@ mpssas_SSU_to_SATA_devices(struct mps_softc *sc)
path_id_t pathid = cam_sim_path(sassc->sim);
target_id_t targetid;
struct mpssas_target *target;
struct mpssas_lun *lun;
char path_str[64];
struct timeval cur_time, start_time;
/*
* For each LUN of each target, issue a StartStopUnit command to stop
* the device.
* For each target, issue a StartStopUnit command to stop the device.
*/
sc->SSU_started = TRUE;
sc->SSU_refcount = 0;
@ -947,63 +1079,58 @@ mpssas_SSU_to_SATA_devices(struct mps_softc *sc)
continue;
}
SLIST_FOREACH(lun, &target->luns, lun_link) {
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
mps_dprint(sc, MPS_FAULT, "Unable to alloc CCB "
"to stop unit.\n");
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
mps_dprint(sc, MPS_FAULT, "Unable to alloc CCB to stop "
"unit.\n");
return;
}
/*
* The stop_at_shutdown flag will be set if this device is
* a SATA direct-access end device.
*/
if (target->stop_at_shutdown) {
if (xpt_create_path(&ccb->ccb_h.path,
xpt_periph, pathid, targetid,
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
mps_dprint(sc, MPS_FAULT, "Unable to create "
"LUN path to stop unit.\n");
xpt_free_ccb(ccb);
return;
}
xpt_path_string(ccb->ccb_h.path, path_str,
sizeof(path_str));
/*
* The stop_at_shutdown flag will be set if this LUN is
* a SATA direct-access end device.
*/
if (lun->stop_at_shutdown) {
if (xpt_create_path(&ccb->ccb_h.path,
xpt_periph, pathid, targetid,
lun->lun_id) != CAM_REQ_CMP) {
mps_dprint(sc, MPS_FAULT, "Unable to "
"create LUN path to stop unit.\n");
xpt_free_ccb(ccb);
return;
}
xpt_path_string(ccb->ccb_h.path, path_str,
sizeof(path_str));
mps_dprint(sc, MPS_INFO, "Sending StopUnit: "
"path %s handle %d\n", path_str,
target->handle);
mps_dprint(sc, MPS_INFO, "Sending StopUnit: path %s "
"handle %d\n", path_str, target->handle);
/*
* Issue a START STOP UNIT command for the LUN.
* Increment the SSU counter to be used to
* count the number of required replies.
*/
mps_dprint(sc, MPS_INFO, "Incrementing SSU "
"count\n");
sc->SSU_refcount++;
ccb->ccb_h.target_id =
xpt_path_target_id(ccb->ccb_h.path);
ccb->ccb_h.target_lun = lun->lun_id;
ccb->ccb_h.ppriv_ptr1 = sassc;
scsi_start_stop(&ccb->csio,
/*retries*/0,
mpssas_stop_unit_done,
MSG_SIMPLE_Q_TAG,
/*start*/FALSE,
/*load/eject*/0,
/*immediate*/FALSE,
MPS_SENSE_LEN,
/*timeout*/10000);
xpt_action(ccb);
}
/*
* Issue a START STOP UNIT command for the target.
* Increment the SSU counter to be used to count the
* number of required replies.
*/
mps_dprint(sc, MPS_INFO, "Incrementing SSU count\n");
sc->SSU_refcount++;
ccb->ccb_h.target_id =
xpt_path_target_id(ccb->ccb_h.path);
ccb->ccb_h.ppriv_ptr1 = sassc;
scsi_start_stop(&ccb->csio,
/*retries*/0,
mpssas_stop_unit_done,
MSG_SIMPLE_Q_TAG,
/*start*/FALSE,
/*load/eject*/0,
/*immediate*/FALSE,
MPS_SENSE_LEN,
/*timeout*/10000);
xpt_action(ccb);
}
}
/*
* Wait until all of the SSU commands have completed or time has
* expired (60 seconds). pause for 100ms each time through. If any
* expired (60 seconds). Pause for 100ms each time through. If any
* command times out, the target will be reset in the SCSI command
* timeout routine.
*/
@ -1063,6 +1190,8 @@ mpssas_ir_shutdown(struct mps_softc *sc)
unsigned int id, found_volume = 0;
struct mps_command *cm;
Mpi2RaidActionRequest_t *action;
target_id_t targetid;
struct mpssas_target *target;
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
@ -1105,7 +1234,7 @@ mpssas_ir_shutdown(struct mps_softc *sc)
action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
mps_wait_command(sc, cm, 5, CAN_SLEEP);
mps_wait_command(sc, cm, 5, CAN_SLEEP);
mps_unlock(sc);
/*
@ -1115,5 +1244,47 @@ mpssas_ir_shutdown(struct mps_softc *sc)
mps_free_command(sc, cm);
out:
/*
* All of the targets must have the correct value set for
* 'stop_at_shutdown' for the current 'enable_ssu' sysctl variable.
*
* The possible values for the 'enable_ssu' variable are:
* 0: disable to SSD and HDD
* 1: disable only to HDD (default)
* 2: disable only to SSD
* 3: enable to SSD and HDD
* anything else will default to 1.
*/
for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) {
target = &sc->sassc->targets[targetid];
if (target->handle == 0x0) {
continue;
}
if (target->supports_SSU) {
switch (sc->enable_ssu) {
case MPS_SSU_DISABLE_SSD_DISABLE_HDD:
target->stop_at_shutdown = FALSE;
break;
case MPS_SSU_DISABLE_SSD_ENABLE_HDD:
target->stop_at_shutdown = TRUE;
if (target->flags & MPS_TARGET_IS_SATA_SSD) {
target->stop_at_shutdown = FALSE;
}
break;
case MPS_SSU_ENABLE_SSD_ENABLE_HDD:
target->stop_at_shutdown = TRUE;
break;
case MPS_SSU_ENABLE_SSD_DISABLE_HDD:
default:
target->stop_at_shutdown = TRUE;
if ((target->flags &
MPS_TARGET_IS_SATA_SSD) == 0) {
target->stop_at_shutdown = FALSE;
}
break;
}
}
}
mpssas_SSU_to_SATA_devices(sc);
}

View File

@ -27,10 +27,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD userland interface
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
*/
/*-
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -54,7 +55,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -90,6 +91,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/scsi/scsi_all.h>
#include <dev/mps/mpi/mpi2_type.h>
@ -101,6 +103,7 @@ __FBSDID("$FreeBSD$");
#include <dev/mps/mps_ioctl.h>
#include <dev/mps/mpsvar.h>
#include <dev/mps/mps_table.h>
#include <dev/mps/mps_sas.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@ -700,7 +703,7 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd)
mps_printf(sc, "Cannot allocate memory %s %d\n",
__func__, __LINE__);
return (ENOMEM);
}
}
cm->cm_data = buf;
cm->cm_length = cmd->len;
} else {
@ -767,6 +770,7 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
int err = 0, dir = 0, sz;
uint8_t function = 0;
u_int sense_len;
struct mpssas_target *targ = NULL;
/*
* Only allow one passthru command at a time. Use the MPS_FLAGS_BUSY
@ -848,11 +852,22 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
task->TaskMID = cm->cm_desc.Default.SMID;
cm->cm_data = NULL;
cm->cm_desc.HighPriority.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_desc.HighPriority.RequestFlags =
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = NULL;
cm->cm_complete_data = NULL;
err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
targ = mpssas_find_target_by_handle(sc->sassc, 0,
task->DevHandle);
if (targ == NULL) {
mps_dprint(sc, MPS_INFO,
"%s %d : invalid handle for requested TM 0x%x \n",
__func__, __LINE__, task->DevHandle);
err = 1;
} else {
mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
}
if (err != 0) {
err = EIO;

View File

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011, 2012 LSI Corp.
* Copyright (c) 2011-2015 LSI Corp.
* Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* LSI MPT-Fusion Host Adapter FreeBSD
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@ -32,7 +33,7 @@
#ifndef _MPSVAR_H
#define _MPSVAR_H
#define MPS_DRIVER_VERSION "19.00.00.00-fbsd"
#define MPS_DRIVER_VERSION "20.00.00.00-fbsd"
#define MPS_DB_MAX_WAIT 2500
@ -50,10 +51,13 @@
#define NO_SLEEP 0
#define MPS_PERIODIC_DELAY 1 /* 1 second heartbeat/watchdog check */
#define MPS_ATA_ID_TIMEOUT 5 /* 5 second timeout for SATA ID cmd */
#define MPS_SCSI_RI_INVALID_FRAME (0x00000002)
#define MPS_STRING_LENGTH 64
#define DEFAULT_SPINUP_WAIT 3 /* seconds to wait for spinup */
#include <sys/endian.h>
/*
@ -232,6 +236,7 @@ struct mps_command {
#define MPS_CM_FLAGS_CHAIN_FAILED (1 << 9)
#define MPS_CM_FLAGS_ERROR_MASK MPS_CM_FLAGS_CHAIN_FAILED
#define MPS_CM_FLAGS_USE_CCB (1 << 10)
#define MPS_CM_FLAGS_SATA_ID_TIMEOUT (1 << 11)
u_int cm_state;
#define MPS_CM_STATE_FREE 0
#define MPS_CM_STATE_BUSY 1
@ -276,6 +281,8 @@ struct mps_softc {
int chain_free;
int max_chains;
int chain_free_lowwater;
u_int enable_ssu;
int spinup_wait_time;
#if __FreeBSD_version >= 900030
uint64_t chain_alloc_fail;
#endif
@ -599,6 +606,11 @@ mps_unlock(struct mps_softc *sc)
#define MPS_MAPPING (1 << 9) /* Trace device mappings */
#define MPS_TRACE (1 << 10) /* Function-by-function trace */
#define MPS_SSU_DISABLE_SSD_DISABLE_HDD 0
#define MPS_SSU_ENABLE_SSD_DISABLE_HDD 1
#define MPS_SSU_DISABLE_SSD_ENABLE_HDD 2
#define MPS_SSU_ENABLE_SSD_ENABLE_HDD 3
#define mps_printf(sc, args...) \
device_printf((sc)->mps_dev, ##args)
@ -764,6 +776,8 @@ void mpssas_realloc_targets(struct mps_softc *sc, int maxtargets);
struct mps_command * mpssas_alloc_tm(struct mps_softc *sc);
void mpssas_free_tm(struct mps_softc *sc, struct mps_command *tm);
void mpssas_release_simq_reinit(struct mpssas_softc *sassc);
int mpssas_send_reset(struct mps_softc *sc, struct mps_command *tm,
uint8_t type);
SYSCTL_DECL(_hw_mps);

View File

@ -0,0 +1,422 @@
/*
* Copyright (C) 2015, Luigi Rizzo. All rights reserved.
*
* 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.
*/
/*
* $FreeBSD$
*
* netmap support for: ixl
*
* derived from ixgbe
* netmap support for a network driver.
* This file contains code but only static or inline functions used
* by a single driver. To avoid replication of code we just #include
* it near the beginning of the standard driver.
* For ixl the file is imported in two places, hence the conditional at the
* beginning.
*/
#include <net/netmap.h>
#include <sys/selinfo.h>
/*
* Some drivers may need the following headers. Others
* already include them by default
#include <vm/vm.h>
#include <vm/pmap.h>
*/
#include <dev/netmap/netmap_kern.h>
int ixl_netmap_txsync(struct netmap_kring *kring, int flags);
int ixl_netmap_rxsync(struct netmap_kring *kring, int flags);
extern int ixl_rx_miss, ixl_rx_miss_bufs, ixl_crcstrip;
#ifdef NETMAP_IXL_MAIN
/*
* device-specific sysctl variables:
*
* ixl_crcstrip: 0: keep CRC in rx frames (default), 1: strip it.
* During regular operations the CRC is stripped, but on some
* hardware reception of frames not multiple of 64 is slower,
* so using crcstrip=0 helps in benchmarks.
*
* ixl_rx_miss, ixl_rx_miss_bufs:
* count packets that might be missed due to lost interrupts.
*/
SYSCTL_DECL(_dev_netmap);
int ixl_rx_miss, ixl_rx_miss_bufs, ixl_crcstrip;
SYSCTL_INT(_dev_netmap, OID_AUTO, ixl_crcstrip,
CTLFLAG_RW, &ixl_crcstrip, 0, "strip CRC on rx frames");
SYSCTL_INT(_dev_netmap, OID_AUTO, ixl_rx_miss,
CTLFLAG_RW, &ixl_rx_miss, 0, "potentially missed rx intr");
SYSCTL_INT(_dev_netmap, OID_AUTO, ixl_rx_miss_bufs,
CTLFLAG_RW, &ixl_rx_miss_bufs, 0, "potentially missed rx intr bufs");
/*
* Register/unregister. We are already under netmap lock.
* Only called on the first register or the last unregister.
*/
static int
ixl_netmap_reg(struct netmap_adapter *na, int onoff)
{
struct ifnet *ifp = na->ifp;
struct ixl_vsi *vsi = ifp->if_softc;
struct ixl_pf *pf = (struct ixl_pf *)vsi->back;
IXL_PF_LOCK(pf);
ixl_disable_intr(vsi);
/* Tell the stack that the interface is no longer active */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
//set_crcstrip(&adapter->hw, onoff);
/* enable or disable flags and callbacks in na and ifp */
if (onoff) {
nm_set_native_flags(na);
} else {
nm_clear_native_flags(na);
}
ixl_init_locked(pf); /* also enables intr */
//set_crcstrip(&adapter->hw, onoff); // XXX why twice ?
IXL_PF_UNLOCK(pf);
return (ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1);
}
/*
* The attach routine, called near the end of ixl_attach(),
* fills the parameters for netmap_attach() and calls it.
* It cannot fail, in the worst case (such as no memory)
* netmap mode will be disabled and the driver will only
* operate in standard mode.
*/
static void
ixl_netmap_attach(struct ixl_vsi *vsi)
{
struct netmap_adapter na;
bzero(&na, sizeof(na));
na.ifp = vsi->ifp;
na.na_flags = NAF_BDG_MAYSLEEP;
// XXX check that queues is set.
printf("queues is %p\n", vsi->queues);
if (vsi->queues) {
na.num_tx_desc = vsi->queues[0].num_desc;
na.num_rx_desc = vsi->queues[0].num_desc;
}
na.nm_txsync = ixl_netmap_txsync;
na.nm_rxsync = ixl_netmap_rxsync;
na.nm_register = ixl_netmap_reg;
na.num_tx_rings = na.num_rx_rings = vsi->num_queues;
netmap_attach(&na);
}
#else /* !NETMAP_IXL_MAIN, code for ixl_txrx.c */
/*
* Reconcile kernel and user view of the transmit ring.
*
* All information is in the kring.
* Userspace wants to send packets up to the one before kring->rhead,
* kernel knows kring->nr_hwcur is the first unsent packet.
*
* Here we push packets out (as many as possible), and possibly
* reclaim buffers from previously completed transmission.
*
* The caller (netmap) guarantees that there is only one instance
* running at any time. Any interference with other driver
* methods should be handled by the individual drivers.
*/
int
ixl_netmap_txsync(struct netmap_kring *kring, int flags)
{
struct netmap_adapter *na = kring->na;
struct ifnet *ifp = na->ifp;
struct netmap_ring *ring = kring->ring;
u_int nm_i; /* index into the netmap ring */
u_int nic_i; /* index into the NIC ring */
u_int n;
u_int const lim = kring->nkr_num_slots - 1;
u_int const head = kring->rhead;
/*
* interrupts on every tx packet are expensive so request
* them every half ring, or where NS_REPORT is set
*/
u_int report_frequency = kring->nkr_num_slots >> 1;
/* device-specific */
struct ixl_vsi *vsi = ifp->if_softc;
struct ixl_queue *que = &vsi->queues[kring->ring_id];
struct tx_ring *txr = &que->txr;
bus_dmamap_sync(txr->dma.tag, txr->dma.map,
BUS_DMASYNC_POSTREAD);
/*
* First part: process new packets to send.
* nm_i is the current index in the netmap ring,
* nic_i is the corresponding index in the NIC ring.
*
* If we have packets to send (nm_i != head)
* iterate over the netmap ring, fetch length and update
* the corresponding slot in the NIC ring. Some drivers also
* need to update the buffer's physical address in the NIC slot
* even NS_BUF_CHANGED is not set (PNMB computes the addresses).
*
* The netmap_reload_map() calls is especially expensive,
* even when (as in this case) the tag is 0, so do only
* when the buffer has actually changed.
*
* If possible do not set the report/intr bit on all slots,
* but only a few times per ring or when NS_REPORT is set.
*
* Finally, on 10G and faster drivers, it might be useful
* to prefetch the next slot and txr entry.
*/
nm_i = kring->nr_hwcur;
if (nm_i != head) { /* we have new packets to send */
nic_i = netmap_idx_k2n(kring, nm_i);
__builtin_prefetch(&ring->slot[nm_i]);
__builtin_prefetch(&txr->buffers[nic_i]);
for (n = 0; nm_i != head; n++) {
struct netmap_slot *slot = &ring->slot[nm_i];
u_int len = slot->len;
uint64_t paddr;
void *addr = PNMB(na, slot, &paddr);
/* device-specific */
struct i40e_tx_desc *curr = &txr->base[nic_i];
struct ixl_tx_buf *txbuf = &txr->buffers[nic_i];
u64 flags = (slot->flags & NS_REPORT ||
nic_i == 0 || nic_i == report_frequency) ?
((u64)I40E_TX_DESC_CMD_RS << I40E_TXD_QW1_CMD_SHIFT) : 0;
/* prefetch for next round */
__builtin_prefetch(&ring->slot[nm_i + 1]);
__builtin_prefetch(&txr->buffers[nic_i + 1]);
NM_CHECK_ADDR_LEN(na, addr, len);
if (slot->flags & NS_BUF_CHANGED) {
/* buffer has changed, reload map */
netmap_reload_map(na, txr->dma.tag, txbuf->map, addr);
}
slot->flags &= ~(NS_REPORT | NS_BUF_CHANGED);
/* Fill the slot in the NIC ring. */
curr->buffer_addr = htole64(paddr);
curr->cmd_type_offset_bsz = htole64(
((u64)len << I40E_TXD_QW1_TX_BUF_SZ_SHIFT) |
flags |
((u64)I40E_TX_DESC_CMD_EOP << I40E_TXD_QW1_CMD_SHIFT)
); // XXX more ?
/* make sure changes to the buffer are synced */
bus_dmamap_sync(txr->dma.tag, txbuf->map,
BUS_DMASYNC_PREWRITE);
nm_i = nm_next(nm_i, lim);
nic_i = nm_next(nic_i, lim);
}
kring->nr_hwcur = head;
/* synchronize the NIC ring */
bus_dmamap_sync(txr->dma.tag, txr->dma.map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* (re)start the tx unit up to slot nic_i (excluded) */
wr32(vsi->hw, txr->tail, nic_i);
}
/*
* Second part: reclaim buffers for completed transmissions.
*/
nic_i = LE32_TO_CPU(*(volatile __le32 *)&txr->base[que->num_desc]);
if (nic_i != txr->next_to_clean) {
/* some tx completed, increment avail */
txr->next_to_clean = nic_i;
kring->nr_hwtail = nm_prev(netmap_idx_n2k(kring, nic_i), lim);
}
nm_txsync_finalize(kring);
return 0;
}
/*
* Reconcile kernel and user view of the receive ring.
* Same as for the txsync, this routine must be efficient.
* The caller guarantees a single invocations, but races against
* the rest of the driver should be handled here.
*
* On call, kring->rhead is the first packet that userspace wants
* to keep, and kring->rcur is the wakeup point.
* The kernel has previously reported packets up to kring->rtail.
*
* If (flags & NAF_FORCE_READ) also check for incoming packets irrespective
* of whether or not we received an interrupt.
*/
int
ixl_netmap_rxsync(struct netmap_kring *kring, int flags)
{
struct netmap_adapter *na = kring->na;
struct ifnet *ifp = na->ifp;
struct netmap_ring *ring = kring->ring;
u_int nm_i; /* index into the netmap ring */
u_int nic_i; /* index into the NIC ring */
u_int n;
u_int const lim = kring->nkr_num_slots - 1;
u_int const head = nm_rxsync_prologue(kring);
int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR;
/* device-specific */
struct ixl_vsi *vsi = ifp->if_softc;
struct ixl_queue *que = &vsi->queues[kring->ring_id];
struct rx_ring *rxr = &que->rxr;
if (head > lim)
return netmap_ring_reinit(kring);
/* XXX check sync modes */
bus_dmamap_sync(rxr->dma.tag, rxr->dma.map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/*
* First part: import newly received packets.
*
* nm_i is the index of the next free slot in the netmap ring,
* nic_i is the index of the next received packet in the NIC ring,
* and they may differ in case if_init() has been called while
* in netmap mode. For the receive ring we have
*
* nic_i = rxr->next_check;
* nm_i = kring->nr_hwtail (previous)
* and
* nm_i == (nic_i + kring->nkr_hwofs) % ring_size
*
* rxr->next_check is set to 0 on a ring reinit
*/
if (netmap_no_pendintr || force_update) {
int crclen = ixl_crcstrip ? 0 : 4;
uint16_t slot_flags = kring->nkr_slot_flags;
nic_i = rxr->next_check; // or also k2n(kring->nr_hwtail)
nm_i = netmap_idx_n2k(kring, nic_i);
for (n = 0; ; n++) {
union i40e_32byte_rx_desc *curr = &rxr->base[nic_i];
uint64_t qword = le64toh(curr->wb.qword1.status_error_len);
uint32_t staterr = (qword & I40E_RXD_QW1_STATUS_MASK)
>> I40E_RXD_QW1_STATUS_SHIFT;
if ((staterr & (1<<I40E_RX_DESC_STATUS_DD_SHIFT)) == 0)
break;
ring->slot[nm_i].len = ((qword & I40E_RXD_QW1_LENGTH_PBUF_MASK)
>> I40E_RXD_QW1_LENGTH_PBUF_SHIFT) - crclen;
ring->slot[nm_i].flags = slot_flags;
bus_dmamap_sync(rxr->ptag,
rxr->buffers[nic_i].pmap, BUS_DMASYNC_POSTREAD);
nm_i = nm_next(nm_i, lim);
nic_i = nm_next(nic_i, lim);
}
if (n) { /* update the state variables */
if (netmap_no_pendintr && !force_update) {
/* diagnostics */
ixl_rx_miss ++;
ixl_rx_miss_bufs += n;
}
rxr->next_check = nic_i;
kring->nr_hwtail = nm_i;
}
kring->nr_kflags &= ~NKR_PENDINTR;
}
/*
* Second part: skip past packets that userspace has released.
* (kring->nr_hwcur to head excluded),
* and make the buffers available for reception.
* As usual nm_i is the index in the netmap ring,
* nic_i is the index in the NIC ring, and
* nm_i == (nic_i + kring->nkr_hwofs) % ring_size
*/
nm_i = kring->nr_hwcur;
if (nm_i != head) {
nic_i = netmap_idx_k2n(kring, nm_i);
for (n = 0; nm_i != head; n++) {
struct netmap_slot *slot = &ring->slot[nm_i];
uint64_t paddr;
void *addr = PNMB(na, slot, &paddr);
union i40e_32byte_rx_desc *curr = &rxr->base[nic_i];
struct ixl_rx_buf *rxbuf = &rxr->buffers[nic_i];
if (addr == NETMAP_BUF_BASE(na)) /* bad buf */
goto ring_reset;
if (slot->flags & NS_BUF_CHANGED) {
/* buffer has changed, reload map */
netmap_reload_map(na, rxr->ptag, rxbuf->pmap, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
curr->read.pkt_addr = htole64(paddr);
curr->read.hdr_addr = 0; // XXX needed
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
BUS_DMASYNC_PREREAD);
nm_i = nm_next(nm_i, lim);
nic_i = nm_next(nic_i, lim);
}
kring->nr_hwcur = head;
bus_dmamap_sync(rxr->dma.tag, rxr->dma.map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/*
* IMPORTANT: we must leave one free slot in the ring,
* so move nic_i back by one unit
*/
nic_i = nm_prev(nic_i, lim);
wr32(vsi->hw, rxr->tail, nic_i);
}
/* tell userspace that there might be new packets */
nm_rxsync_finalize(kring);
return 0;
ring_reset:
return netmap_ring_reinit(kring);
}
#endif /* !NETMAP_IXL_MAIN */
/* end of file */

View File

@ -830,3 +830,4 @@ netmap_loader(__unused struct module *module, int event, __unused void *arg)
DEV_MODULE(netmap, netmap_loader, NULL);
MODULE_VERSION(netmap, 1);

View File

@ -94,6 +94,15 @@ extern "C" {
#define ISP2(x) (((x) & ((x) - 1)) == 0)
#endif
#if defined(__x86_64__)
#if !defined(bus_space_read_stream_8)
#define bus_space_read_stream_8(t, h, o) \
bus_space_read_8((t), (h), (o))
#define bus_space_write_stream_8(t, h, o, v) \
bus_space_write_8((t), (h), (o), (v))
#endif
#endif
#define ENOTACTIVE EINVAL
/* Memory type to use on FreeBSD */
@ -641,8 +650,9 @@ typedef struct efsys_bar_s {
if (_lock) \
SFXGE_BAR_LOCK(_esbp); \
\
(_edp)->ed_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset)); \
(_edp)->ed_u32[0] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset)); \
\
EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \
uint32_t, (_edp)->ed_u32[0]); \
@ -662,8 +672,9 @@ typedef struct efsys_bar_s {
\
SFXGE_BAR_LOCK(_esbp); \
\
(_eqp)->eq_u64[0] = bus_space_read_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset)); \
(_eqp)->eq_u64[0] = bus_space_read_stream_8( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset)); \
\
EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \
uint32_t, (_eqp)->eq_u32[1], \
@ -683,10 +694,12 @@ typedef struct efsys_bar_s {
if (_lock) \
SFXGE_BAR_LOCK(_esbp); \
\
(_eop)->eo_u64[0] = bus_space_read_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset)); \
(_eop)->eo_u64[1] = bus_space_read_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset+8)); \
(_eop)->eo_u64[0] = bus_space_read_stream_8( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset)); \
(_eop)->eo_u64[1] = bus_space_read_stream_8( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset) + 8); \
\
EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \
uint32_t, (_eop)->eo_u32[3], \
@ -709,10 +722,12 @@ typedef struct efsys_bar_s {
\
SFXGE_BAR_LOCK(_esbp); \
\
(_eqp)->eq_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset)); \
(_eqp)->eq_u32[1] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset+4)); \
(_eqp)->eq_u32[0] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset)); \
(_eqp)->eq_u32[1] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset) + 4); \
\
EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \
uint32_t, (_eqp)->eq_u32[1], \
@ -732,14 +747,18 @@ typedef struct efsys_bar_s {
if (_lock) \
SFXGE_BAR_LOCK(_esbp); \
\
(_eop)->eo_u32[0] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset)); \
(_eop)->eo_u32[1] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset+4)); \
(_eop)->eo_u32[2] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset+8)); \
(_eop)->eo_u32[3] = bus_space_read_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, (_offset+12)); \
(_eop)->eo_u32[0] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset)); \
(_eop)->eo_u32[1] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset) + 4); \
(_eop)->eo_u32[2] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset) + 8); \
(_eop)->eo_u32[3] = bus_space_read_stream_4( \
(_esbp)->esb_tag, (_esbp)->esb_handle, \
(_offset) + 12); \
\
EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \
uint32_t, (_eop)->eo_u32[3], \
@ -767,7 +786,8 @@ typedef struct efsys_bar_s {
EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \
uint32_t, (_edp)->ed_u32[0]); \
\
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset), (_edp)->ed_u32[0]); \
\
_NOTE(CONSTANTCONDITION) \
@ -789,7 +809,8 @@ typedef struct efsys_bar_s {
uint32_t, (_eqp)->eq_u32[1], \
uint32_t, (_eqp)->eq_u32[0]); \
\
bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
bus_space_write_stream_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset), (_eqp)->eq_u64[0]); \
\
SFXGE_BAR_UNLOCK(_esbp); \
@ -808,10 +829,12 @@ typedef struct efsys_bar_s {
uint32_t, (_eqp)->eq_u32[1], \
uint32_t, (_eqp)->eq_u32[0]); \
\
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset), (_eqp)->eq_u32[0]); \
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
(_offset+4), (_eqp)->eq_u32[1]); \
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset) + 4, (_eqp)->eq_u32[1]); \
\
SFXGE_BAR_UNLOCK(_esbp); \
_NOTE(CONSTANTCONDITION) \
@ -835,10 +858,12 @@ typedef struct efsys_bar_s {
uint32_t, (_eop)->eo_u32[1], \
uint32_t, (_eop)->eo_u32[0]); \
\
bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
bus_space_write_stream_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset), (_eop)->eo_u64[0]); \
bus_space_write_8((_esbp)->esb_tag, (_esbp)->esb_handle,\
(_offset+8), (_eop)->eo_u64[1]); \
bus_space_write_stream_8((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset) + 8, (_eop)->eo_u64[1]); \
\
_NOTE(CONSTANTCONDITION) \
if (_lock) \
@ -863,14 +888,18 @@ typedef struct efsys_bar_s {
uint32_t, (_eop)->eo_u32[1], \
uint32_t, (_eop)->eo_u32[0]); \
\
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset), (_eop)->eo_u32[0]); \
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
(_offset+4), (_eop)->eo_u32[1]); \
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
(_offset+8), (_eop)->eo_u32[2]); \
bus_space_write_4((_esbp)->esb_tag, (_esbp)->esb_handle,\
(_offset+12), (_eop)->eo_u32[3]); \
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset) + 4, (_eop)->eo_u32[1]); \
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset) + 8, (_eop)->eo_u32[2]); \
bus_space_write_stream_4((_esbp)->esb_tag, \
(_esbp)->esb_handle, \
(_offset) + 12, (_eop)->eo_u32[3]); \
\
_NOTE(CONSTANTCONDITION) \
if (_lock) \
@ -912,7 +941,11 @@ typedef clock_t efsys_timestamp_t;
#define EFSYS_KMEM_ALLOC(_esip, _size, _p) \
do { \
(_esip) = (_esip); \
(_p) = malloc((_size), M_SFXGE, M_WAITOK|M_ZERO); \
/* \
* The macro is used in non-sleepable contexts, for \
* example, holding a mutex. \
*/ \
(_p) = malloc((_size), M_SFXGE, M_NOWAIT|M_ZERO); \
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)

View File

@ -895,7 +895,8 @@ typedef struct efx_nic_cfg_s {
uint32_t enc_txq_limit;
uint32_t enc_rxq_limit;
uint32_t enc_buftbl_limit;
uint32_t enc_evq_moderation_max;
uint32_t enc_evq_timer_quantum_ns;
uint32_t enc_evq_timer_max_us;
uint32_t enc_clk_mult;
#if EFSYS_OPT_LOOPBACK
uint32_t enc_loopback_types[EFX_LINK_NMODES];
@ -1024,6 +1025,10 @@ typedef enum efx_nvram_type_e {
EFX_NVRAM_MC_GOLDEN,
EFX_NVRAM_PHY,
EFX_NVRAM_NULLPHY,
EFX_NVRAM_FPGA,
EFX_NVRAM_FCFW,
EFX_NVRAM_CPLD,
EFX_NVRAM_FPGA_BACKUP,
EFX_NVRAM_NTYPES,
} efx_nvram_type_t;
@ -1731,6 +1736,11 @@ efx_tx_qpost(
__in unsigned int completed,
__inout unsigned int *addedp);
extern __checkReturn int
efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns);
extern void
efx_tx_qpush(
__in efx_txq_t *etp,

View File

@ -857,7 +857,7 @@ efx_ev_qmoderate(
EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
if (us > encp->enc_evq_moderation_max) {
if (us > encp->enc_evq_timer_max_us) {
rc = EINVAL;
goto fail1;
}
@ -876,7 +876,7 @@ efx_ev_qmoderate(
uint32_t timer_val;
/* Calculate the timer value in quanta */
timer_val = us * encp->enc_clk_mult / EFX_EV_TIMER_QUANTUM;
timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
/* Moderation value is base 0 so we need to deduct 1 */
if (timer_val > 0)

View File

@ -204,7 +204,7 @@ typedef struct efx_nic_ops_s {
# define EFX_TXQ_LIMIT_TARGET 259
#endif
#ifndef EFX_RXQ_LIMIT_TARGET
# define EFX_RXQ_LIMIT_TARGET 768
# define EFX_RXQ_LIMIT_TARGET 512
#endif
#ifndef EFX_TXQ_DC_SIZE
#define EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
@ -408,7 +408,8 @@ struct efx_evq_s {
#define EFX_EVQ_MAGIC 0x08081997
#define EFX_EV_TIMER_QUANTUM 5
#define EFX_EVQ_FALCON_TIMER_QUANTUM_NS 4968 /* 621 cycles */
#define EFX_EVQ_SIENA_TIMER_QUANTUM_NS 6144 /* 768 cycles */
struct efx_rxq_s {
uint32_t er_magic;

View File

@ -34,6 +34,13 @@ extern "C" {
#endif
/**************************************************************************
*
* Falcon/Siena registers and descriptors
*
**************************************************************************
*/
/*
* FR_AB_EE_VPD_CFG0_REG_SF(128bit):
* SPI/VPD configuration register 0
@ -3838,6 +3845,18 @@ extern "C" {
#define FSF_AZ_DRIVER_EV_RX_DESCQ_ID_WIDTH 12
/**************************************************************************
*
* Falcon non-volatile configuration
*
**************************************************************************
*/
#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
#ifdef __cplusplus
}
#endif

View File

@ -224,6 +224,53 @@ efx_tx_qpush(
etp->et_index, &dword, B_FALSE);
}
#define EFX_MAX_PACE_VALUE 20
#define EFX_TX_PACE_CLOCK_BASE 104
__checkReturn int
efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns)
{
efx_nic_t *enp = etp->et_enp;
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_oword_t oword;
unsigned int pace_val;
unsigned int timer_period;
int rc;
EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
if (ns == 0) {
pace_val = 0;
} else {
/*
* The pace_val to write into the table is s.t
* ns <= timer_period * (2 ^ pace_val)
*/
timer_period = EFX_TX_PACE_CLOCK_BASE / encp->enc_clk_mult;
for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
if ((timer_period << pace_val) >= ns)
break;
}
}
if (pace_val > EFX_MAX_PACE_VALUE) {
rc = EINVAL;
goto fail1;
}
/* Update the pacing table */
EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index, &oword);
return (0);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
void
efx_tx_qflush(
__in efx_txq_t *etp)
@ -234,6 +281,8 @@ efx_tx_qflush(
EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
efx_tx_qpace(etp, 0);
label = etp->et_index;
/* Flush the queue */

View File

@ -81,7 +81,9 @@ typedef struct siena_mc_static_config_hdr_s { /* GENERATED BY scripts/genfwdef *
efx_byte_t green_mode_valid; /* Whether cal holds a valid value */
efx_word_t mac_addr_count;
efx_word_t mac_addr_stride;
efx_dword_t reserved2[2]; /* (write as zero) */
efx_word_t calibrated_vref;
efx_word_t adc_vref;
efx_dword_t reserved2[1]; /* (write as zero) */
efx_dword_t num_dbi_items;
struct {
efx_word_t addr;

View File

@ -70,6 +70,21 @@ static __cs uint16_t __siena_mon_port0_map[] = {
EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
};
static __cs uint16_t __siena_mon_port1_map[] = {
@ -86,6 +101,21 @@ static __cs uint16_t __siena_mon_port1_map[] = {
EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
};
#define SIENA_STATIC_SENSOR_ASSERT(_field) \

View File

@ -329,8 +329,10 @@ siena_board_cfg(
encp->enc_clk_mult = 2;
}
encp->enc_evq_moderation_max = EFX_EV_TIMER_QUANTUM <<
FRF_AB_TIMER_VAL_WIDTH / encp->enc_clk_mult;
encp->enc_evq_timer_quantum_ns =
EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
/* Resource limits */
req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;

View File

@ -330,6 +330,14 @@ static siena_parttbl_entry_t siena_parttbl[] = {
{MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1, 2, EFX_NVRAM_BOOTROM_CFG},
{MC_CMD_NVRAM_TYPE_PHY_PORT0, 1, EFX_NVRAM_PHY},
{MC_CMD_NVRAM_TYPE_PHY_PORT1, 2, EFX_NVRAM_PHY},
{MC_CMD_NVRAM_TYPE_FPGA, 1, EFX_NVRAM_FPGA},
{MC_CMD_NVRAM_TYPE_FPGA, 2, EFX_NVRAM_FPGA},
{MC_CMD_NVRAM_TYPE_FPGA_BACKUP, 1, EFX_NVRAM_FPGA_BACKUP},
{MC_CMD_NVRAM_TYPE_FPGA_BACKUP, 2, EFX_NVRAM_FPGA_BACKUP},
{MC_CMD_NVRAM_TYPE_FC_FW, 1, EFX_NVRAM_FCFW},
{MC_CMD_NVRAM_TYPE_FC_FW, 2, EFX_NVRAM_FCFW},
{MC_CMD_NVRAM_TYPE_CPLD, 1, EFX_NVRAM_CPLD},
{MC_CMD_NVRAM_TYPE_CPLD, 2, EFX_NVRAM_CPLD},
{0, 0, 0},
};

View File

@ -61,10 +61,10 @@ __FBSDID("$FreeBSD$");
#define SFXGE_CAP (IFCAP_VLAN_MTU | \
IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO | \
IFCAP_JUMBO_MTU | IFCAP_LRO | \
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWSTATS)
#define SFXGE_CAP_ENABLE SFXGE_CAP
#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
IFCAP_JUMBO_MTU | IFCAP_LINKSTATE | IFCAP_HWSTATS)
MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
@ -343,6 +343,8 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
mtx_init(&sc->tx_lock, sc->tx_lock_name, NULL, MTX_DEF);
#endif
ifp->if_get_counter = sfxge_get_counter;
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;

View File

@ -324,6 +324,7 @@ extern void sfxge_mac_link_update(struct sfxge_softc *sc,
efx_link_mode_t mode);
extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
extern uint64_t sfxge_get_counter(struct ifnet *ifp, ift_counter c);
#define SFXGE_MAX_MTU (9 * 1024)

View File

@ -141,7 +141,7 @@ sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len, efsys_mem_t *esmp)
MIN(0x3FFFFFFFFFFFUL, BUS_SPACE_MAXADDR), BUS_SPACE_MAXADDR, NULL,
NULL, len, 1, len, 0, NULL, NULL, &esmp->esm_tag) != 0) {
device_printf(sc->dev, "Couldn't allocate txq DMA tag\n");
return (ENOMEM);
goto fail_tag_create;
}
/* Allocate kernel memory. */
@ -149,17 +149,14 @@ sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len, efsys_mem_t *esmp)
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
&esmp->esm_map) != 0) {
device_printf(sc->dev, "Couldn't allocate DMA memory\n");
bus_dma_tag_destroy(esmp->esm_tag);
return (ENOMEM);
goto fail_alloc;
}
/* Load map into device memory. */
if (bus_dmamap_load(esmp->esm_tag, esmp->esm_map, vaddr, len,
sfxge_dma_cb, &esmp->esm_addr, 0) != 0) {
device_printf(sc->dev, "Couldn't load DMA mapping\n");
bus_dmamem_free(esmp->esm_tag, vaddr, esmp->esm_map);
bus_dma_tag_destroy(esmp->esm_tag);
return (ENOMEM);
goto fail_load;
}
/*
@ -167,15 +164,20 @@ sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len, efsys_mem_t *esmp)
* and will have set esm_addr to 0 if something went
* wrong.
*/
if (esmp->esm_addr == 0) {
bus_dmamem_free(esmp->esm_tag, esmp->esm_base, esmp->esm_map);
bus_dma_tag_destroy(esmp->esm_tag);
return (ENOMEM);
}
if (esmp->esm_addr == 0)
goto fail_load_check;
esmp->esm_base = vaddr;
return (0);
fail_load_check:
fail_load:
bus_dmamem_free(esmp->esm_tag, vaddr, esmp->esm_map);
fail_alloc:
bus_dma_tag_destroy(esmp->esm_tag);
fail_tag_create:
return (ENOMEM);
}
void

View File

@ -50,6 +50,8 @@ sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop)
struct sfxge_rxq *rxq;
struct sfxge_txq *txq;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
index = evq->index;
rxq = sc->rxq[index];
@ -89,6 +91,8 @@ sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
struct sfxge_rx_sw_desc *rx_desc;
evq = arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
if (evq->exception)
@ -140,6 +144,8 @@ sfxge_ev_exception(void *arg, uint32_t code, uint32_t data)
struct sfxge_softc *sc;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
evq->exception = B_TRUE;
@ -165,6 +171,8 @@ sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
uint16_t magic;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
rxq = sc->rxq[rxq_index];
@ -197,6 +205,8 @@ sfxge_ev_rxq_flush_failed(void *arg, uint32_t rxq_index)
uint16_t magic;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
rxq = sc->rxq[rxq_index];
@ -238,6 +248,8 @@ sfxge_ev_tx(void *arg, uint32_t label, uint32_t id)
unsigned int delta;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
txq = sfxge_get_txq_by_label(evq, label);
KASSERT(txq != NULL, ("txq == NULL"));
@ -278,6 +290,8 @@ sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
uint16_t magic;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
txq = sc->txq[txq_index];
@ -308,6 +322,8 @@ sfxge_ev_software(void *arg, uint16_t magic)
unsigned int label;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
label = magic & SFXGE_MAGIC_DMAQ_LABEL_MASK;
@ -506,7 +522,7 @@ sfxge_int_mod_handler(SYSCTL_HANDLER_ARGS)
* so we have to range-check the value ourselves.
*/
if (moderation >
efx_nic_cfg_get(sc->enp)->enc_evq_moderation_max) {
efx_nic_cfg_get(sc->enp)->enc_evq_timer_max_us) {
error = EINVAL;
goto out;
}
@ -533,6 +549,7 @@ sfxge_ev_initialized(void *arg)
struct sfxge_evq *evq;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
KASSERT(evq->init_state == SFXGE_EVQ_STARTING,
("evq not starting"));
@ -549,6 +566,8 @@ sfxge_ev_link_change(void *arg, efx_link_mode_t link_mode)
struct sfxge_softc *sc;
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
sc = evq->sc;
sfxge_mac_link_update(sc, link_mode);

View File

@ -85,6 +85,68 @@ sfxge_mac_stat_update(struct sfxge_softc *sc)
return (rc);
}
uint64_t
sfxge_get_counter(struct ifnet *ifp, ift_counter c)
{
struct sfxge_softc *sc = ifp->if_softc;
uint64_t *mac_stats;
uint64_t val;
SFXGE_PORT_LOCK(&sc->port);
/* Ignore error and use old values */
(void)sfxge_mac_stat_update(sc);
mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
switch (c) {
case IFCOUNTER_IPACKETS:
val = mac_stats[EFX_MAC_RX_PKTS];
break;
case IFCOUNTER_IERRORS:
val = mac_stats[EFX_MAC_RX_ERRORS];
break;
case IFCOUNTER_OPACKETS:
val = mac_stats[EFX_MAC_TX_PKTS];
break;
case IFCOUNTER_OERRORS:
val = mac_stats[EFX_MAC_TX_ERRORS];
break;
case IFCOUNTER_COLLISIONS:
val = mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
break;
case IFCOUNTER_IBYTES:
val = mac_stats[EFX_MAC_RX_OCTETS];
break;
case IFCOUNTER_OBYTES:
val = mac_stats[EFX_MAC_TX_OCTETS];
break;
case IFCOUNTER_OMCASTS:
val = mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
mac_stats[EFX_MAC_TX_BRDCST_PKTS];
break;
case IFCOUNTER_OQDROPS:
SFXGE_PORT_UNLOCK(&sc->port);
return (sfxge_tx_get_drops(sc));
case IFCOUNTER_IMCASTS:
/* if_imcasts is maintained in net/if_ethersubr.c */
case IFCOUNTER_IQDROPS:
/* if_iqdrops is maintained in net/if_ethersubr.c */
case IFCOUNTER_NOPROTO:
/* if_noproto is maintained in net/if_ethersubr.c */
default:
SFXGE_PORT_UNLOCK(&sc->port);
return (if_get_counter_default(ifp, c));
}
SFXGE_PORT_UNLOCK(&sc->port);
return (val);
}
static int
sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
{
@ -228,7 +290,7 @@ static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
[EFX_LINK_100FDX] = IF_Mbps(100),
[EFX_LINK_1000HDX] = IF_Gbps(1),
[EFX_LINK_1000FDX] = IF_Gbps(1),
[EFX_LINK_10000FDX] = IF_Gbps(10),
[EFX_LINK_10000FDX] = IF_Gbps(10),
};
void

View File

@ -1113,7 +1113,6 @@ sfxge_rx_qinit(struct sfxge_softc *sc, unsigned int index)
/* Allocate and zero DMA space. */
if ((rc = sfxge_dma_alloc(sc, EFX_RXQ_SIZE(sc->rxq_entries), esmp)) != 0)
return (rc);
(void)memset(esmp->esm_base, 0, EFX_RXQ_SIZE(sc->rxq_entries));
/* Allocate buffer table entries. */
sfxge_sram_buf_tbl_alloc(sc, EFX_RXQ_NBUFS(sc->rxq_entries),

View File

@ -214,6 +214,9 @@ sfxge_tx_qdpl_swizzle(struct sfxge_txq *txq)
count++;
} while (mbuf != NULL);
if (count > stdp->std_put_hiwat)
stdp->std_put_hiwat = count;
/* Append the reversed put list to the get list. */
KASSERT(*get_tailp == NULL, ("*get_tailp != NULL"));
*stdp->std_getp = get_next;
@ -1400,7 +1403,6 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
/* Allocate and zero DMA space for the descriptor ring. */
if ((rc = sfxge_dma_alloc(sc, EFX_TXQ_SIZE(sc->txq_entries), esmp)) != 0)
return (rc);
(void)memset(esmp->esm_base, 0, EFX_TXQ_SIZE(sc->txq_entries));
/* Allocate buffer table entries. */
sfxge_sram_buf_tbl_alloc(sc, EFX_TXQ_NBUFS(sc->txq_entries),
@ -1486,6 +1488,10 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
SYSCTL_CHILDREN(txq_node), OID_AUTO,
"dpl_get_hiwat", CTLFLAG_RD | CTLFLAG_STATS,
&stdp->std_get_hiwat, 0, "");
SYSCTL_ADD_UINT(device_get_sysctl_ctx(sc->dev),
SYSCTL_CHILDREN(txq_node), OID_AUTO,
"dpl_put_hiwat", CTLFLAG_RD | CTLFLAG_STATS,
&stdp->std_put_hiwat, 0, "");
#endif
txq->type = type;
@ -1567,6 +1573,29 @@ sfxge_tx_stat_init(struct sfxge_softc *sc)
}
}
uint64_t
sfxge_tx_get_drops(struct sfxge_softc *sc)
{
unsigned int index;
uint64_t drops = 0;
struct sfxge_txq *txq;
/* Sum across all TX queues */
for (index = 0; index < sc->txq_count; index++) {
txq = sc->txq[index];
/*
* In theory, txq->put_overflow and txq->netdown_drops
* should use atomic operation and other should be
* obtained under txq lock, but it is just statistics.
*/
drops += txq->drops + txq->get_overflow +
txq->get_non_tcp_overflow +
txq->put_overflow + txq->netdown_drops +
txq->tso_pdrop_too_many + txq->tso_pdrop_no_rsrc;
}
return (drops);
}
void
sfxge_tx_fini(struct sfxge_softc *sc)
{

View File

@ -102,6 +102,8 @@ struct sfxge_tx_dpl {
* in get list */
unsigned int std_get_hiwat; /* Packets in get list
* high watermark */
unsigned int std_put_hiwat; /* Packets in put list
* high watermark */
};
@ -217,6 +219,7 @@ struct sfxge_txq {
struct sfxge_evq;
extern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *);
extern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc);
extern int sfxge_tx_init(struct sfxge_softc *sc);
extern void sfxge_tx_fini(struct sfxge_softc *sc);

View File

@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#define UART_RIS 0x0f /* Raw interrupt status register */
#define UART_RXREADY (1 << 4) /* RX buffer full */
#define UART_TXEMPTY (1 << 5) /* TX buffer empty */
#define RIS_RTIM (1 << 6) /* Receive timeout */
#define RIS_FE (1 << 7) /* Framing error interrupt status */
#define RIS_PE (1 << 8) /* Parity error interrupt status */
#define RIS_BE (1 << 9) /* Break error interrupt status */
@ -278,11 +279,15 @@ static int
uart_pl011_bus_attach(struct uart_softc *sc)
{
struct uart_bas *bas;
int reg;
bas = &sc->sc_bas;
/* Enable RX & TX interrupts */
__uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY));
/* Clear RX & TX interrupts */
/* Enable interrupts */
reg = (UART_RXREADY | RIS_RTIM | UART_TXEMPTY);
__uart_setreg(bas, UART_IMSC, reg);
/* Clear interrupts */
__uart_setreg(bas, UART_ICR, IMSC_MASK_ALL);
return (0);
@ -337,15 +342,16 @@ static int
uart_pl011_bus_ipend(struct uart_softc *sc)
{
struct uart_bas *bas;
int ipend;
uint32_t ints;
int ipend;
int reg;
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
ints = __uart_getreg(bas, UART_MIS);
ipend = 0;
if (ints & UART_RXREADY)
if (ints & (UART_RXREADY | RIS_RTIM))
ipend |= SER_INT_RXREADY;
if (ints & RIS_BE)
ipend |= SER_INT_BREAK;
@ -355,7 +361,10 @@ uart_pl011_bus_ipend(struct uart_softc *sc)
if (sc->sc_txbusy)
ipend |= SER_INT_TXIDLE;
__uart_setreg(bas, UART_IMSC, UART_RXREADY);
/* Disable TX interrupt */
reg = __uart_getreg(bas, UART_IMSC);
reg &= ~(UART_TXEMPTY);
__uart_setreg(bas, UART_IMSC, reg);
}
uart_unlock(sc->sc_hwmtx);
@ -391,14 +400,14 @@ static int
uart_pl011_bus_receive(struct uart_softc *sc)
{
struct uart_bas *bas;
int rx;
uint32_t ints, xc;
int rx;
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
ints = __uart_getreg(bas, UART_MIS);
while (ints & UART_RXREADY) {
while (ints & (UART_RXREADY | RIS_RTIM)) {
if (uart_rx_full(sc)) {
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
break;
@ -411,7 +420,7 @@ uart_pl011_bus_receive(struct uart_softc *sc)
if (xc & DR_PE)
rx |= UART_STAT_PARERR;
__uart_setreg(bas, UART_ICR, UART_RXREADY);
__uart_setreg(bas, UART_ICR, (UART_RXREADY | RIS_RTIM));
uart_rx_put(sc, rx);
ints = __uart_getreg(bas, UART_MIS);
@ -433,6 +442,7 @@ static int
uart_pl011_bus_transmit(struct uart_softc *sc)
{
struct uart_bas *bas;
int reg;
int i;
bas = &sc->sc_bas;
@ -443,7 +453,12 @@ uart_pl011_bus_transmit(struct uart_softc *sc)
uart_barrier(bas);
}
sc->sc_txbusy = 1;
__uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY));
/* Enable TX interrupt */
reg = __uart_getreg(bas, UART_IMSC);
reg |= (UART_TXEMPTY);
__uart_setreg(bas, UART_IMSC, reg);
uart_unlock(sc->sc_hwmtx);
return (0);

View File

@ -108,12 +108,19 @@
GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK | \
GINTSTS_SESSREQINT)
static int dwc_otg_use_hsic;
#define DWC_OTG_PHY_ULPI 0
#define DWC_OTG_PHY_HSIC 1
#define DWC_OTG_PHY_INTERNAL 2
#ifndef DWC_OTG_PHY_DEFAULT
#define DWC_OTG_PHY_DEFAULT DWC_OTG_PHY_ULPI
#endif
static int dwc_otg_phy_type = DWC_OTG_PHY_DEFAULT;
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW, 0, "USB DWC OTG");
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, use_hsic, CTLFLAG_RDTUN,
&dwc_otg_use_hsic, 0, "DWC OTG uses HSIC interface");
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN,
&dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2 - ULPI/HSIC/INTERNAL");
#ifdef USB_DEBUG
static int dwc_otg_debug;
@ -3766,8 +3773,9 @@ dwc_otg_init(struct dwc_otg_softc *sc)
break;
}
/* select HSIC or non-HSIC mode */
if (dwc_otg_use_hsic) {
/* select HSIC, ULPI or internal PHY mode */
switch (dwc_otg_phy_type) {
case DWC_OTG_PHY_HSIC:
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
GUSBCFG_PHYIF |
GUSBCFG_TRD_TIM_SET(5) | temp);
@ -3779,7 +3787,8 @@ dwc_otg_init(struct dwc_otg_softc *sc)
temp & ~GLPMCFG_HSIC_CONN);
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
temp | GLPMCFG_HSIC_CONN);
} else {
break;
case DWC_OTG_PHY_ULPI:
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
GUSBCFG_ULPI_UTMI_SEL |
GUSBCFG_TRD_TIM_SET(5) | temp);
@ -3788,6 +3797,25 @@ dwc_otg_init(struct dwc_otg_softc *sc)
temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
temp & ~GLPMCFG_HSIC_CONN);
break;
case DWC_OTG_PHY_INTERNAL:
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
GUSBCFG_PHYSEL |
GUSBCFG_TRD_TIM_SET(5) | temp);
DWC_OTG_WRITE_4(sc, DOTG_GOTGCTL, 0);
temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
temp & ~GLPMCFG_HSIC_CONN);
temp = DWC_OTG_READ_4(sc, DOTG_GGPIO);
temp &= ~(DOTG_GGPIO_NOVBUSSENS | DOTG_GGPIO_I2CPADEN);
temp |= (DOTG_GGPIO_VBUSASEN | DOTG_GGPIO_VBUSBSEN |
DOTG_GGPIO_PWRDWN);
DWC_OTG_WRITE_4(sc, DOTG_GGPIO, temp);
break;
default:
break;
}
/* clear global nak */
@ -3807,9 +3835,6 @@ dwc_otg_init(struct dwc_otg_softc *sc)
/* wait 10ms */
usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
/* pull up D+ */
dwc_otg_pull_up(sc);
temp = DWC_OTG_READ_4(sc, DOTG_GHWCFG3);
sc->sc_fifo_size = 4 * GHWCFG3_DFIFODEPTH_GET(temp);
@ -4548,11 +4573,15 @@ dwc_otg_roothub_exec(struct usb_device *udev,
/* nops */
break;
case UHF_PORT_POWER:
sc->sc_flags.port_powered = 1;
if (sc->sc_mode == DWC_MODE_HOST || sc->sc_mode == DWC_MODE_OTG) {
sc->sc_hprt_val |= HPRT_PRTPWR;
DWC_OTG_WRITE_4(sc, DOTG_HPRT, sc->sc_hprt_val);
}
sc->sc_flags.port_powered = 1;
if (sc->sc_mode == DWC_MODE_DEVICE || sc->sc_mode == DWC_MODE_OTG) {
/* pull up D+, if any */
dwc_otg_pull_up(sc);
}
break;
default:
err = USB_ERR_IOERROR;

View File

@ -196,6 +196,14 @@
#define GUSBCFG_TOUTCAL_MASK 0x00000007
#define GUSBCFG_TOUTCAL_SHIFT 0
/* STM32F4 */
#define DOTG_GGPIO_NOVBUSSENS (1 << 21)
#define DOTG_GGPIO_SOFOUTEN (1 << 20)
#define DOTG_GGPIO_VBUSBSEN (1 << 19)
#define DOTG_GGPIO_VBUSASEN (1 << 18)
#define DOTG_GGPIO_I2CPADEN (1 << 17)
#define DOTG_GGPIO_PWRDWN (1 << 16)
#define GRSTCTL_AHBIDLE (1<<31)
#define GRSTCTL_DMAREQ (1<<30)
#define GRSTCTL_TXFNUM_MASK 0x000007c0

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