Merge ^/head r318380 through r318559.
This commit is contained in:
commit
ea1e967cbf
@ -1080,9 +1080,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
#endif
|
||||
mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH;
|
||||
if (flags == EV_BACKCMD) {
|
||||
memout.nleft = 0;
|
||||
memout.nextc = memout.buf;
|
||||
memout.bufsize = 64;
|
||||
mode |= REDIR_BACKQ;
|
||||
}
|
||||
savecmdname = commandname;
|
||||
@ -1134,8 +1132,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
exitshell(exitstatus);
|
||||
if (flags == EV_BACKCMD) {
|
||||
backcmd->buf = memout.buf;
|
||||
backcmd->nleft = memout.nextc - memout.buf;
|
||||
backcmd->nleft = memout.buf != NULL ?
|
||||
memout.nextc - memout.buf : 0;
|
||||
memout.buf = NULL;
|
||||
memout.nextc = NULL;
|
||||
memout.bufend = NULL;
|
||||
memout.bufsize = 64;
|
||||
}
|
||||
if (cmdentry.u.index != EXECCMD)
|
||||
popredir();
|
||||
|
@ -71,9 +71,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static int doformat_wr(void *, const char *, int);
|
||||
|
||||
struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
|
||||
struct output errout = {NULL, 0, NULL, 256, 2, 0};
|
||||
struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
|
||||
struct output output = {NULL, NULL, NULL, OUTBUFSIZ, 1, 0};
|
||||
struct output errout = {NULL, NULL, NULL, 256, 2, 0};
|
||||
struct output memout = {NULL, NULL, NULL, 64, MEM_OUT, 0};
|
||||
struct output *out1 = &output;
|
||||
struct output *out2 = &errout;
|
||||
|
||||
@ -208,26 +208,26 @@ outbin(const void *data, size_t len, struct output *file)
|
||||
void
|
||||
emptyoutbuf(struct output *dest)
|
||||
{
|
||||
int offset;
|
||||
int offset, newsize;
|
||||
|
||||
if (dest->buf == NULL) {
|
||||
INTOFF;
|
||||
dest->buf = ckmalloc(dest->bufsize);
|
||||
dest->nextc = dest->buf;
|
||||
dest->nleft = dest->bufsize;
|
||||
dest->bufend = dest->buf + dest->bufsize;
|
||||
INTON;
|
||||
} else if (dest->fd == MEM_OUT) {
|
||||
offset = dest->bufsize;
|
||||
offset = dest->nextc - dest->buf;
|
||||
newsize = dest->bufsize << 1;
|
||||
INTOFF;
|
||||
dest->bufsize <<= 1;
|
||||
dest->buf = ckrealloc(dest->buf, dest->bufsize);
|
||||
dest->nleft = dest->bufsize - offset;
|
||||
dest->buf = ckrealloc(dest->buf, newsize);
|
||||
dest->bufsize = newsize;
|
||||
dest->bufend = dest->buf + newsize;
|
||||
dest->nextc = dest->buf + offset;
|
||||
INTON;
|
||||
} else {
|
||||
flushout(dest);
|
||||
}
|
||||
dest->nleft--;
|
||||
}
|
||||
|
||||
|
||||
@ -248,20 +248,13 @@ flushout(struct output *dest)
|
||||
if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0)
|
||||
dest->flags |= OUTPUT_ERR;
|
||||
dest->nextc = dest->buf;
|
||||
dest->nleft = dest->bufsize;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
freestdout(void)
|
||||
{
|
||||
INTOFF;
|
||||
if (output.buf) {
|
||||
ckfree(output.buf);
|
||||
output.buf = NULL;
|
||||
output.nleft = 0;
|
||||
}
|
||||
INTON;
|
||||
output.nextc = output.buf;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
struct output {
|
||||
char *nextc;
|
||||
int nleft;
|
||||
char *bufend;
|
||||
char *buf;
|
||||
int bufsize;
|
||||
short fd;
|
||||
@ -75,7 +75,7 @@ void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
|
||||
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
|
||||
int xwrite(int, const char *, int);
|
||||
|
||||
#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
|
||||
#define outc(c, file) ((file)->nextc == (file)->bufend ? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
|
||||
#define out1c(c) outc(c, out1);
|
||||
#define out2c(c) outcslow(c, out2);
|
||||
|
||||
|
@ -368,7 +368,7 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
|
||||
int flag)
|
||||
{
|
||||
int error;
|
||||
timestruc_t ts;
|
||||
timespec_t ts;
|
||||
hrtime_t delta;
|
||||
|
||||
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
|
||||
@ -381,8 +381,13 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
|
||||
if (delta <= 0)
|
||||
return (-1);
|
||||
|
||||
ts.tv_sec = delta / NANOSEC;
|
||||
ts.tv_nsec = delta % NANOSEC;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += delta / NANOSEC;
|
||||
ts.tv_nsec += delta % NANOSEC;
|
||||
if (ts.tv_nsec >= NANOSEC) {
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= NANOSEC;
|
||||
}
|
||||
|
||||
ASSERT(mutex_owner(mp) == curthread);
|
||||
mp->m_owner = NULL;
|
||||
|
@ -139,11 +139,6 @@ exclude EXFAIL common/pid/tst.newprobes.ksh
|
||||
exclude EXFAIL common/pid/tst.provregex2.ksh
|
||||
exclude EXFAIL common/pid/tst.provregex4.ksh
|
||||
|
||||
# libproc doesn't properly handle probe sites that correspond to multiple
|
||||
# symbols.
|
||||
exclude EXFAIL common/pid/tst.weak1.d
|
||||
exclude EXFAIL common/pid/tst.weak2.d
|
||||
|
||||
# This test checks for a leading tab on a line before #define. That is illegal
|
||||
# on Solaris, but the clang pre-processor on FreeBSD is happy with code like
|
||||
# that.
|
||||
|
@ -28,6 +28,10 @@
|
||||
# Verifies that vnd works with files stored in tmpfs.
|
||||
#
|
||||
|
||||
# Begin FreeBSD
|
||||
MD_DEVICE_FILE=md.device
|
||||
# End FreeBSD
|
||||
|
||||
atf_test_case basic cleanup
|
||||
basic_head() {
|
||||
atf_set "descr" "Verifies that vnd works with files stored in tmpfs"
|
||||
@ -41,7 +45,10 @@ basic_body() {
|
||||
# Begin FreeBSD
|
||||
if true; then
|
||||
atf_check -s eq:0 -o empty -e empty mkdir mnt
|
||||
atf_check -s eq:0 -o empty -e empty mdmfs -F disk.img md3 mnt
|
||||
atf_check -s eq:0 -o empty -e empty mdmfs -F disk.img md mnt
|
||||
md_dev=$(df mnt | awk 'NR != 1 { print $1 }' | xargs basename)
|
||||
atf_check test -c /dev/$md_dev # Sanity check
|
||||
echo -n $md_dev > $TMPDIR/$MD_DEVICE_FILE
|
||||
else
|
||||
# End FreeBSD
|
||||
atf_check -s eq:0 -o empty -e empty vndconfig /dev/vnd3 disk.img
|
||||
@ -67,31 +74,23 @@ basic_body() {
|
||||
done
|
||||
|
||||
atf_check -s eq:0 -o empty -e empty umount mnt
|
||||
# Begin FreeBSD
|
||||
if true; then
|
||||
atf_check -s eq:0 -o empty -e empty mdconfig -d -u 3
|
||||
else
|
||||
# End FreeBSD
|
||||
atf_check -s eq:0 -o empty -e empty vndconfig -u /dev/vnd3
|
||||
# Begin FreeBSD
|
||||
fi
|
||||
# End FreeBSD
|
||||
|
||||
test_unmount
|
||||
touch done
|
||||
}
|
||||
basic_cleanup() {
|
||||
# Begin FreeBSD
|
||||
if md_dev=$(cat $TMPDIR/$MD_DEVICE_FILE); then
|
||||
echo "Will try disconnecting $md_dev"
|
||||
else
|
||||
echo "$MD_DEVICE_FILE doesn't exist in $TMPDIR; returning early"
|
||||
return 0
|
||||
fi
|
||||
# End FreeBSD
|
||||
if [ ! -f done ]; then
|
||||
umount mnt 2>/dev/null 1>&2
|
||||
# Begin FreeBSD
|
||||
if true; then
|
||||
[ ! -c /dev/md3 ] || mdconfig -d -u 3
|
||||
else
|
||||
# End FreeBSD
|
||||
vndconfig -u /dev/vnd3 2>/dev/null 1>&2
|
||||
# Begin FreeBSD
|
||||
fi
|
||||
# End FreeBSD
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,6 @@ FILESGROUPS= FILES
|
||||
|
||||
# No need as it is empty and just causes rebuilds since this file does so much.
|
||||
UPDATE_DEPENDFILE= no
|
||||
SUBDIR= \
|
||||
newsyslog.conf.d \
|
||||
syslog.d
|
||||
|
||||
.if ${MK_SENDMAIL} != "no"
|
||||
SUBDIR+=sendmail
|
||||
@ -253,9 +250,11 @@ distribution:
|
||||
.if ${MK_CASPER} != "no"
|
||||
${_+_}cd ${.CURDIR}/casper; ${MAKE} install
|
||||
.endif
|
||||
${_+_}cd ${.CURDIR}/cron.d; ${MAKE} install
|
||||
${_+_}cd ${.CURDIR}/defaults; ${MAKE} install
|
||||
${_+_}cd ${.CURDIR}/devd; ${MAKE} install
|
||||
${_+_}cd ${.CURDIR}/gss; ${MAKE} install
|
||||
${_+_}cd ${.CURDIR}/newsyslog.conf.d; ${MAKE} install
|
||||
.if ${MK_NTP} != "no"
|
||||
${_+_}cd ${.CURDIR}/ntp; ${MAKE} install
|
||||
.endif
|
||||
@ -265,6 +264,7 @@ distribution:
|
||||
.endif
|
||||
${_+_}cd ${.CURDIR}/rc.d; ${MAKE} install
|
||||
${_+_}cd ${SRCTOP}/share/termcap; ${MAKE} etc-termcap
|
||||
${_+_}cd ${.CURDIR}/syslog.d; ${MAKE} install
|
||||
${_+_}cd ${SRCTOP}/usr.sbin/rmt; ${MAKE} etc-rmt
|
||||
${_+_}cd ${.CURDIR}/pam.d; ${MAKE} install
|
||||
cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 0444 \
|
||||
|
11
etc/cron.d/Makefile
Normal file
11
etc/cron.d/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
.if ${MK_AT} != "no"
|
||||
FILES+= at
|
||||
.endif
|
||||
|
||||
BINDIR= /etc/cron.d
|
||||
|
||||
.include <bsd.prog.mk>
|
7
etc/cron.d/at
Normal file
7
etc/cron.d/at
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
SHELL=/bin/sh
|
||||
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
||||
# See crontab(5) for field format.
|
||||
*/5 * * * * root /usr/libexec/atrun
|
@ -7,8 +7,6 @@ PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
#
|
||||
#minute hour mday month wday who command
|
||||
#
|
||||
*/5 * * * * root /usr/libexec/atrun
|
||||
#
|
||||
# Save some entropy so that /dev/random can re-seed on boot.
|
||||
*/11 * * * * operator /usr/libexec/save-entropy
|
||||
#
|
||||
|
@ -622,6 +622,8 @@
|
||||
..
|
||||
file2c
|
||||
..
|
||||
getconf
|
||||
..
|
||||
grep
|
||||
..
|
||||
gzip
|
||||
|
@ -41,7 +41,7 @@ typedef int cmp_t(void *, const void *, const void *);
|
||||
typedef int cmp_t(const void *, const void *);
|
||||
#endif
|
||||
static inline char *med3(char *, char *, char *, cmp_t *, void *);
|
||||
static inline void swapfunc(char *, char *, int, int, int);
|
||||
static inline void swapfunc(char *, char *, size_t, int, int);
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? a : b)
|
||||
|
||||
@ -49,7 +49,7 @@ static inline void swapfunc(char *, char *, int, int, int);
|
||||
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
|
||||
*/
|
||||
#define swapcode(TYPE, parmi, parmj, n) { \
|
||||
long i = (n) / sizeof (TYPE); \
|
||||
size_t i = (n) / sizeof (TYPE); \
|
||||
TYPE *pi = (TYPE *) (parmi); \
|
||||
TYPE *pj = (TYPE *) (parmj); \
|
||||
do { \
|
||||
@ -64,7 +64,7 @@ static inline void swapfunc(char *, char *, int, int, int);
|
||||
es % sizeof(TYPE) ? 2 : es == sizeof(TYPE) ? 0 : 1;
|
||||
|
||||
static inline void
|
||||
swapfunc( char *a, char *b, int n, int swaptype_long, int swaptype_int)
|
||||
swapfunc(char *a, char *b, size_t n, int swaptype_long, int swaptype_int)
|
||||
{
|
||||
if (swaptype_long <= 1)
|
||||
swapcode(long, a, b, n)
|
||||
@ -117,7 +117,7 @@ qsort(void *a, size_t n, size_t es, cmp_t *cmp)
|
||||
#endif
|
||||
{
|
||||
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
||||
size_t d, r;
|
||||
size_t d1, d2;
|
||||
int cmp_result;
|
||||
int swaptype_long, swaptype_int, swap_cnt;
|
||||
|
||||
@ -137,7 +137,8 @@ loop: SWAPINIT(long, a, es);
|
||||
pl = a;
|
||||
pn = (char *)a + (n - 1) * es;
|
||||
if (n > 40) {
|
||||
d = (n / 8) * es;
|
||||
size_t d = (n / 8) * es;
|
||||
|
||||
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
|
||||
pm = med3(pm - d, pm, pm + d, cmp, thunk);
|
||||
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
|
||||
@ -182,21 +183,43 @@ loop: SWAPINIT(long, a, es);
|
||||
}
|
||||
|
||||
pn = (char *)a + n * es;
|
||||
r = MIN(pa - (char *)a, pb - pa);
|
||||
vecswap(a, pb - r, r);
|
||||
r = MIN(pd - pc, pn - pd - es);
|
||||
vecswap(pb, pn - r, r);
|
||||
if ((r = pb - pa) > es)
|
||||
d1 = MIN(pa - (char *)a, pb - pa);
|
||||
vecswap(a, pb - d1, d1);
|
||||
d1 = MIN(pd - pc, pn - pd - es);
|
||||
vecswap(pb, pn - d1, d1);
|
||||
|
||||
d1 = pb - pa;
|
||||
d2 = pd - pc;
|
||||
if (d1 <= d2) {
|
||||
/* Recurse on left partition, then iterate on right partition */
|
||||
if (d1 > es) {
|
||||
#ifdef I_AM_QSORT_R
|
||||
qsort_r(a, r / es, es, thunk, cmp);
|
||||
qsort_r(a, d1 / es, es, thunk, cmp);
|
||||
#else
|
||||
qsort(a, r / es, es, cmp);
|
||||
qsort(a, d1 / es, es, cmp);
|
||||
#endif
|
||||
if ((r = pd - pc) > es) {
|
||||
/* Iterate rather than recurse to save stack space */
|
||||
a = pn - r;
|
||||
n = r / es;
|
||||
goto loop;
|
||||
}
|
||||
if (d2 > es) {
|
||||
/* Iterate rather than recurse to save stack space */
|
||||
/* qsort(pn - d2, d2 / es, es, cmp); */
|
||||
a = pn - d2;
|
||||
n = d2 / es;
|
||||
goto loop;
|
||||
}
|
||||
} else {
|
||||
/* Recurse on right partition, then iterate on left partition */
|
||||
if (d2 > es) {
|
||||
#ifdef I_AM_QSORT_R
|
||||
qsort_r(pn - d2, d2 / es, es, thunk, cmp);
|
||||
#else
|
||||
qsort(pn - d2, d2 / es, es, cmp);
|
||||
#endif
|
||||
}
|
||||
if (d1 > es) {
|
||||
/* Iterate rather than recurse to save stack space */
|
||||
/* qsort(a, d1 / es, es, cmp); */
|
||||
n = d1 / es;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
/* qsort(pn - r, r / es, es, cmp);*/
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ ATF_TESTS_C+= popen_test
|
||||
ATF_TESTS_C+= posix_spawn_test
|
||||
ATF_TESTS_C+= wordexp_test
|
||||
ATF_TESTS_C+= dlopen_empty_test
|
||||
ATF_TESTS_C+= realpath2_test
|
||||
|
||||
# TODO: t_closefrom, t_cpuset, t_fmtcheck, t_randomid,
|
||||
# TODO: t_siginfo (fixes require further inspection)
|
||||
|
102
lib/libc/tests/gen/realpath2_test.c
Normal file
102
lib/libc/tests/gen/realpath2_test.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Jan Kokemüller
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
ATF_TC(realpath_buffer_overflow);
|
||||
ATF_TC_HEAD(realpath_buffer_overflow, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Test for out of bounds read from 'left' array "
|
||||
"(compile realpath.c with '-fsanitize=address')");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(realpath_buffer_overflow, tc)
|
||||
{
|
||||
char path[MAXPATHLEN] = { 0 };
|
||||
char resb[MAXPATHLEN] = { 0 };
|
||||
size_t i;
|
||||
|
||||
path[0] = 'a';
|
||||
path[1] = '/';
|
||||
for (i = 2; i < sizeof(path) - 1; ++i) {
|
||||
path[i] = 'a';
|
||||
}
|
||||
|
||||
ATF_REQUIRE(realpath(path, resb) == NULL);
|
||||
}
|
||||
|
||||
ATF_TC(realpath_empty_symlink);
|
||||
ATF_TC_HEAD(realpath_empty_symlink, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Test for correct behavior when encountering empty symlinks");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(realpath_empty_symlink, tc)
|
||||
{
|
||||
char path[MAXPATHLEN] = { 0 };
|
||||
char slnk[MAXPATHLEN] = { 0 };
|
||||
char resb[MAXPATHLEN] = { 0 };
|
||||
int fd;
|
||||
|
||||
(void)strlcat(slnk, "empty_symlink", sizeof(slnk));
|
||||
|
||||
ATF_REQUIRE(symlink("", slnk) == 0);
|
||||
|
||||
fd = open("aaa", O_RDONLY | O_CREAT, 0600);
|
||||
|
||||
ATF_REQUIRE(fd >= 0);
|
||||
ATF_REQUIRE(close(fd) == 0);
|
||||
|
||||
(void)strlcat(path, "empty_symlink", sizeof(path));
|
||||
(void)strlcat(path, "/aaa", sizeof(path));
|
||||
|
||||
ATF_REQUIRE_ERRNO(ENOENT, realpath(path, resb) == NULL);
|
||||
|
||||
ATF_REQUIRE(unlink("aaa") == 0);
|
||||
ATF_REQUIRE(unlink(slnk) == 0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, realpath_buffer_overflow);
|
||||
ATF_TP_ADD_TC(tp, realpath_empty_symlink);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
@ -607,7 +607,7 @@ _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize,
|
||||
/* Kernel checks invalid bits, we check it here too. */
|
||||
size_t i;
|
||||
for (i = kern_size; i < cpusetsize; ++i) {
|
||||
if (((char *)cpusetp)[i])
|
||||
if (((const char *)cpusetp)[i])
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,8 @@ _Unwind_GetCFA(struct _Unwind_Context *context)
|
||||
#endif /* PIC */
|
||||
|
||||
static void
|
||||
thread_unwind_cleanup(_Unwind_Reason_Code code, struct _Unwind_Exception *e)
|
||||
thread_unwind_cleanup(_Unwind_Reason_Code code __unused,
|
||||
struct _Unwind_Exception *e __unused)
|
||||
{
|
||||
/*
|
||||
* Specification said that _Unwind_Resume should not be used here,
|
||||
@ -130,10 +131,10 @@ thread_unwind_cleanup(_Unwind_Reason_Code code, struct _Unwind_Exception *e)
|
||||
}
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
thread_unwind_stop(int version, _Unwind_Action actions,
|
||||
int64_t exc_class,
|
||||
struct _Unwind_Exception *exc_obj,
|
||||
struct _Unwind_Context *context, void *stop_parameter)
|
||||
thread_unwind_stop(int version __unused, _Unwind_Action actions,
|
||||
int64_t exc_class __unused,
|
||||
struct _Unwind_Exception *exc_obj __unused,
|
||||
struct _Unwind_Context *context, void *stop_parameter __unused)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct pthread_cleanup *cur;
|
||||
|
@ -441,7 +441,7 @@ _thr_signal_init(int dlopened)
|
||||
}
|
||||
|
||||
void
|
||||
_thr_sigact_unload(struct dl_phdr_info *phdr_info)
|
||||
_thr_sigact_unload(struct dl_phdr_info *phdr_info __unused)
|
||||
{
|
||||
#if 0
|
||||
struct pthread *curthread = _get_curthread();
|
||||
|
@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
|
||||
static struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
|
||||
|
||||
__weak_reference(_pthread_key_create, pthread_key_create);
|
||||
__weak_reference(_pthread_key_delete, pthread_key_delete);
|
||||
|
@ -290,6 +290,19 @@ _thr_stack_alloc(struct pthread_attr *attr)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable this warning from clang:
|
||||
*
|
||||
* cast from 'char *' to
|
||||
* 'struct stack *' increases required alignment from 1 to 8
|
||||
* [-Werror,-Wcast-align]
|
||||
* spare_stack = (struct stack *)
|
||||
*/
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
#endif
|
||||
|
||||
/* This function must be called with _thread_list_lock held. */
|
||||
void
|
||||
_thr_stack_free(struct pthread_attr *attr)
|
||||
@ -316,3 +329,7 @@ _thr_stack_free(struct pthread_attr *attr)
|
||||
attr->stackaddr_attr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
@ -37,6 +37,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
|
||||
#endif
|
||||
|
||||
/* A collection of symbols needed by debugger */
|
||||
|
||||
/* int _libthr_debug */
|
||||
|
@ -168,7 +168,7 @@ __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
|
||||
}
|
||||
|
||||
int
|
||||
__thr_umutex_unlock(struct umutex *mtx, uint32_t id)
|
||||
__thr_umutex_unlock(struct umutex *mtx)
|
||||
{
|
||||
|
||||
return (_umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0));
|
||||
|
@ -44,7 +44,7 @@ int __thr_umutex_lock(struct umutex *mtx, uint32_t id) __hidden;
|
||||
int __thr_umutex_lock_spin(struct umutex *mtx, uint32_t id) __hidden;
|
||||
int __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
|
||||
const struct timespec *timeout) __hidden;
|
||||
int __thr_umutex_unlock(struct umutex *mtx, uint32_t id) __hidden;
|
||||
int __thr_umutex_unlock(struct umutex *mtx) __hidden;
|
||||
int __thr_umutex_trylock(struct umutex *mtx) __hidden;
|
||||
int __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
|
||||
uint32_t *oldceiling) __hidden;
|
||||
@ -155,7 +155,7 @@ _thr_umutex_unlock2(struct umutex *mtx, uint32_t id, int *defer)
|
||||
if (atomic_cmpset_rel_32(&mtx->m_owner, id, noncst ?
|
||||
UMUTEX_RB_NOTRECOV : UMUTEX_UNOWNED))
|
||||
return (0);
|
||||
return (__thr_umutex_unlock(mtx, id));
|
||||
return (__thr_umutex_unlock(mtx));
|
||||
}
|
||||
|
||||
do {
|
||||
|
@ -192,7 +192,7 @@ the directories specified by
|
||||
will be searched first
|
||||
followed by the set of built-in standard directories.
|
||||
This variable is unset for set-user-ID and set-group-ID programs.
|
||||
.Ev LD_LIBRARY_PATH_FDS
|
||||
.It Ev LD_LIBRARY_PATH_FDS
|
||||
A colon separated list of file descriptor numbers for library directories.
|
||||
This is intended for use within
|
||||
.Xr capsicum 4
|
||||
|
@ -1,10 +1,14 @@
|
||||
/*-
|
||||
* Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
|
||||
* Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
|
||||
* Copyright 2009-2012 Konstantin Belousov <kib@FreeBSD.ORG>.
|
||||
* Copyright 2009-2013 Konstantin Belousov <kib@FreeBSD.ORG>.
|
||||
* Copyright 2012 John Marino <draco@marino.st>.
|
||||
* Copyright 2014-2017 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Konstantin Belousov
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -24,8 +28,6 @@
|
||||
* 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -34,6 +36,9 @@
|
||||
* John Polstra <jdp@polstra.com>.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mman.h>
|
||||
@ -115,8 +120,10 @@ static void objlist_push_head(Objlist *, Obj_Entry *);
|
||||
static void objlist_push_tail(Objlist *, Obj_Entry *);
|
||||
static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *);
|
||||
static void objlist_remove(Objlist *, Obj_Entry *);
|
||||
static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp);
|
||||
static int parse_integer(const char *);
|
||||
static void *path_enumerate(const char *, path_enum_proc, void *);
|
||||
static void print_usage(const char *argv0);
|
||||
static void release_object(Obj_Entry *);
|
||||
static int relocate_object_dag(Obj_Entry *root, bool bind_now,
|
||||
Obj_Entry *rtldobj, int flags, RtldLockState *lockstate);
|
||||
@ -345,12 +352,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
const Elf_Phdr *phdr;
|
||||
Objlist initlist;
|
||||
RtldLockState lockstate;
|
||||
struct stat st;
|
||||
Elf_Addr *argcp;
|
||||
char **argv, *argv0, **env, **envp, *kexecpath, *library_path_rpath;
|
||||
caddr_t imgentry;
|
||||
char buf[MAXPATHLEN];
|
||||
int argc, fd, i, mib[2], phnum;
|
||||
int argc, fd, i, mib[2], phnum, rtld_argc;
|
||||
size_t len;
|
||||
bool dir_enable, explicit_fd, search_in_path;
|
||||
|
||||
/*
|
||||
* On entry, the dynamic linker itself has not been relocated yet.
|
||||
@ -419,38 +428,75 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
assert(aux_info[AT_PHDR] != NULL);
|
||||
phdr = (const Elf_Phdr *)aux_info[AT_PHDR]->a_un.a_ptr;
|
||||
if (phdr == obj_rtld.phdr) {
|
||||
if (!trust) {
|
||||
rtld_printf("Tainted process refusing to run binary %s\n",
|
||||
argv0);
|
||||
rtld_die();
|
||||
}
|
||||
dbg("opening main program in direct exec mode");
|
||||
if (argc >= 2) {
|
||||
argv0 = argv[1];
|
||||
fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY);
|
||||
rtld_argc = parse_args(argv, argc, &search_in_path, &fd);
|
||||
argv0 = argv[rtld_argc];
|
||||
explicit_fd = (fd != -1);
|
||||
if (!explicit_fd)
|
||||
fd = open(argv0, O_RDONLY | O_CLOEXEC | O_VERIFY);
|
||||
if (fd == -1) {
|
||||
rtld_printf("Opening %s: %s\n", argv0,
|
||||
rtld_strerror(errno));
|
||||
rtld_die();
|
||||
}
|
||||
if (fstat(fd, &st) == -1) {
|
||||
_rtld_error("failed to fstat FD %d (%s): %s", fd,
|
||||
explicit_fd ? "user-provided descriptor" : argv0,
|
||||
rtld_strerror(errno));
|
||||
rtld_die();
|
||||
}
|
||||
|
||||
/*
|
||||
* Rough emulation of the permission checks done by
|
||||
* execve(2), only Unix DACs are checked, ACLs are
|
||||
* ignored. Preserve the semantic of disabling owner
|
||||
* to execute if owner x bit is cleared, even if
|
||||
* others x bit is enabled.
|
||||
* mmap(2) does not allow to mmap with PROT_EXEC if
|
||||
* binary' file comes from noexec mount. We cannot
|
||||
* set VV_TEXT on the binary.
|
||||
*/
|
||||
dir_enable = false;
|
||||
if (st.st_uid == geteuid()) {
|
||||
if ((st.st_mode & S_IXUSR) != 0)
|
||||
dir_enable = true;
|
||||
} else if (st.st_gid == getegid()) {
|
||||
if ((st.st_mode & S_IXGRP) != 0)
|
||||
dir_enable = true;
|
||||
} else if ((st.st_mode & S_IXOTH) != 0) {
|
||||
dir_enable = true;
|
||||
}
|
||||
if (!dir_enable) {
|
||||
rtld_printf("No execute permission for binary %s\n",
|
||||
argv0);
|
||||
rtld_die();
|
||||
}
|
||||
|
||||
/*
|
||||
* For direct exec mode, argv[0] is the interpreter
|
||||
* name, we must remove it and shift arguments left by
|
||||
* 1 before invoking binary main. Since stack layout
|
||||
* name, we must remove it and shift arguments left
|
||||
* before invoking binary main. Since stack layout
|
||||
* places environment pointers and aux vectors right
|
||||
* after the terminating NULL, we must shift
|
||||
* environment and aux as well.
|
||||
* XXX Shift will be > 1 when options are implemented.
|
||||
*/
|
||||
main_argc = argc - rtld_argc;
|
||||
for (i = 0; i <= main_argc; i++)
|
||||
argv[i] = argv[i + rtld_argc];
|
||||
*argcp -= rtld_argc;
|
||||
environ = env = envp = argv + main_argc + 1;
|
||||
do {
|
||||
*argv = *(argv + 1);
|
||||
argv++;
|
||||
} while (*argv != NULL);
|
||||
*argcp -= 1;
|
||||
main_argc = argc - 1;
|
||||
environ = env = envp = argv;
|
||||
do {
|
||||
*envp = *(envp + 1);
|
||||
*envp = *(envp + rtld_argc);
|
||||
envp++;
|
||||
} while (*envp != NULL);
|
||||
aux = auxp = (Elf_Auxinfo *)envp;
|
||||
auxpf = (Elf_Auxinfo *)(envp + 1);
|
||||
auxpf = (Elf_Auxinfo *)(envp + rtld_argc);
|
||||
for (;; auxp++, auxpf++) {
|
||||
*auxp = *auxpf;
|
||||
if (auxp->a_type == AT_NULL)
|
||||
@ -5235,6 +5281,81 @@ symlook_init_from_req(SymLook *dst, const SymLook *src)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse a set of command-line arguments.
|
||||
*/
|
||||
static int
|
||||
parse_args(char* argv[], int argc, bool *use_pathp, int *fdp)
|
||||
{
|
||||
const char *arg;
|
||||
int fd, i, j, arglen;
|
||||
char opt;
|
||||
|
||||
dbg("Parsing command-line arguments");
|
||||
*use_pathp = false;
|
||||
*fdp = -1;
|
||||
|
||||
for (i = 1; i < argc; i++ ) {
|
||||
arg = argv[i];
|
||||
dbg("argv[%d]: '%s'", i, arg);
|
||||
|
||||
/*
|
||||
* rtld arguments end with an explicit "--" or with the first
|
||||
* non-prefixed argument.
|
||||
*/
|
||||
if (strcmp(arg, "--") == 0) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if (arg[0] != '-')
|
||||
break;
|
||||
|
||||
/*
|
||||
* All other arguments are single-character options that can
|
||||
* be combined, so we need to search through `arg` for them.
|
||||
*/
|
||||
arglen = strlen(arg);
|
||||
for (j = 1; j < arglen; j++) {
|
||||
opt = arg[j];
|
||||
if (opt == 'h') {
|
||||
print_usage(argv[0]);
|
||||
rtld_die();
|
||||
} else if (opt == 'f') {
|
||||
/*
|
||||
* -f XX can be used to specify a descriptor for the
|
||||
* binary named at the command line (i.e., the later
|
||||
* argument will specify the process name but the
|
||||
* descriptor is what will actually be executed)
|
||||
*/
|
||||
if (j != arglen - 1) {
|
||||
/* -f must be the last option in, e.g., -abcf */
|
||||
_rtld_error("invalid options: %s", arg);
|
||||
rtld_die();
|
||||
}
|
||||
i++;
|
||||
fd = parse_integer(argv[i]);
|
||||
if (fd == -1) {
|
||||
_rtld_error("invalid file descriptor: '%s'",
|
||||
argv[i]);
|
||||
rtld_die();
|
||||
}
|
||||
*fdp = fd;
|
||||
break;
|
||||
/* TODO:
|
||||
} else if (opt == 'p') {
|
||||
*use_pathp = true;
|
||||
*/
|
||||
} else {
|
||||
rtld_printf("invalid argument: '%s'\n", arg);
|
||||
print_usage(argv[0]);
|
||||
rtld_die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a file descriptor number without pulling in more of libc (e.g. atoi).
|
||||
*/
|
||||
@ -5262,6 +5383,21 @@ parse_integer(const char *str)
|
||||
return (n);
|
||||
}
|
||||
|
||||
static void
|
||||
print_usage(const char *argv0)
|
||||
{
|
||||
|
||||
rtld_printf("Usage: %s [-h] [-f <FD>] [--] <binary> [<args>]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -h Display this help message\n"
|
||||
/* TODO: " -p Search in PATH for named binary\n" */
|
||||
" -f <FD> Execute <FD> instead of searching for <binary>\n"
|
||||
" -- End of RTLD options\n"
|
||||
" <binary> Name of process to execute\n"
|
||||
" <args> Arguments to the executed process\n", argv0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for libc_pic-provided functions.
|
||||
*/
|
||||
|
@ -1260,16 +1260,14 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type,
|
||||
if ((p = strchr(arg, ',')) != NULL)
|
||||
*p++ = '\0';
|
||||
|
||||
if ((port = htons(strtol(arg, NULL, 10))) == 0) {
|
||||
port = htons(strtol(arg, &pp, 10));
|
||||
if (*pp != '\0') {
|
||||
if ((sent = getservbyname(arg, NULL)) == NULL)
|
||||
errx(EX_DATAERR, "Unknown service: %s",
|
||||
arg);
|
||||
else
|
||||
key = sent->s_port;
|
||||
port = sent->s_port;
|
||||
}
|
||||
|
||||
tfe->sport = port;
|
||||
|
||||
arg = p;
|
||||
}
|
||||
|
||||
@ -1304,16 +1302,14 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type,
|
||||
if ((p = strchr(arg, ',')) != NULL)
|
||||
*p++ = '\0';
|
||||
|
||||
if ((port = htons(strtol(arg, NULL, 10))) == 0) {
|
||||
port = htons(strtol(arg, &pp, 10));
|
||||
if (*pp != '\0') {
|
||||
if ((sent = getservbyname(arg, NULL)) == NULL)
|
||||
errx(EX_DATAERR, "Unknown service: %s",
|
||||
arg);
|
||||
else
|
||||
key = sent->s_port;
|
||||
port = sent->s_port;
|
||||
}
|
||||
|
||||
tfe->dport = port;
|
||||
|
||||
arg = p;
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ MAN= aac.4 \
|
||||
cc_newreno.4 \
|
||||
cc_vegas.4 \
|
||||
${_ccd.4} \
|
||||
ccr.4 \
|
||||
cd.4 \
|
||||
cdce.4 \
|
||||
cfi.4 \
|
||||
|
110
share/man/man4/ccr.4
Normal file
110
share/man/man4/ccr.4
Normal file
@ -0,0 +1,110 @@
|
||||
.\" Copyright (c) 2017, Chelsio Inc
|
||||
.\" 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$
|
||||
.\"
|
||||
.Dd May 16, 2017
|
||||
.Dt CCR 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ccr
|
||||
.Nd "Chelsio T6 crypto accelerator driver"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following lines in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indeunt
|
||||
.Cd "device ccr"
|
||||
.Ed
|
||||
.Pp
|
||||
To load the driver as a
|
||||
module at boot time, place the following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
ccr_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the crypto accelerator engine included on
|
||||
PCI Express Ethernet adapters based on the Chelsio Terminator 6 ASIC (T6).
|
||||
The driver accelerates AES-CBC, AES-CTR, AES-GCM, AES-XTS, SHA1-HMAC,
|
||||
SHA2-256-HMAC, SHA2-384-HMAC, and SHA2-512-HMAC operations for
|
||||
.Xr crypto 4
|
||||
and
|
||||
.Xr ipsec 4 .
|
||||
The driver also supports chaining one of AES-CBC, AES-CTR, or AES-XTS with
|
||||
SHA1-HMAC, SHA2-256-HMAC, SHA2-384-HMAC, or SHA2-512-HMAC for
|
||||
encrypt-then-authenticate operations.
|
||||
For further hardware information and questions related to hardware
|
||||
requirements, see
|
||||
.Pa http://www.chelsio.com/ .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
driver attaches as a child of an existing Chelsio NIC device and thus
|
||||
requires that the
|
||||
.Xr cxgbe 4
|
||||
driver be active.
|
||||
.Sh HARDWARE
|
||||
The
|
||||
.Nm
|
||||
driver supports the crypto accelerator engine included on adapters
|
||||
based on the T6 ASIC:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Chelsio T6225-CR
|
||||
.It
|
||||
Chelsio T6225-SO-CR
|
||||
.It
|
||||
Chelsio T62100-LP-CR
|
||||
.It
|
||||
Chelsio T62100-SO-CR
|
||||
.It
|
||||
Chelsio T62100-CR
|
||||
.El
|
||||
.Sh SUPPORT
|
||||
For general information and support,
|
||||
go to the Chelsio support website at:
|
||||
.Pa http://www.chelsio.com/ .
|
||||
.Pp
|
||||
If an issue is identified with this driver with a supported adapter,
|
||||
email all the specific information related to the issue to
|
||||
.Aq Mt support@chelsio.com .
|
||||
.Sh SEE ALSO
|
||||
.Xr crypto 4 ,
|
||||
.Xr cxgbe 4 ,
|
||||
.Xr ipsec 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device driver first appeared in
|
||||
.Fx 12.0 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An John Baldwin Aq Mt jhb@FreeBSD.org .
|
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 22, 2016
|
||||
.Dd May 16, 2017
|
||||
.Dt CXGBE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -367,6 +367,7 @@ email all the specific information related to the issue to
|
||||
.Sh SEE ALSO
|
||||
.Xr altq 4 ,
|
||||
.Xr arp 4 ,
|
||||
.Xr ccr 4 ,
|
||||
.Xr cxgb 4 ,
|
||||
.Xr cxgbev 4 ,
|
||||
.Xr netintro 4 ,
|
||||
|
@ -1,8 +1,8 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Spectra Logic Corporation
|
||||
.\" Copyright (c) 2014 LSI Corp
|
||||
.\" Copyright (c) 2016 Avago Technologies
|
||||
.\" Copyright (c) 2016 Broadcom Ltd.
|
||||
.\" Copyright (c) 2017 Avago Technologies
|
||||
.\" Copyright (c) 2017 Broadcom Ltd.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -38,12 +38,12 @@
|
||||
.\" $Id$
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 6, 2016
|
||||
.Dd May 17, 2017
|
||||
.Dt MPR 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mpr
|
||||
.Nd "LSI Fusion-MPT 3 IT/IR 12Gb/s Serial Attached SCSI/SATA driver"
|
||||
.Nd "LSI Fusion-MPT 3/3.5 IT/IR 12Gb/s Serial Attached SCSI/SATA/PCIe driver"
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel, place these lines in the kernel
|
||||
configuration file:
|
||||
@ -62,8 +62,8 @@ mpr_load="YES"
|
||||
The
|
||||
.Nm
|
||||
driver provides support for Broadcom Ltd./Avago Tech (LSI)
|
||||
Fusion-MPT 3 IT/IR
|
||||
.Tn SAS
|
||||
Fusion-MPT 3/3.5 IT/IR
|
||||
.Tn SAS/PCIe
|
||||
controllers.
|
||||
.Sh HARDWARE
|
||||
These controllers are supported by the
|
||||
@ -81,6 +81,24 @@ Broadcom Ltd./Avago Tech (LSI) SAS 3108 (8 Port SAS)
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3216 (16 Port SAS)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3224 (24 Port SAS)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3316 (16 Port SAS)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3324 (24 Port SAS)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3408 (8 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3416 (16 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3508 (8 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3516 (16 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3616 (16 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3708 (8 Port SAS/PCIe)
|
||||
.It
|
||||
Broadcom Ltd./Avago Tech (LSI) SAS 3716 (16 Port SAS/PCIe)
|
||||
.El
|
||||
.Sh CONFIGURATION
|
||||
In all tunable descriptions below, X represents the adapter number.
|
||||
@ -156,6 +174,24 @@ dev.mpr.X.io_cmds_active
|
||||
.Xr sysctl 8
|
||||
variable.
|
||||
.Pp
|
||||
The current number of free PRP pages is stored in the
|
||||
dev.mpr.X.prp_pages_free
|
||||
.Xr sysctl 8
|
||||
variable.
|
||||
PRP pages are used by NVMe devices for I/O transfers, much like Scatter/Gather
|
||||
lists.
|
||||
.Pp
|
||||
The lowest number of free PRP pages seen since boot is stored in the
|
||||
dev.mpr.X.prp_pages_free_lowwater
|
||||
.Xr sysctl 8
|
||||
variable.
|
||||
.Pp
|
||||
The number of times that PRP page allocations have failed since boot is
|
||||
stored in the
|
||||
dev.mpr.X.prp_page_alloc_fail
|
||||
.Xr sysctl 8
|
||||
variable.
|
||||
.Pp
|
||||
To set the maximum number of pages that will be used per I/O for all adapters,
|
||||
set this tunable in
|
||||
.Xr loader.conf 5 :
|
||||
@ -229,13 +265,13 @@ Send SSU to HDDs, but not to SSDs.
|
||||
Send SSU to both HDDs and SSDs.
|
||||
.El
|
||||
.Pp
|
||||
To control the feature for a specific adapter, set this tunable value in
|
||||
To control this feature for a specific adapter, set this tunable value in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
dev.mpr.X.enable_ssu
|
||||
.Ed
|
||||
.Pp
|
||||
The same set of values are valid when setting this tunable for all adapters.
|
||||
The same set of values are valid as when setting this tunable for all adapters.
|
||||
.Pp
|
||||
SATA disks that take several seconds to spin up and fail the SATA Identify
|
||||
command might not be discovered by the driver.
|
||||
@ -261,6 +297,45 @@ dev.mpr.X.spinup_wait_time=NNNN
|
||||
tunable.
|
||||
NNNN is the number of seconds to wait for SATA devices to spin up when they fail
|
||||
the initial SATA Identify command.
|
||||
.Pp
|
||||
The driver can map devices discovered by the adapter so that target IDs
|
||||
corresponding to a specific device persist across resets and reboots.
|
||||
In some cases it is possible for devices to lose their mapped IDs due to
|
||||
unexpected behavior from certain hardware, such as some types of enclosures.
|
||||
To overcome this problem, a tunable is provided that will force the driver to
|
||||
map devices using the Phy number associated with the device.
|
||||
This feature is not recommended if the topology includes multiple
|
||||
enclosures/expanders.
|
||||
If multiple enclosures/expanders are present in the topology, Phy numbers are
|
||||
repeated, causing all devices at these Phy numbers except the first device to
|
||||
fail enumeration.
|
||||
To control this feature for all adapters, set the
|
||||
.Bd -literal -offset indent
|
||||
hw.mpr.use_phy_num
|
||||
.Ed
|
||||
.Pp
|
||||
tunable in
|
||||
.Xr loader.conf 5
|
||||
to one of these values:
|
||||
.Bl -tag -width 6n -offset indent
|
||||
.It -1
|
||||
Only use Phy numbers to map devices and bypass the driver's mapping logic.
|
||||
.It 0
|
||||
Never use Phy numbers to map devices.
|
||||
.It 1
|
||||
Use Phy numbers to map devices, but only if the driver's mapping logic fails
|
||||
to map the device that is being enumerated.
|
||||
This is the default value.
|
||||
.El
|
||||
.Pp
|
||||
To control this feature for a specific adapter, set this tunable value in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
dev.mpr.X.use_phy_num
|
||||
.Ed
|
||||
.Pp
|
||||
The same set of values are valid as when setting this tunable for all adapters.
|
||||
.Pp
|
||||
.Sh DEBUGGING
|
||||
To enable debugging prints from the
|
||||
.Nm
|
||||
|
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 5, 2017
|
||||
.Dd May 16, 2017
|
||||
.Dt ARCH 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -90,7 +90,7 @@ architectures, the final release.
|
||||
.Pp
|
||||
.Bl -column -offset indent "Sy Architecture" "Sy Initial Release" "Sy Final Release"
|
||||
.It Sy Architecture Ta Sy Initial Release Ta Sy Final Release
|
||||
.It alpha Ta 3.x Ta 6.4
|
||||
.It alpha Ta 3.2 Ta 6.4
|
||||
.It amd64 Ta 5.1
|
||||
.It arm Ta 6.0
|
||||
.It armeb Ta 8.0
|
||||
|
@ -1572,6 +1572,7 @@ MLINKS+=sglist.9 sglist_alloc.9 \
|
||||
sglist.9 sglist_append_bio.9 \
|
||||
sglist.9 sglist_append_mbuf.9 \
|
||||
sglist.9 sglist_append_phys.9 \
|
||||
sglist.9 sglist_append_sglist.9 \
|
||||
sglist.9 sglist_append_uio.9 \
|
||||
sglist.9 sglist_append_user.9 \
|
||||
sglist.9 sglist_append_vmpages.9 \
|
||||
|
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 12, 2014
|
||||
.Dd May 16, 2017
|
||||
.Dt SGLIST 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,6 +36,7 @@
|
||||
.Nm sglist_append_bio ,
|
||||
.Nm sglist_append_mbuf ,
|
||||
.Nm sglist_append_phys ,
|
||||
.Nm sglist_append_sglist ,
|
||||
.Nm sglist_append_uio ,
|
||||
.Nm sglist_append_user ,
|
||||
.Nm sglist_append_vmpages ,
|
||||
@ -67,6 +68,8 @@
|
||||
.Ft int
|
||||
.Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
|
||||
.Ft int
|
||||
.Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
|
||||
.Ft int
|
||||
.Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
|
||||
.Ft int
|
||||
.Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
|
||||
@ -252,6 +255,20 @@ and is
|
||||
bytes long.
|
||||
.Pp
|
||||
The
|
||||
.Nm sglist_append_sglist
|
||||
function appends physical address ranges described by the scatter/gather list
|
||||
.Fa source
|
||||
to the scatter/gather list
|
||||
.Fa sg .
|
||||
The physical address ranges start at offset
|
||||
.Fa offset
|
||||
within
|
||||
.Fa source
|
||||
and continue for
|
||||
.Fa len
|
||||
bytes.
|
||||
.Pp
|
||||
The
|
||||
.Nm sglist_append_uio
|
||||
function appends the physical address ranges described by a
|
||||
.Xr uio 9
|
||||
|
@ -169,9 +169,7 @@ update_gdt_fsbase(struct thread *td, uint32_t base)
|
||||
}
|
||||
|
||||
int
|
||||
sysarch(td, uap)
|
||||
struct thread *td;
|
||||
register struct sysarch_args *uap;
|
||||
sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
{
|
||||
int error = 0;
|
||||
struct pcb *pcb = curthread->td_pcb;
|
||||
|
@ -148,13 +148,9 @@ alloc_fpusave(int flags)
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(td1, p2, td2, flags)
|
||||
register struct thread *td1;
|
||||
register struct proc *p2;
|
||||
struct thread *td2;
|
||||
int flags;
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
register struct proc *p1;
|
||||
struct proc *p1;
|
||||
struct pcb *pcb2;
|
||||
struct mdproc *mdp1, *mdp2;
|
||||
struct proc_ldt *pldt;
|
||||
|
@ -52,7 +52,7 @@
|
||||
/*
|
||||
* Virtual memory related constants, all in bytes
|
||||
*/
|
||||
#define MAXTSIZ (128UL*1024*1024) /* max text size */
|
||||
#define MAXTSIZ (32768UL*1024*1024) /* max text size */
|
||||
#ifndef DFLDSIZ
|
||||
#define DFLDSIZ (32768UL*1024*1024) /* initial data size limit */
|
||||
#endif
|
||||
|
@ -188,9 +188,7 @@ arm32_get_tp(struct thread *td, void *args)
|
||||
}
|
||||
|
||||
int
|
||||
sysarch(td, uap)
|
||||
struct thread *td;
|
||||
register struct sysarch_args *uap;
|
||||
sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -93,8 +93,7 @@ uint32_t initial_fpscr = VFPSCR_DN | VFPSCR_FZ;
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(register struct thread *td1, register struct proc *p2,
|
||||
struct thread *td2, int flags)
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct pcb *pcb2;
|
||||
struct trapframe *tf;
|
||||
|
@ -299,7 +299,7 @@ atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
|
||||
static __inline u_int32_t
|
||||
atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
|
||||
{
|
||||
register int done, ras_start = ARM_RAS_START;
|
||||
int done, ras_start = ARM_RAS_START;
|
||||
|
||||
__asm __volatile("1:\n"
|
||||
"adr %1, 1b\n"
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Virtual memory related constants, all in bytes
|
||||
*/
|
||||
#ifndef MAXTSIZ
|
||||
#define MAXTSIZ (64UL*1024*1024) /* max text size */
|
||||
#define MAXTSIZ (256UL*1024*1024) /* max text size */
|
||||
#endif
|
||||
#ifndef DFLDSIZ
|
||||
#define DFLDSIZ (128UL*1024*1024) /* initial data size limit */
|
||||
|
@ -127,7 +127,7 @@ platform_mp_setmaxid(void)
|
||||
|
||||
/* Armada38x family supports maximum 2 cores */
|
||||
mp_ncpus = platform_cnt_cpus();
|
||||
mp_maxid = 1;
|
||||
mp_maxid = mp_ncpus - 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -148,12 +148,11 @@ static void mpic_unmask_irq(uintptr_t nb);
|
||||
static void mpic_mask_irq(uintptr_t nb);
|
||||
static void mpic_mask_irq_err(uintptr_t nb);
|
||||
static void mpic_unmask_irq_err(uintptr_t nb);
|
||||
static boolean_t mpic_irq_is_percpu(uintptr_t);
|
||||
#ifdef INTRNG
|
||||
static int mpic_intr(void *arg);
|
||||
static void mpic_unmask_msi(void);
|
||||
#ifndef INTRNG
|
||||
static void arm_mask_irq_err(uintptr_t);
|
||||
static void arm_unmask_irq_err(uintptr_t);
|
||||
#endif
|
||||
static void mpic_unmask_msi(void);
|
||||
|
||||
#define MPIC_WRITE(softc, reg, val) \
|
||||
bus_space_write_4((softc)->mpic_bst, (softc)->mpic_bsh, (reg), (val))
|
||||
@ -260,8 +259,7 @@ mv_mpic_attach(device_t dev)
|
||||
sc->drbl_bsh = rman_get_bushandle(sc->mpic_res[2]);
|
||||
}
|
||||
|
||||
bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
|
||||
MPIC_CTRL, 1);
|
||||
MPIC_WRITE(mv_mpic_sc, MPIC_CTRL, 1);
|
||||
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);
|
||||
|
||||
val = MPIC_READ(mv_mpic_sc, MPIC_CTRL);
|
||||
@ -273,6 +271,9 @@ mv_mpic_attach(device_t dev)
|
||||
bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
|
||||
|
||||
if (intr_pic_register(dev, OF_xref_from_device(dev)) == NULL) {
|
||||
device_printf(dev, "could not register PIC\n");
|
||||
bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
|
||||
@ -398,7 +399,7 @@ static driver_t mv_mpic_driver = {
|
||||
static devclass_t mv_mpic_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(mpic, simplebus, mv_mpic_driver, mv_mpic_devclass, 0, 0,
|
||||
BUS_PASS_INTERRUPT);
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
|
||||
|
||||
#ifndef INTRNG
|
||||
int
|
||||
@ -432,27 +433,12 @@ arm_mask_irq(uintptr_t nb)
|
||||
mpic_mask_irq(nb);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
arm_mask_irq_err(uintptr_t nb)
|
||||
{
|
||||
|
||||
mpic_mask_irq_err(nb);
|
||||
}
|
||||
|
||||
void
|
||||
arm_unmask_irq(uintptr_t nb)
|
||||
{
|
||||
|
||||
mpic_unmask_irq(nb);
|
||||
}
|
||||
|
||||
void
|
||||
arm_unmask_irq_err(uintptr_t nb)
|
||||
{
|
||||
|
||||
mpic_unmask_irq_err(nb);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
@ -468,8 +454,7 @@ mpic_unmask_irq_err(uintptr_t nb)
|
||||
uint32_t mask;
|
||||
uint8_t bit_off;
|
||||
|
||||
bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
|
||||
MPIC_ISE, MPIC_INT_ERR);
|
||||
MPIC_WRITE(mv_mpic_sc, MPIC_ISE, MPIC_INT_ERR);
|
||||
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, MPIC_INT_ERR);
|
||||
|
||||
bit_off = nb - ERR_IRQ;
|
||||
@ -490,15 +475,24 @@ mpic_mask_irq_err(uintptr_t nb)
|
||||
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
mpic_irq_is_percpu(uintptr_t nb)
|
||||
{
|
||||
if (nb < MPIC_PPI)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
mpic_unmask_irq(uintptr_t nb)
|
||||
{
|
||||
|
||||
if (nb < ERR_IRQ) {
|
||||
bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
|
||||
MPIC_ISE, nb);
|
||||
if (mpic_irq_is_percpu(nb))
|
||||
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, nb);
|
||||
} else if (nb < MSI_IRQ)
|
||||
else if (nb < ERR_IRQ)
|
||||
MPIC_WRITE(mv_mpic_sc, MPIC_ISE, nb);
|
||||
else if (nb < MSI_IRQ)
|
||||
mpic_unmask_irq_err(nb);
|
||||
|
||||
if (nb == 0)
|
||||
@ -509,11 +503,11 @@ static void
|
||||
mpic_mask_irq(uintptr_t nb)
|
||||
{
|
||||
|
||||
if (nb < ERR_IRQ) {
|
||||
bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
|
||||
MPIC_ICE, nb);
|
||||
if (mpic_irq_is_percpu(nb))
|
||||
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ISM, nb);
|
||||
} else if (nb < MSI_IRQ)
|
||||
else if (nb < ERR_IRQ)
|
||||
MPIC_WRITE(mv_mpic_sc, MPIC_ICE, nb);
|
||||
else if (nb < MSI_IRQ)
|
||||
mpic_mask_irq_err(nb);
|
||||
}
|
||||
|
||||
@ -530,8 +524,7 @@ mv_mpic_get_cause_err(void)
|
||||
uint32_t err_cause;
|
||||
uint8_t bit_off;
|
||||
|
||||
err_cause = bus_space_read_4(mv_mpic_sc->mpic_bst,
|
||||
mv_mpic_sc->mpic_bsh, MPIC_ERR_CAUSE);
|
||||
err_cause = MPIC_READ(mv_mpic_sc, MPIC_ERR_CAUSE);
|
||||
|
||||
if (err_cause)
|
||||
bit_off = ffs(err_cause) - 1;
|
||||
@ -612,8 +605,7 @@ pic_ipi_send(cpuset_t cpus, u_int ipi)
|
||||
if (CPU_ISSET(i, &cpus))
|
||||
val |= (1 << (8 + i));
|
||||
val |= ipi;
|
||||
bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
|
||||
MPIC_SOFT_INT, val);
|
||||
MPIC_WRITE(mv_mpic_sc, MPIC_SOFT_INT, val);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -76,6 +76,7 @@ MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
|
||||
|
||||
static int win_eth_can_remap(int i);
|
||||
|
||||
static int decode_win_cesa_valid(void);
|
||||
static int decode_win_cpu_valid(void);
|
||||
static int decode_win_usb_valid(void);
|
||||
static int decode_win_usb3_valid(void);
|
||||
@ -91,6 +92,7 @@ static void decode_win_cpu_setup(void);
|
||||
#ifdef SOC_MV_ARMADAXP
|
||||
static int decode_win_sdram_fixup(void);
|
||||
#endif
|
||||
static void decode_win_cesa_setup(u_long);
|
||||
static void decode_win_usb_setup(u_long);
|
||||
static void decode_win_usb3_setup(u_long);
|
||||
static void decode_win_eth_setup(u_long);
|
||||
@ -101,6 +103,7 @@ static void decode_win_sdhci_setup(u_long);
|
||||
static void decode_win_idma_setup(u_long);
|
||||
static void decode_win_xor_setup(u_long);
|
||||
|
||||
static void decode_win_cesa_dump(u_long);
|
||||
static void decode_win_usb_dump(u_long);
|
||||
static void decode_win_usb3_dump(u_long);
|
||||
static void decode_win_eth_dump(u_long base);
|
||||
@ -139,12 +142,14 @@ struct soc_node_spec {
|
||||
static struct soc_node_spec soc_nodes[] = {
|
||||
{ "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump },
|
||||
{ "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
|
||||
{ "marvell,orion-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
|
||||
{ "marvell,armada-380-xhci", &decode_win_usb3_setup, &decode_win_usb3_dump },
|
||||
{ "marvell,armada-380-ahci", &decode_win_ahci_setup, &decode_win_ahci_dump },
|
||||
{ "marvell,armada-380-sdhci", &decode_win_sdhci_setup, &decode_win_sdhci_dump },
|
||||
{ "mrvl,sata", &decode_win_sata_setup, NULL },
|
||||
{ "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump },
|
||||
{ "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump },
|
||||
{ "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump },
|
||||
{ "mrvl,pcie", &decode_win_pcie_setup, NULL },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
@ -573,7 +578,7 @@ soc_decode_win(void)
|
||||
!decode_win_eth_valid() || !decode_win_idma_valid() ||
|
||||
!decode_win_pcie_valid() || !decode_win_sata_valid() ||
|
||||
!decode_win_xor_valid() || !decode_win_usb3_valid() ||
|
||||
!decode_win_sdhci_valid())
|
||||
!decode_win_sdhci_valid() || !decode_win_cesa_valid())
|
||||
return (EINVAL);
|
||||
|
||||
decode_win_cpu_setup();
|
||||
@ -600,6 +605,11 @@ WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
|
||||
WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
|
||||
WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
|
||||
|
||||
WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL)
|
||||
WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE)
|
||||
WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL)
|
||||
WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE)
|
||||
|
||||
WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
|
||||
WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
|
||||
WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
|
||||
@ -1069,6 +1079,63 @@ ddr_target(int i)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CESA windows routines
|
||||
**************************************************************************/
|
||||
static int
|
||||
decode_win_cesa_valid(void)
|
||||
{
|
||||
|
||||
return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
|
||||
}
|
||||
|
||||
static void
|
||||
decode_win_cesa_dump(u_long base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MV_WIN_CESA_MAX; i++)
|
||||
printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
|
||||
win_cesa_cr_read(base, i), win_cesa_br_read(base, i));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set CESA decode windows.
|
||||
*/
|
||||
static void
|
||||
decode_win_cesa_setup(u_long base)
|
||||
{
|
||||
uint32_t br, cr;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < MV_WIN_CESA_MAX; i++) {
|
||||
win_cesa_cr_write(base, i, 0);
|
||||
win_cesa_br_write(base, i, 0);
|
||||
}
|
||||
|
||||
/* Only access to active DRAM banks is required */
|
||||
for (i = 0; i < MV_WIN_DDR_MAX; i++) {
|
||||
if (ddr_is_active(i)) {
|
||||
br = ddr_base(i);
|
||||
|
||||
cr = (((ddr_size(i) - 1) & 0xffff0000) |
|
||||
(ddr_attr(i) << IO_WIN_ATTR_SHIFT) |
|
||||
(ddr_target(i) << IO_WIN_TGT_SHIFT) |
|
||||
IO_WIN_ENA_MASK);
|
||||
|
||||
/* Set the first free CESA window */
|
||||
for (j = 0; j < MV_WIN_CESA_MAX; j++) {
|
||||
if (win_cesa_cr_read(base, j) & 0x1)
|
||||
continue;
|
||||
|
||||
win_cesa_br_write(base, j, br);
|
||||
win_cesa_cr_write(base, j, cr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* USB windows routines
|
||||
**************************************************************************/
|
||||
@ -2279,11 +2346,12 @@ win_cpu_from_dt(void)
|
||||
static int
|
||||
fdt_win_setup(void)
|
||||
{
|
||||
phandle_t node, child;
|
||||
phandle_t node, child, sb;
|
||||
struct soc_node_spec *soc_node;
|
||||
u_long size, base;
|
||||
int err, i;
|
||||
|
||||
sb = 0;
|
||||
node = OF_finddevice("/");
|
||||
if (node == -1)
|
||||
panic("fdt_win_setup: no root node");
|
||||
@ -2325,7 +2393,7 @@ fdt_win_setup(void)
|
||||
*/
|
||||
child = OF_peer(child);
|
||||
if ((child == 0) && (node == OF_finddevice("/"))) {
|
||||
node = fdt_find_compatible(node, "simple-bus", 0);
|
||||
sb = node = fdt_find_compatible(node, "simple-bus", 0);
|
||||
if (node == 0)
|
||||
return (ENXIO);
|
||||
child = OF_child(node);
|
||||
@ -2335,7 +2403,7 @@ fdt_win_setup(void)
|
||||
* it is present) and its children. This node also have
|
||||
* "simple-bus" compatible.
|
||||
*/
|
||||
if ((child == 0) && (node == OF_finddevice("simple-bus"))) {
|
||||
if ((child == 0) && (node == sb)) {
|
||||
node = fdt_find_compatible(node, "simple-bus", 0);
|
||||
if (node == 0)
|
||||
return (0);
|
||||
|
@ -216,12 +216,17 @@
|
||||
#define MV_WIN_CESA_ATTR(eng_sel) 0
|
||||
#endif
|
||||
|
||||
/* CESA TDMA address decoding registers */
|
||||
#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xA04)
|
||||
#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xA00)
|
||||
#define MV_WIN_CESA_MAX 4
|
||||
|
||||
#define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x320)
|
||||
#define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x324)
|
||||
#define MV_WIN_USB_MAX 4
|
||||
|
||||
#define MV_WIN_USB3_CTRL(n) (0x8 * (n))
|
||||
#define MV_WIN_USB3_BASE(n) (0x8 * (n) + 0x4)
|
||||
#define MV_WIN_USB3_CTRL(n) (0x8 * (n) + 0x4000)
|
||||
#define MV_WIN_USB3_BASE(n) (0x8 * (n) + 0x4004)
|
||||
#define MV_WIN_USB3_MAX 8
|
||||
|
||||
#define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200)
|
||||
@ -305,18 +310,6 @@
|
||||
#define MV_BOOTROM_WIN_SIZE 0xF
|
||||
#define MV_CPU_SUBSYS_REGS_LEN 0x100
|
||||
|
||||
/* IO Window Control Register fields */
|
||||
#define IO_WIN_SIZE_SHIFT 16
|
||||
#define IO_WIN_SIZE_MASK 0xFFFF
|
||||
#define IO_WIN_ATTR_SHIFT 8
|
||||
#define IO_WIN_ATTR_MASK 0xFF
|
||||
#define IO_WIN_TGT_SHIFT 4
|
||||
#define IO_WIN_TGT_MASK 0xF
|
||||
#define IO_WIN_SYNC_SHIFT 1
|
||||
#define IO_WIN_SYNC_MASK 0x1
|
||||
#define IO_WIN_ENA_SHIFT 0
|
||||
#define IO_WIN_ENA_MASK 0x1
|
||||
|
||||
#define IO_WIN_9_CTRL_OFFSET 0x98
|
||||
#define IO_WIN_9_BASE_OFFSET 0x9C
|
||||
|
||||
@ -329,6 +322,18 @@
|
||||
#define MV_SYNC_BARRIER_CTRL_ALL 0xFFFF
|
||||
#endif
|
||||
|
||||
/* IO Window Control Register fields */
|
||||
#define IO_WIN_SIZE_SHIFT 16
|
||||
#define IO_WIN_SIZE_MASK 0xFFFF
|
||||
#define IO_WIN_ATTR_SHIFT 8
|
||||
#define IO_WIN_ATTR_MASK 0xFF
|
||||
#define IO_WIN_TGT_SHIFT 4
|
||||
#define IO_WIN_TGT_MASK 0xF
|
||||
#define IO_WIN_SYNC_SHIFT 1
|
||||
#define IO_WIN_SYNC_MASK 0x1
|
||||
#define IO_WIN_ENA_SHIFT 0
|
||||
#define IO_WIN_ENA_MASK 0x1
|
||||
|
||||
#define WIN_REG_IDX_RD(pre,reg,off,base) \
|
||||
static __inline uint32_t \
|
||||
pre ## _ ## reg ## _read(int i) \
|
||||
|
@ -419,7 +419,7 @@
|
||||
|
||||
mpic: interrupt-controller@20a00 {
|
||||
compatible = "marvell,mpic";
|
||||
reg = <0x20a00 0x2d0>, <0x21070 0x58>;
|
||||
reg = <0x20a00 0x2d0>, <0x21870 0x58>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
interrupt-controller;
|
||||
|
@ -435,7 +435,7 @@ linux_cdev_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type,
|
||||
err = vmap->vm_ops->fault(vmap, &vmf);
|
||||
|
||||
while (vmap->vm_pfn_count == 0 && err == VM_FAULT_NOPAGE) {
|
||||
kern_yield(0);
|
||||
kern_yield(PRI_USER);
|
||||
err = vmap->vm_ops->fault(vmap, &vmf);
|
||||
}
|
||||
}
|
||||
|
@ -2849,6 +2849,8 @@ device cryptodev # /dev/crypto for access to h/w
|
||||
|
||||
device rndtest # FIPS 140-2 entropy tester
|
||||
|
||||
device ccr # Chelsio T6
|
||||
|
||||
device hifn # Hifn 7951, 7781, etc.
|
||||
options HIFN_DEBUG # enable debugging support: hw.hifn.debug
|
||||
options HIFN_RNDTEST # enable rndtest support
|
||||
|
@ -1428,6 +1428,8 @@ t6fw.fw optional cxgbe \
|
||||
compile-with "${NORMAL_FW}" \
|
||||
no-obj no-implicit-rule \
|
||||
clean "t6fw.fw"
|
||||
dev/cxgbe/crypto/t4_crypto.c optional ccr \
|
||||
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
|
||||
dev/cy/cy.c optional cy
|
||||
dev/cy/cy_isa.c optional cy isa
|
||||
dev/cy/cy_pci.c optional cy pci
|
||||
|
@ -69,14 +69,14 @@ extern const DES_LONG des_SPtrans[8][64];
|
||||
|
||||
void des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc)
|
||||
{
|
||||
register DES_LONG l,r,t,u;
|
||||
DES_LONG l,r,t,u;
|
||||
#ifdef DES_PTR
|
||||
register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
|
||||
const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
|
||||
#endif
|
||||
#ifndef DES_UNROLL
|
||||
register int i;
|
||||
int i;
|
||||
#endif
|
||||
register DES_LONG *s;
|
||||
DES_LONG *s;
|
||||
|
||||
r=data[0];
|
||||
l=data[1];
|
||||
@ -167,14 +167,14 @@ void des_encrypt1(DES_LONG *data, des_key_schedule ks, int enc)
|
||||
|
||||
void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
|
||||
{
|
||||
register DES_LONG l,r,t,u;
|
||||
DES_LONG l,r,t,u;
|
||||
#ifdef DES_PTR
|
||||
register const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
|
||||
const unsigned char *des_SP=(const unsigned char *)des_SPtrans;
|
||||
#endif
|
||||
#ifndef DES_UNROLL
|
||||
register int i;
|
||||
int i;
|
||||
#endif
|
||||
register DES_LONG *s;
|
||||
DES_LONG *s;
|
||||
|
||||
r=data[0];
|
||||
l=data[1];
|
||||
@ -259,7 +259,7 @@ void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
|
||||
void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
|
||||
des_key_schedule ks3)
|
||||
{
|
||||
register DES_LONG l,r;
|
||||
DES_LONG l,r;
|
||||
|
||||
l=data[0];
|
||||
r=data[1];
|
||||
@ -279,7 +279,7 @@ void des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
|
||||
void des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2,
|
||||
des_key_schedule ks3)
|
||||
{
|
||||
register DES_LONG l,r;
|
||||
DES_LONG l,r;
|
||||
|
||||
l=data[0];
|
||||
r=data[1];
|
||||
|
@ -172,10 +172,10 @@ int des_set_key_checked(des_cblock *key, des_key_schedule schedule)
|
||||
void des_set_key_unchecked(des_cblock *key, des_key_schedule schedule)
|
||||
{
|
||||
static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
|
||||
register DES_LONG c,d,t,s,t2;
|
||||
register const unsigned char *in;
|
||||
register DES_LONG *k;
|
||||
register int i;
|
||||
DES_LONG c,d,t,s,t2;
|
||||
const unsigned char *in;
|
||||
DES_LONG *k;
|
||||
int i;
|
||||
|
||||
k = &schedule->ks.deslong[0];
|
||||
in = &(*key)[0];
|
||||
|
@ -57,8 +57,8 @@ db_expr_t
|
||||
db_get_value(db_addr_t addr, int size, bool is_signed)
|
||||
{
|
||||
char data[sizeof(u_int64_t)];
|
||||
register db_expr_t value;
|
||||
register int i;
|
||||
db_expr_t value;
|
||||
int i;
|
||||
|
||||
if (db_read_bytes(addr, size, data) != 0) {
|
||||
db_printf("*** error reading from address %llx ***\n",
|
||||
@ -87,7 +87,7 @@ void
|
||||
db_put_value(db_addr_t addr, int size, db_expr_t value)
|
||||
{
|
||||
char data[sizeof(int)];
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
#if BYTE_MSF
|
||||
for (i = size - 1; i >= 0; i--)
|
||||
|
@ -92,7 +92,7 @@ static void db_pager(void);
|
||||
void
|
||||
db_force_whitespace(void)
|
||||
{
|
||||
register int last_print, next_tab;
|
||||
int last_print, next_tab;
|
||||
|
||||
last_print = db_last_non_space;
|
||||
while (last_print < db_output_position) {
|
||||
@ -355,7 +355,7 @@ db_iprintf(const char *fmt,...)
|
||||
char bufr[DDB_BUFR_SIZE];
|
||||
#endif
|
||||
struct dbputchar_arg dca;
|
||||
register int i;
|
||||
int i;
|
||||
va_list listp;
|
||||
|
||||
for (i = db_indent; i >= 8; i -= 8)
|
||||
|
@ -286,10 +286,10 @@ static c_db_sym_t
|
||||
db_lookup(const char *symstr)
|
||||
{
|
||||
c_db_sym_t sp;
|
||||
register int i;
|
||||
int i;
|
||||
int symtab_start = 0;
|
||||
int symtab_end = db_nsymtab;
|
||||
register const char *cp;
|
||||
const char *cp;
|
||||
|
||||
/*
|
||||
* Look for, remove, and remember any symbol table specifier.
|
||||
@ -343,8 +343,8 @@ static bool
|
||||
db_symbol_is_ambiguous(c_db_sym_t sym)
|
||||
{
|
||||
const char *sym_name;
|
||||
register int i;
|
||||
register bool found_once = false;
|
||||
int i;
|
||||
bool found_once = false;
|
||||
|
||||
if (!db_qualify_ambiguous_names)
|
||||
return (false);
|
||||
@ -367,10 +367,9 @@ db_symbol_is_ambiguous(c_db_sym_t sym)
|
||||
c_db_sym_t
|
||||
db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
|
||||
{
|
||||
register
|
||||
unsigned int diff;
|
||||
size_t newdiff;
|
||||
register int i;
|
||||
int i;
|
||||
c_db_sym_t ret = C_DB_SYM_NULL, sym;
|
||||
|
||||
newdiff = diff = val;
|
||||
|
@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
#include <arm/mv/mvreg.h>
|
||||
#include <arm/mv/mvwin.h>
|
||||
#include <arm/mv/mvvar.h>
|
||||
#include "cesa.h"
|
||||
|
||||
@ -80,7 +79,6 @@ static void cesa_intr(void *);
|
||||
static int cesa_newsession(device_t, u_int32_t *, struct cryptoini *);
|
||||
static int cesa_freesession(device_t, u_int64_t);
|
||||
static int cesa_process(device_t, struct cryptop *, int);
|
||||
static int decode_win_cesa_setup(struct cesa_softc *sc);
|
||||
|
||||
static struct resource_spec cesa_res_spec[] = {
|
||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
|
||||
@ -1085,13 +1083,6 @@ cesa_attach(device_t dev)
|
||||
goto err0;
|
||||
}
|
||||
|
||||
/* Setup CESA decoding windows */
|
||||
error = decode_win_cesa_setup(sc);
|
||||
if (error) {
|
||||
device_printf(dev, "could not setup decoding windows\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
/* Acquire SRAM base address */
|
||||
error = cesa_setup_sram(sc);
|
||||
if (error) {
|
||||
@ -1706,50 +1697,3 @@ cesa_process(device_t dev, struct cryptop *crp, int hint)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set CESA TDMA decode windows.
|
||||
*/
|
||||
static int
|
||||
decode_win_cesa_setup(struct cesa_softc *sc)
|
||||
{
|
||||
struct mem_region availmem_regions[FDT_MEM_REGIONS];
|
||||
int availmem_regions_sz;
|
||||
uint32_t br, cr, i;
|
||||
|
||||
/* Grab physical memory regions information from DTS */
|
||||
if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz,
|
||||
NULL) != 0)
|
||||
return (ENXIO);
|
||||
|
||||
if (availmem_regions_sz > MV_WIN_CESA_MAX) {
|
||||
device_printf(sc->sc_dev, "Too much memory regions, cannot "
|
||||
" set CESA windows to cover whole DRAM \n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Disable and clear all CESA windows */
|
||||
for (i = 0; i < MV_WIN_CESA_MAX; i++) {
|
||||
CESA_TDMA_WRITE(sc, MV_WIN_CESA_BASE(i), 0);
|
||||
CESA_TDMA_WRITE(sc, MV_WIN_CESA_CTRL(i), 0);
|
||||
}
|
||||
|
||||
/* Fill CESA TDMA decoding windows with information acquired from DTS */
|
||||
for (i = 0; i < availmem_regions_sz; i++) {
|
||||
br = availmem_regions[i].mr_start;
|
||||
cr = availmem_regions[i].mr_size;
|
||||
|
||||
/* Don't add entries with size lower than 64KB */
|
||||
if (cr & 0xffff0000) {
|
||||
cr = (((cr - 1) & 0xffff0000) |
|
||||
(MV_WIN_DDR_ATTR(i) << MV_WIN_CPU_ATTR_SHIFT) |
|
||||
(MV_WIN_DDR_TARGET << MV_WIN_CPU_TARGET_SHIFT) |
|
||||
MV_WIN_CPU_ENABLE_BIT);
|
||||
CESA_TDMA_WRITE(sc, MV_WIN_CESA_BASE(i), br);
|
||||
CESA_TDMA_WRITE(sc, MV_WIN_CESA_CTRL(i), cr);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -350,11 +350,6 @@ struct cesa_chain_info {
|
||||
#define CESA_TDMA_EMR_BOTH_HIT CESA_TDMA_ECR_BOTH_HIT
|
||||
#define CESA_TDMA_EMR_DATA_ERROR CESA_TDMA_ECR_DATA_ERROR
|
||||
|
||||
/* CESA TDMA address decoding registers */
|
||||
#define MV_WIN_CESA_CTRL(n) (0x8 * (n) + 0xA04)
|
||||
#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xA00)
|
||||
#define MV_WIN_CESA_MAX 4
|
||||
|
||||
/* CESA SA registers definitions */
|
||||
#define CESA_SA_CMD 0x0E00
|
||||
#define CESA_SA_CMD_ACTVATE (1 << 0)
|
||||
|
@ -1038,7 +1038,7 @@ cs_setmode(struct cs_softc *sc)
|
||||
}
|
||||
|
||||
static int
|
||||
cs_ioctl(register struct ifnet *ifp, u_long command, caddr_t data)
|
||||
cs_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
{
|
||||
struct cs_softc *sc=ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *)data;
|
||||
|
@ -796,6 +796,7 @@ struct adapter {
|
||||
struct tom_tunables tt;
|
||||
void *iwarp_softc; /* (struct c4iw_dev *) */
|
||||
void *iscsi_ulp_softc; /* (struct cxgbei_data *) */
|
||||
void *ccr_softc; /* (struct ccr_softc *) */
|
||||
struct l2t_data *l2t; /* L2 table */
|
||||
struct tid_info tids;
|
||||
|
||||
|
2102
sys/dev/cxgbe/crypto/t4_crypto.c
Normal file
2102
sys/dev/cxgbe/crypto/t4_crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
186
sys/dev/cxgbe/crypto/t4_crypto.h
Normal file
186
sys/dev/cxgbe/crypto/t4_crypto.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Chelsio Communications, Inc.
|
||||
* All rights reserved.
|
||||
* Written by: John Baldwin <jhb@FreeBSD.org>
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef __T4_CRYPTO_H__
|
||||
#define __T4_CRYPTO_H__
|
||||
|
||||
/* From chr_core.h */
|
||||
#define PAD_ERROR_BIT 1
|
||||
#define CHK_PAD_ERR_BIT(x) (((x) >> PAD_ERROR_BIT) & 1)
|
||||
|
||||
#define MAC_ERROR_BIT 0
|
||||
#define CHK_MAC_ERR_BIT(x) (((x) >> MAC_ERROR_BIT) & 1)
|
||||
#define MAX_SALT 4
|
||||
|
||||
struct _key_ctx {
|
||||
__be32 ctx_hdr;
|
||||
u8 salt[MAX_SALT];
|
||||
__be64 reserverd;
|
||||
unsigned char key[0];
|
||||
};
|
||||
|
||||
struct chcr_wr {
|
||||
struct fw_crypto_lookaside_wr wreq;
|
||||
struct ulp_txpkt ulptx;
|
||||
struct ulptx_idata sc_imm;
|
||||
struct cpl_tx_sec_pdu sec_cpl;
|
||||
struct _key_ctx key_ctx;
|
||||
};
|
||||
|
||||
/* From chr_algo.h */
|
||||
|
||||
/* Crypto key context */
|
||||
#define S_KEY_CONTEXT_CTX_LEN 24
|
||||
#define M_KEY_CONTEXT_CTX_LEN 0xff
|
||||
#define V_KEY_CONTEXT_CTX_LEN(x) ((x) << S_KEY_CONTEXT_CTX_LEN)
|
||||
#define G_KEY_CONTEXT_CTX_LEN(x) \
|
||||
(((x) >> S_KEY_CONTEXT_CTX_LEN) & M_KEY_CONTEXT_CTX_LEN)
|
||||
|
||||
#define S_KEY_CONTEXT_DUAL_CK 12
|
||||
#define M_KEY_CONTEXT_DUAL_CK 0x1
|
||||
#define V_KEY_CONTEXT_DUAL_CK(x) ((x) << S_KEY_CONTEXT_DUAL_CK)
|
||||
#define G_KEY_CONTEXT_DUAL_CK(x) \
|
||||
(((x) >> S_KEY_CONTEXT_DUAL_CK) & M_KEY_CONTEXT_DUAL_CK)
|
||||
#define F_KEY_CONTEXT_DUAL_CK V_KEY_CONTEXT_DUAL_CK(1U)
|
||||
|
||||
#define S_KEY_CONTEXT_OPAD_PRESENT 11
|
||||
#define M_KEY_CONTEXT_OPAD_PRESENT 0x1
|
||||
#define V_KEY_CONTEXT_OPAD_PRESENT(x) ((x) << S_KEY_CONTEXT_OPAD_PRESENT)
|
||||
#define G_KEY_CONTEXT_OPAD_PRESENT(x) \
|
||||
(((x) >> S_KEY_CONTEXT_OPAD_PRESENT) & \
|
||||
M_KEY_CONTEXT_OPAD_PRESENT)
|
||||
#define F_KEY_CONTEXT_OPAD_PRESENT V_KEY_CONTEXT_OPAD_PRESENT(1U)
|
||||
|
||||
#define S_KEY_CONTEXT_SALT_PRESENT 10
|
||||
#define M_KEY_CONTEXT_SALT_PRESENT 0x1
|
||||
#define V_KEY_CONTEXT_SALT_PRESENT(x) ((x) << S_KEY_CONTEXT_SALT_PRESENT)
|
||||
#define G_KEY_CONTEXT_SALT_PRESENT(x) \
|
||||
(((x) >> S_KEY_CONTEXT_SALT_PRESENT) & \
|
||||
M_KEY_CONTEXT_SALT_PRESENT)
|
||||
#define F_KEY_CONTEXT_SALT_PRESENT V_KEY_CONTEXT_SALT_PRESENT(1U)
|
||||
|
||||
#define S_KEY_CONTEXT_CK_SIZE 6
|
||||
#define M_KEY_CONTEXT_CK_SIZE 0xf
|
||||
#define V_KEY_CONTEXT_CK_SIZE(x) ((x) << S_KEY_CONTEXT_CK_SIZE)
|
||||
#define G_KEY_CONTEXT_CK_SIZE(x) \
|
||||
(((x) >> S_KEY_CONTEXT_CK_SIZE) & M_KEY_CONTEXT_CK_SIZE)
|
||||
|
||||
#define S_KEY_CONTEXT_MK_SIZE 2
|
||||
#define M_KEY_CONTEXT_MK_SIZE 0xf
|
||||
#define V_KEY_CONTEXT_MK_SIZE(x) ((x) << S_KEY_CONTEXT_MK_SIZE)
|
||||
#define G_KEY_CONTEXT_MK_SIZE(x) \
|
||||
(((x) >> S_KEY_CONTEXT_MK_SIZE) & M_KEY_CONTEXT_MK_SIZE)
|
||||
|
||||
#define S_KEY_CONTEXT_VALID 0
|
||||
#define M_KEY_CONTEXT_VALID 0x1
|
||||
#define V_KEY_CONTEXT_VALID(x) ((x) << S_KEY_CONTEXT_VALID)
|
||||
#define G_KEY_CONTEXT_VALID(x) \
|
||||
(((x) >> S_KEY_CONTEXT_VALID) & \
|
||||
M_KEY_CONTEXT_VALID)
|
||||
#define F_KEY_CONTEXT_VALID V_KEY_CONTEXT_VALID(1U)
|
||||
|
||||
#define CHCR_HASH_MAX_DIGEST_SIZE 64
|
||||
|
||||
#define DUMMY_BYTES 16
|
||||
|
||||
#define TRANSHDR_SIZE(kctx_len)\
|
||||
(sizeof(struct chcr_wr) +\
|
||||
kctx_len)
|
||||
#define CIPHER_TRANSHDR_SIZE(kctx_len, sge_pairs) \
|
||||
(TRANSHDR_SIZE((kctx_len)) + (sge_pairs) +\
|
||||
sizeof(struct cpl_rx_phys_dsgl))
|
||||
#define HASH_TRANSHDR_SIZE(kctx_len)\
|
||||
(TRANSHDR_SIZE(kctx_len) + DUMMY_BYTES)
|
||||
|
||||
#define CRYPTO_MAX_IMM_TX_PKT_LEN 256
|
||||
|
||||
struct phys_sge_pairs {
|
||||
__be16 len[8];
|
||||
__be64 addr[8];
|
||||
};
|
||||
|
||||
/* From chr_crypto.h */
|
||||
#define CHCR_AES_MAX_KEY_LEN (AES_XTS_MAX_KEY)
|
||||
#define CHCR_MAX_CRYPTO_IV_LEN 16 /* AES IV len */
|
||||
|
||||
#define CHCR_ENCRYPT_OP 0
|
||||
#define CHCR_DECRYPT_OP 1
|
||||
|
||||
#define CHCR_SCMD_PROTO_VERSION_GENERIC 4
|
||||
|
||||
#define CHCR_SCMD_CIPHER_MODE_NOP 0
|
||||
#define CHCR_SCMD_CIPHER_MODE_AES_CBC 1
|
||||
#define CHCR_SCMD_CIPHER_MODE_AES_GCM 2
|
||||
#define CHCR_SCMD_CIPHER_MODE_AES_CTR 3
|
||||
#define CHCR_SCMD_CIPHER_MODE_GENERIC_AES 4
|
||||
#define CHCR_SCMD_CIPHER_MODE_AES_XTS 6
|
||||
#define CHCR_SCMD_CIPHER_MODE_AES_CCM 7
|
||||
|
||||
#define CHCR_SCMD_AUTH_MODE_NOP 0
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA1 1
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA224 2
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA256 3
|
||||
#define CHCR_SCMD_AUTH_MODE_GHASH 4
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA512_224 5
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA512_256 6
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA512_384 7
|
||||
#define CHCR_SCMD_AUTH_MODE_SHA512_512 8
|
||||
#define CHCR_SCMD_AUTH_MODE_CBCMAC 9
|
||||
#define CHCR_SCMD_AUTH_MODE_CMAC 10
|
||||
|
||||
#define CHCR_SCMD_HMAC_CTRL_NOP 0
|
||||
#define CHCR_SCMD_HMAC_CTRL_NO_TRUNC 1
|
||||
#define CHCR_SCMD_HMAC_CTRL_TRUNC_RFC4366 2
|
||||
#define CHCR_SCMD_HMAC_CTRL_IPSEC_96BIT 3
|
||||
#define CHCR_SCMD_HMAC_CTRL_PL1 4
|
||||
#define CHCR_SCMD_HMAC_CTRL_PL2 5
|
||||
#define CHCR_SCMD_HMAC_CTRL_PL3 6
|
||||
#define CHCR_SCMD_HMAC_CTRL_DIV2 7
|
||||
|
||||
/* This are not really mac key size. They are intermediate values
|
||||
* of sha engine and its size
|
||||
*/
|
||||
#define CHCR_KEYCTX_MAC_KEY_SIZE_128 0
|
||||
#define CHCR_KEYCTX_MAC_KEY_SIZE_160 1
|
||||
#define CHCR_KEYCTX_MAC_KEY_SIZE_192 2
|
||||
#define CHCR_KEYCTX_MAC_KEY_SIZE_256 3
|
||||
#define CHCR_KEYCTX_MAC_KEY_SIZE_512 4
|
||||
#define CHCR_KEYCTX_CIPHER_KEY_SIZE_128 0
|
||||
#define CHCR_KEYCTX_CIPHER_KEY_SIZE_192 1
|
||||
#define CHCR_KEYCTX_CIPHER_KEY_SIZE_256 2
|
||||
#define CHCR_KEYCTX_NO_KEY 15
|
||||
|
||||
#define IV_NOP 0
|
||||
#define IV_IMMEDIATE 1
|
||||
#define IV_DSGL 2
|
||||
|
||||
#define CHCR_HASH_MAX_BLOCK_SIZE_64 64
|
||||
#define CHCR_HASH_MAX_BLOCK_SIZE_128 128
|
||||
|
||||
#endif /* !__T4_CRYPTO_H__ */
|
@ -1186,6 +1186,12 @@ t4_attach(device_t dev)
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = bus_generic_probe(dev);
|
||||
if (rc != 0) {
|
||||
device_printf(dev, "failed to probe child drivers: %d\n", rc);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = bus_generic_attach(dev);
|
||||
if (rc != 0) {
|
||||
device_printf(dev,
|
||||
@ -1339,6 +1345,8 @@ t4_detach_common(device_t dev)
|
||||
}
|
||||
}
|
||||
|
||||
device_delete_children(dev);
|
||||
|
||||
if (sc->flags & FULL_INIT_DONE)
|
||||
adapter_full_uninit(sc);
|
||||
|
||||
|
@ -126,7 +126,7 @@ ttm_bo_vm_fault(vm_object_t vm_obj, vm_ooffset_t offset,
|
||||
ret = ttm_bo_reserve(bo, false, false, false, 0);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret == -EBUSY) {
|
||||
kern_yield(0);
|
||||
kern_yield(PRI_USER);
|
||||
goto reserve;
|
||||
}
|
||||
}
|
||||
@ -139,7 +139,7 @@ ttm_bo_vm_fault(vm_object_t vm_obj, vm_ooffset_t offset,
|
||||
case -EBUSY:
|
||||
case -ERESTARTSYS:
|
||||
case -EINTR:
|
||||
kern_yield(0);
|
||||
kern_yield(PRI_USER);
|
||||
goto reserve;
|
||||
default:
|
||||
retval = VM_PAGER_ERROR;
|
||||
|
@ -136,7 +136,7 @@ ttm_vm_page_free(vm_page_t m)
|
||||
KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("ttm got unmanaged %p", m));
|
||||
m->flags &= ~PG_FICTITIOUS;
|
||||
m->oflags |= VPO_UNMANAGED;
|
||||
vm_page_unwire(m, PQ_INACTIVE);
|
||||
vm_page_unwire(m, PQ_NONE);
|
||||
vm_page_free(m);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ typedef struct e6000sw_softc {
|
||||
char *ifname[E6000SW_MAX_PORTS];
|
||||
device_t miibus[E6000SW_MAX_PORTS];
|
||||
struct mii_data *mii[E6000SW_MAX_PORTS];
|
||||
struct callout tick_callout;
|
||||
struct proc *kproc;
|
||||
|
||||
uint32_t cpuports_mask;
|
||||
uint32_t fixed_mask;
|
||||
@ -149,8 +149,6 @@ static __inline int e6000sw_is_phyport(e6000sw_softc_t *sc, int port);
|
||||
static __inline struct mii_data *e6000sw_miiforphy(e6000sw_softc_t *sc,
|
||||
unsigned int phy);
|
||||
|
||||
static struct proc *e6000sw_kproc;
|
||||
|
||||
static device_method_t e6000sw_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_identify, e6000sw_identify),
|
||||
@ -321,9 +319,11 @@ e6000sw_init_interface(e6000sw_softc_t *sc, int port)
|
||||
sc->ifp[port]->if_softc = sc;
|
||||
sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST |
|
||||
IFF_DRV_RUNNING | IFF_SIMPLEX;
|
||||
sc->ifname[port] = malloc(strlen(name) + 1, M_E6000SW, M_WAITOK);
|
||||
if (sc->ifname[port] == NULL)
|
||||
sc->ifname[port] = malloc(strlen(name) + 1, M_E6000SW, M_NOWAIT);
|
||||
if (sc->ifname[port] == NULL) {
|
||||
if_free(sc->ifp[port]);
|
||||
return (ENOMEM);
|
||||
}
|
||||
memcpy(sc->ifname[port], name, strlen(name) + 1);
|
||||
if_initname(sc->ifp[port], sc->ifname[port], port);
|
||||
|
||||
@ -417,24 +417,32 @@ e6000sw_attach(device_t dev)
|
||||
bus_generic_probe(dev);
|
||||
bus_generic_attach(dev);
|
||||
|
||||
kproc_create(e6000sw_tick, sc, &e6000sw_kproc, 0, 0,
|
||||
"e6000sw tick kproc");
|
||||
kproc_create(e6000sw_tick, sc, &sc->kproc, 0, 0, "e6000sw tick kproc");
|
||||
|
||||
return (0);
|
||||
|
||||
out_fail:
|
||||
E6000SW_UNLOCK(sc);
|
||||
e6000sw_detach(dev);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static __inline int
|
||||
e6000sw_poll_done(e6000sw_softc_t *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
while (e6000sw_readreg(sc, REG_GLOBAL2, PHY_CMD) &
|
||||
(1 << PHY_CMD_SMI_BUSY))
|
||||
continue;
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
||||
if (!(e6000sw_readreg(sc, REG_GLOBAL2, PHY_CMD) &
|
||||
(1 << PHY_CMD_SMI_BUSY)))
|
||||
return (0);
|
||||
|
||||
pause("e6000sw PHY poll", hz/1000);
|
||||
}
|
||||
|
||||
return (ETIMEDOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -446,6 +454,7 @@ e6000sw_readphy(device_t dev, int phy, int reg)
|
||||
{
|
||||
e6000sw_softc_t *sc;
|
||||
uint32_t val;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
val = 0;
|
||||
@ -457,14 +466,25 @@ e6000sw_readphy(device_t dev, int phy, int reg)
|
||||
|
||||
E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
|
||||
|
||||
e6000sw_poll_done(sc);
|
||||
err = e6000sw_poll_done(sc);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Timeout while waiting for switch\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
val |= 1 << PHY_CMD_SMI_BUSY;
|
||||
val |= PHY_CMD_MODE_MDIO << PHY_CMD_MODE;
|
||||
val |= PHY_CMD_OPCODE_READ << PHY_CMD_OPCODE;
|
||||
val |= (reg << PHY_CMD_REG_ADDR) & PHY_CMD_REG_ADDR_MASK;
|
||||
val |= (phy << PHY_CMD_DEV_ADDR) & PHY_CMD_DEV_ADDR_MASK;
|
||||
e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, val);
|
||||
e6000sw_poll_done(sc);
|
||||
|
||||
err = e6000sw_poll_done(sc);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Timeout while waiting for switch\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG)
|
||||
& PHY_DATA_MASK;
|
||||
|
||||
@ -476,6 +496,7 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data)
|
||||
{
|
||||
e6000sw_softc_t *sc;
|
||||
uint32_t val;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
val = 0;
|
||||
@ -487,7 +508,12 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data)
|
||||
|
||||
E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
|
||||
|
||||
e6000sw_poll_done(sc);
|
||||
err = e6000sw_poll_done(sc);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Timeout while waiting for switch\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
val |= PHY_CMD_MODE_MDIO << PHY_CMD_MODE;
|
||||
val |= 1 << PHY_CMD_SMI_BUSY;
|
||||
val |= PHY_CMD_OPCODE_WRITE << PHY_CMD_OPCODE;
|
||||
@ -496,7 +522,12 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data)
|
||||
e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG,
|
||||
data & PHY_DATA_MASK);
|
||||
e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG, val);
|
||||
e6000sw_poll_done(sc);
|
||||
|
||||
err = e6000sw_poll_done(sc);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Timeout while waiting for switch\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -976,23 +1007,65 @@ e6000sw_get_pvid(e6000sw_softc_t *sc, int port, int *pvid)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert port status to ifmedia.
|
||||
*/
|
||||
static void
|
||||
e6000sw_update_ifmedia(uint16_t portstatus, u_int *media_status, u_int *media_active)
|
||||
{
|
||||
*media_active = IFM_ETHER;
|
||||
*media_status = IFM_AVALID;
|
||||
|
||||
if ((portstatus & PORT_STATUS_LINK_MASK) != 0)
|
||||
*media_status |= IFM_ACTIVE;
|
||||
else {
|
||||
*media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (portstatus & PORT_STATUS_SPEED_MASK) {
|
||||
case PORT_STATUS_SPEED_10:
|
||||
*media_active |= IFM_10_T;
|
||||
break;
|
||||
case PORT_STATUS_SPEED_100:
|
||||
*media_active |= IFM_100_TX;
|
||||
break;
|
||||
case PORT_STATUS_SPEED_1000:
|
||||
*media_active |= IFM_1000_T;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((portstatus & PORT_STATUS_DUPLEX_MASK) == 0)
|
||||
*media_active |= IFM_FDX;
|
||||
else
|
||||
*media_active |= IFM_HDX;
|
||||
}
|
||||
|
||||
static void
|
||||
e6000sw_tick (void *arg)
|
||||
{
|
||||
e6000sw_softc_t *sc;
|
||||
struct mii_softc *miisc;
|
||||
uint16_t portstatus;
|
||||
int port;
|
||||
|
||||
sc = arg;
|
||||
|
||||
E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
|
||||
|
||||
for (;;) {
|
||||
E6000SW_LOCK(sc);
|
||||
for (port = 0; port < sc->num_ports; port++) {
|
||||
/* Tick only on PHY ports */
|
||||
if (!e6000sw_is_phyport(sc, port))
|
||||
continue;
|
||||
mii_tick(sc->mii[port]);
|
||||
|
||||
portstatus = e6000sw_readreg(sc, REG_PORT(port), PORT_STATUS);
|
||||
|
||||
e6000sw_update_ifmedia(portstatus,
|
||||
&sc->mii[port]->mii_media_status,
|
||||
&sc->mii[port]->mii_media_active);
|
||||
|
||||
LIST_FOREACH(miisc, &sc->mii[port]->mii_phys, mii_list) {
|
||||
if (IFM_INST(sc->mii[port]->mii_media.ifm_cur->ifm_media)
|
||||
!= miisc->mii_inst)
|
||||
|
@ -55,6 +55,14 @@ struct atu_opt {
|
||||
* Per-Port Switch Registers
|
||||
*/
|
||||
#define PORT_STATUS 0x0
|
||||
#define PORT_STATUS_SPEED_MASK 0x300
|
||||
#define PORT_STATUS_SPEED_10 0
|
||||
#define PORT_STATUS_SPEED_100 1
|
||||
#define PORT_STATUS_SPEED_1000 2
|
||||
#define PORT_STATUS_DUPLEX_MASK (1 << 10)
|
||||
#define PORT_STATUS_LINK_MASK (1 << 11)
|
||||
#define PORT_STATUS_PHY_DETECT_MASK (1 << 12)
|
||||
|
||||
#define PSC_CONTROL 0x1
|
||||
#define SWITCH_ID 0x3
|
||||
#define PORT_CONTROL 0x4
|
||||
|
@ -1777,7 +1777,7 @@ static int
|
||||
ixgb_get_buf(int i, struct adapter * adapter,
|
||||
struct mbuf * nmp)
|
||||
{
|
||||
struct mbuf *mp = nmp;
|
||||
struct mbuf *mp = nmp;
|
||||
struct ixgb_buffer *rx_buffer;
|
||||
struct ifnet *ifp;
|
||||
bus_addr_t paddr;
|
||||
|
@ -216,7 +216,7 @@ lge_eeprom_getword(sc, addr, dest)
|
||||
int addr;
|
||||
u_int16_t *dest;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
u_int32_t val;
|
||||
|
||||
CSR_WRITE_4(sc, LGE_EECTL, LGE_EECTL_CMD_READ|
|
||||
@ -413,7 +413,7 @@ static void
|
||||
lge_reset(sc)
|
||||
struct lge_softc *sc;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
LGE_SETBIT(sc, LGE_MODE1, LGE_MODE1_SETRST_CTL0|LGE_MODE1_SOFTRST);
|
||||
|
||||
@ -756,7 +756,7 @@ lge_alloc_jumbo_mem(sc)
|
||||
struct lge_softc *sc;
|
||||
{
|
||||
caddr_t ptr;
|
||||
register int i;
|
||||
int i;
|
||||
struct lge_jpool_entry *entry;
|
||||
|
||||
/* Grab a big chunk o' storage. */
|
||||
@ -1524,7 +1524,7 @@ static void
|
||||
lge_stop(sc)
|
||||
struct lge_softc *sc;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
struct ifnet *ifp;
|
||||
|
||||
LGE_LOCK_ASSERT(sc);
|
||||
|
@ -1169,8 +1169,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->caps.num_comp_vectors; ++i) {
|
||||
err = mlx4_create_eq(dev, dev->caps.num_cqs -
|
||||
dev->caps.reserved_cqs +
|
||||
err = mlx4_create_eq(dev, dev->quotas.cq +
|
||||
MLX4_NUM_SPARE_EQE,
|
||||
(dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
|
||||
&priv->eq_table.eq[i]);
|
||||
@ -1190,8 +1189,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
|
||||
for (i = dev->caps.num_comp_vectors + 1;
|
||||
i < dev->caps.num_comp_vectors + dev->caps.comp_pool + 1; ++i) {
|
||||
|
||||
err = mlx4_create_eq(dev, dev->caps.num_cqs -
|
||||
dev->caps.reserved_cqs +
|
||||
err = mlx4_create_eq(dev, dev->quotas.cq +
|
||||
MLX4_NUM_SPARE_EQE,
|
||||
(dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
|
||||
&priv->eq_table.eq[i]);
|
||||
|
@ -3446,6 +3446,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||
goto err_free_eq;
|
||||
}
|
||||
|
||||
mlx4_init_quotas(dev);
|
||||
|
||||
err = mlx4_setup_hca(dev);
|
||||
if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) &&
|
||||
!mlx4_is_mfunc(dev)) {
|
||||
@ -3459,7 +3461,6 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||
if (err)
|
||||
goto err_steer;
|
||||
|
||||
mlx4_init_quotas(dev);
|
||||
mlx4_init_hca_info(dev);
|
||||
|
||||
for (port = 1; port <= dev->caps.num_ports; port++) {
|
||||
|
@ -44,7 +44,7 @@
|
||||
* scatter/gather formats.
|
||||
* Creation Date: June 21, 2006
|
||||
*
|
||||
* mpi2.h Version: 02.00.42
|
||||
* mpi2.h Version: 02.00.46
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
@ -132,7 +132,8 @@
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 03-16-15 02.00.37 Updated for MPI v2.6.
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* Added Scratchpad registers to
|
||||
* Added Scratchpad registers and
|
||||
* AtomicRequestDescriptorPost register to
|
||||
* MPI2_SYSTEM_INTERFACE_REGS.
|
||||
* Added MPI2_DIAG_SBR_RELOAD.
|
||||
* Added MPI2_IOCSTATUS_INSUFFICIENT_POWER.
|
||||
@ -142,6 +143,14 @@
|
||||
* Added V7 HostDiagnostic register defines
|
||||
* 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT
|
||||
* 01-01-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT
|
||||
* 04-05-16 02.00.43 Modified MPI26_DIAG_BOOT_DEVICE_SELECT defines
|
||||
* to be unique within first 32 characters.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 04-10-16 02.00.44 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 07-06-16 02.00.45 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 09-02-16 02.00.46 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -185,7 +194,7 @@
|
||||
|
||||
|
||||
/* Unit and Dev versioning for this MPI header set */
|
||||
#define MPI2_HEADER_VERSION_UNIT (0x2A)
|
||||
#define MPI2_HEADER_VERSION_UNIT (0x2E)
|
||||
#define MPI2_HEADER_VERSION_DEV (0x00)
|
||||
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
|
||||
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
|
||||
@ -245,7 +254,8 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
|
||||
U32 Scratchpad[4]; /* 0xB0 */
|
||||
U32 RequestDescriptorPostLow; /* 0xC0 */
|
||||
U32 RequestDescriptorPostHigh; /* 0xC4 */
|
||||
U32 Reserved7[14]; /* 0xC8 */
|
||||
U32 AtomicRequestDescriptorPost;/* 0xC8 */ /* MPI v2.6 and later; reserved in earlier versions */
|
||||
U32 Reserved7[13]; /* 0xCC */
|
||||
} MPI2_SYSTEM_INTERFACE_REGS, MPI2_POINTER PTR_MPI2_SYSTEM_INTERFACE_REGS,
|
||||
Mpi2SystemInterfaceRegs_t, MPI2_POINTER pMpi2SystemInterfaceRegs_t;
|
||||
|
||||
@ -293,10 +303,11 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
|
||||
#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800)
|
||||
|
||||
/* Defines for V7A/V7R HostDiagnostic Register */
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SELECT_FLASH64 (0x00000000)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SELECT_HCDW64 (0x00000800)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SELECT_FLASH32 (0x00001000)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SELECT_HCDW32 (0x00001800)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SEL_64FLASH (0x00000000)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SEL_64HCDW (0x00000800)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SEL_32FLASH (0x00001000)
|
||||
#define MPI26_DIAG_BOOT_DEVICE_SEL_32HCDW (0x00001800)
|
||||
|
||||
#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400)
|
||||
#define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200)
|
||||
#define MPI2_DIAG_HCB_MODE (0x00000100)
|
||||
@ -379,6 +390,7 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
|
||||
*/
|
||||
#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0)
|
||||
#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4)
|
||||
#define MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET (0x000000C8)
|
||||
|
||||
|
||||
/* Hard Reset delay timings */
|
||||
@ -415,6 +427,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
|
||||
#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08)
|
||||
#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A)
|
||||
#define MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO (0x0C)
|
||||
#define MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED (0x10)
|
||||
|
||||
#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
|
||||
|
||||
@ -482,6 +495,14 @@ typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
|
||||
MPI2_POINTER pMpi25FastPathSCSIIORequestDescriptor_t;
|
||||
|
||||
|
||||
/* PCIe Encapsulated Request Descriptor */
|
||||
typedef MPI2_SCSI_IO_REQUEST_DESCRIPTOR
|
||||
MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
|
||||
MPI2_POINTER PTR_MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR,
|
||||
Mpi26PCIeEncapsulatedRequestDescriptor_t,
|
||||
MPI2_POINTER pMpi26PCIeEncapsulatedRequestDescriptor_t;
|
||||
|
||||
|
||||
/* union of Request Descriptors */
|
||||
typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
|
||||
{
|
||||
@ -491,11 +512,35 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
|
||||
MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
|
||||
MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
|
||||
MPI25_FP_SCSI_IO_REQUEST_DESCRIPTOR FastPathSCSIIO;
|
||||
MPI26_PCIE_ENCAPSULATED_REQUEST_DESCRIPTOR PCIeEncapsulated;
|
||||
U64 Words;
|
||||
} MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
|
||||
Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t;
|
||||
|
||||
|
||||
/* Atomic Request Descriptors */
|
||||
|
||||
/*
|
||||
* All Atomic Request Descriptors have the same format, so the following
|
||||
* structure is used for all Atomic Request Descriptors:
|
||||
* Atomic Default Request Descriptor
|
||||
* Atomic High Priority Request Descriptor
|
||||
* Atomic SCSI IO Request Descriptor
|
||||
* Atomic SCSI Target Request Descriptor
|
||||
* Atomic RAID Accelerator Request Descriptor
|
||||
* Atomic Fast Path SCSI IO Request Descriptor
|
||||
* Atomic PCIe Encapsulated Request Descriptor
|
||||
*/
|
||||
|
||||
/* Atomic Request Descriptor */
|
||||
typedef struct _MPI26_ATOMIC_REQUEST_DESCRIPTOR
|
||||
{
|
||||
U8 RequestFlags; /* 0x00 */
|
||||
U8 MSIxIndex; /* 0x01 */
|
||||
U16 SMID; /* 0x02 */
|
||||
} MPI26_ATOMIC_REQUEST_DESCRIPTOR,
|
||||
MPI2_POINTER PTR_MPI26_ATOMIC_REQUEST_DESCRIPTOR,
|
||||
Mpi26AtomicRequestDescriptor_t, MPI2_POINTER pMpi26AtomicRequestDescriptor_t;
|
||||
|
||||
/* for the RequestFlags field, use the same defines as MPI2_DEFAULT_REQUEST_DESCRIPTOR */
|
||||
|
||||
@ -520,6 +565,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
|
||||
#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03)
|
||||
#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05)
|
||||
#define MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS (0x06)
|
||||
#define MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS (0x08)
|
||||
#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F)
|
||||
|
||||
/* values for marking a reply descriptor as unused */
|
||||
@ -607,6 +653,14 @@ typedef MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
|
||||
MPI2_POINTER pMpi25FastPathSCSIIOSuccessReplyDescriptor_t;
|
||||
|
||||
|
||||
/* PCIe Encapsulated Success Reply Descriptor */
|
||||
typedef MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
|
||||
MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
|
||||
MPI2_POINTER PTR_MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR,
|
||||
Mpi26PCIeEncapsulatedSuccessReplyDescriptor_t,
|
||||
MPI2_POINTER pMpi26PCIeEncapsulatedSuccessReplyDescriptor_t;
|
||||
|
||||
|
||||
/* union of Reply Descriptors */
|
||||
typedef union _MPI2_REPLY_DESCRIPTORS_UNION
|
||||
{
|
||||
@ -617,6 +671,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
|
||||
MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
|
||||
MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess;
|
||||
MPI25_FP_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR FastPathSCSIIOSuccess;
|
||||
MPI26_PCIE_ENCAPSULATED_SUCCESS_REPLY_DESCRIPTOR PCIeEncapsulatedSuccess;
|
||||
U64 Words;
|
||||
} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION,
|
||||
Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t;
|
||||
@ -659,6 +714,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
|
||||
#define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) /* Host Based Discovery Action */
|
||||
#define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) /* Power Management Control */
|
||||
#define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31) /* Send Host Message */
|
||||
#define MPI2_FUNCTION_NVME_ENCAPSULATED (0x33) /* NVMe Encapsulated (MPI v2.6) */
|
||||
#define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) /* beginning of product-specific range */
|
||||
#define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF) /* end of product-specific range */
|
||||
|
||||
@ -1232,6 +1288,8 @@ typedef union _MPI25_SGE_IO_UNION
|
||||
|
||||
#define MPI26_IEEE_SGE_FLAGS_NSF_MASK (0x1C)
|
||||
#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE (0x00)
|
||||
#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP (0x08)
|
||||
#define MPI26_IEEE_SGE_FLAGS_NSF_NVME_SGL (0x10)
|
||||
|
||||
/* Data Location Address Space */
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Title: MPI Configuration messages and pages
|
||||
* Creation Date: November 10, 2006
|
||||
*
|
||||
* mpi2_cnfg.h Version: 02.00.35
|
||||
* mpi2_cnfg.h Version: 02.00.39
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
@ -223,9 +223,38 @@
|
||||
* Flags field to IO Unit Page 7.
|
||||
* Added IO Unit Page 11.
|
||||
* Added new SAS Phy Event codes
|
||||
* Added PCIe configuration pages.
|
||||
* 03-19-15 02.00.32 Fixed PCIe Link Config page structure names to be
|
||||
* unique in first 32 characters.
|
||||
* 05-25-15 02.00.33 Added more defines for the BiosOptions field of
|
||||
* MPI2_CONFIG_PAGE_BIOS_1.
|
||||
* 08-25-15 02.00.34 Added PCIe Device Page 2 SGL format capability.
|
||||
* 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4.
|
||||
* 01-21-16 02.00.36 Added/modified MPI2_MFGPAGE_DEVID_SAS defines.
|
||||
* Added Link field to PCIe Link Pages
|
||||
* Added EnclosureLevel and ConnectorName to PCIe
|
||||
* Device Page 0.
|
||||
* Added define for PCIE IoUnit page 1 max rate shift.
|
||||
* Added comment for reserved ExtPageTypes.
|
||||
* Added SAS 4 22.5 gbs speed support.
|
||||
* Added PCIe 4 16.0 GT/sec speec support.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* Added NegotiatedLinkRate and NegotiatedPortWidth to
|
||||
* PCIe device page 0.
|
||||
* 04-10-16 02.00.37 Fixed MPI2_MFGPAGE_DEVID_SAS3616/3708 defines
|
||||
* 07-01-16 02.00.38 Added Manufacturing page 7 Connector types.
|
||||
* Changed declaration of ConnectorName in PCIe DevicePage0
|
||||
* to match SAS DevicePage 0.
|
||||
* Added SATADeviceWaitTime to IO Unit Page 11.
|
||||
* Added MPI26_MFGPAGE_DEVID_SAS4008
|
||||
* Added x16 PCIe width to IO Unit Page 7
|
||||
* Added LINKFLAGS to control SRIS in PCIe IO Unit page 1
|
||||
* phy data.
|
||||
* Added InitStatus to PCIe IO Unit Page 1 header.
|
||||
* 09-01-16 02.00.39 Added MPI26_CONFIG_PAGE_ENCLOSURE_0 and related defines.
|
||||
* Added MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE and
|
||||
* MPI26_ENCLOS_PGAD_FORM_HANDLE page address formats.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -310,6 +339,12 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18)
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19)
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING (0x1A)
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT (0x1B) /* MPI v2.6 and later */
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_PCIE_SWITCH (0x1C) /* MPI v2.6 and later */
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE (0x1D) /* MPI v2.6 and later */
|
||||
#define MPI2_CONFIG_EXTPAGETYPE_PCIE_LINK (0x1E) /* MPI v2.6 and later */
|
||||
/* Product specific reserved values 0xE0 - 0xEF */
|
||||
/* Vendor specific reserved values 0xF0 - 0xFF */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@ -377,6 +412,12 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
|
||||
|
||||
#define MPI2_SAS_ENCLOS_PGAD_HANDLE_MASK (0x0000FFFF)
|
||||
|
||||
/* Enclosure PageAddress format */
|
||||
#define MPI26_ENCLOS_PGAD_FORM_MASK (0xF0000000)
|
||||
#define MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
|
||||
#define MPI26_ENCLOS_PGAD_FORM_HANDLE (0x10000000)
|
||||
|
||||
#define MPI26_ENCLOS_PGAD_HANDLE_MASK (0x0000FFFF)
|
||||
|
||||
/* RAID Configuration PageAddress format */
|
||||
#define MPI2_RAID_PGAD_FORM_MASK (0xF0000000)
|
||||
@ -403,6 +444,33 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
|
||||
#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF)
|
||||
|
||||
|
||||
/* PCIe Switch PageAddress format */
|
||||
#define MPI26_PCIE_SWITCH_PGAD_FORM_MASK (0xF0000000)
|
||||
#define MPI26_PCIE_SWITCH_PGAD_FORM_GET_NEXT_HNDL (0x00000000)
|
||||
#define MPI26_PCIE_SWITCH_PGAD_FORM_HNDL_PORTNUM (0x10000000)
|
||||
#define MPI26_PCIE_SWITCH_EXPAND_PGAD_FORM_HNDL (0x20000000)
|
||||
|
||||
#define MPI26_PCIE_SWITCH_PGAD_HANDLE_MASK (0x0000FFFF)
|
||||
#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_MASK (0x00FF0000)
|
||||
#define MPI26_PCIE_SWITCH_PGAD_PORTNUM_SHIFT (16)
|
||||
|
||||
|
||||
/* PCIe Device PageAddress format */
|
||||
#define MPI26_PCIE_DEVICE_PGAD_FORM_MASK (0xF0000000)
|
||||
#define MPI26_PCIE_DEVICE_PGAD_FORM_GET_NEXT_HANDLE (0x00000000)
|
||||
#define MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE (0x20000000)
|
||||
|
||||
#define MPI26_PCIE_DEVICE_PGAD_HANDLE_MASK (0x0000FFFF)
|
||||
|
||||
/* PCIe Link PageAddress format */
|
||||
#define MPI26_PCIE_LINK_PGAD_FORM_MASK (0xF0000000)
|
||||
#define MPI26_PCIE_LINK_PGAD_FORM_GET_NEXT_LINK (0x00000000)
|
||||
#define MPI26_PCIE_LINK_PGAD_FORM_LINK_NUM (0x10000000)
|
||||
|
||||
#define MPI26_PCIE_DEVICE_PGAD_LINKNUM_MASK (0x000000FF)
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Configuration messages
|
||||
****************************************************************************/
|
||||
@ -518,6 +586,20 @@ typedef struct _MPI2_CONFIG_REPLY
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3324_3 (0x00C2)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3324_4 (0x00C3)
|
||||
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3516 (0x00AA)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3516_1 (0x00AB)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3416 (0x00AC)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3508 (0x00AD)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3508_1 (0x00AE)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3408 (0x00AF)
|
||||
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3716 (0x00D0)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3616 (0x00D1)
|
||||
#define MPI26_MFGPAGE_DEVID_SAS3708 (0x00D2)
|
||||
|
||||
#define MPI26_MFGPAGE_DEVID_SAS4008 (0x00A1)
|
||||
|
||||
|
||||
/* Manufacturing Page 0 */
|
||||
|
||||
typedef struct _MPI2_CONFIG_PAGE_MAN_0
|
||||
@ -755,6 +837,12 @@ typedef struct _MPI2_MANPAGE7_CONNECTOR_INFO
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8644_8X (0x0B)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8644_16X (0x0C)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8436 (0x0D)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8088_A (0x0E)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8643_16i (0x0F)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8654_4i (0x10)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8654_8i (0x11)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8611_4i (0x12)
|
||||
#define MPI2_MANPAGE7_PINOUT_SFF_8611_8i (0x13)
|
||||
|
||||
/* defines for the Location field */
|
||||
#define MPI2_MANPAGE7_LOCATION_UNKNOWN (0x01)
|
||||
@ -1017,11 +1105,13 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7
|
||||
#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X16 (0x10)
|
||||
|
||||
/* defines for IO Unit Page 7 PCIeSpeed field */
|
||||
#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02)
|
||||
#define MPI2_IOUNITPAGE7_PCIE_SPEED_16_0_GBPS (0x03)
|
||||
|
||||
/* defines for IO Unit Page 7 ProcessorState field */
|
||||
#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F)
|
||||
@ -1079,6 +1169,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7
|
||||
/* defines for IO Unit Page 7 Flags field */
|
||||
#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC (0x01)
|
||||
|
||||
|
||||
/* IO Unit Page 8 */
|
||||
|
||||
#define MPI2_IOUNIT8_NUM_THRESHOLDS (4)
|
||||
@ -1228,7 +1319,7 @@ typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11
|
||||
U32 Reserved3; /* 0x1C */
|
||||
U32 Reserved4; /* 0x20 */
|
||||
U8 BootDeviceWaitTime; /* 0x24 */
|
||||
U8 Reserved5; /* 0x25 */
|
||||
U8 SATADeviceWaitTime; /* 0x25 */
|
||||
U16 Reserved6; /* 0x26 */
|
||||
U8 NumPhys; /* 0x28 */
|
||||
U8 PEInitialSpinupDelay; /* 0x29 */
|
||||
@ -1249,9 +1340,6 @@ typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* IOC Config Pages
|
||||
****************************************************************************/
|
||||
@ -1968,6 +2056,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
|
||||
#define MPI2_SAS_NEG_LINK_RATE_3_0 (0x09)
|
||||
#define MPI2_SAS_NEG_LINK_RATE_6_0 (0x0A)
|
||||
#define MPI25_SAS_NEG_LINK_RATE_12_0 (0x0B)
|
||||
#define MPI26_SAS_NEG_LINK_RATE_22_5 (0x0C)
|
||||
|
||||
|
||||
/* values for AttachedPhyInfo fields */
|
||||
@ -2035,12 +2124,14 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
|
||||
#define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90)
|
||||
#define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0)
|
||||
#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0)
|
||||
#define MPI26_SAS_PRATE_MAX_RATE_22_5 (0xC0)
|
||||
#define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F)
|
||||
#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00)
|
||||
#define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08)
|
||||
#define MPI2_SAS_PRATE_MIN_RATE_3_0 (0x09)
|
||||
#define MPI2_SAS_PRATE_MIN_RATE_6_0 (0x0A)
|
||||
#define MPI25_SAS_PRATE_MIN_RATE_12_0 (0x0B)
|
||||
#define MPI26_SAS_PRATE_MIN_RATE_22_5 (0x0C)
|
||||
|
||||
|
||||
/* values for SAS HwLinkRate fields */
|
||||
@ -2049,11 +2140,13 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1
|
||||
#define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90)
|
||||
#define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0)
|
||||
#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0)
|
||||
#define MPI26_SAS_HWRATE_MAX_RATE_22_5 (0xC0)
|
||||
#define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F)
|
||||
#define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08)
|
||||
#define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09)
|
||||
#define MPI2_SAS_HWRATE_MIN_RATE_6_0 (0x0A)
|
||||
#define MPI25_SAS_HWRATE_MIN_RATE_12_0 (0x0B)
|
||||
#define MPI26_SAS_HWRATE_MIN_RATE_22_5 (0x0C)
|
||||
|
||||
|
||||
|
||||
@ -2227,11 +2320,13 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
|
||||
#define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90)
|
||||
#define MPI2_SASIOUNIT1_MAX_RATE_6_0 (0xA0)
|
||||
#define MPI25_SASIOUNIT1_MAX_RATE_12_0 (0xB0)
|
||||
#define MPI26_SASIOUNIT1_MAX_RATE_22_5 (0xC0)
|
||||
#define MPI2_SASIOUNIT1_MIN_RATE_MASK (0x0F)
|
||||
#define MPI2_SASIOUNIT1_MIN_RATE_1_5 (0x08)
|
||||
#define MPI2_SASIOUNIT1_MIN_RATE_3_0 (0x09)
|
||||
#define MPI2_SASIOUNIT1_MIN_RATE_6_0 (0x0A)
|
||||
#define MPI25_SASIOUNIT1_MIN_RATE_12_0 (0x0B)
|
||||
#define MPI26_SASIOUNIT1_MIN_RATE_22_5 (0x0C)
|
||||
|
||||
/* see mpi2_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
|
||||
|
||||
@ -2718,7 +2813,6 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
|
||||
#define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID (0x0002)
|
||||
#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
|
||||
|
||||
|
||||
/* SAS Device Page 1 */
|
||||
|
||||
typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_1
|
||||
@ -2885,7 +2979,6 @@ typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG
|
||||
#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT (0xD0)
|
||||
#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1)
|
||||
#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2)
|
||||
|
||||
/* Following codes are product specific and in MPI v2.6 and later */
|
||||
#define MPI2_SASPHY3_EVENT_CODE_LCARB_WAIT_TIME (0xD3)
|
||||
#define MPI2_SASPHY3_EVENT_CODE_RCVD_CONN_RESP_WAIT_TIME (0xD4)
|
||||
@ -2898,7 +2991,6 @@ typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG
|
||||
#define MPI2_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE (0xDB)
|
||||
#define MPI2_SASPHY3_EVENT_CODE_SMP_RX_START_RECEIVE (0xDC)
|
||||
|
||||
|
||||
/* values for the CounterType field */
|
||||
#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00)
|
||||
#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01)
|
||||
@ -2989,7 +3081,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PORT_0
|
||||
* SAS Enclosure Config Pages
|
||||
****************************************************************************/
|
||||
|
||||
/* SAS Enclosure Page 0 */
|
||||
/* SAS Enclosure Page 0, Enclosure Page 0 */
|
||||
|
||||
typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
|
||||
{
|
||||
@ -3007,7 +3099,10 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
|
||||
U32 Reserved4; /* 0x24 */
|
||||
} MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
|
||||
MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0,
|
||||
Mpi2SasEnclosurePage0_t, MPI2_POINTER pMpi2SasEnclosurePage0_t;
|
||||
Mpi2SasEnclosurePage0_t, MPI2_POINTER pMpi2SasEnclosurePage0_t,
|
||||
MPI26_CONFIG_PAGE_ENCLOSURE_0,
|
||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_ENCLOSURE_0,
|
||||
Mpi26EnclosurePage0_t, MPI2_POINTER pMpi26EnclosurePage0_t;
|
||||
|
||||
#define MPI2_SASENCLOSURE0_PAGEVERSION (0x04)
|
||||
|
||||
@ -3021,6 +3116,17 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0
|
||||
#define MPI2_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
|
||||
#define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
|
||||
|
||||
#define MPI26_ENCLOSURE0_PAGEVERSION (0x04)
|
||||
|
||||
/* Values for Enclosure Page 0 Flags field */
|
||||
#define MPI26_ENCLS0_FLAGS_ENCL_LEVEL_VALID (0x0010)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_MASK (0x000F)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_IOC_SES (0x0001)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
|
||||
#define MPI26_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
|
||||
|
||||
/****************************************************************************
|
||||
* Log Config Page
|
||||
@ -3300,5 +3406,424 @@ typedef struct _MPI2_CONFIG_PAGE_EXT_MAN_PS
|
||||
|
||||
/* PageVersion should be provided by product-specific code */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* values for fields used by several types of PCIe Config Pages
|
||||
****************************************************************************/
|
||||
|
||||
/* values for NegotiatedLinkRates fields */
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_MASK_PHYSICAL (0x0F)
|
||||
/* link rates used for Negotiated Physical Link Rate */
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_UNKNOWN (0x00)
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_PHY_DISABLED (0x01)
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_2_5 (0x02)
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_5_0 (0x03)
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_8_0 (0x04)
|
||||
#define MPI26_PCIE_NEG_LINK_RATE_16_0 (0x05)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PCIe IO Unit Config Pages (MPI v2.6 and later)
|
||||
****************************************************************************/
|
||||
|
||||
/* PCIe IO Unit Page 0 */
|
||||
|
||||
typedef struct _MPI26_PCIE_IO_UNIT0_PHY_DATA
|
||||
{
|
||||
U8 Link; /* 0x00 */
|
||||
U8 LinkFlags; /* 0x01 */
|
||||
U8 PhyFlags; /* 0x02 */
|
||||
U8 NegotiatedLinkRate; /* 0x03 */
|
||||
U32 ControllerPhyDeviceInfo;/* 0x04 */
|
||||
U16 AttachedDevHandle; /* 0x08 */
|
||||
U16 ControllerDevHandle; /* 0x0A */
|
||||
U32 EnumerationStatus; /* 0x0C */
|
||||
U32 Reserved1; /* 0x10 */
|
||||
} MPI26_PCIE_IO_UNIT0_PHY_DATA, MPI2_POINTER PTR_MPI26_PCIE_IO_UNIT0_PHY_DATA,
|
||||
Mpi26PCIeIOUnit0PhyData_t, MPI2_POINTER pMpi26PCIeIOUnit0PhyData_t;
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check the value returned for NumPhys at runtime.
|
||||
*/
|
||||
#ifndef MPI26_PCIE_IOUNIT0_PHY_MAX
|
||||
#define MPI26_PCIE_IOUNIT0_PHY_MAX (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_0
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U32 Reserved1; /* 0x08 */
|
||||
U8 NumPhys; /* 0x0C */
|
||||
U8 InitStatus; /* 0x0D */
|
||||
U16 Reserved3; /* 0x0E */
|
||||
MPI26_PCIE_IO_UNIT0_PHY_DATA PhyData[MPI26_PCIE_IOUNIT0_PHY_MAX]; /* 0x10 */
|
||||
} MPI26_CONFIG_PAGE_PIOUNIT_0,
|
||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PIOUNIT_0,
|
||||
Mpi26PCIeIOUnitPage0_t, MPI2_POINTER pMpi26PCIeIOUnitPage0_t;
|
||||
|
||||
#define MPI26_PCIEIOUNITPAGE0_PAGEVERSION (0x00)
|
||||
|
||||
/* values for PCIe IO Unit Page 0 LinkFlags */
|
||||
#define MPI26_PCIEIOUNIT0_LINKFLAGS_ENUMERATION_IN_PROGRESS (0x08)
|
||||
|
||||
/* values for PCIe IO Unit Page 0 PhyFlags */
|
||||
#define MPI26_PCIEIOUNIT0_PHYFLAGS_PHY_DISABLED (0x08)
|
||||
|
||||
/* use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
|
||||
|
||||
/* see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo values */
|
||||
|
||||
/* values for PCIe IO Unit Page 0 EnumerationStatus */
|
||||
#define MPI26_PCIEIOUNIT0_ES_MAX_SWITCHES_EXCEEDED (0x40000000)
|
||||
#define MPI26_PCIEIOUNIT0_ES_MAX_DEVICES_EXCEEDED (0x20000000)
|
||||
|
||||
|
||||
/* PCIe IO Unit Page 1 */
|
||||
|
||||
typedef struct _MPI26_PCIE_IO_UNIT1_PHY_DATA
|
||||
{
|
||||
U8 Link; /* 0x00 */
|
||||
U8 LinkFlags; /* 0x01 */
|
||||
U8 PhyFlags; /* 0x02 */
|
||||
U8 MaxMinLinkRate; /* 0x03 */
|
||||
U32 ControllerPhyDeviceInfo; /* 0x04 */
|
||||
U32 Reserved1; /* 0x08 */
|
||||
} MPI26_PCIE_IO_UNIT1_PHY_DATA, MPI2_POINTER PTR_MPI26_PCIE_IO_UNIT1_PHY_DATA,
|
||||
Mpi26PCIeIOUnit1PhyData_t, MPI2_POINTER pMpi26PCIeIOUnit1PhyData_t;
|
||||
|
||||
/* values for LinkFlags */
|
||||
#define MPI26_PCIEIOUNIT1_LINKFLAGS_DIS_SRIS (0x00)
|
||||
#define MPI26_PCIEIOUNIT1_LINKFLAGS_EN_SRIS (0x01)
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check the value returned for NumPhys at runtime.
|
||||
*/
|
||||
#ifndef MPI26_PCIE_IOUNIT1_PHY_MAX
|
||||
#define MPI26_PCIE_IOUNIT1_PHY_MAX (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PIOUNIT_1
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U16 ControlFlags; /* 0x08 */
|
||||
U16 Reserved; /* 0x0A */
|
||||
U16 AdditionalControlFlags; /* 0x0C */
|
||||
U16 NVMeMaxQueueDepth; /* 0x0E */
|
||||
U8 NumPhys; /* 0x10 */
|
||||
U8 Reserved1; /* 0x11 */
|
||||
U16 Reserved2; /* 0x12 */
|
||||
MPI26_PCIE_IO_UNIT1_PHY_DATA PhyData[MPI26_PCIE_IOUNIT1_PHY_MAX];/* 0x14 */
|
||||
} MPI26_CONFIG_PAGE_PIOUNIT_1,
|
||||
MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PIOUNIT_1,
|
||||
Mpi26PCIeIOUnitPage1_t, MPI2_POINTER pMpi26PCIeIOUnitPage1_t;
|
||||
|
||||
#define MPI26_PCIEIOUNITPAGE1_PAGEVERSION (0x00)
|
||||
|
||||
/* values for PCIe IO Unit Page 1 PhyFlags */
|
||||
#define MPI26_PCIEIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08)
|
||||
#define MPI26_PCIEIOUNIT1_PHYFLAGS_ENDPOINT_ONLY (0x01)
|
||||
|
||||
/* values for PCIe IO Unit Page 1 MaxMinLinkRate */
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_MASK (0xF0)
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_SHIFT (4)
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_2_5 (0x20)
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_5_0 (0x30)
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_8_0 (0x40)
|
||||
#define MPI26_PCIEIOUNIT1_MAX_RATE_16_0 (0x50)
|
||||
|
||||
/* see mpi2_pci.h for values for PCIe IO Unit Page 0 ControllerPhyDeviceInfo values */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PCIe Switch Config Pages (MPI v2.6 and later)
|
||||
****************************************************************************/
|
||||
|
||||
/* PCIe Switch Page 0 */
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PSWITCH_0
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U8 PhysicalPort; /* 0x08 */
|
||||
U8 Reserved1; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U16 DevHandle; /* 0x0C */
|
||||
U16 ParentDevHandle; /* 0x0E */
|
||||
U8 NumPorts; /* 0x10 */
|
||||
U8 PCIeLevel; /* 0x11 */
|
||||
U16 Reserved3; /* 0x12 */
|
||||
U32 Reserved4; /* 0x14 */
|
||||
U32 Reserved5; /* 0x18 */
|
||||
U32 Reserved6; /* 0x1C */
|
||||
} MPI26_CONFIG_PAGE_PSWITCH_0, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PSWITCH_0,
|
||||
Mpi26PCIeSwitchPage0_t, MPI2_POINTER pMpi26PCIeSwitchPage0_t;
|
||||
|
||||
#define MPI26_PCIESWITCH0_PAGEVERSION (0x00)
|
||||
|
||||
|
||||
/* PCIe Switch Page 1 */
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PSWITCH_1
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U8 PhysicalPort; /* 0x08 */
|
||||
U8 Reserved1; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U8 NumPorts; /* 0x0C */
|
||||
U8 PortNum; /* 0x0D */
|
||||
U16 AttachedDevHandle; /* 0x0E */
|
||||
U16 SwitchDevHandle; /* 0x10 */
|
||||
U8 NegotiatedPortWidth; /* 0x12 */
|
||||
U8 NegotiatedLinkRate; /* 0x13 */
|
||||
U32 Reserved4; /* 0x14 */
|
||||
U32 Reserved5; /* 0x18 */
|
||||
} MPI26_CONFIG_PAGE_PSWITCH_1, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PSWITCH_1,
|
||||
Mpi26PCIeSwitchPage1_t, MPI2_POINTER pMpi26PCIeSwitchPage1_t;
|
||||
|
||||
#define MPI26_PCIESWITCH1_PAGEVERSION (0x00)
|
||||
|
||||
/* use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PCIe Device Config Pages (MPI v2.6 and later)
|
||||
****************************************************************************/
|
||||
|
||||
/* PCIe Device Page 0 */
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_0
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U16 Slot; /* 0x08 */
|
||||
U16 EnclosureHandle; /* 0x0A */
|
||||
U64 WWID; /* 0x0C */
|
||||
U16 ParentDevHandle; /* 0x14 */
|
||||
U8 PortNum; /* 0x16 */
|
||||
U8 AccessStatus; /* 0x17 */
|
||||
U16 DevHandle; /* 0x18 */
|
||||
U8 PhysicalPort; /* 0x1A */
|
||||
U8 Reserved1; /* 0x1B */
|
||||
U32 DeviceInfo; /* 0x1C */
|
||||
U32 Flags; /* 0x20 */
|
||||
U8 SupportedLinkRates; /* 0x24 */
|
||||
U8 MaxPortWidth; /* 0x25 */
|
||||
U8 NegotiatedPortWidth; /* 0x26 */
|
||||
U8 NegotiatedLinkRate; /* 0x27 */
|
||||
U8 EnclosureLevel; /* 0x28 */
|
||||
U8 Reserved2; /* 0x29 */
|
||||
U16 Reserved3; /* 0x2A */
|
||||
U8 ConnectorName[4]; /* 0x2C */
|
||||
U32 Reserved4; /* 0x30 */
|
||||
U32 Reserved5; /* 0x34 */
|
||||
} MPI26_CONFIG_PAGE_PCIEDEV_0, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PCIEDEV_0,
|
||||
Mpi26PCIeDevicePage0_t, MPI2_POINTER pMpi26PCIeDevicePage0_t;
|
||||
|
||||
#define MPI26_PCIEDEVICE0_PAGEVERSION (0x01)
|
||||
|
||||
/* values for PCIe Device Page 0 AccessStatus field */
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NO_ERRORS (0x00)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NEEDS_INITIALIZATION (0x04)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_CAPABILITY_FAILED (0x02)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_DEVICE_BLOCKED (0x07)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_MEMORY_SPACE_ACCESS_FAILED (0x08)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_UNSUPPORTED_DEVICE (0x09)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_MSIX_REQUIRED (0x0A)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_UNKNOWN (0x10)
|
||||
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_READY_TIMEOUT (0x30)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_DEVCFG_UNSUPPORTED (0x31)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_IDENTIFY_FAILED (0x32)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_QCONFIG_FAILED (0x33)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_QCREATION_FAILED (0x34)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_EVENTCFG_FAILED (0x35)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_GET_FEATURE_STAT_FAILED (0x36)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_IDLE_TIMEOUT (0x37)
|
||||
#define MPI26_PCIEDEV0_ASTATUS_NVME_FAILURE_STATUS (0x38)
|
||||
|
||||
#define MPI26_PCIEDEV0_ASTATUS_INIT_FAIL_MAX (0x3F)
|
||||
|
||||
/* see mpi2_pci.h for the MPI26_PCIE_DEVINFO_ defines used for the DeviceInfo field */
|
||||
|
||||
/* values for PCIe Device Page 0 Flags field */
|
||||
#define MPI26_PCIEDEV0_FLAGS_UNAUTHORIZED_DEVICE (0x8000)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH (0x4000)
|
||||
#define MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE (0x2000)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ASYNCHRONOUS_NOTIFICATION (0x0400)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ATA_SW_PRESERVATION (0x0200)
|
||||
#define MPI26_PCIEDEV0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ATA_48BIT_LBA_SUPPORTED (0x0080)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ATA_SMART_SUPPORTED (0x0040)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ATA_NCQ_SUPPORTED (0x0020)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ATA_FUA_SUPPORTED (0x0010)
|
||||
#define MPI26_PCIEDEV0_FLAGS_ENCL_LEVEL_VALID (0x0002)
|
||||
#define MPI26_PCIEDEV0_FLAGS_DEVICE_PRESENT (0x0001)
|
||||
|
||||
/* values for PCIe Device Page 0 SupportedLinkRates field */
|
||||
#define MPI26_PCIEDEV0_LINK_RATE_16_0_SUPPORTED (0x08)
|
||||
#define MPI26_PCIEDEV0_LINK_RATE_8_0_SUPPORTED (0x04)
|
||||
#define MPI26_PCIEDEV0_LINK_RATE_5_0_SUPPORTED (0x02)
|
||||
#define MPI26_PCIEDEV0_LINK_RATE_2_5_SUPPORTED (0x01)
|
||||
|
||||
/* use MPI26_PCIE_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
|
||||
|
||||
|
||||
/* PCIe Device Page 2 */
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PCIEDEV_2
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U16 DevHandle; /* 0x08 */
|
||||
U16 Reserved1; /* 0x0A */
|
||||
U32 MaximumDataTransferSize;/* 0x0C */
|
||||
U32 Capabilities; /* 0x10 */
|
||||
U32 Reserved2; /* 0x14 */
|
||||
} MPI26_CONFIG_PAGE_PCIEDEV_2, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PCIEDEV_2,
|
||||
Mpi26PCIeDevicePage2_t, MPI2_POINTER pMpi26PCIeDevicePage2_t;
|
||||
|
||||
#define MPI26_PCIEDEVICE2_PAGEVERSION (0x00)
|
||||
|
||||
/* defines for PCIe Device Page 2 Capabilities field */
|
||||
#define MPI26_PCIEDEV2_CAP_SGL_FORMAT (0x00000004)
|
||||
#define MPI26_PCIEDEV2_CAP_BIT_BUCKET_SUPPORT (0x00000002)
|
||||
#define MPI26_PCIEDEV2_CAP_SGL_SUPPORT (0x00000001)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PCIe Link Config Pages (MPI v2.6 and later)
|
||||
****************************************************************************/
|
||||
|
||||
/* PCIe Link Page 1 */
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PCIELINK_1
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U8 Link; /* 0x08 */
|
||||
U8 Reserved1; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U32 CorrectableErrorCount; /* 0x0C */
|
||||
U16 NonFatalErrorCount; /* 0x10 */
|
||||
U16 Reserved3; /* 0x12 */
|
||||
U16 FatalErrorCount; /* 0x14 */
|
||||
U16 Reserved4; /* 0x16 */
|
||||
} MPI26_CONFIG_PAGE_PCIELINK_1, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PCIELINK_1,
|
||||
Mpi26PcieLinkPage1_t, MPI2_POINTER pMpi26PcieLinkPage1_t;
|
||||
|
||||
#define MPI26_PCIELINK1_PAGEVERSION (0x00)
|
||||
|
||||
/* PCIe Link Page 2 */
|
||||
|
||||
typedef struct _MPI26_PCIELINK2_LINK_EVENT
|
||||
{
|
||||
U8 LinkEventCode; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U16 Reserved2; /* 0x02 */
|
||||
U32 LinkEventInfo; /* 0x04 */
|
||||
} MPI26_PCIELINK2_LINK_EVENT, MPI2_POINTER PTR_MPI26_PCIELINK2_LINK_EVENT,
|
||||
Mpi26PcieLink2LinkEvent_t, MPI2_POINTER pMpi26PcieLink2LinkEvent_t;
|
||||
|
||||
/* use MPI26_PCIELINK3_EVTCODE_ for the LinkEventCode field */
|
||||
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check the value returned for NumLinkEvents at runtime.
|
||||
*/
|
||||
#ifndef MPI26_PCIELINK2_LINK_EVENT_MAX
|
||||
#define MPI26_PCIELINK2_LINK_EVENT_MAX (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PCIELINK_2
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U8 Link; /* 0x08 */
|
||||
U8 Reserved1; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U8 NumLinkEvents; /* 0x0C */
|
||||
U8 Reserved3; /* 0x0D */
|
||||
U16 Reserved4; /* 0x0E */
|
||||
MPI26_PCIELINK2_LINK_EVENT LinkEvent[MPI26_PCIELINK2_LINK_EVENT_MAX]; /* 0x10 */
|
||||
} MPI26_CONFIG_PAGE_PCIELINK_2, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PCIELINK_2,
|
||||
Mpi26PcieLinkPage2_t, MPI2_POINTER pMpi26PcieLinkPage2_t;
|
||||
|
||||
#define MPI26_PCIELINK2_PAGEVERSION (0x00)
|
||||
|
||||
|
||||
/* PCIe Link Page 3 */
|
||||
|
||||
typedef struct _MPI26_PCIELINK3_LINK_EVENT_CONFIG
|
||||
{
|
||||
U8 LinkEventCode; /* 0x00 */
|
||||
U8 Reserved1; /* 0x01 */
|
||||
U16 Reserved2; /* 0x02 */
|
||||
U8 CounterType; /* 0x04 */
|
||||
U8 ThresholdWindow; /* 0x05 */
|
||||
U8 TimeUnits; /* 0x06 */
|
||||
U8 Reserved3; /* 0x07 */
|
||||
U32 EventThreshold; /* 0x08 */
|
||||
U16 ThresholdFlags; /* 0x0C */
|
||||
U16 Reserved4; /* 0x0E */
|
||||
} MPI26_PCIELINK3_LINK_EVENT_CONFIG, MPI2_POINTER PTR_MPI26_PCIELINK3_LINK_EVENT_CONFIG,
|
||||
Mpi26PcieLink3LinkEventConfig_t, MPI2_POINTER pMpi26PcieLink3LinkEventConfig_t;
|
||||
|
||||
/* values for LinkEventCode field */
|
||||
#define MPI26_PCIELINK3_EVTCODE_NO_EVENT (0x00)
|
||||
#define MPI26_PCIELINK3_EVTCODE_CORRECTABLE_ERROR_RECEIVED (0x01)
|
||||
#define MPI26_PCIELINK3_EVTCODE_NON_FATAL_ERROR_RECEIVED (0x02)
|
||||
#define MPI26_PCIELINK3_EVTCODE_FATAL_ERROR_RECEIVED (0x03)
|
||||
#define MPI26_PCIELINK3_EVTCODE_DATA_LINK_ERROR_DETECTED (0x04)
|
||||
#define MPI26_PCIELINK3_EVTCODE_TRANSACTION_LAYER_ERROR_DETECTED (0x05)
|
||||
#define MPI26_PCIELINK3_EVTCODE_TLP_ECRC_ERROR_DETECTED (0x06)
|
||||
#define MPI26_PCIELINK3_EVTCODE_POISONED_TLP (0x07)
|
||||
#define MPI26_PCIELINK3_EVTCODE_RECEIVED_NAK_DLLP (0x08)
|
||||
#define MPI26_PCIELINK3_EVTCODE_SENT_NAK_DLLP (0x09)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_RECOVERY_STATE (0x0A)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_RXL0S_STATE (0x0B)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_TXL0S_STATE (0x0C)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_L1_STATE (0x0D)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_DISABLED_STATE (0x0E)
|
||||
#define MPI26_PCIELINK3_EVTCODE_LTSSM_HOT_RESET_STATE (0x0F)
|
||||
#define MPI26_PCIELINK3_EVTCODE_SYSTEM_ERROR (0x10)
|
||||
#define MPI26_PCIELINK3_EVTCODE_DECODE_ERROR (0x11)
|
||||
#define MPI26_PCIELINK3_EVTCODE_DISPARITY_ERROR (0x12)
|
||||
|
||||
/* values for the CounterType field */
|
||||
#define MPI26_PCIELINK3_COUNTER_TYPE_WRAPPING (0x00)
|
||||
#define MPI26_PCIELINK3_COUNTER_TYPE_SATURATING (0x01)
|
||||
#define MPI26_PCIELINK3_COUNTER_TYPE_PEAK_VALUE (0x02)
|
||||
|
||||
/* values for the TimeUnits field */
|
||||
#define MPI26_PCIELINK3_TM_UNITS_10_MICROSECONDS (0x00)
|
||||
#define MPI26_PCIELINK3_TM_UNITS_100_MICROSECONDS (0x01)
|
||||
#define MPI26_PCIELINK3_TM_UNITS_1_MILLISECOND (0x02)
|
||||
#define MPI26_PCIELINK3_TM_UNITS_10_MILLISECONDS (0x03)
|
||||
|
||||
/* values for the ThresholdFlags field */
|
||||
#define MPI26_PCIELINK3_TFLAGS_EVENT_NOTIFY (0x0001)
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check the value returned for NumLinkEvents at runtime.
|
||||
*/
|
||||
#ifndef MPI26_PCIELINK3_LINK_EVENT_MAX
|
||||
#define MPI26_PCIELINK3_LINK_EVENT_MAX (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI26_CONFIG_PAGE_PCIELINK_3
|
||||
{
|
||||
MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
|
||||
U8 Link; /* 0x08 */
|
||||
U8 Reserved1; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U8 NumLinkEvents; /* 0x0C */
|
||||
U8 Reserved3; /* 0x0D */
|
||||
U16 Reserved4; /* 0x0E */
|
||||
MPI26_PCIELINK3_LINK_EVENT_CONFIG LinkEventConfig[MPI26_PCIELINK3_LINK_EVENT_MAX]; /* 0x10 */
|
||||
} MPI26_CONFIG_PAGE_PCIELINK_3, MPI2_POINTER PTR_MPI26_CONFIG_PAGE_PCIELINK_3,
|
||||
Mpi26PcieLinkPage3_t, MPI2_POINTER pMpi26PcieLinkPage3_t;
|
||||
|
||||
#define MPI26_PCIELINK3_PAGEVERSION (0x00)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Title: MPI Host Based Discovery messages and structures
|
||||
* Creation Date: October 21, 2009
|
||||
*
|
||||
* mpi2_hbd.h Version: 02.00.03
|
||||
* mpi2_hbd.h Version: 02.00.04
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
@ -59,6 +59,7 @@
|
||||
* HBD Action request, replaced by AdditionalInfo field.
|
||||
* 11-18-11 02.00.02 Incorporating additions for MPI v2.5.
|
||||
* 11-18-14 02.00.03 Updated copyright information.
|
||||
* 02-17-16 02.00.04 Added SAS 4 22.5 gbs speed support.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -129,6 +130,7 @@ typedef struct _MPI2_HBD_ACTION_REQUEST
|
||||
#define MPI2_HBD_MAX_RATE_3_0 (0x09)
|
||||
#define MPI2_HBD_MAX_RATE_6_0 (0x0A)
|
||||
#define MPI25_HBD_MAX_RATE_12_0 (0x0B)
|
||||
#define MPI26_HBD_MAX_RATE_22_5 (0x0C)
|
||||
|
||||
|
||||
/* Host Based Discovery Action Reply Message */
|
||||
|
@ -41,24 +41,25 @@
|
||||
All rights reserved.
|
||||
|
||||
---------------------------------------
|
||||
Header Set Release Version: 02.00.42
|
||||
Header Set Release Date: 01-04-16
|
||||
Header Set Release Version: 02.00.46
|
||||
Header Set Release Date: 09-07-16
|
||||
---------------------------------------
|
||||
|
||||
Filename Current version Prior version
|
||||
---------- --------------- -------------
|
||||
mpi2.h 02.00.42 02.00.41
|
||||
mpi2_cnfg.h 02.00.35 02.00.34
|
||||
mpi2_init.h 02.00.20 02.00.19
|
||||
mpi2_ioc.h 02.00.27 02.00.27
|
||||
mpi2.h 02.00.46 02.00.45
|
||||
mpi2_cnfg.h 02.00.39 02.00.38
|
||||
mpi2_init.h 02.00.21 02.00.21
|
||||
mpi2_ioc.h 02.00.30 02.00.29
|
||||
mpi2_raid.h 02.00.11 02.00.11
|
||||
mpi2_sas.h 02.00.10 02.00.10
|
||||
mpi2_targ.h 02.00.09 02.00.09
|
||||
mpi2_tool.h 02.00.13 02.00.13
|
||||
mpi2_tool.h 02.00.14 02.00.13
|
||||
mpi2_type.h 02.00.01 02.00.01
|
||||
mpi2_ra.h 02.00.01 02.00.01
|
||||
mpi2_hbd.h 02.00.03 02.00.03
|
||||
mpi2_history.txt 02.00.41 02.00.40
|
||||
mpi2_hbd.h 02.00.04 02.00.04
|
||||
mpi2_pci.h 02.00.02 02.00.02
|
||||
mpi2_history.txt 02.00.43 02.00.43
|
||||
|
||||
|
||||
* Date Version Description
|
||||
@ -141,7 +142,8 @@ mpi2.h
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 03-16-15 02.00.37 Updated for MPI v2.6.
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* Added Scratchpad registers to
|
||||
* Added Scratchpad registers and
|
||||
* AtomicRequestDescriptorPost register to
|
||||
* MPI2_SYSTEM_INTERFACE_REGS.
|
||||
* Added MPI2_DIAG_SBR_RELOAD.
|
||||
* Added MPI2_IOCSTATUS_INSUFFICIENT_POWER.
|
||||
@ -151,6 +153,14 @@ mpi2.h
|
||||
* Added V7 HostDiagnostic register defines
|
||||
* 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT
|
||||
* 01-04-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT
|
||||
* 04-05-16 02.00.43 Modified MPI26_DIAG_BOOT_DEVICE_SELECT defines
|
||||
* to be unique within first 32 characters.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 04-10-16 02.00.44 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 07-06-16 02.00.45 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* 09-02-16 02.00.46 Bumped MPI2_HEADER_VERSION_UNIT.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_cnfg.h
|
||||
@ -323,9 +333,38 @@ mpi2_cnfg.h
|
||||
* Flags field to IO Unit Page 7.
|
||||
* Added IO Unit Page 11.
|
||||
* Added new SAS Phy Event codes
|
||||
* Added PCIe configuration pages.
|
||||
* 03-19-15 02.00.32 Fixed PCIe Link Config page structure names to be
|
||||
* unique in first 32 characters.
|
||||
* 05-25-15 02.00.33 Added more defines for the BiosOptions field of
|
||||
* MPI2_CONFIG_PAGE_BIOS_1.
|
||||
* 08-25-15 02.00.34 Added PCIe Device Page 2 SGL format capability.
|
||||
* 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4.
|
||||
* 01-21-16 02.00.36 Added/modified MPI2_MFGPAGE_DEVID_SAS defines.
|
||||
* Added Link field to PCIe Link Pages
|
||||
* Added EnclosureLevel and ConnectorName to PCIe
|
||||
* Device Page 0.
|
||||
* Added define for PCIE IoUnit page 1 max rate shift.
|
||||
* Added comment for reserved ExtPageTypes.
|
||||
* Added SAS 4 22.5 gbs speed support.
|
||||
* Added PCIe 4 16.0 GT/sec speec support.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* Added NegotiatedLinkRate and NegotiatedPortWidth to
|
||||
* PCIe device page 0.
|
||||
* 04-10-16 02.00.37 Fixed MPI2_MFGPAGE_DEVID_SAS3616/3708 defines
|
||||
* 07-01-16 02.00.38 Added Manufacturing page 7 Connector types.
|
||||
* Changed declaration of ConnectorName in PCIe DevicePage0
|
||||
* to match SAS DevicePage 0.
|
||||
* Added SATADeviceWaitTime to IO Unit Page 11.
|
||||
* Added MPI26_MFGPAGE_DEVID_SAS4008
|
||||
* Added x16 PCIe width to IO Unit Page 7
|
||||
* Added LINKFLAGS to control SRIS in PCIe IO Unit page 1
|
||||
* phy data.
|
||||
* Added InitStatus to PCIe IO Unit Page 1 header.
|
||||
* 09-01-16 02.00.39 Added MPI26_CONFIG_PAGE_ENCLOSURE_0 and related defines.
|
||||
* Added MPI26_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE and
|
||||
* MPI26_ENCLOS_PGAD_FORM_HANDLE page address formats.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_init.h
|
||||
@ -365,6 +404,8 @@ mpi2_init.h
|
||||
* 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset.
|
||||
* 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message.
|
||||
* 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message.
|
||||
* 01-21-16 02.00.21 Modified MPI26_SCSITASKMGMT_MSGFLAGS_PCIE* defines to
|
||||
* be unique within first 32 characters.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_ioc.h
|
||||
@ -491,9 +532,30 @@ mpi2_ioc.h
|
||||
* MPI26_EVENT_DATA_PCIE_LINK_COUNTER.
|
||||
* Added MPI26_CTRL_OP_SHUTDOWN.
|
||||
* Added MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG
|
||||
* Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS
|
||||
* Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
|
||||
* MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
|
||||
* 08-25-15 02.00.27 Added IC ARCH Class based signature defines.
|
||||
* --------------------------------------------------------------------------
|
||||
* Added MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED event.
|
||||
* Added ConigurationFlags field to IOCInit message to
|
||||
* support NVMe SGL format control.
|
||||
* Added PCIe SRIOV support.
|
||||
* 02-17-16 02.00.28 Added SAS 4 22.5 gbs speed support.
|
||||
* Added PCIe 4 16.0 GT/sec speec support.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* 07-01-16 02.00.29 Added Archclass for 4008 product.
|
||||
* Added IOCException MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED.
|
||||
* 08-23-16 02.00.30 Added new defines for the ImageType field of FWDownload
|
||||
* Request Message.
|
||||
* Added new defines for the ImageType field of FWUpload
|
||||
* Request Message.
|
||||
* Added new values for the RegionType field in the Layout
|
||||
* Data sections of the FLASH Layout Extended Image Data.
|
||||
* Added new defines for the ReasonCode field of
|
||||
* Active Cable Exception Event.
|
||||
* Added MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE and
|
||||
* MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_raid.h
|
||||
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
|
||||
@ -581,6 +643,8 @@ mpi2_tool.h
|
||||
* 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
|
||||
* 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
|
||||
* 11-18-14 02.00.13 Updated copyright information.
|
||||
* 08-25-16 02.00.14 Added new values for the Flags field of Toolbox Clean
|
||||
* Tool Request Message.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_type.h
|
||||
@ -599,24 +663,33 @@ mpi2_hbd.h
|
||||
* HBD Action request, replaced by AdditionalInfo field.
|
||||
* 11-18-11 02.00.02 Incorporating additions for MPI v2.5.
|
||||
* 11-18-14 02.00.03 Updated copyright information.
|
||||
* 02-17-16 02.00.04 Added SAS 4 22.5 gbs speed support.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_pci.h
|
||||
* 03-16-15 02.00.00 Initial version.
|
||||
* 02-17-16 02.00.01 Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* 07-01-16 02.00.02 Added MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP to
|
||||
* NVME Encapsulated Request.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi2_history.txt Parts list history
|
||||
|
||||
Filename 02.00.42
|
||||
---------- --------
|
||||
mpi2.h 02.00.42
|
||||
mpi2_cnfg.h 02.00.35
|
||||
mpi2_init.h 02.00.20
|
||||
mpi2_ioc.h 02.00.27
|
||||
mpi2_raid.h 02.00.11
|
||||
mpi2_sas.h 02.00.10
|
||||
mpi2_targ.h 02.00.09
|
||||
mpi2_tool.h 02.00.13
|
||||
mpi2_type.h 02.00.01
|
||||
mpi2_ra.h 02.00.01
|
||||
mpi2_hbd.h 02.00.03
|
||||
Filename 02.00.46 02.00.45 02.00.44 02.00.43 02.00.42
|
||||
---------- -------- -------- -------- -------- --------
|
||||
mpi2.h 02.00.46 02.00.45 02.00.44 02.00.43 02.00.42
|
||||
mpi2_cnfg.h 02.00.39 02.00.38 02.00.37 02.00.36 02.00.35
|
||||
mpi2_init.h 02.00.21 02.00.21 02.00.21 02.00.21 02.00.20
|
||||
mpi2_ioc.h 02.00.30 02.00.29 02.00.28 02.00.28 02.00.27
|
||||
mpi2_raid.h 02.00.11 02.00.11 02.00.11 02.00.11 02.00.11
|
||||
mpi2_sas.h 02.00.10 02.00.10 02.00.10 02.00.10 02.00.10
|
||||
mpi2_targ.h 02.00.09 02.00.09 02.00.09 02.00.09 02.00.09
|
||||
mpi2_tool.h 02.00.14 02.00.13 02.00.13 02.00.13 02.00.13
|
||||
mpi2_type.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
|
||||
mpi2_ra.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
|
||||
mpi2_hbd.h 02.00.04 02.00.04 02.00.04 02.00.04 02.00.03
|
||||
mpi2_pci.h 02.00.02 02.00.02 02.00.01 02.00.01 02.00.00
|
||||
|
||||
Filename 02.00.41 02.00.40 02.00.39 02.00.38 02.00.37 02.00.36
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
@ -631,6 +704,7 @@ mpi2_tool.h 02.00.13 02.00.13 02.00.13 02.00.13 02.00.13 02.00.13
|
||||
mpi2_type.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
|
||||
mpi2_ra.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
|
||||
mpi2_hbd.h 02.00.03 02.00.03 02.00.03 02.00.03 02.00.03 02.00.03
|
||||
mpi2_pci.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
|
||||
|
||||
Filename 02.00.35 02.00.34 02.00.33 02.00.32 02.00.31 02.00.30
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Title: MPI SCSI initiator mode messages and structures
|
||||
* Creation Date: June 23, 2006
|
||||
*
|
||||
* mpi2_init.h Version: 02.00.20
|
||||
* mpi2_init.h Version: 02.00.21
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
@ -62,7 +62,7 @@
|
||||
* 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
|
||||
* 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
|
||||
* Control field Task Attribute flags.
|
||||
* Moved LUN field defines to mpi2.h becasue they are
|
||||
* Moved LUN field defines to mpi2.h because they are
|
||||
* common to many structures.
|
||||
* 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
|
||||
* Query Asynchronous Event.
|
||||
@ -90,6 +90,8 @@
|
||||
* 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset.
|
||||
* 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message.
|
||||
* 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message.
|
||||
* 01-21-16 02.00.21 Modified MPI26_SCSITASKMGMT_MSGFLAGS_PCIE* defines to
|
||||
* be unique within first 32 characters.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -491,12 +493,13 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
|
||||
#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT)
|
||||
|
||||
/* MsgFlags bits */
|
||||
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18)
|
||||
#define MPI26_SCSITASKMGMT_MSGFLAGS_HOT_RESET_PCIE (0x00)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08)
|
||||
#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10)
|
||||
#define MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE (0x18)
|
||||
|
||||
|
||||
/* SCSI Task Management Reply Message */
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
|
||||
* Creation Date: October 11, 2006
|
||||
*
|
||||
* mpi2_ioc.h Version: 02.00.27
|
||||
* mpi2_ioc.h Version: 02.00.30
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
@ -177,9 +177,29 @@
|
||||
* MPI26_EVENT_DATA_PCIE_LINK_COUNTER.
|
||||
* Added MPI26_CTRL_OP_SHUTDOWN.
|
||||
* Added MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG
|
||||
* Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS
|
||||
* 08-25-15 02.00.27 Added IC ARCH Class based signature defines
|
||||
*
|
||||
* Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
|
||||
* MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
|
||||
* 08-25-15 02.00.27 Added IC ARCH Class based signature defines.
|
||||
* Added MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED event.
|
||||
* Added ConigurationFlags field to IOCInit message to
|
||||
* support NVMe SGL format control.
|
||||
* Added PCIe SRIOV support.
|
||||
* 02-17-16 02.00.28 Added SAS 4 22.5 gbs speed support.
|
||||
* Added PCIe 4 16.0 GT/sec speec support.
|
||||
* Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* 07-01-16 02.00.29 Added Archclass for 4008 product.
|
||||
* Added IOCException MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED
|
||||
* 08-23-16 02.00.30 Added new defines for the ImageType field of FWDownload
|
||||
* Request Message.
|
||||
* Added new defines for the ImageType field of FWUpload
|
||||
* Request Message.
|
||||
* Added new values for the RegionType field in the Layout
|
||||
* Data sections of the FLASH Layout Extended Image Data.
|
||||
* Added new defines for the ReasonCode field of
|
||||
* Active Cable Exception Event.
|
||||
* Added MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE and
|
||||
* MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -251,6 +271,9 @@ typedef struct _MPI2_IOC_INIT_REQUEST
|
||||
#define MPI2_IOCINIT_HDRVERSION_DEV_MASK (0x00FF)
|
||||
#define MPI2_IOCINIT_HDRVERSION_DEV_SHIFT (0)
|
||||
|
||||
/* ConfigurationFlags */
|
||||
#define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT (0x0001)
|
||||
|
||||
/* minimum depth for a Reply Descriptor Post Queue */
|
||||
#define MPI2_RDPQ_DEPTH_MIN (16)
|
||||
|
||||
@ -363,6 +386,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
|
||||
#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0)
|
||||
|
||||
/* IOCExceptions */
|
||||
#define MPI2_IOCFACTS_EXCEPT_PCIE_DISABLED (0x0400)
|
||||
#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200)
|
||||
#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100)
|
||||
|
||||
@ -383,6 +407,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY
|
||||
/* ProductID field uses MPI2_FW_HEADER_PID_ */
|
||||
|
||||
/* IOCCapabilities */
|
||||
#define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV (0x00100000)
|
||||
#define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000)
|
||||
#define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000)
|
||||
#define MPI25_IOCFACTS_CAPABILITY_FAST_PATH_CAPABLE (0x00020000)
|
||||
#define MPI2_IOCFACTS_CAPABILITY_HOST_BASED_DISCOVERY (0x00010000)
|
||||
@ -400,6 +426,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
|
||||
#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
|
||||
|
||||
/* ProtocolFlags */
|
||||
#define MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES (0x0008) /* MPI v2.6 and later */
|
||||
#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR (0x0002)
|
||||
#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001)
|
||||
|
||||
@ -452,6 +479,7 @@ typedef struct _MPI2_PORT_FACTS_REPLY
|
||||
#define MPI2_PORTFACTS_PORTTYPE_ISCSI (0x20)
|
||||
#define MPI2_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30)
|
||||
#define MPI2_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31)
|
||||
#define MPI2_PORTFACTS_PORTTYPE_TRI_MODE (0x40) /* MPI v2.6 and later */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
@ -564,6 +592,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
|
||||
#define MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW (0x0019)
|
||||
#define MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST (0x001C)
|
||||
#define MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE (0x001D)
|
||||
#define MPI2_EVENT_ENCL_DEVICE_STATUS_CHANGE (0x001D) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_IR_VOLUME (0x001E)
|
||||
#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F)
|
||||
#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020)
|
||||
@ -576,6 +605,10 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
|
||||
#define MPI2_EVENT_TEMP_THRESHOLD (0x0027)
|
||||
#define MPI2_EVENT_HOST_MESSAGE (0x0028)
|
||||
#define MPI2_EVENT_POWER_PERFORMANCE_CHANGE (0x0029)
|
||||
#define MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE (0x0030) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_PCIE_ENUMERATION (0x0031) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST (0x0032) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_PCIE_LINK_COUNTER (0x0033) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION (0x0034) /* MPI v2.6 and later */
|
||||
#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E)
|
||||
#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F)
|
||||
@ -688,11 +721,9 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT
|
||||
MPI2_POINTER pMpi26EventDataActiveCableExcept_t;
|
||||
|
||||
/* defines for ReasonCode field */
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_PRESENT (0x01)
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED (0x02)
|
||||
|
||||
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_PRESENT (0x01)
|
||||
#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED (0x02)
|
||||
|
||||
/* Hard Reset Received Event data */
|
||||
|
||||
@ -1048,6 +1079,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST
|
||||
#define MPI2_EVENT_SAS_TOPO_LR_RATE_3_0 (0x09)
|
||||
#define MPI2_EVENT_SAS_TOPO_LR_RATE_6_0 (0x0A)
|
||||
#define MPI25_EVENT_SAS_TOPO_LR_RATE_12_0 (0x0B)
|
||||
#define MPI26_EVENT_SAS_TOPO_LR_RATE_22_5 (0x0C)
|
||||
|
||||
/* values for the PhyStatus field */
|
||||
#define MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT (0x80)
|
||||
@ -1075,12 +1107,19 @@ typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE
|
||||
} MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
|
||||
MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE,
|
||||
Mpi2EventDataSasEnclDevStatusChange_t,
|
||||
MPI2_POINTER pMpi2EventDataSasEnclDevStatusChange_t;
|
||||
MPI2_POINTER pMpi2EventDataSasEnclDevStatusChange_t,
|
||||
MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_DATA_ENCL_DEV_STATUS_CHANGE,
|
||||
Mpi26EventDataEnclDevStatusChange_t,
|
||||
MPI2_POINTER pMpi26EventDataEnclDevStatusChange_t;
|
||||
|
||||
/* SAS Enclosure Device Status Change event ReasonCode values */
|
||||
#define MPI2_EVENT_SAS_ENCL_RC_ADDED (0x01)
|
||||
#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02)
|
||||
|
||||
/* Enclosure Device Status Change event ReasonCode values */
|
||||
#define MPI26_EVENT_ENCL_RC_ADDED (0x01)
|
||||
#define MPI26_EVENT_ENCL_RC_NOT_RESPONDING (0x02)
|
||||
|
||||
/* SAS PHY Counter Event data */
|
||||
|
||||
@ -1168,6 +1207,167 @@ typedef struct _MPI2_EVENT_DATA_HBD_PHY
|
||||
#define MPI2_EVENT_HBD_DT_SAS (0x01)
|
||||
|
||||
|
||||
/* PCIe Device Status Change Event data (MPI v2.6 and later) */
|
||||
|
||||
typedef struct _MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE
|
||||
{
|
||||
U16 TaskTag; /* 0x00 */
|
||||
U8 ReasonCode; /* 0x02 */
|
||||
U8 PhysicalPort; /* 0x03 */
|
||||
U8 ASC; /* 0x04 */
|
||||
U8 ASCQ; /* 0x05 */
|
||||
U16 DevHandle; /* 0x06 */
|
||||
U32 Reserved2; /* 0x08 */
|
||||
U64 WWID; /* 0x0C */
|
||||
U8 LUN[8]; /* 0x14 */
|
||||
} MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_DATA_PCIE_DEVICE_STATUS_CHANGE,
|
||||
Mpi26EventDataPCIeDeviceStatusChange_t,
|
||||
MPI2_POINTER pMpi26EventDataPCIeDeviceStatusChange_t;
|
||||
|
||||
/* PCIe Device Status Change Event data ReasonCode values */
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_SMART_DATA (0x05)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_UNSUPPORTED (0x07)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_TASK_ABORT_INTERNAL (0x09)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F)
|
||||
#define MPI26_EVENT_PCIDEV_STAT_RC_DEV_INIT_FAILURE (0x10)
|
||||
|
||||
|
||||
/* PCIe Enumeration Event data (MPI v2.6 and later) */
|
||||
|
||||
typedef struct _MPI26_EVENT_DATA_PCIE_ENUMERATION
|
||||
{
|
||||
U8 Flags; /* 0x00 */
|
||||
U8 ReasonCode; /* 0x01 */
|
||||
U8 PhysicalPort; /* 0x02 */
|
||||
U8 Reserved1; /* 0x03 */
|
||||
U32 EnumerationStatus; /* 0x04 */
|
||||
} MPI26_EVENT_DATA_PCIE_ENUMERATION,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_DATA_PCIE_ENUMERATION,
|
||||
Mpi26EventDataPCIeEnumeration_t,
|
||||
MPI2_POINTER pMpi26EventDataPCIeEnumeration_t;
|
||||
|
||||
/* PCIe Enumeration Event data Flags values */
|
||||
#define MPI26_EVENT_PCIE_ENUM_DEVICE_CHANGE (0x02)
|
||||
#define MPI26_EVENT_PCIE_ENUM_IN_PROGRESS (0x01)
|
||||
|
||||
/* PCIe Enumeration Event data ReasonCode values */
|
||||
#define MPI26_EVENT_PCIE_ENUM_RC_STARTED (0x01)
|
||||
#define MPI26_EVENT_PCIE_ENUM_RC_COMPLETED (0x02)
|
||||
|
||||
/* PCIe Enumeration Event data EnumerationStatus values */
|
||||
#define MPI26_EVENT_PCIE_ENUM_ES_MAX_SWITCHES_EXCEED (0x40000000)
|
||||
#define MPI26_EVENT_PCIE_ENUM_ES_MAX_DEVICES_EXCEED (0x20000000)
|
||||
#define MPI26_EVENT_PCIE_ENUM_ES_RESOURCES_EXHAUSTED (0x10000000)
|
||||
|
||||
|
||||
/* PCIe Topology Change List Event data (MPI v2.6 and later) */
|
||||
|
||||
/*
|
||||
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to
|
||||
* one and check NumEntries at runtime.
|
||||
*/
|
||||
#ifndef MPI26_EVENT_PCIE_TOPO_PORT_COUNT
|
||||
#define MPI26_EVENT_PCIE_TOPO_PORT_COUNT (1)
|
||||
#endif
|
||||
|
||||
typedef struct _MPI26_EVENT_PCIE_TOPO_PORT_ENTRY
|
||||
{
|
||||
U16 AttachedDevHandle; /* 0x00 */
|
||||
U8 PortStatus; /* 0x02 */
|
||||
U8 Reserved1; /* 0x03 */
|
||||
U8 CurrentPortInfo; /* 0x04 */
|
||||
U8 Reserved2; /* 0x05 */
|
||||
U8 PreviousPortInfo; /* 0x06 */
|
||||
U8 Reserved3; /* 0x07 */
|
||||
} MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_PCIE_TOPO_PORT_ENTRY,
|
||||
Mpi26EventPCIeTopoPortEntry_t,
|
||||
MPI2_POINTER pMpi26EventPCIeTopoPortEntry_t;
|
||||
|
||||
/* PCIe Topology Change List Event data PortStatus values */
|
||||
#define MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED (0x01)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING (0x02)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED (0x03)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE (0x04)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING (0x05)
|
||||
|
||||
/* PCIe Topology Change List Event data defines for CurrentPortInfo and PreviousPortInfo */
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_LANE_MASK (0xF0)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_LANES_UNKNOWN (0x00)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_1_LANE (0x10)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_2_LANES (0x20)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_4_LANES (0x30)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_8_LANES (0x40)
|
||||
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK (0x0F)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_UNKNOWN (0x00)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_DISABLED (0x01)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5 (0x02)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_5_0 (0x03)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_8_0 (0x04)
|
||||
#define MPI26_EVENT_PCIE_TOPO_PI_RATE_16_0 (0x05)
|
||||
|
||||
typedef struct _MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST
|
||||
{
|
||||
U16 EnclosureHandle; /* 0x00 */
|
||||
U16 SwitchDevHandle; /* 0x02 */
|
||||
U8 NumPorts; /* 0x04 */
|
||||
U8 Reserved1; /* 0x05 */
|
||||
U16 Reserved2; /* 0x06 */
|
||||
U8 NumEntries; /* 0x08 */
|
||||
U8 StartPortNum; /* 0x09 */
|
||||
U8 SwitchStatus; /* 0x0A */
|
||||
U8 PhysicalPort; /* 0x0B */
|
||||
MPI26_EVENT_PCIE_TOPO_PORT_ENTRY PortEntry[MPI26_EVENT_PCIE_TOPO_PORT_COUNT]; /* 0x0C */
|
||||
} MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST,
|
||||
Mpi26EventDataPCIeTopologyChangeList_t,
|
||||
MPI2_POINTER pMpi26EventDataPCIeTopologyChangeList_t;
|
||||
|
||||
/* PCIe Topology Change List Event data SwitchStatus values */
|
||||
#define MPI26_EVENT_PCIE_TOPO_SS_NO_PCIE_SWITCH (0x00)
|
||||
#define MPI26_EVENT_PCIE_TOPO_SS_ADDED (0x01)
|
||||
#define MPI26_EVENT_PCIE_TOPO_SS_NOT_RESPONDING (0x02)
|
||||
#define MPI26_EVENT_PCIE_TOPO_SS_RESPONDING (0x03)
|
||||
#define MPI26_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING (0x04)
|
||||
|
||||
/* PCIe Link Counter Event data (MPI v2.6 and later) */
|
||||
|
||||
typedef struct _MPI26_EVENT_DATA_PCIE_LINK_COUNTER
|
||||
{
|
||||
U64 TimeStamp; /* 0x00 */
|
||||
U32 Reserved1; /* 0x08 */
|
||||
U8 LinkEventCode; /* 0x0C */
|
||||
U8 LinkNum; /* 0x0D */
|
||||
U16 Reserved2; /* 0x0E */
|
||||
U32 LinkEventInfo; /* 0x10 */
|
||||
U8 CounterType; /* 0x14 */
|
||||
U8 ThresholdWindow; /* 0x15 */
|
||||
U8 TimeUnits; /* 0x16 */
|
||||
U8 Reserved3; /* 0x17 */
|
||||
U32 EventThreshold; /* 0x18 */
|
||||
U16 ThresholdFlags; /* 0x1C */
|
||||
U16 Reserved4; /* 0x1E */
|
||||
} MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
|
||||
MPI2_POINTER PTR_MPI26_EVENT_DATA_PCIE_LINK_COUNTER,
|
||||
Mpi26EventDataPcieLinkCounter_t, MPI2_POINTER pMpi26EventDataPcieLinkCounter_t;
|
||||
|
||||
|
||||
/* use MPI26_PCIELINK3_EVTCODE_ values from mpi2_cnfg.h for the LinkEventCode field */
|
||||
|
||||
/* use MPI26_PCIELINK3_COUNTER_TYPE_ values from mpi2_cnfg.h for the CounterType field */
|
||||
|
||||
/* use MPI26_PCIELINK3_TIME_UNITS_ values from mpi2_cnfg.h for the TimeUnits field */
|
||||
|
||||
/* use MPI26_PCIELINK3_TFLAGS_ values from mpi2_cnfg.h for the ThresholdFlags field */
|
||||
|
||||
/****************************************************************************
|
||||
* EventAck message
|
||||
****************************************************************************/
|
||||
@ -1293,6 +1493,13 @@ typedef struct _MPI2_FW_DOWNLOAD_REQUEST
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_COMPLETE (0x0A)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY (0x0C) /* MPI v2.5 and newer */
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_SBR (0x0E)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_SBR_BACKUP (0x0F)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_HIIM (0x10)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_HIIA (0x11)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_CTLR (0x12)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_IMR_FIRMWARE (0x13)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_MR_NVDATA (0x14)
|
||||
#define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0)
|
||||
|
||||
/* MPI v2.0 FWDownload TransactionContext Element */
|
||||
@ -1386,6 +1593,13 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST
|
||||
#define MPI2_FW_UPLOAD_ITYPE_COMPLETE (0x0A)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP (0x0D)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_SBR (0x0E)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_SBR_BACKUP (0x0F)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_HIIM (0x10)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_HIIA (0x11)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_CTLR (0x12)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_IMR_FIRMWARE (0x13)
|
||||
#define MPI2_FW_UPLOAD_ITYPE_MR_NVDATA (0x14)
|
||||
|
||||
/* MPI v2.0 FWUpload TransactionContext Element */
|
||||
typedef struct _MPI2_FW_UPLOAD_TCSGE
|
||||
@ -1509,8 +1723,10 @@ typedef struct _MPI2_FW_IMAGE_HEADER
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_ARC_0 (0x5A)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_ARC_1 (0x00)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_ARC_2 (0x01)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_ARC_3 (0x02)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0 (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0) // legacy (0x5AEAA55A)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_3516 (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1)
|
||||
#define MPI26_FW_HEADER_SIGNATURE0_4008 (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_3)
|
||||
|
||||
/* Signature1 field */
|
||||
#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08)
|
||||
@ -1665,7 +1881,13 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA
|
||||
#define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK (0x0A)
|
||||
#define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK) /* older name */
|
||||
#define MPI2_FLASH_REGION_CBB_BACKUP (0x0D)
|
||||
|
||||
#define MPI2_FLASH_REGION_SBR (0x0E)
|
||||
#define MPI2_FLASH_REGION_SBR_BACKUP (0x0F)
|
||||
#define MPI2_FLASH_REGION_HIIM (0x10)
|
||||
#define MPI2_FLASH_REGION_HIIA (0x11)
|
||||
#define MPI2_FLASH_REGION_CTLR (0x12)
|
||||
#define MPI2_FLASH_REGION_IMR_FIRMWARE (0x13)
|
||||
#define MPI2_FLASH_REGION_MR_NVDATA (0x14)
|
||||
|
||||
/* ImageRevision */
|
||||
#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00)
|
||||
@ -1960,6 +2182,8 @@ typedef struct _MPI26_IOUNIT_CONTROL_REQUEST
|
||||
#define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION (0x17)
|
||||
#define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION (0x18)
|
||||
#define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION (0x19)
|
||||
#define MPI26_CTRL_OP_ENABLE_NVME_SGL_FORMAT (0x1A)
|
||||
#define MPI26_CTRL_OP_DISABLE_NVME_SGL_FORMAT (0x1B)
|
||||
#define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN (0x80)
|
||||
|
||||
/* values for the PrimFlags field */
|
||||
|
151
sys/dev/mpr/mpi/mpi2_pci.h
Executable file
151
sys/dev/mpr/mpi/mpi2_pci.h
Executable file
@ -0,0 +1,151 @@
|
||||
/*-
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2016 Avago Technologies
|
||||
* 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.
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2016 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Name: mpi2_pci.h
|
||||
* Title: MPI PCIe Attached Devices structures and definitions.
|
||||
* Creation Date: October 9, 2012
|
||||
*
|
||||
* mpi2_pci.h Version: 02.00.02
|
||||
*
|
||||
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
|
||||
* prefix are for use only on MPI v2.5 products, and must not be used
|
||||
* with MPI v2.0 products. Unless otherwise noted, names beginning with
|
||||
* MPI2 or Mpi2 are for use with both MPI v2.0 and MPI v2.5 products.
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 03-16-15 02.00.00 Initial version.
|
||||
* 02-17-16 02.00.01 Removed AHCI support.
|
||||
* Removed SOP support.
|
||||
* 07-01-16 02.00.02 Added MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP to
|
||||
* NVME Encapsulated Request.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPI2_PCI_H
|
||||
#define MPI2_PCI_H
|
||||
|
||||
|
||||
/*
|
||||
* Values for the PCIe DeviceInfo field used in PCIe Device Status Change Event
|
||||
* data and PCIe Configuration pages.
|
||||
*/
|
||||
#define MPI26_PCIE_DEVINFO_DIRECT_ATTACH (0x00000010)
|
||||
|
||||
#define MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE (0x0000000F)
|
||||
#define MPI26_PCIE_DEVINFO_NO_DEVICE (0x00000000)
|
||||
#define MPI26_PCIE_DEVINFO_PCI_SWITCH (0x00000001)
|
||||
#define MPI26_PCIE_DEVINFO_NVME (0x00000003)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* NVMe Encapsulated message
|
||||
****************************************************************************/
|
||||
|
||||
/* NVME Encapsulated Request Message */
|
||||
typedef struct _MPI26_NVME_ENCAPSULATED_REQUEST
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 ChainOffset; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 EncapsulatedCommandLength; /* 0x04 */
|
||||
U8 Reserved1; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U32 Reserved3; /* 0x0C */
|
||||
U64 ErrorResponseBaseAddress; /* 0x10 */
|
||||
U16 ErrorResponseAllocationLength; /* 0x18 */
|
||||
U16 Flags; /* 0x1A */
|
||||
U32 DataLength; /* 0x1C */
|
||||
U8 NVMe_Command[4]; /* 0x20 */ /* variable length */
|
||||
|
||||
} MPI26_NVME_ENCAPSULATED_REQUEST, MPI2_POINTER PTR_MPI26_NVME_ENCAPSULATED_REQUEST,
|
||||
Mpi26NVMeEncapsulatedRequest_t, MPI2_POINTER pMpi26NVMeEncapsulatedRequest_t;
|
||||
|
||||
/* defines for the Flags field */
|
||||
#define MPI26_NVME_FLAGS_FORCE_ADMIN_ERR_RESP (0x0020)
|
||||
/* Submission Queue Type*/
|
||||
#define MPI26_NVME_FLAGS_SUBMISSIONQ_MASK (0x0010)
|
||||
#define MPI26_NVME_FLAGS_SUBMISSIONQ_IO (0x0000)
|
||||
#define MPI26_NVME_FLAGS_SUBMISSIONQ_ADMIN (0x0010)
|
||||
/* Error Response Address Space */
|
||||
#define MPI26_NVME_FLAGS_MASK_ERROR_RSP_ADDR (0x000C)
|
||||
#define MPI26_NVME_FLAGS_SYSTEM_RSP_ADDR (0x0000)
|
||||
#define MPI26_NVME_FLAGS_IOCPLB_RSP_ADDR (0x0008)
|
||||
#define MPI26_NVME_FLAGS_IOCPLBNTA_RSP_ADDR (0x000C)
|
||||
/* Data Direction*/
|
||||
#define MPI26_NVME_FLAGS_DATADIRECTION_MASK (0x0003)
|
||||
#define MPI26_NVME_FLAGS_NODATATRANSFER (0x0000)
|
||||
#define MPI26_NVME_FLAGS_WRITE (0x0001)
|
||||
#define MPI26_NVME_FLAGS_READ (0x0002)
|
||||
#define MPI26_NVME_FLAGS_BIDIRECTIONAL (0x0003)
|
||||
|
||||
|
||||
/* NVMe Encapuslated Reply Message */
|
||||
typedef struct _MPI26_NVME_ENCAPSULATED_ERROR_REPLY
|
||||
{
|
||||
U16 DevHandle; /* 0x00 */
|
||||
U8 MsgLength; /* 0x02 */
|
||||
U8 Function; /* 0x03 */
|
||||
U16 EncapsulatedCommandLength; /* 0x04 */
|
||||
U8 Reserved1; /* 0x06 */
|
||||
U8 MsgFlags; /* 0x07 */
|
||||
U8 VP_ID; /* 0x08 */
|
||||
U8 VF_ID; /* 0x09 */
|
||||
U16 Reserved2; /* 0x0A */
|
||||
U16 Reserved3; /* 0x0C */
|
||||
U16 IOCStatus; /* 0x0E */
|
||||
U32 IOCLogInfo; /* 0x10 */
|
||||
U16 ErrorResponseCount; /* 0x14 */
|
||||
U16 Reserved4; /* 0x16 */
|
||||
} MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
|
||||
MPI2_POINTER PTR_MPI26_NVME_ENCAPSULATED_ERROR_REPLY,
|
||||
Mpi26NVMeEncapsulatedErrorReply_t,
|
||||
MPI2_POINTER pMpi26NVMeEncapsulatedErrorReply_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
* Title: MPI diagnostic tool structures and definitions
|
||||
* Creation Date: March 26, 2007
|
||||
*
|
||||
* mpi2_tool.h Version: 02.00.13
|
||||
* mpi2_tool.h Version: 02.00.14
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -71,6 +71,8 @@
|
||||
* 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
|
||||
* 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
|
||||
* 11-18-14 02.00.13 Updated copyright information.
|
||||
* 08-25-16 02.00.14 Added new values for the Flags field of Toolbox Clean
|
||||
* Tool Request Message.
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -145,6 +147,16 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
|
||||
#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000)
|
||||
#define MPI2_TOOLBOX_CLEAN_SBR (0x00800000)
|
||||
#define MPI2_TOOLBOX_CLEAN_SBR_BACKUP (0x00400000)
|
||||
#define MPI2_TOOLBOX_CLEAN_HIIM (0x00200000)
|
||||
#define MPI2_TOOLBOX_CLEAN_HIIA (0x00100000)
|
||||
#define MPI2_TOOLBOX_CLEAN_CTLR (0x00080000)
|
||||
#define MPI2_TOOLBOX_CLEAN_IMR_FIRMWARE (0x00040000)
|
||||
#define MPI2_TOOLBOX_CLEAN_MR_NVDATA (0x00020000)
|
||||
#define MPI2_TOOLBOX_CLEAN_RESERVED_5_16 (0x0001FFE0)
|
||||
#define MPI2_TOOLBOX_CLEAN_ALL_BUT_MPB (0x00000010)
|
||||
#define MPI2_TOOLBOX_CLEAN_ENTIRE_FLASH (0x00000008)
|
||||
#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004)
|
||||
#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002)
|
||||
#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001)
|
||||
|
@ -63,18 +63,21 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <cam/cam.h>
|
||||
#include <cam/cam_ccb.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
|
||||
#include <dev/mpr/mpi/mpi2_type.h>
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_sas.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
#include <dev/mpr/mpr_ioctl.h>
|
||||
#include <dev/mpr/mprvar.h>
|
||||
#include <dev/mpr/mpr_table.h>
|
||||
#include <dev/mpr/mpr_sas.h>
|
||||
|
||||
static int mpr_diag_reset(struct mpr_softc *sc, int sleep_flag);
|
||||
static int mpr_init_queues(struct mpr_softc *sc);
|
||||
@ -87,6 +90,7 @@ static int mpr_send_iocinit(struct mpr_softc *sc);
|
||||
static int mpr_alloc_queues(struct mpr_softc *sc);
|
||||
static int mpr_alloc_replies(struct mpr_softc *sc);
|
||||
static int mpr_alloc_requests(struct mpr_softc *sc);
|
||||
static int mpr_alloc_nvme_prp_pages(struct mpr_softc *sc);
|
||||
static int mpr_attach_log(struct mpr_softc *sc);
|
||||
static __inline void mpr_complete_command(struct mpr_softc *sc,
|
||||
struct mpr_command *cm);
|
||||
@ -110,7 +114,7 @@ static char mpt2_reset_magic[] = { 0x00, 0x0f, 0x04, 0x0b, 0x02, 0x07, 0x0d };
|
||||
|
||||
/*
|
||||
* Added this union to smoothly convert le64toh cm->cm_desc.Words.
|
||||
* Compiler only supports unint64_t to be passed as an argument.
|
||||
* Compiler only supports uint64_t to be passed as an argument.
|
||||
* Otherwise it will through this error:
|
||||
* "aggregate value used where an integer was expected"
|
||||
*/
|
||||
@ -120,7 +124,7 @@ typedef union _reply_descriptor {
|
||||
u32 low;
|
||||
u32 high;
|
||||
} u;
|
||||
}reply_descriptor,address_descriptor;
|
||||
} reply_descriptor, request_descriptor;
|
||||
|
||||
/* Rate limit chain-fail messages to 1 per minute */
|
||||
static struct timeval mpr_chainfail_interval = { 60, 0 };
|
||||
@ -311,7 +315,6 @@ mpr_transition_ready(struct mpr_softc *sc)
|
||||
|
||||
if (error)
|
||||
device_printf(sc->mpr_dev, "Cannot transition IOC to ready\n");
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -392,7 +395,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
mpr_printf(sc, "IOCCapabilities: %b\n", sc->facts->IOCCapabilities,
|
||||
"\20" "\3ScsiTaskFull" "\4DiagTrace" "\5SnapBuf" "\6ExtBuf"
|
||||
"\7EEDP" "\10BiDirTarg" "\11Multicast" "\14TransRetry" "\15IR"
|
||||
"\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc");
|
||||
"\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc"
|
||||
"\22FastPath" "\23RDPQArray" "\24AtomicReqDesc" "\25PCIeSRIOV");
|
||||
|
||||
/*
|
||||
* If the chip doesn't support event replay then a hard reset will be
|
||||
@ -480,12 +484,15 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
enabled = TRUE;
|
||||
|
||||
/*
|
||||
* Set flag if EEDP is supported and if TLR is supported.
|
||||
* Set flags for some supported items.
|
||||
*/
|
||||
if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP)
|
||||
sc->eedp_enabled = TRUE;
|
||||
if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)
|
||||
sc->control_TLR = TRUE;
|
||||
if (sc->facts->IOCCapabilities &
|
||||
MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ)
|
||||
sc->atomic_desc_capable = TRUE;
|
||||
|
||||
/*
|
||||
* Size the queues. Since the reply queues always need one free
|
||||
@ -501,6 +508,7 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
TAILQ_INIT(&sc->req_list);
|
||||
TAILQ_INIT(&sc->high_priority_req_list);
|
||||
TAILQ_INIT(&sc->chain_list);
|
||||
TAILQ_INIT(&sc->prp_page_list);
|
||||
TAILQ_INIT(&sc->tm_list);
|
||||
}
|
||||
|
||||
@ -634,6 +642,14 @@ mpr_iocfacts_free(struct mpr_softc *sc)
|
||||
if (sc->sense_dmat != NULL)
|
||||
bus_dma_tag_destroy(sc->sense_dmat);
|
||||
|
||||
if (sc->prp_page_busaddr != 0)
|
||||
bus_dmamap_unload(sc->prp_page_dmat, sc->prp_page_map);
|
||||
if (sc->prp_pages != NULL)
|
||||
bus_dmamem_free(sc->prp_page_dmat, sc->prp_pages,
|
||||
sc->prp_page_map);
|
||||
if (sc->prp_page_dmat != NULL)
|
||||
bus_dma_tag_destroy(sc->prp_page_dmat);
|
||||
|
||||
if (sc->reply_busaddr != 0)
|
||||
bus_dmamap_unload(sc->reply_dmat, sc->reply_map);
|
||||
if (sc->reply_frames != NULL)
|
||||
@ -651,6 +667,8 @@ mpr_iocfacts_free(struct mpr_softc *sc)
|
||||
|
||||
if (sc->chains != NULL)
|
||||
free(sc->chains, M_MPR);
|
||||
if (sc->prps != NULL)
|
||||
free(sc->prps, M_MPR);
|
||||
if (sc->commands != NULL) {
|
||||
for (i = 1; i < sc->num_reqs; i++) {
|
||||
cm = &sc->commands[i];
|
||||
@ -804,7 +822,7 @@ mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag)
|
||||
count++;
|
||||
} while (--cntdn);
|
||||
|
||||
out:
|
||||
out:
|
||||
mpr_dprint(sc, MPR_FAULT, "%s: failed due to timeout count(%d), "
|
||||
"int_status(%x)!\n", __func__, count, int_status);
|
||||
return (ETIMEDOUT);
|
||||
@ -959,7 +977,7 @@ mpr_request_sync(struct mpr_softc *sc, void *req, MPI2_DEFAULT_REPLY *reply,
|
||||
static void
|
||||
mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
{
|
||||
reply_descriptor rd;
|
||||
request_descriptor rd;
|
||||
|
||||
MPR_FUNCTRACE(sc);
|
||||
mpr_dprint(sc, MPR_TRACE, "SMID %u cm %p ccb %p\n",
|
||||
@ -972,14 +990,19 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
if (++sc->io_cmds_active > sc->io_cmds_highwater)
|
||||
sc->io_cmds_highwater++;
|
||||
|
||||
rd.u.low = cm->cm_desc.Words.Low;
|
||||
rd.u.high = cm->cm_desc.Words.High;
|
||||
rd.word = htole64(rd.word);
|
||||
/* TODO-We may need to make below regwrite atomic */
|
||||
mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET,
|
||||
rd.u.low);
|
||||
mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET,
|
||||
rd.u.high);
|
||||
if (sc->atomic_desc_capable) {
|
||||
rd.u.low = cm->cm_desc.Words.Low;
|
||||
mpr_regwrite(sc, MPI26_ATOMIC_REQUEST_DESCRIPTOR_POST_OFFSET,
|
||||
rd.u.low);
|
||||
} else {
|
||||
rd.u.low = cm->cm_desc.Words.Low;
|
||||
rd.u.high = cm->cm_desc.Words.High;
|
||||
rd.word = htole64(rd.word);
|
||||
mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET,
|
||||
rd.u.low);
|
||||
mpr_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET,
|
||||
rd.u.high);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1047,6 +1070,7 @@ mpr_send_iocinit(struct mpr_softc *sc)
|
||||
time_in_msec = (now.tv_sec * 1000 + now.tv_usec/1000);
|
||||
init.TimeStamp.High = htole32((time_in_msec >> 32) & 0xFFFFFFFF);
|
||||
init.TimeStamp.Low = htole32(time_in_msec & 0xFFFFFFFF);
|
||||
init.HostPageSize = HOST_PAGE_SIZE_4K;
|
||||
|
||||
error = mpr_request_sync(sc, &init, &reply, req_sz, reply_sz, 5);
|
||||
if ((reply.IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
|
||||
@ -1276,6 +1300,16 @@ mpr_alloc_requests(struct mpr_softc *sc)
|
||||
sc->chain_free_lowwater++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate NVMe PRP Pages for NVMe SGL support only if the FW supports
|
||||
* these devices.
|
||||
*/
|
||||
if ((sc->facts->MsgVersion >= MPI2_VERSION_02_06) &&
|
||||
(sc->facts->ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES)) {
|
||||
if (mpr_alloc_nvme_prp_pages(sc) == ENOMEM)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
/* XXX Need to pick a more precise value */
|
||||
nsegs = (MAXPHYS / PAGE_SIZE) + 1;
|
||||
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
|
||||
@ -1316,15 +1350,17 @@ mpr_alloc_requests(struct mpr_softc *sc)
|
||||
cm->cm_desc.Default.SMID = i;
|
||||
cm->cm_sc = sc;
|
||||
TAILQ_INIT(&cm->cm_chain_list);
|
||||
TAILQ_INIT(&cm->cm_prp_page_list);
|
||||
callout_init_mtx(&cm->cm_callout, &sc->mpr_mtx, 0);
|
||||
|
||||
/* XXX Is a failure here a critical problem? */
|
||||
if (bus_dmamap_create(sc->buffer_dmat, 0, &cm->cm_dmamap) == 0)
|
||||
if (bus_dmamap_create(sc->buffer_dmat, 0, &cm->cm_dmamap)
|
||||
== 0) {
|
||||
if (i <= sc->facts->HighPriorityCredit)
|
||||
mpr_free_high_priority_command(sc, cm);
|
||||
else
|
||||
mpr_free_command(sc, cm);
|
||||
else {
|
||||
} else {
|
||||
panic("failed to allocate command %d\n", i);
|
||||
sc->num_reqs = i;
|
||||
break;
|
||||
@ -1334,6 +1370,86 @@ mpr_alloc_requests(struct mpr_softc *sc)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate contiguous buffers for PCIe NVMe devices for building native PRPs,
|
||||
* which are scatter/gather lists for NVMe devices.
|
||||
*
|
||||
* This buffer must be contiguous due to the nature of how NVMe PRPs are built
|
||||
* and translated by FW.
|
||||
*
|
||||
* returns ENOMEM if memory could not be allocated, otherwise returns 0.
|
||||
*/
|
||||
static int
|
||||
mpr_alloc_nvme_prp_pages(struct mpr_softc *sc)
|
||||
{
|
||||
int PRPs_per_page, PRPs_required, pages_required;
|
||||
int rsize, i;
|
||||
struct mpr_prp_page *prp_page;
|
||||
|
||||
/*
|
||||
* Assuming a MAX_IO_SIZE of 1MB and a PAGE_SIZE of 4k, the max number
|
||||
* of PRPs (NVMe's Scatter/Gather Element) needed per I/O is:
|
||||
* MAX_IO_SIZE / PAGE_SIZE = 256
|
||||
*
|
||||
* 1 PRP entry in main frame for PRP list pointer still leaves 255 PRPs
|
||||
* required for the remainder of the 1MB I/O. 512 PRPs can fit into one
|
||||
* page (4096 / 8 = 512), so only one page is required for each I/O.
|
||||
*
|
||||
* Each of these buffers will need to be contiguous. For simplicity,
|
||||
* only one buffer is allocated here, which has all of the space
|
||||
* required for the NVMe Queue Depth. If there are problems allocating
|
||||
* this one buffer, this function will need to change to allocate
|
||||
* individual, contiguous NVME_QDEPTH buffers.
|
||||
*
|
||||
* The real calculation will use the real max io size. Above is just an
|
||||
* example.
|
||||
*
|
||||
*/
|
||||
PRPs_required = sc->maxio / PAGE_SIZE;
|
||||
PRPs_per_page = (PAGE_SIZE / PRP_ENTRY_SIZE) - 1;
|
||||
pages_required = (PRPs_required / PRPs_per_page) + 1;
|
||||
|
||||
sc->prp_buffer_size = PAGE_SIZE * pages_required;
|
||||
rsize = sc->prp_buffer_size * NVME_QDEPTH;
|
||||
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
|
||||
4, 0, /* algnmnt, boundary */
|
||||
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
rsize, /* maxsize */
|
||||
1, /* nsegments */
|
||||
rsize, /* maxsegsize */
|
||||
0, /* flags */
|
||||
NULL, NULL, /* lockfunc, lockarg */
|
||||
&sc->prp_page_dmat)) {
|
||||
device_printf(sc->mpr_dev, "Cannot allocate NVMe PRP DMA "
|
||||
"tag\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (bus_dmamem_alloc(sc->prp_page_dmat, (void **)&sc->prp_pages,
|
||||
BUS_DMA_NOWAIT, &sc->prp_page_map)) {
|
||||
device_printf(sc->mpr_dev, "Cannot allocate NVMe PRP memory\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
bzero(sc->prp_pages, rsize);
|
||||
bus_dmamap_load(sc->prp_page_dmat, sc->prp_page_map, sc->prp_pages,
|
||||
rsize, mpr_memaddr_cb, &sc->prp_page_busaddr, 0);
|
||||
|
||||
sc->prps = malloc(sizeof(struct mpr_prp_page) * NVME_QDEPTH, M_MPR,
|
||||
M_WAITOK | M_ZERO);
|
||||
for (i = 0; i < NVME_QDEPTH; i++) {
|
||||
prp_page = &sc->prps[i];
|
||||
prp_page->prp_page = (uint64_t *)(sc->prp_pages +
|
||||
i * sc->prp_buffer_size);
|
||||
prp_page->prp_page_busaddr = (uint64_t)(sc->prp_page_busaddr +
|
||||
i * sc->prp_buffer_size);
|
||||
mpr_free_prp_page(sc, prp_page);
|
||||
sc->prp_pages_free_lowwater++;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
mpr_init_queues(struct mpr_softc *sc)
|
||||
{
|
||||
@ -1352,8 +1468,10 @@ mpr_init_queues(struct mpr_softc *sc)
|
||||
/*
|
||||
* Initialize all of the free queue entries.
|
||||
*/
|
||||
for (i = 0; i < sc->fqdepth; i++)
|
||||
sc->free_queue[i] = sc->reply_busaddr + (i * sc->facts->ReplyFrameSize * 4);
|
||||
for (i = 0; i < sc->fqdepth; i++) {
|
||||
sc->free_queue[i] = sc->reply_busaddr +
|
||||
(i * sc->facts->ReplyFrameSize * 4);
|
||||
}
|
||||
sc->replyfreeindex = sc->num_replies;
|
||||
|
||||
return (0);
|
||||
@ -1520,6 +1638,18 @@ mpr_setup_sysctl(struct mpr_softc *sc)
|
||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0,
|
||||
"Use the phy number for enumeration");
|
||||
|
||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "prp_pages_free", CTLFLAG_RD,
|
||||
&sc->prp_pages_free, 0, "number of free PRP pages");
|
||||
|
||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "prp_pages_free_lowwater", CTLFLAG_RD,
|
||||
&sc->prp_pages_free_lowwater, 0,"lowest number of free PRP pages");
|
||||
|
||||
SYSCTL_ADD_UQUAD(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "prp_page_alloc_fail", CTLFLAG_RD,
|
||||
&sc->prp_page_alloc_fail, "PRP page allocation failures");
|
||||
}
|
||||
|
||||
int
|
||||
@ -1912,6 +2042,7 @@ mpr_intr_locked(void *data)
|
||||
switch (flags) {
|
||||
case MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS:
|
||||
case MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS:
|
||||
case MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS:
|
||||
cm = &sc->commands[le16toh(desc->SCSIIOSuccess.SMID)];
|
||||
cm->cm_reply = NULL;
|
||||
break;
|
||||
@ -2200,6 +2331,519 @@ mpr_deregister_events(struct mpr_softc *sc, struct mpr_event_handle *handle)
|
||||
return (mpr_update_events(sc, NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* mpr_build_nvme_prp - This function is called for NVMe end devices to build a
|
||||
* native SGL (NVMe PRP). The native SGL is built starting in the first PRP entry
|
||||
* of the NVMe message (PRP1). If the data buffer is small enough to be described
|
||||
* entirely using PRP1, then PRP2 is not used. If needed, PRP2 is used to
|
||||
* describe a larger data buffer. If the data buffer is too large to describe
|
||||
* using the two PRP entriess inside the NVMe message, then PRP1 describes the
|
||||
* first data memory segment, and PRP2 contains a pointer to a PRP list located
|
||||
* elsewhere in memory to describe the remaining data memory segments. The PRP
|
||||
* list will be contiguous.
|
||||
|
||||
* The native SGL for NVMe devices is a Physical Region Page (PRP). A PRP
|
||||
* consists of a list of PRP entries to describe a number of noncontigous
|
||||
* physical memory segments as a single memory buffer, just as a SGL does. Note
|
||||
* however, that this function is only used by the IOCTL call, so the memory
|
||||
* given will be guaranteed to be contiguous. There is no need to translate
|
||||
* non-contiguous SGL into a PRP in this case. All PRPs will describe contiguous
|
||||
* space that is one page size each.
|
||||
*
|
||||
* Each NVMe message contains two PRP entries. The first (PRP1) either contains
|
||||
* a PRP list pointer or a PRP element, depending upon the command. PRP2 contains
|
||||
* the second PRP element if the memory being described fits within 2 PRP
|
||||
* entries, or a PRP list pointer if the PRP spans more than two entries.
|
||||
*
|
||||
* A PRP list pointer contains the address of a PRP list, structured as a linear
|
||||
* array of PRP entries. Each PRP entry in this list describes a segment of
|
||||
* physical memory.
|
||||
*
|
||||
* Each 64-bit PRP entry comprises an address and an offset field. The address
|
||||
* always points to the beginning of a PAGE_SIZE physical memory page, and the
|
||||
* offset describes where within that page the memory segment begins. Only the
|
||||
* first element in a PRP list may contain a non-zero offest, implying that all
|
||||
* memory segments following the first begin at the start of a PAGE_SIZE page.
|
||||
*
|
||||
* Each PRP element normally describes a chunck of PAGE_SIZE physical memory,
|
||||
* with exceptions for the first and last elements in the list. If the memory
|
||||
* being described by the list begins at a non-zero offset within the first page,
|
||||
* then the first PRP element will contain a non-zero offset indicating where the
|
||||
* region begins within the page. The last memory segment may end before the end
|
||||
* of the PAGE_SIZE segment, depending upon the overall size of the memory being
|
||||
* described by the PRP list.
|
||||
*
|
||||
* Since PRP entries lack any indication of size, the overall data buffer length
|
||||
* is used to determine where the end of the data memory buffer is located, and
|
||||
* how many PRP entries are required to describe it.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
void
|
||||
mpr_build_nvme_prp(struct mpr_softc *sc, struct mpr_command *cm,
|
||||
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request, void *data,
|
||||
uint32_t data_in_sz, uint32_t data_out_sz)
|
||||
{
|
||||
int prp_size = PRP_ENTRY_SIZE;
|
||||
uint64_t *prp_entry, *prp1_entry, *prp2_entry;
|
||||
uint64_t *prp_entry_phys, *prp_page, *prp_page_phys;
|
||||
uint32_t offset, entry_len, page_mask_result, page_mask;
|
||||
bus_addr_t paddr;
|
||||
size_t length;
|
||||
struct mpr_prp_page *prp_page_info = NULL;
|
||||
|
||||
/*
|
||||
* Not all commands require a data transfer. If no data, just return
|
||||
* without constructing any PRP.
|
||||
*/
|
||||
if (!data_in_sz && !data_out_sz)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Set pointers to PRP1 and PRP2, which are in the NVMe command. PRP1 is
|
||||
* located at a 24 byte offset from the start of the NVMe command. Then
|
||||
* set the current PRP entry pointer to PRP1.
|
||||
*/
|
||||
prp1_entry = (uint64_t *)(nvme_encap_request->NVMe_Command +
|
||||
NVME_CMD_PRP1_OFFSET);
|
||||
prp2_entry = (uint64_t *)(nvme_encap_request->NVMe_Command +
|
||||
NVME_CMD_PRP2_OFFSET);
|
||||
prp_entry = prp1_entry;
|
||||
|
||||
/*
|
||||
* For the PRP entries, use the specially allocated buffer of
|
||||
* contiguous memory. PRP Page allocation failures should not happen
|
||||
* because there should be enough PRP page buffers to account for the
|
||||
* possible NVMe QDepth.
|
||||
*/
|
||||
prp_page_info = mpr_alloc_prp_page(sc);
|
||||
KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be "
|
||||
"used for building a native NVMe SGL.\n", __func__));
|
||||
prp_page = (uint64_t *)prp_page_info->prp_page;
|
||||
prp_page_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr;
|
||||
|
||||
/*
|
||||
* Insert the allocated PRP page into the command's PRP page list. This
|
||||
* will be freed when the command is freed.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&cm->cm_prp_page_list, prp_page_info, prp_page_link);
|
||||
|
||||
/*
|
||||
* Check if we are within 1 entry of a page boundary we don't want our
|
||||
* first entry to be a PRP List entry.
|
||||
*/
|
||||
page_mask = PAGE_SIZE - 1;
|
||||
page_mask_result = (uintptr_t)((uint8_t *)prp_page + prp_size) &
|
||||
page_mask;
|
||||
if (!page_mask_result)
|
||||
{
|
||||
/* Bump up to next page boundary. */
|
||||
prp_page = (uint64_t *)((uint8_t *)prp_page + prp_size);
|
||||
prp_page_phys = (uint64_t *)((uint8_t *)prp_page_phys +
|
||||
prp_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set PRP physical pointer, which initially points to the current PRP
|
||||
* DMA memory page.
|
||||
*/
|
||||
prp_entry_phys = prp_page_phys;
|
||||
|
||||
/* Get physical address and length of the data buffer. */
|
||||
paddr = (bus_addr_t)data;
|
||||
if (data_in_sz)
|
||||
length = data_in_sz;
|
||||
else
|
||||
length = data_out_sz;
|
||||
|
||||
/* Loop while the length is not zero. */
|
||||
while (length)
|
||||
{
|
||||
/*
|
||||
* Check if we need to put a list pointer here if we are at page
|
||||
* boundary - prp_size (8 bytes).
|
||||
*/
|
||||
page_mask_result = (uintptr_t)((uint8_t *)prp_entry_phys +
|
||||
prp_size) & page_mask;
|
||||
if (!page_mask_result)
|
||||
{
|
||||
/*
|
||||
* This is the last entry in a PRP List, so we need to
|
||||
* put a PRP list pointer here. What this does is:
|
||||
* - bump the current memory pointer to the next
|
||||
* address, which will be the next full page.
|
||||
* - set the PRP Entry to point to that page. This is
|
||||
* now the PRP List pointer.
|
||||
* - bump the PRP Entry pointer the start of the next
|
||||
* page. Since all of this PRP memory is contiguous,
|
||||
* no need to get a new page - it's just the next
|
||||
* address.
|
||||
*/
|
||||
prp_entry_phys++;
|
||||
*prp_entry =
|
||||
htole64((uint64_t)(uintptr_t)prp_entry_phys);
|
||||
prp_entry++;
|
||||
}
|
||||
|
||||
/* Need to handle if entry will be part of a page. */
|
||||
offset = (uint32_t)paddr & page_mask;
|
||||
entry_len = PAGE_SIZE - offset;
|
||||
|
||||
if (prp_entry == prp1_entry)
|
||||
{
|
||||
/*
|
||||
* Must fill in the first PRP pointer (PRP1) before
|
||||
* moving on.
|
||||
*/
|
||||
*prp1_entry = htole64((uint64_t)paddr);
|
||||
|
||||
/*
|
||||
* Now point to the second PRP entry within the
|
||||
* command (PRP2).
|
||||
*/
|
||||
prp_entry = prp2_entry;
|
||||
}
|
||||
else if (prp_entry == prp2_entry)
|
||||
{
|
||||
/*
|
||||
* Should the PRP2 entry be a PRP List pointer or just a
|
||||
* regular PRP pointer? If there is more than one more
|
||||
* page of data, must use a PRP List pointer.
|
||||
*/
|
||||
if (length > PAGE_SIZE)
|
||||
{
|
||||
/*
|
||||
* PRP2 will contain a PRP List pointer because
|
||||
* more PRP's are needed with this command. The
|
||||
* list will start at the beginning of the
|
||||
* contiguous buffer.
|
||||
*/
|
||||
*prp2_entry =
|
||||
htole64(
|
||||
(uint64_t)(uintptr_t)prp_entry_phys);
|
||||
|
||||
/*
|
||||
* The next PRP Entry will be the start of the
|
||||
* first PRP List.
|
||||
*/
|
||||
prp_entry = prp_page;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* After this, the PRP Entries are complete.
|
||||
* This command uses 2 PRP's and no PRP list.
|
||||
*/
|
||||
*prp2_entry = htole64((uint64_t)paddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Put entry in list and bump the addresses.
|
||||
*
|
||||
* After PRP1 and PRP2 are filled in, this will fill in
|
||||
* all remaining PRP entries in a PRP List, one per each
|
||||
* time through the loop.
|
||||
*/
|
||||
*prp_entry = htole64((uint64_t)paddr);
|
||||
prp_entry++;
|
||||
prp_entry_phys++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bump the phys address of the command's data buffer by the
|
||||
* entry_len.
|
||||
*/
|
||||
paddr += entry_len;
|
||||
|
||||
/* Decrement length accounting for last partial page. */
|
||||
if (entry_len > length)
|
||||
length = 0;
|
||||
else
|
||||
length -= entry_len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mpr_check_pcie_native_sgl - This function is called for PCIe end devices to
|
||||
* determine if the driver needs to build a native SGL. If so, that native SGL
|
||||
* is built in the contiguous buffers allocated especially for PCIe SGL
|
||||
* creation. If the driver will not build a native SGL, return TRUE and a
|
||||
* normal IEEE SGL will be built. Currently this routine supports NVMe devices
|
||||
* only.
|
||||
*
|
||||
* Returns FALSE (0) if native SGL was built, TRUE (1) if no SGL was built.
|
||||
*/
|
||||
static int
|
||||
mpr_check_pcie_native_sgl(struct mpr_softc *sc, struct mpr_command *cm,
|
||||
bus_dma_segment_t *segs, int segs_left)
|
||||
{
|
||||
uint32_t i, sge_dwords, length, offset, entry_len;
|
||||
uint32_t num_entries, buff_len = 0, sges_in_segment;
|
||||
uint32_t page_mask, page_mask_result, *curr_buff;
|
||||
uint32_t *ptr_sgl, *ptr_first_sgl, first_page_offset;
|
||||
uint32_t first_page_data_size, end_residual;
|
||||
uint64_t *msg_phys;
|
||||
bus_addr_t paddr;
|
||||
int build_native_sgl = 0, first_prp_entry;
|
||||
int prp_size = PRP_ENTRY_SIZE;
|
||||
Mpi25IeeeSgeChain64_t *main_chain_element = NULL;
|
||||
struct mpr_prp_page *prp_page_info = NULL;
|
||||
|
||||
mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
|
||||
|
||||
/*
|
||||
* Add up the sizes of each segment length to get the total transfer
|
||||
* size, which will be checked against the Maximum Data Transfer Size.
|
||||
* If the data transfer length exceeds the MDTS for this device, just
|
||||
* return 1 so a normal IEEE SGL will be built. F/W will break the I/O
|
||||
* up into multiple I/O's. [nvme_mdts = 0 means unlimited]
|
||||
*/
|
||||
for (i = 0; i < segs_left; i++)
|
||||
buff_len += htole32(segs[i].ds_len);
|
||||
if ((cm->cm_targ->MDTS > 0) && (buff_len > cm->cm_targ->MDTS))
|
||||
return 1;
|
||||
|
||||
/* Create page_mask (to get offset within page) */
|
||||
page_mask = PAGE_SIZE - 1;
|
||||
|
||||
/*
|
||||
* Check if the number of elements exceeds the max number that can be
|
||||
* put in the main message frame (H/W can only translate an SGL that
|
||||
* is contained entirely in the main message frame).
|
||||
*/
|
||||
sges_in_segment = (sc->facts->IOCRequestFrameSize -
|
||||
offsetof(Mpi25SCSIIORequest_t, SGL)) / sizeof(MPI25_SGE_IO_UNION);
|
||||
if (segs_left > sges_in_segment)
|
||||
build_native_sgl = 1;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* NVMe uses one PRP for each physical page (or part of physical
|
||||
* page).
|
||||
* if 4 pages or less then IEEE is OK
|
||||
* if > 5 pages then we need to build a native SGL
|
||||
* if > 4 and <= 5 pages, then check the physical address of
|
||||
* the first SG entry, then if this first size in the page
|
||||
* is >= the residual beyond 4 pages then use IEEE,
|
||||
* otherwise use native SGL
|
||||
*/
|
||||
if (buff_len > (PAGE_SIZE * 5))
|
||||
build_native_sgl = 1;
|
||||
else if ((buff_len > (PAGE_SIZE * 4)) &&
|
||||
(buff_len <= (PAGE_SIZE * 5)) )
|
||||
{
|
||||
msg_phys = (uint64_t *)segs[0].ds_addr;
|
||||
first_page_offset =
|
||||
((uint32_t)(uint64_t)(uintptr_t)msg_phys &
|
||||
page_mask);
|
||||
first_page_data_size = PAGE_SIZE - first_page_offset;
|
||||
end_residual = buff_len % PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* If offset into first page pushes the end of the data
|
||||
* beyond end of the 5th page, we need the extra PRP
|
||||
* list.
|
||||
*/
|
||||
if (first_page_data_size < end_residual)
|
||||
build_native_sgl = 1;
|
||||
|
||||
/*
|
||||
* Check if first SG entry size is < residual beyond 4
|
||||
* pages.
|
||||
*/
|
||||
if (htole32(segs[0].ds_len) <
|
||||
(buff_len - (PAGE_SIZE * 4)))
|
||||
build_native_sgl = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if native SGL is needed */
|
||||
if (!build_native_sgl)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Native SGL is needed.
|
||||
* Put a chain element in main message frame that points to the first
|
||||
* chain buffer.
|
||||
*
|
||||
* NOTE: The ChainOffset field must be 0 when using a chain pointer to
|
||||
* a native SGL.
|
||||
*/
|
||||
|
||||
/* Set main message chain element pointer */
|
||||
main_chain_element = (pMpi25IeeeSgeChain64_t)cm->cm_sge;
|
||||
|
||||
/*
|
||||
* For NVMe the chain element needs to be the 2nd SGL entry in the main
|
||||
* message.
|
||||
*/
|
||||
main_chain_element = (Mpi25IeeeSgeChain64_t *)
|
||||
((uint8_t *)main_chain_element + sizeof(MPI25_IEEE_SGE_CHAIN64));
|
||||
|
||||
/*
|
||||
* For the PRP entries, use the specially allocated buffer of
|
||||
* contiguous memory. PRP Page allocation failures should not happen
|
||||
* because there should be enough PRP page buffers to account for the
|
||||
* possible NVMe QDepth.
|
||||
*/
|
||||
prp_page_info = mpr_alloc_prp_page(sc);
|
||||
KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be "
|
||||
"used for building a native NVMe SGL.\n", __func__));
|
||||
curr_buff = (uint32_t *)prp_page_info->prp_page;
|
||||
msg_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr;
|
||||
|
||||
/*
|
||||
* Insert the allocated PRP page into the command's PRP page list. This
|
||||
* will be freed when the command is freed.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&cm->cm_prp_page_list, prp_page_info, prp_page_link);
|
||||
|
||||
/*
|
||||
* Check if we are within 1 entry of a page boundary we don't want our
|
||||
* first entry to be a PRP List entry.
|
||||
*/
|
||||
page_mask_result = (uintptr_t)((uint8_t *)curr_buff + prp_size) &
|
||||
page_mask;
|
||||
if (!page_mask_result) {
|
||||
/* Bump up to next page boundary. */
|
||||
curr_buff = (uint32_t *)((uint8_t *)curr_buff + prp_size);
|
||||
msg_phys = (uint64_t *)((uint8_t *)msg_phys + prp_size);
|
||||
}
|
||||
|
||||
/* Fill in the chain element and make it an NVMe segment type. */
|
||||
main_chain_element->Address.High =
|
||||
htole32((uint32_t)((uint64_t)(uintptr_t)msg_phys >> 32));
|
||||
main_chain_element->Address.Low =
|
||||
htole32((uint32_t)(uintptr_t)msg_phys);
|
||||
main_chain_element->NextChainOffset = 0;
|
||||
main_chain_element->Flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
|
||||
MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
|
||||
MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP;
|
||||
|
||||
/* Set SGL pointer to start of contiguous PCIe buffer. */
|
||||
ptr_sgl = curr_buff;
|
||||
sge_dwords = 2;
|
||||
num_entries = 0;
|
||||
|
||||
/*
|
||||
* NVMe has a very convoluted PRP format. One PRP is required for each
|
||||
* page or partial page. We need to split up OS SG entries if they are
|
||||
* longer than one page or cross a page boundary. We also have to insert
|
||||
* a PRP list pointer entry as the last entry in each physical page of
|
||||
* the PRP list.
|
||||
*
|
||||
* NOTE: The first PRP "entry" is actually placed in the first SGL entry
|
||||
* in the main message in IEEE 64 format. The 2nd entry in the main
|
||||
* message is the chain element, and the rest of the PRP entries are
|
||||
* built in the contiguous PCIe buffer.
|
||||
*/
|
||||
first_prp_entry = 1;
|
||||
ptr_first_sgl = (uint32_t *)cm->cm_sge;
|
||||
|
||||
for (i = 0; i < segs_left; i++) {
|
||||
/* Get physical address and length of this SG entry. */
|
||||
paddr = segs[i].ds_addr;
|
||||
length = segs[i].ds_len;
|
||||
|
||||
/*
|
||||
* Check whether a given SGE buffer lies on a non-PAGED
|
||||
* boundary if this is not the first page. If so, this is not
|
||||
* expected so have FW build the SGL.
|
||||
*/
|
||||
if (i) {
|
||||
if ((uint32_t)paddr & page_mask) {
|
||||
mpr_dprint(sc, MPR_ERROR, "Unaligned SGE while "
|
||||
"building NVMe PRPs, low address is 0x%x\n",
|
||||
(uint32_t)paddr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apart from last SGE, if any other SGE boundary is not page
|
||||
* aligned then it means that hole exists. Existence of hole
|
||||
* leads to data corruption. So fallback to IEEE SGEs.
|
||||
*/
|
||||
if (i != (segs_left - 1)) {
|
||||
if (((uint32_t)paddr + length) & page_mask) {
|
||||
mpr_dprint(sc, MPR_ERROR, "Unaligned SGE "
|
||||
"boundary while building NVMe PRPs, low "
|
||||
"address: 0x%x and length: %u\n",
|
||||
(uint32_t)paddr, length);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop while the length is not zero. */
|
||||
while (length) {
|
||||
/*
|
||||
* Check if we need to put a list pointer here if we are
|
||||
* at page boundary - prp_size.
|
||||
*/
|
||||
page_mask_result = (uintptr_t)((uint8_t *)ptr_sgl +
|
||||
prp_size) & page_mask;
|
||||
if (!page_mask_result) {
|
||||
/*
|
||||
* Need to put a PRP list pointer here.
|
||||
*/
|
||||
msg_phys = (uint64_t *)((uint8_t *)msg_phys +
|
||||
prp_size);
|
||||
*ptr_sgl = htole32((uintptr_t)msg_phys);
|
||||
*(ptr_sgl+1) = htole32((uint64_t)(uintptr_t)
|
||||
msg_phys >> 32);
|
||||
ptr_sgl += sge_dwords;
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
/* Need to handle if entry will be part of a page. */
|
||||
offset = (uint32_t)paddr & page_mask;
|
||||
entry_len = PAGE_SIZE - offset;
|
||||
if (first_prp_entry) {
|
||||
/*
|
||||
* Put IEEE entry in first SGE in main message.
|
||||
* (Simple element, System addr, not end of
|
||||
* list.)
|
||||
*/
|
||||
*ptr_first_sgl = htole32((uint32_t)paddr);
|
||||
*(ptr_first_sgl + 1) =
|
||||
htole32((uint32_t)((uint64_t)paddr >> 32));
|
||||
*(ptr_first_sgl + 2) = htole32(entry_len);
|
||||
*(ptr_first_sgl + 3) = 0;
|
||||
|
||||
/* No longer the first PRP entry. */
|
||||
first_prp_entry = 0;
|
||||
} else {
|
||||
/* Put entry in list. */
|
||||
*ptr_sgl = htole32((uint32_t)paddr);
|
||||
*(ptr_sgl + 1) =
|
||||
htole32((uint32_t)((uint64_t)paddr >> 32));
|
||||
|
||||
/* Bump ptr_sgl, msg_phys, and num_entries. */
|
||||
ptr_sgl += sge_dwords;
|
||||
msg_phys = (uint64_t *)((uint8_t *)msg_phys +
|
||||
prp_size);
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
/* Bump the phys address by the entry_len. */
|
||||
paddr += entry_len;
|
||||
|
||||
/* Decrement length accounting for last partial page. */
|
||||
if (entry_len > length)
|
||||
length = 0;
|
||||
else
|
||||
length -= entry_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set chain element Length. */
|
||||
main_chain_element->Length = htole32(num_entries * prp_size);
|
||||
|
||||
/* Return 0, indicating we built a native SGL. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a chain element as the next SGE for the specified command.
|
||||
* Reset cm_sge and cm_sgesize to indicate all the available space. Chains are
|
||||
@ -2540,6 +3184,13 @@ mpr_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
} else
|
||||
dir = BUS_DMASYNC_PREREAD;
|
||||
|
||||
/* Check if a native SG list is needed for an NVMe PCIe device. */
|
||||
if (cm->cm_targ && cm->cm_targ->is_nvme &&
|
||||
mpr_check_pcie_native_sgl(sc, cm, segs, nsegs) == 0) {
|
||||
/* A native SG list was built, skip to end. */
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
if ((cm->cm_flags & MPR_CM_FLAGS_SMP_PASS) && (i != 0)) {
|
||||
sflags &= ~MPI2_SGE_FLAGS_DIRECTION;
|
||||
@ -2557,6 +3208,7 @@ mpr_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir);
|
||||
mpr_enqueue_request(sc, cm);
|
||||
|
||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_sas.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
@ -91,7 +92,7 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
|
||||
request->Header.PageNumber = 8;
|
||||
request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
@ -137,7 +138,7 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_IOC;
|
||||
request->Header.PageNumber = 8;
|
||||
request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->Header.PageLength = mpi_reply->Header.PageLength;
|
||||
cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
|
||||
cm->cm_sge = &request->PageBufferSGE;
|
||||
@ -221,7 +222,7 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
|
||||
request->Header.PageNumber = 8;
|
||||
request->Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
@ -267,7 +268,7 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT;
|
||||
request->Header.PageNumber = 8;
|
||||
request->Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->Header.PageLength = mpi_reply->Header.PageLength;
|
||||
cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
|
||||
cm->cm_sge = &request->PageBufferSGE;
|
||||
@ -387,7 +388,7 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION;
|
||||
request->ExtPageLength = request->Header.PageVersion = 0;
|
||||
request->PageAddress = sc->max_dpm_entries <<
|
||||
MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
@ -436,7 +437,7 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->PageAddress = sc->max_dpm_entries <<
|
||||
MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
|
||||
request->ExtPageLength = mpi_reply->ExtPageLength;
|
||||
@ -522,7 +523,7 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION;
|
||||
request->ExtPageLength = request->Header.PageVersion = 0;
|
||||
/* We can remove below two lines ????*/
|
||||
request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
|
||||
request->PageAddress |= htole16(entry_idx);
|
||||
@ -572,7 +573,7 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_DRIVERMAPPING0_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->ExtPageLength = mpi_reply->ExtPageLength;
|
||||
request->PageAddress = 1 << MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
|
||||
request->PageAddress |= htole16(entry_idx);
|
||||
@ -660,7 +661,7 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
|
||||
request->ExtPageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
@ -707,7 +708,7 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->ExtPageLength = mpi_reply->ExtPageLength;
|
||||
request->PageAddress = htole32(form | handle);
|
||||
cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
|
||||
@ -758,6 +759,276 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
return (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* mpr_config_get_pcie_device_pg0 - obtain PCIe device page 0
|
||||
* @sc: per adapter object
|
||||
* @mpi_reply: reply mf payload returned from firmware
|
||||
* @config_page: contents of the config page
|
||||
* @form: GET_NEXT_HANDLE or HANDLE
|
||||
* @handle: device handle
|
||||
* Context: sleep.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
int
|
||||
mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle)
|
||||
{
|
||||
MPI2_CONFIG_REQUEST *request;
|
||||
MPI2_CONFIG_REPLY *reply;
|
||||
struct mpr_command *cm;
|
||||
Mpi26PCIeDevicePage0_t *page = NULL;
|
||||
int error = 0;
|
||||
u16 ioc_status;
|
||||
|
||||
mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
|
||||
|
||||
if ((cm = mpr_alloc_command(sc)) == NULL) {
|
||||
printf("%s: command alloc failed @ line %d\n", __func__,
|
||||
__LINE__);
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
|
||||
bzero(request, sizeof(MPI2_CONFIG_REQUEST));
|
||||
request->Function = MPI2_FUNCTION_CONFIG;
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
|
||||
request->Header.PageNumber = 0;
|
||||
request->ExtPageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
|
||||
if (error || (reply == NULL)) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: request for header completed with error %d",
|
||||
__func__, error);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: header read with error; iocstatus = 0x%x\n",
|
||||
__func__, ioc_status);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
/* We have to do free and alloc for the reply-free and reply-post
|
||||
* counters to match - Need to review the reply FIFO handling.
|
||||
*/
|
||||
mpr_free_command(sc, cm);
|
||||
|
||||
if ((cm = mpr_alloc_command(sc)) == NULL) {
|
||||
printf("%s: command alloc failed @ line %d\n", __func__,
|
||||
__LINE__);
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
|
||||
bzero(request, sizeof(MPI2_CONFIG_REQUEST));
|
||||
request->Function = MPI2_FUNCTION_CONFIG;
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->ExtPageLength = mpi_reply->ExtPageLength;
|
||||
request->PageAddress = htole32(form | handle);
|
||||
cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
|
||||
cm->cm_sge = &request->PageBufferSGE;
|
||||
cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
|
||||
cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
|
||||
if (!page) {
|
||||
printf("%s: page alloc failed\n", __func__);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
cm->cm_data = page;
|
||||
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
|
||||
if (error || (reply == NULL)) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: request for page completed with error %d",
|
||||
__func__, error);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: page read with error; iocstatus = 0x%x\n",
|
||||
__func__, ioc_status);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
bcopy(page, config_page, MIN(cm->cm_length,
|
||||
sizeof(Mpi26PCIeDevicePage0_t)));
|
||||
out:
|
||||
free(page, M_MPR);
|
||||
if (cm)
|
||||
mpr_free_command(sc, cm);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* mpr_config_get_pcie_device_pg2 - obtain PCIe device page 2
|
||||
* @sc: per adapter object
|
||||
* @mpi_reply: reply mf payload returned from firmware
|
||||
* @config_page: contents of the config page
|
||||
* @form: GET_NEXT_HANDLE or HANDLE
|
||||
* @handle: device handle
|
||||
* Context: sleep.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
int
|
||||
mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle)
|
||||
{
|
||||
MPI2_CONFIG_REQUEST *request;
|
||||
MPI2_CONFIG_REPLY *reply;
|
||||
struct mpr_command *cm;
|
||||
Mpi26PCIeDevicePage2_t *page = NULL;
|
||||
int error = 0;
|
||||
u16 ioc_status;
|
||||
|
||||
mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
|
||||
|
||||
if ((cm = mpr_alloc_command(sc)) == NULL) {
|
||||
printf("%s: command alloc failed @ line %d\n", __func__,
|
||||
__LINE__);
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
|
||||
bzero(request, sizeof(MPI2_CONFIG_REQUEST));
|
||||
request->Function = MPI2_FUNCTION_CONFIG;
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
|
||||
request->Header.PageNumber = 2;
|
||||
request->ExtPageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
|
||||
if (error || (reply == NULL)) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: request for header completed with error %d",
|
||||
__func__, error);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: header read with error; iocstatus = 0x%x\n",
|
||||
__func__, ioc_status);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
/* We have to do free and alloc for the reply-free and reply-post
|
||||
* counters to match - Need to review the reply FIFO handling.
|
||||
*/
|
||||
mpr_free_command(sc, cm);
|
||||
|
||||
if ((cm = mpr_alloc_command(sc)) == NULL) {
|
||||
printf("%s: command alloc failed @ line %d\n", __func__,
|
||||
__LINE__);
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
request = (MPI2_CONFIG_REQUEST *)cm->cm_req;
|
||||
bzero(request, sizeof(MPI2_CONFIG_REQUEST));
|
||||
request->Function = MPI2_FUNCTION_CONFIG;
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
request->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_DEVICE;
|
||||
request->Header.PageNumber = 2;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->ExtPageLength = mpi_reply->ExtPageLength;
|
||||
request->PageAddress = htole32(form | handle);
|
||||
cm->cm_length = le16toh(mpi_reply->ExtPageLength) * 4;
|
||||
cm->cm_sge = &request->PageBufferSGE;
|
||||
cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
|
||||
cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
page = malloc(cm->cm_length, M_MPR, M_ZERO | M_NOWAIT);
|
||||
if (!page) {
|
||||
printf("%s: page alloc failed\n", __func__);
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
cm->cm_data = page;
|
||||
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
|
||||
if (error || (reply == NULL)) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: request for page completed with error %d",
|
||||
__func__, error);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
ioc_status = le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
|
||||
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
/* FIXME */
|
||||
/*
|
||||
* If the request returns an error then we need to do a diag
|
||||
* reset
|
||||
*/
|
||||
printf("%s: page read with error; iocstatus = 0x%x\n",
|
||||
__func__, ioc_status);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
bcopy(page, config_page, MIN(cm->cm_length,
|
||||
sizeof(Mpi26PCIeDevicePage2_t)));
|
||||
out:
|
||||
free(page, M_MPR);
|
||||
if (cm)
|
||||
mpr_free_command(sc, cm);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* mpr_config_get_bios_pg3 - obtain BIOS page 3
|
||||
* @sc: per adapter object
|
||||
@ -792,7 +1063,7 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
|
||||
request->Header.PageNumber = 3;
|
||||
request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
@ -838,7 +1109,7 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_BIOS;
|
||||
request->Header.PageNumber = 3;
|
||||
request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
|
||||
request->Header.PageVersion = mpi_reply->Header.PageVersion;
|
||||
request->Header.PageLength = mpi_reply->Header.PageLength;
|
||||
cm->cm_length = le16toh(mpi_reply->Header.PageLength) * 4;
|
||||
cm->cm_sge = &request->PageBufferSGE;
|
||||
@ -922,7 +1193,7 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
|
||||
@ -1051,7 +1322,7 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
|
||||
request->Header.PageNumber = 1;
|
||||
request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
|
||||
@ -1208,7 +1479,7 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
|
||||
request->Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
|
||||
request->Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
|
||||
request->Header.PageNumber = 0;
|
||||
request->Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
|
||||
request->Header.PageLength = request->Header.PageVersion = 0;
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
cm->cm_data = NULL;
|
||||
|
||||
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_sas.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
@ -675,6 +676,55 @@ _mapping_add_to_removal_table(struct mpr_softc *sc, u16 handle,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_inc_missing_count
|
||||
* @sc: per adapter object
|
||||
* @map_idx: index into the mapping table for the device that is missing
|
||||
*
|
||||
* Increment the missing count in the mapping table for a SAS, SATA, or PCIe
|
||||
* device that is not responding. If Persitent Mapping is used, increment the
|
||||
* DPM entry as well. Also, add this device to the removal table for possible
|
||||
* removal if a new device is added.
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
static void
|
||||
_mapping_inc_missing_count(struct mpr_softc *sc, u32 map_idx)
|
||||
{
|
||||
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
|
||||
struct dev_mapping_table *mt_entry;
|
||||
Mpi2DriverMap0Entry_t *dpm_entry;
|
||||
|
||||
if (map_idx == MPR_MAPTABLE_BAD_IDX) {
|
||||
mpr_dprint(sc, MPR_INFO, "%s: device is already removed from "
|
||||
"mapping table\n", __func__);
|
||||
return;
|
||||
}
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
if (!mt_entry->init_complete) {
|
||||
if (mt_entry->missing_count < MPR_MAX_MISSING_COUNT)
|
||||
mt_entry->missing_count++;
|
||||
else
|
||||
mt_entry->init_complete = 1;
|
||||
}
|
||||
if (!mt_entry->missing_count)
|
||||
mt_entry->missing_count++;
|
||||
_mapping_add_to_removal_table(sc, mt_entry->dev_handle, 0);
|
||||
mt_entry->dev_handle = 0;
|
||||
|
||||
if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) &&
|
||||
sc->is_dpm_enable && !mt_entry->init_complete &&
|
||||
mt_entry->dpm_entry_num != MPR_DPM_BAD_IDX) {
|
||||
dpm_entry = (Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 +
|
||||
sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
|
||||
dpm_entry += mt_entry->dpm_entry_num;
|
||||
dpm_entry->MappingInformation = mt_entry->missing_count;
|
||||
sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1;
|
||||
}
|
||||
mt_entry->init_complete = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_update_missing_count - Update missing count for a device
|
||||
* @sc: per adapter object
|
||||
@ -689,12 +739,9 @@ static void
|
||||
_mapping_update_missing_count(struct mpr_softc *sc,
|
||||
struct _map_topology_change *topo_change)
|
||||
{
|
||||
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
|
||||
u8 entry;
|
||||
struct _map_phy_change *phy_change;
|
||||
u32 map_idx;
|
||||
struct dev_mapping_table *mt_entry;
|
||||
Mpi2DriverMap0Entry_t *dpm_entry;
|
||||
|
||||
for (entry = 0; entry < topo_change->num_entries; entry++) {
|
||||
phy_change = &topo_change->phy_details[entry];
|
||||
@ -704,35 +751,37 @@ _mapping_update_missing_count(struct mpr_softc *sc,
|
||||
map_idx = _mapping_get_mt_idx_from_handle(sc, phy_change->
|
||||
dev_handle);
|
||||
phy_change->is_processed = 1;
|
||||
if (map_idx == MPR_MAPTABLE_BAD_IDX) {
|
||||
printf("%s: device is already removed from mapping "
|
||||
"table\n", __func__);
|
||||
continue;
|
||||
}
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
if (!mt_entry->init_complete) {
|
||||
if (mt_entry->missing_count < MPR_MAX_MISSING_COUNT)
|
||||
mt_entry->missing_count++;
|
||||
else
|
||||
mt_entry->init_complete = 1;
|
||||
}
|
||||
if (!mt_entry->missing_count)
|
||||
mt_entry->missing_count++;
|
||||
_mapping_add_to_removal_table(sc, mt_entry->dev_handle, 0);
|
||||
mt_entry->dev_handle = 0;
|
||||
_mapping_inc_missing_count(sc, map_idx);
|
||||
}
|
||||
}
|
||||
|
||||
if (((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) &&
|
||||
sc->is_dpm_enable && !mt_entry->init_complete &&
|
||||
mt_entry->dpm_entry_num != MPR_DPM_BAD_IDX) {
|
||||
dpm_entry =
|
||||
(Mpi2DriverMap0Entry_t *) ((u8 *)sc->dpm_pg0 +
|
||||
sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER));
|
||||
dpm_entry += mt_entry->dpm_entry_num;
|
||||
dpm_entry->MappingInformation = mt_entry->missing_count;
|
||||
sc->dpm_flush_entry[mt_entry->dpm_entry_num] = 1;
|
||||
}
|
||||
mt_entry->init_complete = 1;
|
||||
/**
|
||||
* _mapping_update_pcie_missing_count - Update missing count for a PCIe device
|
||||
* @sc: per adapter object
|
||||
* @topo_change: Topology change event entry
|
||||
*
|
||||
* Search through the PCIe topology change list and if any device is found not
|
||||
* responding it's associated map table entry and DPM entry is updated
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
static void
|
||||
_mapping_update_pcie_missing_count(struct mpr_softc *sc,
|
||||
struct _map_pcie_topology_change *topo_change)
|
||||
{
|
||||
u8 entry;
|
||||
struct _map_port_change *port_change;
|
||||
u32 map_idx;
|
||||
|
||||
for (entry = 0; entry < topo_change->num_entries; entry++) {
|
||||
port_change = &topo_change->port_details[entry];
|
||||
if (!port_change->dev_handle || (port_change->reason !=
|
||||
MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING))
|
||||
continue;
|
||||
map_idx = _mapping_get_mt_idx_from_handle(sc, port_change->
|
||||
dev_handle);
|
||||
port_change->is_processed = 1;
|
||||
_mapping_inc_missing_count(sc, map_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -940,7 +989,7 @@ _mapping_get_dev_info(struct mpr_softc *sc,
|
||||
|
||||
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 = device_info;
|
||||
|
||||
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
|
||||
@ -990,12 +1039,118 @@ _mapping_get_dev_info(struct mpr_softc *sc,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found space in enclosure for mapping entry */
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
for (index = map_idx; index < (et_entry->num_slots
|
||||
+ map_idx); index++, mt_entry++) {
|
||||
mt_entry->device_info = MPR_DEV_RESERVED;
|
||||
mt_entry->physical_id = et_entry->enclosure_id;
|
||||
mt_entry->phy_bits = et_entry->phy_bits;
|
||||
mt_entry->missing_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_get_pcie_dev_info -get information about newly added PCIe devices
|
||||
* @sc: per adapter object
|
||||
* @topo_change: Topology change event entry
|
||||
*
|
||||
* Searches through the PCIe topology change event list and issues PCIe device
|
||||
* pg0 requests for the newly added PCIe device. If the device is in an
|
||||
* enclosure, search for available space in the enclosure mapping table for the
|
||||
* device and reserve that space.
|
||||
*
|
||||
* Returns nothing
|
||||
*/
|
||||
static void
|
||||
_mapping_get_pcie_dev_info(struct mpr_softc *sc,
|
||||
struct _map_pcie_topology_change *topo_change)
|
||||
{
|
||||
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
Mpi26PCIeDevicePage0_t pcie_device_pg0;
|
||||
u8 entry, enc_idx, port_idx;
|
||||
u32 map_idx, index;
|
||||
struct _map_port_change *port_change, *tmp_port_change;
|
||||
uint64_t pcie_wwid;
|
||||
struct enc_mapping_table *et_entry;
|
||||
struct dev_mapping_table *mt_entry;
|
||||
u8 add_code = MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED;
|
||||
|
||||
for (entry = 0; entry < topo_change->num_entries; entry++) {
|
||||
port_change = &topo_change->port_details[entry];
|
||||
if (port_change->is_processed || !port_change->dev_handle ||
|
||||
port_change->reason != MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED)
|
||||
continue;
|
||||
if (mpr_config_get_pcie_device_pg0(sc, &mpi_reply,
|
||||
&pcie_device_pg0, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE,
|
||||
port_change->dev_handle)) {
|
||||
port_change->is_processed = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
pcie_wwid = pcie_device_pg0.WWID.High;
|
||||
pcie_wwid = (pcie_wwid << 32) | pcie_device_pg0.WWID.Low;
|
||||
port_change->physical_id = pcie_wwid;
|
||||
port_change->slot = le16toh(pcie_device_pg0.Slot);
|
||||
port_change->device_info = le32toh(pcie_device_pg0.DeviceInfo);
|
||||
|
||||
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
|
||||
enc_idx = _mapping_get_enc_idx_from_handle(sc,
|
||||
topo_change->enc_handle);
|
||||
if (enc_idx == MPR_ENCTABLE_BAD_IDX) {
|
||||
port_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_MAPPING, "%s: failed to add "
|
||||
"the device with handle 0x%04x because the "
|
||||
"enclosure is not in the mapping table\n",
|
||||
__func__, port_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
if (!(port_change->device_info &
|
||||
MPI26_PCIE_DEVINFO_NVME)) {
|
||||
port_change->is_processed = 1;
|
||||
continue;
|
||||
}
|
||||
et_entry = &sc->enclosure_table[enc_idx];
|
||||
if (et_entry->start_index != MPR_MAPTABLE_BAD_IDX)
|
||||
continue;
|
||||
if (!topo_change->switch_dev_handle) {
|
||||
map_idx = sc->num_rsvd_entries;
|
||||
et_entry->start_index = map_idx;
|
||||
} else {
|
||||
map_idx = _mapping_find_enc_map_space(sc,
|
||||
et_entry);
|
||||
et_entry->start_index = map_idx;
|
||||
if (et_entry->start_index ==
|
||||
MPR_MAPTABLE_BAD_IDX) {
|
||||
port_change->is_processed = 1;
|
||||
for (port_idx = 0; port_idx <
|
||||
topo_change->num_entries;
|
||||
port_idx++) {
|
||||
tmp_port_change =
|
||||
&topo_change->port_details
|
||||
[port_idx];
|
||||
if (tmp_port_change->reason ==
|
||||
add_code)
|
||||
tmp_port_change->
|
||||
is_processed = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found space in enclosure for mapping entry */
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
for (index = map_idx; index < (et_entry->num_slots
|
||||
+ map_idx); index++, mt_entry++) {
|
||||
mt_entry->device_info = MPR_DEV_RESERVED;
|
||||
mt_entry->physical_id = et_entry->enclosure_id;
|
||||
mt_entry->phy_bits = et_entry->phy_bits;
|
||||
mt_entry->missing_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1106,8 +1261,8 @@ _mapping_clear_removed_entries(struct mpr_softc *sc)
|
||||
* @sc: per adapter object
|
||||
* @topo_change: Topology change event entry
|
||||
*
|
||||
* Search through the topology change event list and updates map table,
|
||||
* enclosure table and DPM pages for for the newly added devices.
|
||||
* Search through the topology change event list and update map table,
|
||||
* enclosure table and DPM pages for the newly added devices.
|
||||
*
|
||||
* Returns nothing
|
||||
*/
|
||||
@ -1144,10 +1299,10 @@ _mapping_add_new_device(struct mpr_softc *sc,
|
||||
(sc, topo_change->enc_handle);
|
||||
if (enc_idx == MPR_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);
|
||||
mpr_dprint(sc, MPR_ERROR, "%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;
|
||||
}
|
||||
et_entry = &sc->enclosure_table[enc_idx];
|
||||
@ -1157,10 +1312,11 @@ _mapping_add_new_device(struct mpr_softc *sc,
|
||||
sc->mt_add_device_failed = 1;
|
||||
continue;
|
||||
}
|
||||
printf("%s: failed to add the device with "
|
||||
"handle 0x%04x because there is no free "
|
||||
"space available in the mapping table\n",
|
||||
__func__, phy_change->dev_handle);
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed to add "
|
||||
"the device with handle 0x%04x because "
|
||||
"there is no free space available in the "
|
||||
"mapping table\n", __func__,
|
||||
phy_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
map_idx = et_entry->start_index + phy_change->slot -
|
||||
@ -1268,10 +1424,11 @@ _mapping_add_new_device(struct mpr_softc *sc,
|
||||
sc->mt_add_device_failed = 1;
|
||||
continue;
|
||||
}
|
||||
printf("%s: failed to add the device with "
|
||||
"handle 0x%04x because there is no free "
|
||||
"space available in the mapping table\n",
|
||||
__func__, phy_change->dev_handle);
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed to add "
|
||||
"the device with handle 0x%04x because "
|
||||
"there is no free space available in the "
|
||||
"mapping table\n", __func__,
|
||||
phy_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
if (sc->is_dpm_enable) {
|
||||
@ -1314,14 +1471,13 @@ _mapping_add_new_device(struct mpr_softc *sc,
|
||||
sc->dpm_flush_entry[dpm_idx] = 1;
|
||||
phy_change->is_processed = 1;
|
||||
} else if (dpm_idx == MPR_DPM_BAD_IDX) {
|
||||
phy_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_INFO, "%s: "
|
||||
"failed to add the device "
|
||||
"with handle 0x%04x to "
|
||||
"persistent table because "
|
||||
"there is no free space "
|
||||
"available\n", __func__,
|
||||
phy_change->dev_handle);
|
||||
phy_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed "
|
||||
"to add the device with handle "
|
||||
"0x%04x to persistent table "
|
||||
"because there is no free space "
|
||||
"available\n", __func__,
|
||||
phy_change->dev_handle);
|
||||
}
|
||||
}
|
||||
mt_entry->init_complete = 1;
|
||||
@ -1333,6 +1489,241 @@ _mapping_add_new_device(struct mpr_softc *sc,
|
||||
_mapping_clear_removed_entries(sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_add_new_pcie_device -Add the new PCIe device into mapping table
|
||||
* @sc: per adapter object
|
||||
* @topo_change: Topology change event entry
|
||||
*
|
||||
* Search through the PCIe topology change event list and update map table,
|
||||
* enclosure table and DPM pages for the newly added devices.
|
||||
*
|
||||
* Returns nothing
|
||||
*/
|
||||
static void
|
||||
_mapping_add_new_pcie_device(struct mpr_softc *sc,
|
||||
struct _map_pcie_topology_change *topo_change)
|
||||
{
|
||||
u8 enc_idx, missing_cnt, is_removed = 0;
|
||||
u16 dpm_idx;
|
||||
u32 search_idx, map_idx;
|
||||
u32 entry;
|
||||
struct dev_mapping_table *mt_entry;
|
||||
struct enc_mapping_table *et_entry;
|
||||
struct _map_port_change *port_change;
|
||||
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
|
||||
Mpi2DriverMap0Entry_t *dpm_entry;
|
||||
uint64_t temp64_var;
|
||||
u8 map_shift = MPI2_DRVMAP0_MAPINFO_SLOT_SHIFT;
|
||||
u8 hdr_sz = sizeof(MPI2_CONFIG_EXTENDED_PAGE_HEADER);
|
||||
u16 max_num_phy_ids = le16toh(sc->ioc_pg8.MaxNumPhysicalMappedIDs);
|
||||
|
||||
for (entry = 0; entry < topo_change->num_entries; entry++) {
|
||||
port_change = &topo_change->port_details[entry];
|
||||
if (port_change->is_processed)
|
||||
continue;
|
||||
if (port_change->reason != MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED ||
|
||||
!port_change->dev_handle) {
|
||||
port_change->is_processed = 1;
|
||||
continue;
|
||||
}
|
||||
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
|
||||
enc_idx = _mapping_get_enc_idx_from_handle
|
||||
(sc, topo_change->enc_handle);
|
||||
if (enc_idx == MPR_ENCTABLE_BAD_IDX) {
|
||||
port_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_ERROR, "%s: failed to add "
|
||||
"the device with handle 0x%04x because the "
|
||||
"enclosure is not in the mapping table\n",
|
||||
__func__, port_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
et_entry = &sc->enclosure_table[enc_idx];
|
||||
if (et_entry->start_index == MPR_MAPTABLE_BAD_IDX) {
|
||||
port_change->is_processed = 1;
|
||||
if (!sc->mt_full_retry) {
|
||||
sc->mt_add_device_failed = 1;
|
||||
continue;
|
||||
}
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed to add "
|
||||
"the device with handle 0x%04x because "
|
||||
"there is no free space available in the "
|
||||
"mapping table\n", __func__,
|
||||
port_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
map_idx = et_entry->start_index + port_change->slot -
|
||||
et_entry->start_slot;
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
mt_entry->physical_id = port_change->physical_id;
|
||||
mt_entry->channel = 0;
|
||||
mt_entry->id = map_idx;
|
||||
mt_entry->dev_handle = port_change->dev_handle;
|
||||
mt_entry->missing_count = 0;
|
||||
mt_entry->dpm_entry_num = et_entry->dpm_entry_num;
|
||||
mt_entry->device_info = port_change->device_info |
|
||||
(MPR_DEV_RESERVED | MPR_MAP_IN_USE);
|
||||
if (sc->is_dpm_enable) {
|
||||
dpm_idx = et_entry->dpm_entry_num;
|
||||
if (dpm_idx == MPR_DPM_BAD_IDX)
|
||||
dpm_idx = _mapping_get_dpm_idx_from_id
|
||||
(sc, et_entry->enclosure_id,
|
||||
et_entry->phy_bits);
|
||||
if (dpm_idx == MPR_DPM_BAD_IDX) {
|
||||
dpm_idx = _mapping_get_free_dpm_idx(sc);
|
||||
if (dpm_idx != MPR_DPM_BAD_IDX) {
|
||||
dpm_entry =
|
||||
(Mpi2DriverMap0Entry_t *)
|
||||
((u8 *) sc->dpm_pg0 +
|
||||
hdr_sz);
|
||||
dpm_entry += dpm_idx;
|
||||
dpm_entry->
|
||||
PhysicalIdentifier.Low =
|
||||
(0xFFFFFFFF &
|
||||
et_entry->enclosure_id);
|
||||
dpm_entry->
|
||||
PhysicalIdentifier.High =
|
||||
( et_entry->enclosure_id
|
||||
>> 32);
|
||||
dpm_entry->DeviceIndex =
|
||||
(U16)et_entry->start_index;
|
||||
dpm_entry->MappingInformation =
|
||||
et_entry->num_slots;
|
||||
dpm_entry->MappingInformation
|
||||
<<= map_shift;
|
||||
dpm_entry->PhysicalBitsMapping
|
||||
= et_entry->phy_bits;
|
||||
et_entry->dpm_entry_num =
|
||||
dpm_idx;
|
||||
/* FIXME Do I need to set the dpm_idxin mt_entry too */
|
||||
sc->dpm_entry_used[dpm_idx] = 1;
|
||||
sc->dpm_flush_entry[dpm_idx] =
|
||||
1;
|
||||
port_change->is_processed = 1;
|
||||
} else {
|
||||
port_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_INFO, "%s: "
|
||||
"failed to add the device "
|
||||
"with handle 0x%04x to "
|
||||
"persistent table because "
|
||||
"there is no free space "
|
||||
"available\n", __func__,
|
||||
port_change->dev_handle);
|
||||
}
|
||||
} else {
|
||||
et_entry->dpm_entry_num = dpm_idx;
|
||||
mt_entry->dpm_entry_num = dpm_idx;
|
||||
}
|
||||
}
|
||||
/* FIXME Why not mt_entry too? */
|
||||
et_entry->init_complete = 1;
|
||||
} else if ((ioc_pg8_flags &
|
||||
MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
|
||||
MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
|
||||
map_idx = _mapping_get_mt_idx_from_id
|
||||
(sc, port_change->physical_id);
|
||||
if (map_idx == MPR_MAPTABLE_BAD_IDX) {
|
||||
search_idx = sc->num_rsvd_entries;
|
||||
if (topo_change->switch_dev_handle)
|
||||
search_idx += max_num_phy_ids;
|
||||
map_idx = _mapping_get_free_mt_idx(sc,
|
||||
search_idx);
|
||||
}
|
||||
if (map_idx == MPR_MAPTABLE_BAD_IDX) {
|
||||
map_idx = _mapping_get_high_missing_mt_idx(sc);
|
||||
if (map_idx != MPR_MAPTABLE_BAD_IDX) {
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
if (mt_entry->dev_handle) {
|
||||
_mapping_add_to_removal_table
|
||||
(sc, mt_entry->dev_handle,
|
||||
0);
|
||||
is_removed = 1;
|
||||
}
|
||||
mt_entry->init_complete = 0;
|
||||
}
|
||||
}
|
||||
if (map_idx != MPR_MAPTABLE_BAD_IDX) {
|
||||
mt_entry = &sc->mapping_table[map_idx];
|
||||
mt_entry->physical_id =
|
||||
port_change->physical_id;
|
||||
mt_entry->channel = 0;
|
||||
mt_entry->id = map_idx;
|
||||
mt_entry->dev_handle = port_change->dev_handle;
|
||||
mt_entry->missing_count = 0;
|
||||
mt_entry->device_info =
|
||||
port_change->device_info |
|
||||
(MPR_DEV_RESERVED | MPR_MAP_IN_USE);
|
||||
} else {
|
||||
port_change->is_processed = 1;
|
||||
if (!sc->mt_full_retry) {
|
||||
sc->mt_add_device_failed = 1;
|
||||
continue;
|
||||
}
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed to add "
|
||||
"the device with handle 0x%04x because "
|
||||
"there is no free space available in the "
|
||||
"mapping table\n", __func__,
|
||||
port_change->dev_handle);
|
||||
continue;
|
||||
}
|
||||
if (sc->is_dpm_enable) {
|
||||
if (mt_entry->dpm_entry_num !=
|
||||
MPR_DPM_BAD_IDX) {
|
||||
dpm_idx = mt_entry->dpm_entry_num;
|
||||
dpm_entry = (Mpi2DriverMap0Entry_t *)
|
||||
((u8 *)sc->dpm_pg0 + hdr_sz);
|
||||
dpm_entry += dpm_idx;
|
||||
missing_cnt = dpm_entry->
|
||||
MappingInformation &
|
||||
MPI2_DRVMAP0_MAPINFO_MISSING_MASK;
|
||||
temp64_var = dpm_entry->
|
||||
PhysicalIdentifier.High;
|
||||
temp64_var = (temp64_var << 32) |
|
||||
dpm_entry->PhysicalIdentifier.Low;
|
||||
if ((mt_entry->physical_id ==
|
||||
temp64_var) && !missing_cnt)
|
||||
mt_entry->init_complete = 1;
|
||||
} else {
|
||||
dpm_idx = _mapping_get_free_dpm_idx(sc);
|
||||
mt_entry->init_complete = 0;
|
||||
}
|
||||
if (dpm_idx != MPR_DPM_BAD_IDX &&
|
||||
!mt_entry->init_complete) {
|
||||
mt_entry->init_complete = 1;
|
||||
mt_entry->dpm_entry_num = dpm_idx;
|
||||
dpm_entry = (Mpi2DriverMap0Entry_t *)
|
||||
((u8 *)sc->dpm_pg0 + hdr_sz);
|
||||
dpm_entry += dpm_idx;
|
||||
dpm_entry->PhysicalIdentifier.Low =
|
||||
(0xFFFFFFFF &
|
||||
mt_entry->physical_id);
|
||||
dpm_entry->PhysicalIdentifier.High =
|
||||
(mt_entry->physical_id >> 32);
|
||||
dpm_entry->DeviceIndex = (U16) map_idx;
|
||||
dpm_entry->MappingInformation = 0;
|
||||
dpm_entry->PhysicalBitsMapping = 0;
|
||||
sc->dpm_entry_used[dpm_idx] = 1;
|
||||
sc->dpm_flush_entry[dpm_idx] = 1;
|
||||
port_change->is_processed = 1;
|
||||
} else if (dpm_idx == MPR_DPM_BAD_IDX) {
|
||||
port_change->is_processed = 1;
|
||||
mpr_dprint(sc, MPR_INFO, "%s: failed "
|
||||
"to add the device with handle "
|
||||
"0x%04x to persistent table "
|
||||
"because there is no free space "
|
||||
"available\n", __func__,
|
||||
port_change->dev_handle);
|
||||
}
|
||||
}
|
||||
mt_entry->init_complete = 1;
|
||||
}
|
||||
|
||||
port_change->is_processed = 1;
|
||||
}
|
||||
if (is_removed)
|
||||
_mapping_clear_removed_entries(sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_flush_dpm_pages -Flush the DPM pages to NVRAM
|
||||
* @sc: per adapter object
|
||||
@ -2072,6 +2463,56 @@ mpr_mapping_topology_change_event(struct mpr_softc *sc,
|
||||
sc->pending_map_events--;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpr_mapping_pcie_topology_change_event - handle PCIe topology change events
|
||||
* @sc: per adapter object
|
||||
* @event_data: event data payload
|
||||
*
|
||||
* Returns nothing.
|
||||
*/
|
||||
void
|
||||
mpr_mapping_pcie_topology_change_event(struct mpr_softc *sc,
|
||||
Mpi26EventDataPCIeTopologyChangeList_t *event_data)
|
||||
{
|
||||
struct _map_pcie_topology_change topo_change;
|
||||
struct _map_port_change *port_change;
|
||||
Mpi26EventPCIeTopoPortEntry_t *event_port_change;
|
||||
u8 i, num_entries;
|
||||
|
||||
topo_change.switch_dev_handle = le16toh(event_data->SwitchDevHandle);
|
||||
topo_change.enc_handle = le16toh(event_data->EnclosureHandle);
|
||||
num_entries = event_data->NumEntries;
|
||||
topo_change.num_entries = num_entries;
|
||||
topo_change.start_port_num = event_data->StartPortNum;
|
||||
topo_change.num_ports = event_data->NumPorts;
|
||||
topo_change.switch_status = event_data->SwitchStatus;
|
||||
event_port_change = event_data->PortEntry;
|
||||
topo_change.port_details = NULL;
|
||||
|
||||
if (!num_entries)
|
||||
goto out;
|
||||
port_change = malloc(sizeof(struct _map_port_change) * num_entries,
|
||||
M_MPR, M_NOWAIT|M_ZERO);
|
||||
topo_change.port_details = port_change;
|
||||
if (!port_change)
|
||||
goto out;
|
||||
for (i = 0; i < num_entries; i++, event_port_change++, port_change++) {
|
||||
port_change->dev_handle = le16toh(event_port_change->
|
||||
AttachedDevHandle);
|
||||
port_change->reason = event_port_change->PortStatus;
|
||||
}
|
||||
_mapping_update_pcie_missing_count(sc, &topo_change);
|
||||
_mapping_get_pcie_dev_info(sc, &topo_change);
|
||||
_mapping_clear_removed_entries(sc);
|
||||
_mapping_add_new_pcie_device(sc, &topo_change);
|
||||
|
||||
out:
|
||||
free(topo_change.port_details, M_MPR);
|
||||
_mapping_flush_dpm_pages(sc);
|
||||
if (sc->pending_map_events)
|
||||
sc->pending_map_events--;
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapping_check_update_ir_mt_idx - Check and update IR map table index
|
||||
* @sc: per adapter object
|
||||
|
@ -53,9 +53,36 @@ struct _map_phy_change {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct _map_topology_change - entries to be removed from mapping table
|
||||
* @dpm_entry_num: index of this device in device persistent map table
|
||||
* struct _map_port_change - PCIe Port entries received in PCIe Topology change
|
||||
* list event
|
||||
* @physical_id: WWID of the device attached to the associated port
|
||||
* @device_info: bitfield provides detailed info about the device
|
||||
* @MDTS: Maximum Data Transfer Size for the device
|
||||
* @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
|
||||
*/
|
||||
struct _map_port_change {
|
||||
uint64_t physical_id;
|
||||
uint32_t device_info;
|
||||
uint32_t MDTS;
|
||||
uint16_t dev_handle;
|
||||
uint16_t slot;
|
||||
uint8_t reason;
|
||||
uint8_t is_processed;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct _map_topology_change - SAS/SATA entries to be removed from mapping
|
||||
* table
|
||||
* @enc_handle: enclosure handle where this device is located
|
||||
* @exp_handle: expander handle where this device is located
|
||||
* @num_entries: number of entries in the SAS Topology Change List event
|
||||
* @start_phy_num: PHY number of the first PHY in the event data
|
||||
* @num_phys: number of PHYs in the expander where this device is located
|
||||
* @exp_status: status for the expander where this device is located
|
||||
* @phy_details: more details about each PHY in the event data
|
||||
*/
|
||||
struct _map_topology_change {
|
||||
uint16_t enc_handle;
|
||||
@ -67,6 +94,26 @@ struct _map_topology_change {
|
||||
struct _map_phy_change *phy_details;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct _map_pcie_topology_change - PCIe entries to be removed from mapping
|
||||
* table
|
||||
* @enc_handle: enclosure handle where this device is located
|
||||
* @switch_dev_handle: PCIe switch device handle where this device is located
|
||||
* @num_entries: number of entries in the PCIe Topology Change List event
|
||||
* @start_port_num: port number of the first port in the event data
|
||||
* @num_ports: number of ports in the PCIe switch device
|
||||
* @switch_status: status for the PCIe switch where this device is located
|
||||
* @port_details: more details about each Port in the event data
|
||||
*/
|
||||
struct _map_pcie_topology_change {
|
||||
uint16_t enc_handle;
|
||||
uint16_t switch_dev_handle;
|
||||
uint8_t num_entries;
|
||||
uint8_t start_port_num;
|
||||
uint8_t num_ports;
|
||||
uint8_t switch_status;
|
||||
struct _map_port_change *port_details;
|
||||
};
|
||||
|
||||
extern int
|
||||
mprsas_get_sas_address_for_sata_disk(struct mpr_softc *ioc,
|
||||
|
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/kthread.h>
|
||||
@ -110,6 +111,10 @@ struct mpr_ident {
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3216" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3224" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
|
||||
@ -118,10 +123,24 @@ struct mpr_ident {
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_2" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3216" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3224" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3408,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3408" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3416,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3416" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3508" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508_1,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3508_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3516" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516_1,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3516_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3616,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3616" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3708,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3708" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3716,
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3716" },
|
||||
{ 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
@ -164,7 +183,7 @@ mpr_pci_attach(device_t dev)
|
||||
{
|
||||
struct mpr_softc *sc;
|
||||
struct mpr_ident *m;
|
||||
int error;
|
||||
int error, i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
bzero(sc, sizeof(*sc));
|
||||
@ -175,13 +194,32 @@ mpr_pci_attach(device_t dev)
|
||||
/* Twiddle basic PCI config bits for a sanity check */
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
/* Allocate the System Interface Register Set */
|
||||
sc->mpr_regs_rid = PCIR_BAR(1);
|
||||
if ((sc->mpr_regs_resource = bus_alloc_resource_any(dev,
|
||||
SYS_RES_MEMORY, &sc->mpr_regs_rid, RF_ACTIVE)) == NULL) {
|
||||
/* Set flag if this is a Gen3.5 IOC */
|
||||
if ((m->device == MPI26_MFGPAGE_DEVID_SAS3508) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3508_1) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3408) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3516) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3516_1) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3416) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3716) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3616) ||
|
||||
(m->device == MPI26_MFGPAGE_DEVID_SAS3708)) {
|
||||
sc->mpr_flags |= MPR_FLAGS_GEN35_IOC;
|
||||
}
|
||||
|
||||
for (i = 0; i < PCI_MAXMAPS_0; i++) {
|
||||
sc->mpr_regs_rid = PCIR_BAR(i);
|
||||
|
||||
if ((sc->mpr_regs_resource = bus_alloc_resource_any(dev,
|
||||
SYS_RES_MEMORY, &sc->mpr_regs_rid, RF_ACTIVE)) != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc->mpr_regs_resource == NULL) {
|
||||
mpr_printf(sc, "Cannot allocate PCI registers\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
sc->mpr_btag = rman_get_bustag(sc->mpr_regs_resource);
|
||||
sc->mpr_bhandle = rman_get_bushandle(sc->mpr_regs_resource);
|
||||
|
||||
|
@ -72,10 +72,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <cam/scsi/smp_all.h>
|
||||
#endif
|
||||
|
||||
#include <dev/nvme/nvme.h>
|
||||
|
||||
#include <dev/mpr/mpi/mpi2_type.h>
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_sas.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
@ -477,13 +480,13 @@ mprsas_prepare_volume_remove(struct mprsas_softc *sassc, uint16_t handle)
|
||||
}
|
||||
|
||||
/*
|
||||
* The MPT3 firmware performs debounce on the link to avoid transient link
|
||||
* errors and false removals. When it does decide that link has been lost
|
||||
* and a device needs to go away, it expects that the host will perform a
|
||||
* target reset and then an op remove. The reset has the side-effect of
|
||||
* aborting any outstanding requests for the device, which is required for
|
||||
* the op-remove to succeed. It's not clear if the host should check for
|
||||
* the device coming back alive after the reset.
|
||||
* The firmware performs debounce on the link to avoid transient link errors
|
||||
* and false removals. When it does decide that link has been lost and a
|
||||
* device needs to go away, it expects that the host will perform a target reset
|
||||
* and then an op remove. The reset has the side-effect of aborting any
|
||||
* outstanding requests for the device, which is required for the op-remove to
|
||||
* succeed. It's not clear if the host should check for the device coming back
|
||||
* alive after the reset.
|
||||
*/
|
||||
void
|
||||
mprsas_prepare_remove(struct mprsas_softc *sassc, uint16_t handle)
|
||||
@ -705,7 +708,14 @@ mprsas_register_events(struct mpr_softc *sc)
|
||||
setbit(events, MPI2_EVENT_IR_PHYSICAL_DISK);
|
||||
setbit(events, MPI2_EVENT_IR_OPERATION_STATUS);
|
||||
setbit(events, MPI2_EVENT_TEMP_THRESHOLD);
|
||||
setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
|
||||
if (sc->facts->MsgVersion >= MPI2_VERSION_02_06) {
|
||||
setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
|
||||
if (sc->mpr_flags & MPR_FLAGS_GEN35_IOC) {
|
||||
setbit(events, MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
|
||||
setbit(events, MPI2_EVENT_PCIE_ENUMERATION);
|
||||
setbit(events, MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
mpr_register_events(sc, events, mprsas_evt_handler, NULL,
|
||||
&sc->sassc->mprsas_eh);
|
||||
@ -1018,6 +1028,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
|
||||
if ((sc->max_io_pages > 0) && (sc->max_io_pages * PAGE_SIZE <
|
||||
cpi->maxio))
|
||||
cpi->maxio = sc->max_io_pages * PAGE_SIZE;
|
||||
sc->maxio = cpi->maxio;
|
||||
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
|
||||
break;
|
||||
}
|
||||
@ -1636,7 +1647,7 @@ mprsas_scsiio_timeout(void *data)
|
||||
targ->timeouts++;
|
||||
|
||||
mprsas_log_command(cm, MPR_ERROR, "command timeout %d cm %p target "
|
||||
"%u, handle(0x%04x)\n", cm->cm_ccb->ccb_h.timeout, cm, targ->tid,
|
||||
"%u, handle(0x%04x)\n", cm->cm_ccb->ccb_h.timeout, cm, targ->tid,
|
||||
targ->handle);
|
||||
if (targ->encl_level_valid) {
|
||||
mpr_dprint(sc, MPR_ERROR, "At enclosure level %d, slot %d, "
|
||||
@ -1680,6 +1691,160 @@ mprsas_scsiio_timeout(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mprsas_build_nvme_unmap - Build Native NVMe DSM command equivalent
|
||||
* to SCSI Unmap.
|
||||
* Return 0 - for success,
|
||||
* 1 - to immediately return back the command with success status to CAM
|
||||
* negative value - to fallback to firmware path i.e. issue scsi unmap
|
||||
* to FW without any translation.
|
||||
*/
|
||||
static int
|
||||
mprsas_build_nvme_unmap(struct mpr_softc *sc, struct mpr_command *cm,
|
||||
union ccb *ccb, struct mprsas_target *targ)
|
||||
{
|
||||
Mpi26NVMeEncapsulatedRequest_t *req = NULL;
|
||||
struct ccb_scsiio *csio;
|
||||
struct unmap_parm_list *plist;
|
||||
struct nvme_dsm_range *nvme_dsm_ranges = NULL;
|
||||
struct nvme_command *c;
|
||||
int i, res;
|
||||
uint16_t ndesc, list_len, data_length;
|
||||
struct mpr_prp_page *prp_page_info;
|
||||
uint64_t nvme_dsm_ranges_dma_handle;
|
||||
|
||||
csio = &ccb->csio;
|
||||
#if __FreeBSD_version >= 1100103
|
||||
list_len = (scsiio_cdb_ptr(csio)[7] << 8 | scsiio_cdb_ptr(csio)[8]);
|
||||
#else
|
||||
if (csio->ccb_h.flags & CAM_CDB_POINTER) {
|
||||
list_len = (ccb->csio.cdb_io.cdb_ptr[7] << 8 |
|
||||
ccb->csio.cdb_io.cdb_ptr[8]);
|
||||
} else {
|
||||
list_len = (ccb->csio.cdb_io.cdb_bytes[7] << 8 |
|
||||
ccb->csio.cdb_io.cdb_bytes[8]);
|
||||
}
|
||||
#endif
|
||||
if (!list_len) {
|
||||
mpr_dprint(sc, MPR_ERROR, "Parameter list length is Zero\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
plist = malloc(csio->dxfer_len, M_MPR, M_ZERO|M_NOWAIT);
|
||||
if (!plist) {
|
||||
mpr_dprint(sc, MPR_ERROR, "Unable to allocate memory to "
|
||||
"save UNMAP data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Copy SCSI unmap data to a local buffer */
|
||||
bcopy(csio->data_ptr, plist, csio->dxfer_len);
|
||||
|
||||
/* return back the unmap command to CAM with success status,
|
||||
* if number of descripts is zero.
|
||||
*/
|
||||
ndesc = be16toh(plist->unmap_blk_desc_data_len) >> 4;
|
||||
if (!ndesc) {
|
||||
mpr_dprint(sc, MPR_XINFO, "Number of descriptors in "
|
||||
"UNMAP cmd is Zero\n");
|
||||
res = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data_length = ndesc * sizeof(struct nvme_dsm_range);
|
||||
if (data_length > targ->MDTS) {
|
||||
mpr_dprint(sc, MPR_ERROR, "data length: %d is greater than "
|
||||
"Device's MDTS: %d\n", data_length, targ->MDTS);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
prp_page_info = mpr_alloc_prp_page(sc);
|
||||
KASSERT(prp_page_info != NULL, ("%s: There is no PRP Page for "
|
||||
"UNMAP command.\n", __func__));
|
||||
|
||||
/*
|
||||
* Insert the allocated PRP page into the command's PRP page list. This
|
||||
* will be freed when the command is freed.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&cm->cm_prp_page_list, prp_page_info, prp_page_link);
|
||||
|
||||
nvme_dsm_ranges = (struct nvme_dsm_range *)prp_page_info->prp_page;
|
||||
nvme_dsm_ranges_dma_handle = prp_page_info->prp_page_busaddr;
|
||||
|
||||
bzero(nvme_dsm_ranges, data_length);
|
||||
|
||||
/* Convert SCSI unmap's descriptor data to NVMe DSM specific Range data
|
||||
* for each descriptors contained in SCSI UNMAP data.
|
||||
*/
|
||||
for (i = 0; i < ndesc; i++) {
|
||||
nvme_dsm_ranges[i].length =
|
||||
htole32(be32toh(plist->desc[i].nlb));
|
||||
nvme_dsm_ranges[i].starting_lba =
|
||||
htole64(be64toh(plist->desc[i].slba));
|
||||
nvme_dsm_ranges[i].attributes = 0;
|
||||
}
|
||||
|
||||
/* Build MPI2.6's NVMe Encapsulated Request Message */
|
||||
req = (Mpi26NVMeEncapsulatedRequest_t *)cm->cm_req;
|
||||
bzero(req, sizeof(*req));
|
||||
req->DevHandle = htole16(targ->handle);
|
||||
req->Function = MPI2_FUNCTION_NVME_ENCAPSULATED;
|
||||
req->Flags = MPI26_NVME_FLAGS_WRITE;
|
||||
req->ErrorResponseBaseAddress.High =
|
||||
htole32((uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32));
|
||||
req->ErrorResponseBaseAddress.Low =
|
||||
htole32(cm->cm_sense_busaddr);
|
||||
req->ErrorResponseAllocationLength =
|
||||
htole16(sizeof(struct nvme_completion));
|
||||
req->EncapsulatedCommandLength =
|
||||
htole16(sizeof(struct nvme_command));
|
||||
req->DataLength = htole32(data_length);
|
||||
|
||||
/* Build NVMe DSM command */
|
||||
c = (struct nvme_command *) req->NVMe_Command;
|
||||
c->opc = NVME_OPC_DATASET_MANAGEMENT;
|
||||
c->nsid = htole32(csio->ccb_h.target_lun + 1);
|
||||
c->cdw10 = htole32(ndesc - 1);
|
||||
c->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE);
|
||||
|
||||
cm->cm_length = data_length;
|
||||
cm->cm_data = NULL;
|
||||
|
||||
cm->cm_complete = mprsas_scsiio_complete;
|
||||
cm->cm_complete_data = ccb;
|
||||
cm->cm_targ = targ;
|
||||
cm->cm_lun = csio->ccb_h.target_lun;
|
||||
cm->cm_ccb = ccb;
|
||||
|
||||
cm->cm_desc.Default.RequestFlags =
|
||||
MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
|
||||
|
||||
#if __FreeBSD_version >= 1000029
|
||||
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
|
||||
mprsas_scsiio_timeout, cm, 0);
|
||||
#else //__FreeBSD_version < 1000029
|
||||
callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
|
||||
mprsas_scsiio_timeout, cm);
|
||||
#endif //__FreeBSD_version >= 1000029
|
||||
|
||||
targ->issued++;
|
||||
targ->outstanding++;
|
||||
TAILQ_INSERT_TAIL(&targ->commands, cm, cm_link);
|
||||
ccb->ccb_h.status |= CAM_SIM_QUEUED;
|
||||
|
||||
mprsas_log_command(cm, MPR_XINFO, "%s cm %p ccb %p outstanding %u\n",
|
||||
__func__, cm, ccb, targ->outstanding);
|
||||
|
||||
mpr_build_nvme_prp(sc, cm, req, (void *)nvme_dsm_ranges_dma_handle, 0,
|
||||
data_length);
|
||||
mpr_map_command(sc, cm);
|
||||
|
||||
out:
|
||||
free(plist, M_MPR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
{
|
||||
@ -1689,9 +1854,10 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
struct mprsas_target *targ;
|
||||
struct mprsas_lun *lun;
|
||||
struct mpr_command *cm;
|
||||
uint8_t i, lba_byte, *ref_tag_addr;
|
||||
uint8_t i, lba_byte, *ref_tag_addr, scsi_opcode;
|
||||
uint16_t eedp_flags;
|
||||
uint32_t mpi_control;
|
||||
int rc;
|
||||
|
||||
sc = sassc->sc;
|
||||
MPR_FUNCTRACE(sc);
|
||||
@ -1777,6 +1943,30 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
return;
|
||||
}
|
||||
|
||||
/* For NVME device's issue UNMAP command directly to NVME drives by
|
||||
* constructing equivalent native NVMe DataSetManagement command.
|
||||
*/
|
||||
#if __FreeBSD_version >= 1100103
|
||||
scsi_opcode = scsiio_cdb_ptr(csio)[0];
|
||||
#else
|
||||
if (csio->ccb_h.flags & CAM_CDB_POINTER)
|
||||
scsi_opcode = csio->cdb_io.cdb_ptr[0];
|
||||
else
|
||||
scsi_opcode = csio->cdb_io.cdb_bytes[0];
|
||||
#endif
|
||||
if (scsi_opcode == UNMAP &&
|
||||
targ->is_nvme &&
|
||||
(csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) {
|
||||
rc = mprsas_build_nvme_unmap(sc, cm, ccb, targ);
|
||||
if (rc == 1) { /* return command to CAM with success status */
|
||||
mpr_free_command(sc, cm);
|
||||
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
} else if (!rc) /* Issued NVMe Encapsulated Request Message */
|
||||
return;
|
||||
}
|
||||
|
||||
req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
|
||||
bzero(req, sizeof(*req));
|
||||
req->DevHandle = htole16(targ->handle);
|
||||
@ -1849,8 +2039,8 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len);
|
||||
else {
|
||||
KASSERT(csio->cdb_len <= IOCDBLEN,
|
||||
("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER is not set",
|
||||
csio->cdb_len));
|
||||
("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER "
|
||||
"is not set", csio->cdb_len));
|
||||
bcopy(csio->cdb_io.cdb_bytes, &req->CDB.CDB32[0],csio->cdb_len);
|
||||
}
|
||||
req->IoFlags = htole16(csio->cdb_len);
|
||||
@ -1874,6 +2064,10 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
eedp_flags |= (MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
|
||||
MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
|
||||
MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD);
|
||||
if (sc->mpr_flags & MPR_FLAGS_GEN35_IOC) {
|
||||
eedp_flags |=
|
||||
MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE;
|
||||
}
|
||||
req->EEDPFlags = htole16(eedp_flags);
|
||||
|
||||
/*
|
||||
@ -1933,11 +2127,15 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
|
||||
req->IoFlags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH;
|
||||
cm->cm_desc.FastPathSCSIIO.RequestFlags =
|
||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
|
||||
cm->cm_desc.FastPathSCSIIO.DevHandle = htole16(targ->handle);
|
||||
if (!sc->atomic_desc_capable) {
|
||||
cm->cm_desc.FastPathSCSIIO.DevHandle =
|
||||
htole16(targ->handle);
|
||||
}
|
||||
} else {
|
||||
cm->cm_desc.SCSIIO.RequestFlags =
|
||||
MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
|
||||
cm->cm_desc.SCSIIO.DevHandle = htole16(targ->handle);
|
||||
if (!sc->atomic_desc_capable)
|
||||
cm->cm_desc.SCSIIO.DevHandle = htole16(targ->handle);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 1000029
|
||||
@ -2160,6 +2358,200 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio,
|
||||
}
|
||||
}
|
||||
|
||||
/** mprsas_nvme_trans_status_code
|
||||
*
|
||||
* Convert Native NVMe command error status to
|
||||
* equivalent SCSI error status.
|
||||
*
|
||||
* Returns appropriate scsi_status
|
||||
*/
|
||||
static u8
|
||||
mprsas_nvme_trans_status_code(struct nvme_status nvme_status,
|
||||
struct mpr_command *cm)
|
||||
{
|
||||
u8 status = MPI2_SCSI_STATUS_GOOD;
|
||||
int skey, asc, ascq;
|
||||
union ccb *ccb = cm->cm_complete_data;
|
||||
int returned_sense_len;
|
||||
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_NO_SENSE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
|
||||
switch (nvme_status.sct) {
|
||||
case NVME_SCT_GENERIC:
|
||||
switch (nvme_status.sc) {
|
||||
case NVME_SC_SUCCESS:
|
||||
status = MPI2_SCSI_STATUS_GOOD;
|
||||
skey = SSD_KEY_NO_SENSE;
|
||||
asc = SCSI_ASC_NO_SENSE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_INVALID_OPCODE:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_ILLEGAL_COMMAND;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_INVALID_FIELD:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_INVALID_CDB;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_DATA_TRANSFER_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_NO_SENSE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_ABORTED_POWER_LOSS:
|
||||
status = MPI2_SCSI_STATUS_TASK_ABORTED;
|
||||
skey = SSD_KEY_ABORTED_COMMAND;
|
||||
asc = SCSI_ASC_WARNING;
|
||||
ascq = SCSI_ASCQ_POWER_LOSS_EXPECTED;
|
||||
break;
|
||||
case NVME_SC_INTERNAL_DEVICE_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_HARDWARE_ERROR;
|
||||
asc = SCSI_ASC_INTERNAL_TARGET_FAILURE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_ABORTED_BY_REQUEST:
|
||||
case NVME_SC_ABORTED_SQ_DELETION:
|
||||
case NVME_SC_ABORTED_FAILED_FUSED:
|
||||
case NVME_SC_ABORTED_MISSING_FUSED:
|
||||
status = MPI2_SCSI_STATUS_TASK_ABORTED;
|
||||
skey = SSD_KEY_ABORTED_COMMAND;
|
||||
asc = SCSI_ASC_NO_SENSE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_INVALID_NAMESPACE_OR_FORMAT:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_ACCESS_DENIED_INVALID_LUN_ID;
|
||||
ascq = SCSI_ASCQ_INVALID_LUN_ID;
|
||||
break;
|
||||
case NVME_SC_LBA_OUT_OF_RANGE:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_ILLEGAL_BLOCK;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_CAPACITY_EXCEEDED:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_NO_SENSE;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_NAMESPACE_NOT_READY:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_NOT_READY;
|
||||
asc = SCSI_ASC_LUN_NOT_READY;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NVME_SCT_COMMAND_SPECIFIC:
|
||||
switch (nvme_status.sc) {
|
||||
case NVME_SC_INVALID_FORMAT:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_FORMAT_COMMAND_FAILED;
|
||||
ascq = SCSI_ASCQ_FORMAT_COMMAND_FAILED;
|
||||
break;
|
||||
case NVME_SC_CONFLICTING_ATTRIBUTES:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_INVALID_CDB;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NVME_SCT_MEDIA_ERROR:
|
||||
switch (nvme_status.sc) {
|
||||
case NVME_SC_WRITE_FAULTS:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_PERIPHERAL_DEV_WRITE_FAULT;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_UNRECOVERED_READ_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_UNRECOVERED_READ_ERROR;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_GUARD_CHECK_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_LOG_BLOCK_GUARD_CHECK_FAILED;
|
||||
ascq = SCSI_ASCQ_LOG_BLOCK_GUARD_CHECK_FAILED;
|
||||
break;
|
||||
case NVME_SC_APPLICATION_TAG_CHECK_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_LOG_BLOCK_APPTAG_CHECK_FAILED;
|
||||
ascq = SCSI_ASCQ_LOG_BLOCK_APPTAG_CHECK_FAILED;
|
||||
break;
|
||||
case NVME_SC_REFERENCE_TAG_CHECK_ERROR:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MEDIUM_ERROR;
|
||||
asc = SCSI_ASC_LOG_BLOCK_REFTAG_CHECK_FAILED;
|
||||
ascq = SCSI_ASCQ_LOG_BLOCK_REFTAG_CHECK_FAILED;
|
||||
break;
|
||||
case NVME_SC_COMPARE_FAILURE:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_MISCOMPARE;
|
||||
asc = SCSI_ASC_MISCOMPARE_DURING_VERIFY;
|
||||
ascq = SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
case NVME_SC_ACCESS_DENIED:
|
||||
status = MPI2_SCSI_STATUS_CHECK_CONDITION;
|
||||
skey = SSD_KEY_ILLEGAL_REQUEST;
|
||||
asc = SCSI_ASC_ACCESS_DENIED_INVALID_LUN_ID;
|
||||
ascq = SCSI_ASCQ_INVALID_LUN_ID;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
returned_sense_len = sizeof(struct scsi_sense_data);
|
||||
if (returned_sense_len < ccb->csio.sense_len)
|
||||
ccb->csio.sense_resid = ccb->csio.sense_len -
|
||||
returned_sense_len;
|
||||
else
|
||||
ccb->csio.sense_resid = 0;
|
||||
|
||||
scsi_set_sense_data(&ccb->csio.sense_data, SSD_TYPE_FIXED,
|
||||
1, skey, asc, ascq, SSD_ELEM_NONE);
|
||||
ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/** mprsas_complete_nvme_unmap
|
||||
*
|
||||
* Complete native NVMe command issued using NVMe Encapsulated
|
||||
* Request Message.
|
||||
*/
|
||||
static u8
|
||||
mprsas_complete_nvme_unmap(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
{
|
||||
Mpi26NVMeEncapsulatedErrorReply_t *mpi_reply;
|
||||
struct nvme_completion *nvme_completion = NULL;
|
||||
u8 scsi_status = MPI2_SCSI_STATUS_GOOD;
|
||||
|
||||
mpi_reply =(Mpi26NVMeEncapsulatedErrorReply_t *)cm->cm_reply;
|
||||
if (le16toh(mpi_reply->ErrorResponseCount)){
|
||||
nvme_completion = (struct nvme_completion *)cm->cm_sense;
|
||||
scsi_status = mprsas_nvme_trans_status_code(
|
||||
nvme_completion->status, cm);
|
||||
}
|
||||
return scsi_status;
|
||||
}
|
||||
|
||||
static void
|
||||
mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
{
|
||||
@ -2168,7 +2560,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
struct ccb_scsiio *csio;
|
||||
struct mprsas_softc *sassc;
|
||||
struct scsi_vpd_supported_page_list *vpd_list = NULL;
|
||||
u8 *TLR_bits, TLR_on;
|
||||
u8 *TLR_bits, TLR_on, *scsi_cdb;
|
||||
int dir = 0, i;
|
||||
u16 alloc_len;
|
||||
struct mprsas_target *target;
|
||||
@ -2266,6 +2658,20 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Point to the SCSI CDB, which is dependent on the CAM_CDB_POINTER
|
||||
* flag, and use it in a few places in the rest of this function for
|
||||
* convenience. Use the macro if available.
|
||||
*/
|
||||
#if __FreeBSD_version >= 1100103
|
||||
scsi_cdb = scsiio_cdb_ptr(csio);
|
||||
#else
|
||||
if (csio->ccb_h.flags & CAM_CDB_POINTER)
|
||||
scsi_cdb = csio->cdb_io.cdb_ptr;
|
||||
else
|
||||
scsi_cdb = csio->cdb_io.cdb_bytes;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this is a Start Stop Unit command and it was issued by the driver
|
||||
* during shutdown, decrement the refcount to account for all of the
|
||||
@ -2273,7 +2679,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
* shutdown completes, meaning SSU_refcount will be 0 after SSU_started
|
||||
* is TRUE.
|
||||
*/
|
||||
if (sc->SSU_started && (csio->cdb_io.cdb_bytes[0] == START_STOP_UNIT)) {
|
||||
if (sc->SSU_started && (scsi_cdb[0] == START_STOP_UNIT)) {
|
||||
mpr_dprint(sc, MPR_INFO, "Decrementing SSU count.\n");
|
||||
sc->SSU_refcount--;
|
||||
}
|
||||
@ -2314,6 +2720,14 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
return;
|
||||
}
|
||||
|
||||
target = &sassc->targets[target_id];
|
||||
if (scsi_cdb[0] == UNMAP &&
|
||||
target->is_nvme &&
|
||||
(csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) {
|
||||
rep->SCSIStatus = mprsas_complete_nvme_unmap(sc, cm);
|
||||
csio->scsi_status = rep->SCSIStatus;
|
||||
}
|
||||
|
||||
mprsas_log_command(cm, MPR_XINFO,
|
||||
"ioc %x scsi %x state %x xfer %u\n",
|
||||
le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState,
|
||||
@ -2325,7 +2739,6 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
/* FALLTHROUGH */
|
||||
case MPI2_IOCSTATUS_SUCCESS:
|
||||
case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
|
||||
|
||||
if ((le16toh(rep->IOCStatus) & MPI2_IOCSTATUS_MASK) ==
|
||||
MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR)
|
||||
mprsas_log_command(cm, MPR_XINFO, "recovered error\n");
|
||||
@ -2403,9 +2816,9 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
* controller, turn the TLR_bits value ON if page 0x90 is
|
||||
* supported.
|
||||
*/
|
||||
if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) &&
|
||||
(csio->cdb_io.cdb_bytes[1] & SI_EVPD) &&
|
||||
(csio->cdb_io.cdb_bytes[2] == SVPD_SUPPORTED_PAGE_LIST) &&
|
||||
if ((scsi_cdb[0] == INQUIRY) &&
|
||||
(scsi_cdb[1] & SI_EVPD) &&
|
||||
(scsi_cdb[2] == SVPD_SUPPORTED_PAGE_LIST) &&
|
||||
((csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) &&
|
||||
(csio->data_ptr != NULL) &&
|
||||
((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) &&
|
||||
@ -2417,8 +2830,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
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) +
|
||||
csio->cdb_io.cdb_bytes[4];
|
||||
alloc_len = ((u16)scsi_cdb[3] << 8) + scsi_cdb[4];
|
||||
alloc_len -= csio->resid;
|
||||
for (i = 0; i < MIN(vpd_list->length, alloc_len); i++) {
|
||||
if (vpd_list->list[i] == 0x90) {
|
||||
@ -2433,7 +2845,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
* a SCSI StartStopUnit command will be sent to it when the
|
||||
* driver is being shutdown.
|
||||
*/
|
||||
if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) &&
|
||||
if ((scsi_cdb[0] == INQUIRY) &&
|
||||
(csio->data_ptr != NULL) &&
|
||||
((csio->data_ptr[0] & 0x1f) == T_DIRECT) &&
|
||||
(sc->mapping_table[target_id].device_info &
|
||||
@ -2524,7 +2936,14 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
rep->SCSIStatus, rep->SCSIState,
|
||||
le32toh(rep->TransferCount));
|
||||
csio->resid = cm->cm_length;
|
||||
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
|
||||
|
||||
if (scsi_cdb[0] == UNMAP &&
|
||||
target->is_nvme &&
|
||||
(csio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR)
|
||||
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
|
||||
else
|
||||
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,8 @@ struct mprsas_target {
|
||||
uint8_t scsi_req_desc_type;
|
||||
uint8_t stop_at_shutdown;
|
||||
uint8_t supports_SSU;
|
||||
uint8_t is_nvme;
|
||||
uint32_t MDTS;
|
||||
};
|
||||
|
||||
struct mprsas_softc {
|
||||
|
@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
#include <dev/mpr/mpi/mpi2_ioc.h>
|
||||
#include <dev/mpr/mpi/mpi2_sas.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_raid.h>
|
||||
@ -116,6 +117,8 @@ static void mprsas_fw_work(struct mpr_softc *sc,
|
||||
static void mprsas_fw_event_free(struct mpr_softc *,
|
||||
struct mpr_fw_event_work *);
|
||||
static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate);
|
||||
static int mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle,
|
||||
u8 linkrate);
|
||||
static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
|
||||
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz,
|
||||
u32 devinfo);
|
||||
@ -156,6 +159,7 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
|
||||
bcopy(event->EventData, fw_event->event_data, sz);
|
||||
fw_event->event = event->Event;
|
||||
if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
|
||||
event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
|
||||
event->Event == MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE ||
|
||||
event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
|
||||
sc->track_mapping_events)
|
||||
@ -167,13 +171,13 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
|
||||
* events are processed.
|
||||
*/
|
||||
if ((event->Event == MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
|
||||
event->Event == MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
|
||||
event->Event == MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST) &&
|
||||
sc->wait_for_port_enable)
|
||||
mprsas_startup_increment(sc->sassc);
|
||||
|
||||
TAILQ_INSERT_TAIL(&sc->sassc->ev_queue, fw_event, ev_link);
|
||||
taskqueue_enqueue(sc->sassc->ev_tq, &sc->sassc->ev_task);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -205,7 +209,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
|
||||
{
|
||||
MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
|
||||
MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
|
||||
int i;
|
||||
uint8_t i;
|
||||
|
||||
data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
|
||||
fw_event->event_data;
|
||||
@ -674,6 +678,60 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
|
||||
{
|
||||
MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *data;
|
||||
MPI26_EVENT_PCIE_TOPO_PORT_ENTRY *port_entry;
|
||||
uint8_t i, link_rate;
|
||||
uint16_t handle;
|
||||
|
||||
data = (MPI26_EVENT_DATA_PCIE_TOPOLOGY_CHANGE_LIST *)
|
||||
fw_event->event_data;
|
||||
|
||||
mpr_mapping_pcie_topology_change_event(sc,
|
||||
fw_event->event_data);
|
||||
|
||||
for (i = 0; i < data->NumEntries; i++) {
|
||||
port_entry = &data->PortEntry[i];
|
||||
handle = le16toh(port_entry->AttachedDevHandle);
|
||||
link_rate = port_entry->CurrentPortInfo &
|
||||
MPI26_EVENT_PCIE_TOPO_PI_RATE_MASK;
|
||||
switch (port_entry->PortStatus) {
|
||||
case MPI26_EVENT_PCIE_TOPO_PS_DEV_ADDED:
|
||||
if (link_rate <
|
||||
MPI26_EVENT_PCIE_TOPO_PI_RATE_2_5) {
|
||||
mpr_dprint(sc, MPR_ERROR, "%s: Cannot "
|
||||
"add PCIe device with handle 0x%x "
|
||||
"with unknown link rate.\n",
|
||||
__func__, handle);
|
||||
break;
|
||||
}
|
||||
if (mprsas_add_pcie_device(sc, handle,
|
||||
link_rate)) {
|
||||
mpr_dprint(sc, MPR_ERROR, "%s: failed "
|
||||
"to add PCIe device with handle "
|
||||
"0x%x\n", __func__, handle);
|
||||
mprsas_prepare_remove(sassc, handle);
|
||||
}
|
||||
break;
|
||||
case MPI26_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:
|
||||
mprsas_prepare_remove(sassc, handle);
|
||||
break;
|
||||
case MPI26_EVENT_PCIE_TOPO_PS_PORT_CHANGED:
|
||||
case MPI26_EVENT_PCIE_TOPO_PS_NO_CHANGE:
|
||||
case MPI26_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* refcount was incremented for this event in
|
||||
* mprsas_evt_handler. Decrement it here because the event has
|
||||
* been processed.
|
||||
*/
|
||||
mprsas_startup_decrement(sassc);
|
||||
break;
|
||||
}
|
||||
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
||||
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
|
||||
default:
|
||||
@ -703,7 +761,8 @@ mprsas_firmware_event_work(void *arg, int pending)
|
||||
}
|
||||
|
||||
static int
|
||||
mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
||||
mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
|
||||
{
|
||||
char devstring[80];
|
||||
struct mprsas_softc *sassc;
|
||||
struct mprsas_target *targ;
|
||||
@ -779,8 +838,8 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
||||
if (sc->use_phynum != -1)
|
||||
id = mpr_mapping_get_sas_id(sc, sas_address, handle);
|
||||
if (id == MPR_MAP_BAD_ID) {
|
||||
if ((sc->use_phynum == 0)
|
||||
|| ((id = config_page.PhyNum) > sassc->maxtargets)) {
|
||||
if ((sc->use_phynum == 0) ||
|
||||
((id = config_page.PhyNum) > sassc->maxtargets)) {
|
||||
mpr_dprint(sc, MPR_INFO, "failure at %s:%d/%s()! "
|
||||
"Could not get ID for device with handle 0x%04x\n",
|
||||
__FILE__, __LINE__, __func__, handle);
|
||||
@ -827,8 +886,10 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
|
||||
if (is_SATA_SSD) {
|
||||
targ->flags = MPR_TARGET_IS_SATA_SSD;
|
||||
}
|
||||
if (le16toh(config_page.Flags) &
|
||||
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) {
|
||||
if ((le16toh(config_page.Flags) &
|
||||
MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) &&
|
||||
(le16toh(config_page.Flags) &
|
||||
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE)) {
|
||||
targ->scsi_req_desc_type =
|
||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
|
||||
}
|
||||
@ -1139,6 +1200,141 @@ mprsas_ata_id_timeout(void *data)
|
||||
wakeup(cm);
|
||||
}
|
||||
|
||||
static int
|
||||
mprsas_add_pcie_device(struct mpr_softc *sc, u16 handle, u8 linkrate)
|
||||
{
|
||||
char devstring[80];
|
||||
struct mprsas_softc *sassc;
|
||||
struct mprsas_target *targ;
|
||||
Mpi2ConfigReply_t mpi_reply;
|
||||
Mpi26PCIeDevicePage0_t config_page;
|
||||
Mpi26PCIeDevicePage2_t config_page2;
|
||||
uint64_t pcie_wwid, parent_wwid = 0;
|
||||
u32 device_info, parent_devinfo = 0;
|
||||
unsigned int id;
|
||||
int error = 0;
|
||||
struct mprsas_lun *lun;
|
||||
|
||||
sassc = sc->sassc;
|
||||
mprsas_startup_increment(sassc);
|
||||
if ((mpr_config_get_pcie_device_pg0(sc, &mpi_reply, &config_page,
|
||||
MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) {
|
||||
printf("%s: error reading PCIe device page0\n", __func__);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
device_info = le32toh(config_page.DeviceInfo);
|
||||
|
||||
if (((device_info & MPI26_PCIE_DEVINFO_PCI_SWITCH) == 0)
|
||||
&& (le16toh(config_page.ParentDevHandle) != 0)) {
|
||||
Mpi2ConfigReply_t tmp_mpi_reply;
|
||||
Mpi26PCIeDevicePage0_t parent_config_page;
|
||||
|
||||
if ((mpr_config_get_pcie_device_pg0(sc, &tmp_mpi_reply,
|
||||
&parent_config_page, MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE,
|
||||
le16toh(config_page.ParentDevHandle)))) {
|
||||
printf("%s: error reading PCIe device %#x page0\n",
|
||||
__func__, le16toh(config_page.ParentDevHandle));
|
||||
} else {
|
||||
parent_wwid = parent_config_page.WWID.High;
|
||||
parent_wwid = (parent_wwid << 32) |
|
||||
parent_config_page.WWID.Low;
|
||||
parent_devinfo = le32toh(parent_config_page.DeviceInfo);
|
||||
}
|
||||
}
|
||||
/* TODO Check proper endianness */
|
||||
pcie_wwid = config_page.WWID.High;
|
||||
pcie_wwid = (pcie_wwid << 32) | config_page.WWID.Low;
|
||||
mpr_dprint(sc, MPR_INFO, "PCIe WWID from PCIe device page0 = %jx\n",
|
||||
pcie_wwid);
|
||||
|
||||
if ((mpr_config_get_pcie_device_pg2(sc, &mpi_reply, &config_page2,
|
||||
MPI26_PCIE_DEVICE_PGAD_FORM_HANDLE, handle))) {
|
||||
printf("%s: error reading PCIe device page2\n", __func__);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
id = mpr_mapping_get_sas_id(sc, pcie_wwid, handle);
|
||||
if (id == MPR_MAP_BAD_ID) {
|
||||
printf("failure at %s:%d/%s()! Could not get ID for device "
|
||||
"with handle 0x%04x\n", __FILE__, __LINE__, __func__,
|
||||
handle);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mprsas_check_id(sassc, id) != 0) {
|
||||
device_printf(sc->mpr_dev, "Excluding target id %d\n", id);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mpr_dprint(sc, MPR_MAPPING, "WWID from PCIe device page0 = %jx\n",
|
||||
pcie_wwid);
|
||||
targ = &sassc->targets[id];
|
||||
targ->devinfo = device_info;
|
||||
targ->encl_handle = le16toh(config_page.EnclosureHandle);
|
||||
targ->encl_slot = le16toh(config_page.Slot);
|
||||
targ->encl_level = config_page.EnclosureLevel;
|
||||
targ->connector_name[0] = ((char *)&config_page.ConnectorName)[0];
|
||||
targ->connector_name[1] = ((char *)&config_page.ConnectorName)[1];
|
||||
targ->connector_name[2] = ((char *)&config_page.ConnectorName)[2];
|
||||
targ->connector_name[3] = ((char *)&config_page.ConnectorName)[3];
|
||||
targ->is_nvme = device_info & MPI26_PCIE_DEVINFO_NVME;
|
||||
targ->MDTS = config_page2.MaximumDataTransferSize;
|
||||
/*
|
||||
* Assume always TRUE for encl_level_valid because there is no valid
|
||||
* flag for PCIe.
|
||||
*/
|
||||
targ->encl_level_valid = TRUE;
|
||||
targ->handle = handle;
|
||||
targ->parent_handle = le16toh(config_page.ParentDevHandle);
|
||||
targ->sasaddr = mpr_to_u64(&config_page.WWID);
|
||||
targ->parent_sasaddr = le64toh(parent_wwid);
|
||||
targ->parent_devinfo = parent_devinfo;
|
||||
targ->tid = id;
|
||||
targ->linkrate = linkrate;
|
||||
targ->flags = 0;
|
||||
if ((le16toh(config_page.Flags) &
|
||||
MPI26_PCIEDEV0_FLAGS_ENABLED_FAST_PATH) &&
|
||||
(le16toh(config_page.Flags) &
|
||||
MPI26_PCIEDEV0_FLAGS_FAST_PATH_CAPABLE)) {
|
||||
targ->scsi_req_desc_type =
|
||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
|
||||
}
|
||||
TAILQ_INIT(&targ->commands);
|
||||
TAILQ_INIT(&targ->timedout_commands);
|
||||
while (!SLIST_EMPTY(&targ->luns)) {
|
||||
lun = SLIST_FIRST(&targ->luns);
|
||||
SLIST_REMOVE_HEAD(&targ->luns, lun_link);
|
||||
free(lun, M_MPR);
|
||||
}
|
||||
SLIST_INIT(&targ->luns);
|
||||
|
||||
mpr_describe_devinfo(targ->devinfo, devstring, 80);
|
||||
mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found PCIe device <%s> <%s> "
|
||||
"handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring,
|
||||
mpr_describe_table(mpr_pcie_linkrate_names, targ->linkrate),
|
||||
targ->handle, targ->encl_handle, targ->encl_slot);
|
||||
if (targ->encl_level_valid) {
|
||||
mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d "
|
||||
"and connector name (%4s)\n", targ->encl_level,
|
||||
targ->connector_name);
|
||||
}
|
||||
#if ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000039)) || \
|
||||
(__FreeBSD_version < 902502)
|
||||
if ((sassc->flags & MPRSAS_IN_STARTUP) == 0)
|
||||
#endif
|
||||
mprsas_rescan_target(sc, targ);
|
||||
mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid);
|
||||
|
||||
out:
|
||||
mprsas_startup_decrement(sassc);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
mprsas_volume_add(struct mpr_softc *sc, u16 handle)
|
||||
{
|
||||
@ -1235,8 +1431,8 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
|
||||
if (target->stop_at_shutdown) {
|
||||
ccb = xpt_alloc_ccb_nowait();
|
||||
if (ccb == NULL) {
|
||||
mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop "
|
||||
"unit.\n");
|
||||
mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB "
|
||||
"to stop unit.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpr_ioctl.h>
|
||||
#include <dev/mpr/mprvar.h>
|
||||
#include <dev/mpr/mpr_table.h>
|
||||
@ -74,6 +75,7 @@ mpr_describe_table(struct mpr_table_lookup *table, u_int code)
|
||||
return(table[i+1].string);
|
||||
}
|
||||
|
||||
//SLM-Add new PCIe info to all of these tables
|
||||
struct mpr_table_lookup mpr_event_names[] = {
|
||||
{"LogData", 0x01},
|
||||
{"StateChange", 0x02},
|
||||
@ -100,6 +102,10 @@ struct mpr_table_lookup mpr_event_names[] = {
|
||||
{"TempThreshold", 0x27},
|
||||
{"HostMessage", 0x28},
|
||||
{"PowerPerformanceChange", 0x29},
|
||||
{"PCIeDeviceStatusChange", 0x30},
|
||||
{"PCIeEnumeration", 0x31},
|
||||
{"PCIeTopologyChangeList", 0x32},
|
||||
{"PCIeLinkCounter", 0x33},
|
||||
{"CableEvent", 0x34},
|
||||
{NULL, 0},
|
||||
{"Unknown Event", 0}
|
||||
@ -192,6 +198,16 @@ struct mpr_table_lookup mpr_sasdev_reason[] = {
|
||||
{"Unknown", 0x00}
|
||||
};
|
||||
|
||||
struct mpr_table_lookup mpr_pcie_linkrate_names[] = {
|
||||
{"Port disabled", 0x01},
|
||||
{"2.5GT/sec", 0x02},
|
||||
{"5.0GT/sec", 0x03},
|
||||
{"8.0GT/sec", 0x04},
|
||||
{"16.0GT/sec", 0x05},
|
||||
{NULL, 0},
|
||||
{"LinkRate Unknown", 0x00}
|
||||
};
|
||||
|
||||
void
|
||||
mpr_describe_devinfo(uint32_t devinfo, char *string, int len)
|
||||
{
|
||||
@ -321,6 +337,7 @@ _mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
|
||||
"\40MaxEnclosures");
|
||||
break;
|
||||
}
|
||||
//SLM-add for PCIE EVENT too
|
||||
case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
|
||||
{
|
||||
MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
|
||||
|
@ -40,6 +40,7 @@ void mpr_describe_devinfo(uint32_t devinfo, char *string, int len);
|
||||
extern struct mpr_table_lookup mpr_event_names[];
|
||||
extern struct mpr_table_lookup mpr_phystatus_names[];
|
||||
extern struct mpr_table_lookup mpr_linkrate_names[];
|
||||
extern struct mpr_table_lookup mpr_pcie_linkrate_names[];
|
||||
|
||||
void _mpr_print_iocfacts(struct mpr_softc *, MPI2_IOC_FACTS_REPLY *);
|
||||
void _mpr_print_portfacts(struct mpr_softc *, MPI2_PORT_FACTS_REPLY *);
|
||||
|
@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mpr/mpi/mpi2_cnfg.h>
|
||||
#include <dev/mpr/mpi/mpi2_init.h>
|
||||
#include <dev/mpr/mpi/mpi2_tool.h>
|
||||
#include <dev/mpr/mpi/mpi2_pci.h>
|
||||
#include <dev/mpr/mpr_ioctl.h>
|
||||
#include <dev/mpr/mprvar.h>
|
||||
#include <dev/mpr/mpr_table.h>
|
||||
@ -747,6 +748,8 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
|
||||
{
|
||||
MPI2_REQUEST_HEADER *hdr, tmphdr;
|
||||
MPI2_DEFAULT_REPLY *rpl;
|
||||
Mpi26NVMeEncapsulatedErrorReply_t *nvme_error_reply = NULL;
|
||||
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;
|
||||
struct mpr_command *cm = NULL;
|
||||
int i, err = 0, dir = 0, sz;
|
||||
uint8_t tool, function = 0;
|
||||
@ -923,8 +926,8 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
|
||||
cm->cm_data, data->DataSize);
|
||||
}
|
||||
if (err != 0)
|
||||
mpr_dprint(sc, MPR_FAULT, "%s: failed to copy "
|
||||
"IOCTL data from user space\n", __func__);
|
||||
mpr_dprint(sc, MPR_FAULT, "%s: failed to copy IOCTL "
|
||||
"data from user space\n", __func__);
|
||||
}
|
||||
/*
|
||||
* Set this flag only if processing a command that does not need an
|
||||
@ -946,6 +949,35 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
|
||||
}
|
||||
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
|
||||
if (function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
|
||||
nvme_encap_request =
|
||||
(Mpi26NVMeEncapsulatedRequest_t *)cm->cm_req;
|
||||
cm->cm_desc.Default.RequestFlags =
|
||||
MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
|
||||
|
||||
/*
|
||||
* Get the Physical Address of the sense buffer.
|
||||
* Save the user's Error Response buffer address and use that
|
||||
* field to hold the sense buffer address.
|
||||
* Clear the internal sense buffer, which will potentially hold
|
||||
* the Completion Queue Entry on return, or 0 if no Entry.
|
||||
* Build the PRPs and set direction bits.
|
||||
* Send the request.
|
||||
*/
|
||||
cm->nvme_error_response =
|
||||
(uint64_t *)(uintptr_t)(((uint64_t)nvme_encap_request->
|
||||
ErrorResponseBaseAddress.High << 32) |
|
||||
(uint64_t)nvme_encap_request->
|
||||
ErrorResponseBaseAddress.Low);
|
||||
nvme_encap_request->ErrorResponseBaseAddress.High =
|
||||
htole32((uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32));
|
||||
nvme_encap_request->ErrorResponseBaseAddress.Low =
|
||||
htole32(cm->cm_sense_busaddr);
|
||||
memset(cm->cm_sense, 0, NVME_ERROR_RESPONSE_SIZE);
|
||||
mpr_build_nvme_prp(sc, cm, nvme_encap_request, cm->cm_data,
|
||||
data->DataSize, data->DataOutSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up Sense buffer and SGL offset for IO passthru. SCSI IO request
|
||||
* uses SCSI IO or Fast Path SCSI IO descriptor.
|
||||
@ -994,15 +1026,19 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
|
||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO) {
|
||||
cm->cm_desc.FastPathSCSIIO.RequestFlags =
|
||||
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
|
||||
cm->cm_desc.FastPathSCSIIO.DevHandle =
|
||||
scsi_io_req->DevHandle;
|
||||
if (!sc->atomic_desc_capable) {
|
||||
cm->cm_desc.FastPathSCSIIO.DevHandle =
|
||||
scsi_io_req->DevHandle;
|
||||
}
|
||||
scsi_io_req->IoFlags |=
|
||||
MPI25_SCSIIO_IOFLAGS_FAST_PATH;
|
||||
} else {
|
||||
cm->cm_desc.SCSIIO.RequestFlags =
|
||||
MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
|
||||
cm->cm_desc.SCSIIO.DevHandle =
|
||||
scsi_io_req->DevHandle;
|
||||
if (!sc->atomic_desc_capable) {
|
||||
cm->cm_desc.SCSIIO.DevHandle =
|
||||
scsi_io_req->DevHandle;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1079,6 +1115,38 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
|
||||
mpr_lock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy out the NVMe Error Reponse to user. The Error Response
|
||||
* buffer is given by the user, but a sense buffer is used to
|
||||
* get that data from the IOC. The user's
|
||||
* ErrorResponseBaseAddress is saved in the
|
||||
* 'nvme_error_response' field before the command because that
|
||||
* field is set to a sense buffer. When the command is
|
||||
* complete, the Error Response data from the IOC is copied to
|
||||
* that user address after it is checked for validity.
|
||||
* Also note that 'sense' buffers are not defined for
|
||||
* NVMe commands. Sense terminalogy is only used here so that
|
||||
* the same IOCTL structure and sense buffers can be used for
|
||||
* NVMe.
|
||||
*/
|
||||
if (function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
|
||||
if (cm->nvme_error_response == NULL) {
|
||||
mpr_dprint(sc, MPR_INFO, "NVMe Error Response "
|
||||
"buffer is NULL. Response data will not be "
|
||||
"returned.\n");
|
||||
mpr_unlock(sc);
|
||||
goto RetFreeUnlocked;
|
||||
}
|
||||
|
||||
nvme_error_reply =
|
||||
(Mpi26NVMeEncapsulatedErrorReply_t *)cm->cm_reply;
|
||||
sz = MIN(le32toh(nvme_error_reply->ErrorResponseCount),
|
||||
NVME_ERROR_RESPONSE_SIZE);
|
||||
mpr_unlock(sc);
|
||||
copyout(cm->cm_sense, cm->nvme_error_response, sz);
|
||||
mpr_lock(sc);
|
||||
}
|
||||
}
|
||||
mpr_unlock(sc);
|
||||
|
||||
@ -2068,7 +2136,7 @@ mpr_user_btdh(struct mpr_softc *sc, mpr_btdh_mapping_t *data)
|
||||
return (EINVAL);
|
||||
|
||||
if (target > sc->max_devices) {
|
||||
mpr_dprint(sc, MPR_FAULT, "Target ID is out of range "
|
||||
mpr_dprint(sc, MPR_XINFO, "Target ID is out of range "
|
||||
"for Bus/Target to DevHandle mapping.");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
#ifndef _MPRVAR_H
|
||||
#define _MPRVAR_H
|
||||
|
||||
#define MPR_DRIVER_VERSION "15.01.00.00-fbsd"
|
||||
#define MPR_DRIVER_VERSION "15.02.00.00-fbsd"
|
||||
|
||||
#define MPR_DB_MAX_WAIT 2500
|
||||
|
||||
@ -50,6 +50,17 @@
|
||||
#define MPR_DEFAULT_CHAIN_SEG_SIZE 8
|
||||
#define MPR_MAX_CHAIN_ELEMENT_SIZE 16
|
||||
|
||||
/*
|
||||
* PCIe NVMe Specific defines
|
||||
*/
|
||||
//SLM-for now just use the same value as a SAS disk
|
||||
#define NVME_QDEPTH MPR_REQ_FRAMES
|
||||
#define PRP_ENTRY_SIZE 8
|
||||
#define NVME_CMD_PRP1_OFFSET 24 /* PRP1 offset in NVMe cmd */
|
||||
#define NVME_CMD_PRP2_OFFSET 32 /* PRP2 offset in NVMe cmd */
|
||||
#define NVME_ERROR_RESPONSE_SIZE 16 /* Max NVME Error Response */
|
||||
#define HOST_PAGE_SIZE_4K 12
|
||||
|
||||
#define MPR_FUNCTRACE(sc) \
|
||||
mpr_dprint((sc), MPR_TRACE, "%s\n", __func__)
|
||||
|
||||
@ -184,6 +195,12 @@ struct mpr_chain {
|
||||
uint64_t chain_busaddr;
|
||||
};
|
||||
|
||||
struct mpr_prp_page {
|
||||
TAILQ_ENTRY(mpr_prp_page) prp_page_link;
|
||||
uint64_t *prp_page;
|
||||
uint64_t prp_page_busaddr;
|
||||
};
|
||||
|
||||
/*
|
||||
* This needs to be at least 2 to support SMP passthrough.
|
||||
*/
|
||||
@ -229,9 +246,11 @@ struct mpr_command {
|
||||
#define MPR_CM_STATE_TIMEDOUT 2
|
||||
bus_dmamap_t cm_dmamap;
|
||||
struct scsi_sense_data *cm_sense;
|
||||
uint64_t *nvme_error_response;
|
||||
TAILQ_HEAD(, mpr_chain) cm_chain_list;
|
||||
TAILQ_HEAD(, mpr_prp_page) cm_prp_page_list;
|
||||
uint32_t cm_req_busaddr;
|
||||
uint32_t cm_sense_busaddr;
|
||||
bus_addr_t cm_sense_busaddr;
|
||||
struct callout cm_callout;
|
||||
};
|
||||
|
||||
@ -257,27 +276,35 @@ struct mpr_softc {
|
||||
#define MPR_FLAGS_SHUTDOWN (1 << 3)
|
||||
#define MPR_FLAGS_DIAGRESET (1 << 4)
|
||||
#define MPR_FLAGS_ATTACH_DONE (1 << 5)
|
||||
#define MPR_FLAGS_GEN35_IOC (1 << 6)
|
||||
u_int mpr_debug;
|
||||
u_int disable_msix;
|
||||
u_int disable_msi;
|
||||
u_int atomic_desc_capable;
|
||||
int tm_cmds_active;
|
||||
int io_cmds_active;
|
||||
int io_cmds_highwater;
|
||||
int chain_free;
|
||||
int max_chains;
|
||||
int max_io_pages;
|
||||
u_int maxio;
|
||||
int chain_free_lowwater;
|
||||
uint32_t chain_frame_size;
|
||||
uint16_t chain_seg_size;
|
||||
int prp_buffer_size;
|
||||
int prp_pages_free;
|
||||
int prp_pages_free_lowwater;
|
||||
u_int enable_ssu;
|
||||
int spinup_wait_time;
|
||||
int use_phynum;
|
||||
uint64_t chain_alloc_fail;
|
||||
uint64_t prp_page_alloc_fail;
|
||||
struct sysctl_ctx_list sysctl_ctx;
|
||||
struct sysctl_oid *sysctl_tree;
|
||||
char fw_version[16];
|
||||
struct mpr_command *commands;
|
||||
struct mpr_chain *chains;
|
||||
struct mpr_prp_page *prps;
|
||||
struct callout periodic;
|
||||
|
||||
struct mprsas_softc *sassc;
|
||||
@ -285,6 +312,7 @@ struct mpr_softc {
|
||||
TAILQ_HEAD(, mpr_command) req_list;
|
||||
TAILQ_HEAD(, mpr_command) high_priority_req_list;
|
||||
TAILQ_HEAD(, mpr_chain) chain_list;
|
||||
TAILQ_HEAD(, mpr_prp_page) prp_page_list;
|
||||
TAILQ_HEAD(, mpr_command) tm_list;
|
||||
int replypostindex;
|
||||
int replyfreeindex;
|
||||
@ -333,6 +361,11 @@ struct mpr_softc {
|
||||
bus_dma_tag_t chain_dmat;
|
||||
bus_dmamap_t chain_map;
|
||||
|
||||
uint8_t *prp_pages;
|
||||
bus_addr_t prp_page_busaddr;
|
||||
bus_dma_tag_t prp_page_dmat;
|
||||
bus_dmamap_t prp_page_map;
|
||||
|
||||
MPI2_REPLY_DESCRIPTORS_UNION *post_queue;
|
||||
bus_addr_t post_busaddr;
|
||||
uint32_t *free_queue;
|
||||
@ -471,10 +504,33 @@ mpr_free_chain(struct mpr_softc *sc, struct mpr_chain *chain)
|
||||
TAILQ_INSERT_TAIL(&sc->chain_list, chain, chain_link);
|
||||
}
|
||||
|
||||
static __inline struct mpr_prp_page *
|
||||
mpr_alloc_prp_page(struct mpr_softc *sc)
|
||||
{
|
||||
struct mpr_prp_page *prp_page;
|
||||
|
||||
if ((prp_page = TAILQ_FIRST(&sc->prp_page_list)) != NULL) {
|
||||
TAILQ_REMOVE(&sc->prp_page_list, prp_page, prp_page_link);
|
||||
sc->prp_pages_free--;
|
||||
if (sc->prp_pages_free < sc->prp_pages_free_lowwater)
|
||||
sc->prp_pages_free_lowwater = sc->prp_pages_free;
|
||||
} else
|
||||
sc->prp_page_alloc_fail++;
|
||||
return (prp_page);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
mpr_free_prp_page(struct mpr_softc *sc, struct mpr_prp_page *prp_page)
|
||||
{
|
||||
sc->prp_pages_free++;
|
||||
TAILQ_INSERT_TAIL(&sc->prp_page_list, prp_page, prp_page_link);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
mpr_free_command(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
{
|
||||
struct mpr_chain *chain, *chain_temp;
|
||||
struct mpr_prp_page *prp_page, *prp_page_temp;
|
||||
|
||||
if (cm->cm_reply != NULL)
|
||||
mpr_free_reply(sc, cm->cm_reply_data);
|
||||
@ -497,6 +553,11 @@ mpr_free_command(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link);
|
||||
mpr_free_chain(sc, chain);
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(prp_page, &cm->cm_prp_page_list, prp_page_link,
|
||||
prp_page_temp) {
|
||||
TAILQ_REMOVE(&cm->cm_prp_page_list, prp_page, prp_page_link);
|
||||
mpr_free_prp_page(sc, prp_page);
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&sc->req_list, cm, cm_link);
|
||||
}
|
||||
|
||||
@ -510,7 +571,8 @@ mpr_alloc_command(struct mpr_softc *sc)
|
||||
return (NULL);
|
||||
|
||||
TAILQ_REMOVE(&sc->req_list, cm, cm_link);
|
||||
KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy command\n"));
|
||||
KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy "
|
||||
"command\n"));
|
||||
cm->cm_state = MPR_CM_STATE_BUSY;
|
||||
return (cm);
|
||||
}
|
||||
@ -547,7 +609,8 @@ mpr_alloc_high_priority_command(struct mpr_softc *sc)
|
||||
return (NULL);
|
||||
|
||||
TAILQ_REMOVE(&sc->high_priority_req_list, cm, cm_link);
|
||||
KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy command\n"));
|
||||
KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy "
|
||||
"command\n"));
|
||||
cm->cm_state = MPR_CM_STATE_BUSY;
|
||||
return (cm);
|
||||
}
|
||||
@ -653,6 +716,9 @@ int mpr_register_events(struct mpr_softc *, uint8_t *, mpr_evt_callback_t *,
|
||||
int mpr_restart(struct mpr_softc *);
|
||||
int mpr_update_events(struct mpr_softc *, struct mpr_event_handle *, uint8_t *);
|
||||
int mpr_deregister_events(struct mpr_softc *, struct mpr_event_handle *);
|
||||
void mpr_build_nvme_prp(struct mpr_softc *sc, struct mpr_command *cm,
|
||||
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request, void *data,
|
||||
uint32_t data_in_sz, uint32_t data_out_sz);
|
||||
int mpr_push_sge(struct mpr_command *, MPI2_SGE_SIMPLE64 *, size_t, int);
|
||||
int mpr_push_ieee_sge(struct mpr_command *, void *, int);
|
||||
int mpr_add_dmaseg(struct mpr_command *, vm_paddr_t, size_t, u_int, int);
|
||||
@ -682,6 +748,10 @@ int mpr_config_get_iounit_pg8(struct mpr_softc *sc,
|
||||
Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page);
|
||||
int mpr_config_get_sas_device_pg0(struct mpr_softc *, Mpi2ConfigReply_t *,
|
||||
Mpi2SasDevicePage0_t *, u32 , u16 );
|
||||
int mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle);
|
||||
int mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
|
||||
*mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle);
|
||||
int mpr_config_get_dpm_pg0(struct mpr_softc *, Mpi2ConfigReply_t *,
|
||||
Mpi2DriverMappingPage0_t *, u16 );
|
||||
int mpr_config_get_raid_volume_pg1(struct mpr_softc *sc,
|
||||
@ -702,6 +772,8 @@ void mpr_base_static_config_pages(struct mpr_softc *sc);
|
||||
int mpr_mapping_initialize(struct mpr_softc *);
|
||||
void mpr_mapping_topology_change_event(struct mpr_softc *,
|
||||
Mpi2EventDataSasTopologyChangeList_t *);
|
||||
void mpr_mapping_pcie_topology_change_event(struct mpr_softc *sc,
|
||||
Mpi26EventDataPCIeTopologyChangeList_t *event_data);
|
||||
int mpr_mapping_is_reinit_required(struct mpr_softc *);
|
||||
void mpr_mapping_free_memory(struct mpr_softc *sc);
|
||||
int mpr_config_set_dpm_pg0(struct mpr_softc *, Mpi2ConfigReply_t *,
|
||||
@ -769,5 +841,52 @@ SYSCTL_DECL(_hw_mpr);
|
||||
#define CAM_PRIORITY_NORMAL CAM_PRIORITY_NONE
|
||||
#endif
|
||||
|
||||
/* Definitions for SCSI unmap translation to NVMe DSM command */
|
||||
|
||||
/* UNMAP block descriptor structure */
|
||||
struct unmap_blk_desc {
|
||||
uint64_t slba;
|
||||
uint32_t nlb;
|
||||
uint32_t resv;
|
||||
};
|
||||
|
||||
/* UNMAP command's data */
|
||||
struct unmap_parm_list {
|
||||
uint16_t unmap_data_len;
|
||||
uint16_t unmap_blk_desc_data_len;
|
||||
uint32_t resv;
|
||||
struct unmap_blk_desc desc[0];
|
||||
};
|
||||
|
||||
/* SCSI ADDITIONAL SENSE Codes */
|
||||
#define FIXED_SENSE_DATA 0x70
|
||||
#define SCSI_ASC_NO_SENSE 0x00
|
||||
#define SCSI_ASC_PERIPHERAL_DEV_WRITE_FAULT 0x03
|
||||
#define SCSI_ASC_LUN_NOT_READY 0x04
|
||||
#define SCSI_ASC_WARNING 0x0B
|
||||
#define SCSI_ASC_LOG_BLOCK_GUARD_CHECK_FAILED 0x10
|
||||
#define SCSI_ASC_LOG_BLOCK_APPTAG_CHECK_FAILED 0x10
|
||||
#define SCSI_ASC_LOG_BLOCK_REFTAG_CHECK_FAILED 0x10
|
||||
#define SCSI_ASC_UNRECOVERED_READ_ERROR 0x11
|
||||
#define SCSI_ASC_MISCOMPARE_DURING_VERIFY 0x1D
|
||||
#define SCSI_ASC_ACCESS_DENIED_INVALID_LUN_ID 0x20
|
||||
#define SCSI_ASC_ILLEGAL_COMMAND 0x20
|
||||
#define SCSI_ASC_ILLEGAL_BLOCK 0x21
|
||||
#define SCSI_ASC_INVALID_CDB 0x24
|
||||
#define SCSI_ASC_INVALID_LUN 0x25
|
||||
#define SCSI_ASC_INVALID_PARAMETER 0x26
|
||||
#define SCSI_ASC_FORMAT_COMMAND_FAILED 0x31
|
||||
#define SCSI_ASC_INTERNAL_TARGET_FAILURE 0x44
|
||||
|
||||
/* SCSI ADDITIONAL SENSE Code Qualifiers */
|
||||
#define SCSI_ASCQ_CAUSE_NOT_REPORTABLE 0x00
|
||||
#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASCQ_LOG_BLOCK_GUARD_CHECK_FAILED 0x01
|
||||
#define SCSI_ASCQ_LOG_BLOCK_APPTAG_CHECK_FAILED 0x02
|
||||
#define SCSI_ASCQ_LOG_BLOCK_REFTAG_CHECK_FAILED 0x03
|
||||
#define SCSI_ASCQ_FORMAT_IN_PROGRESS 0x04
|
||||
#define SCSI_ASCQ_POWER_LOSS_EXPECTED 0x08
|
||||
#define SCSI_ASCQ_INVALID_LUN_ID 0x09
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -309,7 +309,7 @@ mse_disablelogi(struct resource *port)
|
||||
static void
|
||||
mse_getlogi(struct resource *port, int *dx, int *dy, int *but)
|
||||
{
|
||||
register char x, y;
|
||||
char x, y;
|
||||
|
||||
bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RXLOW);
|
||||
x = bus_read_1(port, MSE_PORTA);
|
||||
|
@ -751,7 +751,7 @@ my_setcfg(struct my_softc * sc, int bmcr)
|
||||
static void
|
||||
my_reset(struct my_softc * sc)
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
MY_LOCK_ASSERT(sc);
|
||||
MY_SETBIT(sc, MY_BCR, MY_SWR);
|
||||
@ -1717,7 +1717,7 @@ my_watchdog(void *arg)
|
||||
static void
|
||||
my_stop(struct my_softc * sc)
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
struct ifnet *ifp;
|
||||
|
||||
MY_LOCK_ASSERT(sc);
|
||||
|
@ -1453,7 +1453,7 @@ pcn_watchdog(struct pcn_softc *sc)
|
||||
static void
|
||||
pcn_stop(struct pcn_softc *sc)
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
struct ifnet *ifp;
|
||||
|
||||
PCN_LOCK_ASSERT(sc);
|
||||
|
@ -674,10 +674,10 @@ imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
|
||||
int *ret)
|
||||
{
|
||||
device_t ppbus = device_get_parent(vpo->vpo_dev);
|
||||
register char r;
|
||||
char r;
|
||||
char l, h = 0;
|
||||
int len, error = 0, not_connected = 0;
|
||||
register int k;
|
||||
int k;
|
||||
int negociated = 0;
|
||||
|
||||
/*
|
||||
|
@ -680,10 +680,10 @@ vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
|
||||
int *ret)
|
||||
{
|
||||
device_t ppbus = device_get_parent(vpo->vpo_dev);
|
||||
register char r;
|
||||
char r;
|
||||
char l, h = 0;
|
||||
int len, error = 0;
|
||||
register int k;
|
||||
int k;
|
||||
|
||||
/*
|
||||
* enter disk state, allocate the ppbus
|
||||
|
@ -285,7 +285,7 @@ ppc_detect_port(struct ppc_data *ppc)
|
||||
static void
|
||||
ppc_reset_epp_timeout(struct ppc_data *ppc)
|
||||
{
|
||||
register char r;
|
||||
char r;
|
||||
|
||||
r = r_str(ppc);
|
||||
w_str(ppc, r | 0x1);
|
||||
@ -1321,10 +1321,10 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
|
||||
int i, iter, len;
|
||||
int error;
|
||||
|
||||
register int reg;
|
||||
register char mask;
|
||||
register int accum = 0;
|
||||
register char *ptr = NULL;
|
||||
int reg;
|
||||
char mask;
|
||||
int accum = 0;
|
||||
char *ptr = NULL;
|
||||
|
||||
struct ppb_microseq *stack = NULL;
|
||||
|
||||
|
@ -191,6 +191,7 @@ struct qlnx_fastpath {
|
||||
struct mtx tx_mtx;
|
||||
char tx_mtx_name[32];
|
||||
struct buf_ring *tx_br;
|
||||
uint32_t tx_ring_full;
|
||||
|
||||
struct task fp_task;
|
||||
struct taskqueue *fp_taskqueue;
|
||||
@ -364,6 +365,8 @@ struct qlnx_host {
|
||||
/* debug */
|
||||
|
||||
uint32_t dbg_level;
|
||||
uint32_t dbg_trace_lro_cnt;
|
||||
uint32_t dbg_trace_tso_pkt_len;
|
||||
uint32_t dp_level;
|
||||
uint32_t dp_module;
|
||||
|
||||
@ -386,7 +389,6 @@ struct qlnx_host {
|
||||
|
||||
/* tx related */
|
||||
struct callout tx_callout;
|
||||
struct mtx tx_lock;
|
||||
uint32_t txr_idx;
|
||||
|
||||
/* rx related */
|
||||
@ -481,35 +483,141 @@ typedef struct qlnx_host qlnx_host_t;
|
||||
|
||||
#ifdef QLNX_DEBUG
|
||||
|
||||
#define QL_DPRINT1(ha, x) if (ha->dbg_level & 0x0001) device_printf x
|
||||
#define QL_DPRINT2(ha, x) if (ha->dbg_level & 0x0002) device_printf x
|
||||
#define QL_DPRINT3(ha, x) if (ha->dbg_level & 0x0004) device_printf x
|
||||
#define QL_DPRINT4(ha, x) if (ha->dbg_level & 0x0008) device_printf x
|
||||
#define QL_DPRINT5(ha, x) if (ha->dbg_level & 0x0010) device_printf x
|
||||
#define QL_DPRINT6(ha, x) if (ha->dbg_level & 0x0020) device_printf x
|
||||
#define QL_DPRINT7(ha, x) if (ha->dbg_level & 0x0040) device_printf x
|
||||
#define QL_DPRINT8(ha, x) if (ha->dbg_level & 0x0080) device_printf x
|
||||
#define QL_DPRINT9(ha, x) if (ha->dbg_level & 0x0100) device_printf x
|
||||
#define QL_DPRINT11(ha, x) if (ha->dbg_level & 0x0400) device_printf x
|
||||
#define QL_DPRINT12(ha, x) if (ha->dbg_level & 0x0800) device_printf x
|
||||
#define QL_DPRINT13(ha, x) if (ha->dbg_level & 0x1000) device_printf x
|
||||
#define QL_DPRINT14(ha, x) if (ha->dbg_level & 0x2000) device_printf x
|
||||
#define QL_DPRINT1(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0001) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT2(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0002) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT3(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0004) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT4(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0008) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT5(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0010) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT6(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0020) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT7(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0040) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT8(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0080) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT9(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0100) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT11(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0400) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT12(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x0800) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QL_DPRINT13(ha, x, ...) \
|
||||
do { \
|
||||
if ((ha)->dbg_level & 0x1000) { \
|
||||
device_printf ((ha)->pci_dev, \
|
||||
"[%s:%d]" x, \
|
||||
__func__, __LINE__, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define QL_DPRINT1(ha, x)
|
||||
#define QL_DPRINT2(ha, x)
|
||||
#define QL_DPRINT3(ha, x)
|
||||
#define QL_DPRINT4(ha, x)
|
||||
#define QL_DPRINT5(ha, x)
|
||||
#define QL_DPRINT6(ha, x)
|
||||
#define QL_DPRINT7(ha, x)
|
||||
#define QL_DPRINT8(ha, x)
|
||||
#define QL_DPRINT9(ha, x)
|
||||
#define QL_DPRINT11(ha, x)
|
||||
#define QL_DPRINT12(ha, x)
|
||||
#define QL_DPRINT13(ha, x)
|
||||
#define QL_DPRINT14(ha, x)
|
||||
#define QL_DPRINT1(ha, x, ...)
|
||||
#define QL_DPRINT2(ha, x, ...)
|
||||
#define QL_DPRINT3(ha, x, ...)
|
||||
#define QL_DPRINT4(ha, x, ...)
|
||||
#define QL_DPRINT5(ha, x, ...)
|
||||
#define QL_DPRINT6(ha, x, ...)
|
||||
#define QL_DPRINT7(ha, x, ...)
|
||||
#define QL_DPRINT8(ha, x, ...)
|
||||
#define QL_DPRINT9(ha, x, ...)
|
||||
#define QL_DPRINT11(ha, x, ...)
|
||||
#define QL_DPRINT12(ha, x, ...)
|
||||
#define QL_DPRINT13(ha, x, ...)
|
||||
|
||||
#endif /* #ifdef QLNX_DEBUG */
|
||||
|
||||
|
@ -121,8 +121,7 @@ qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
|
||||
p_ptt = ecore_ptt_acquire(p_hwfn);
|
||||
|
||||
if (!p_ptt) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev, "%s : ecore_ptt_acquire failed\n",
|
||||
__func__));
|
||||
QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
|
||||
return (rval);
|
||||
}
|
||||
|
||||
@ -133,9 +132,8 @@ qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
|
||||
rval = 0;
|
||||
ha->grcdump_taken = 1;
|
||||
} else
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s : ecore_dbg_grc_dump failed [%d, 0x%x]\n",
|
||||
__func__, hwfn_index, rval));
|
||||
QL_DPRINT1(ha,"ecore_dbg_grc_dump failed [%d, 0x%x]\n",
|
||||
hwfn_index, rval);
|
||||
|
||||
ecore_ptt_release(p_hwfn, p_ptt);
|
||||
|
||||
@ -177,8 +175,7 @@ qlnx_get_grc_dump(qlnx_host_t *ha, qlnx_grcdump_t *grcdump)
|
||||
|
||||
grcdump->grcdump_dwords[i] = dwords;
|
||||
|
||||
QL_DPRINT1(ha, (ha->pci_dev, "%s: grcdump_dwords[%d] = 0x%x\n",
|
||||
__func__, i, dwords));
|
||||
QL_DPRINT1(ha,"grcdump_dwords[%d] = 0x%x\n", i, dwords);
|
||||
|
||||
rval = copyout(ha->grcdump[i], grcdump->grcdump[i],
|
||||
ha->grcdump_size[i]);
|
||||
@ -213,8 +210,7 @@ qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
|
||||
p_ptt = ecore_ptt_acquire(p_hwfn);
|
||||
|
||||
if (!p_ptt) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s : ecore_ptt_acquire failed\n", __func__));
|
||||
QL_DPRINT1(ha,"ecore_ptt_acquire failed\n");
|
||||
return (rval);
|
||||
}
|
||||
|
||||
@ -225,9 +221,8 @@ qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords, int hwfn_index)
|
||||
rval = 0;
|
||||
ha->idle_chk_taken = 1;
|
||||
} else
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s : ecore_dbg_idle_chk_dump failed [%d, 0x%x]\n",
|
||||
__func__, hwfn_index, rval));
|
||||
QL_DPRINT1(ha,"ecore_dbg_idle_chk_dump failed [%d, 0x%x]\n",
|
||||
hwfn_index, rval);
|
||||
|
||||
ecore_ptt_release(p_hwfn, p_ptt);
|
||||
|
||||
@ -271,8 +266,7 @@ qlnx_get_idle_chk(qlnx_host_t *ha, qlnx_idle_chk_t *idle_chk)
|
||||
|
||||
idle_chk->idle_chk_dwords[i] = dwords;
|
||||
|
||||
QL_DPRINT1(ha, (ha->pci_dev, "%s: idle_chk_dwords[%d] = 0x%x\n",
|
||||
__func__, i, dwords));
|
||||
QL_DPRINT1(ha,"idle_chk_dwords[%d] = 0x%x\n", i, dwords);
|
||||
|
||||
rval = copyout(ha->idle_chk[i], idle_chk->idle_chk[i],
|
||||
ha->idle_chk_size[i]);
|
||||
@ -299,9 +293,8 @@ qlnx_get_trace_cmd_size(qlnx_host_t *ha, int hwfn_index, uint16_t cmd)
|
||||
p_ptt = ecore_ptt_acquire(p_hwfn);
|
||||
|
||||
if (!p_ptt) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s: ecore_ptt_acquire [%d, 0x%x]failed\n",
|
||||
__func__, hwfn_index, cmd));
|
||||
QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
|
||||
hwfn_index, cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -334,8 +327,7 @@ qlnx_get_trace_cmd_size(qlnx_host_t *ha, int hwfn_index, uint16_t cmd)
|
||||
}
|
||||
|
||||
if (rval != DBG_STATUS_OK) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev, "%s : cmd = 0x%x failed [0x%x]\n",
|
||||
__func__, cmd, rval));
|
||||
QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", cmd, rval);
|
||||
num_dwords = 0;
|
||||
}
|
||||
|
||||
@ -369,9 +361,8 @@ qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace)
|
||||
|
||||
buffer = qlnx_zalloc(trace->size[hwfn_index]);
|
||||
if (buffer == NULL) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s: qlnx_zalloc [%d, 0x%x]failed\n",
|
||||
__func__, hwfn_index, trace->cmd));
|
||||
QL_DPRINT1(ha,"qlnx_zalloc [%d, 0x%x]failed\n",
|
||||
hwfn_index, trace->cmd);
|
||||
return (ENXIO);
|
||||
}
|
||||
ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver());
|
||||
@ -380,9 +371,8 @@ qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace)
|
||||
p_ptt = ecore_ptt_acquire(p_hwfn);
|
||||
|
||||
if (!p_ptt) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev,
|
||||
"%s: ecore_ptt_acquire [%d, 0x%x]failed\n",
|
||||
__func__, hwfn_index, trace->cmd));
|
||||
QL_DPRINT1(ha, "ecore_ptt_acquire [%d, 0x%x]failed\n",
|
||||
hwfn_index, trace->cmd);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
@ -420,8 +410,7 @@ qlnx_get_trace(qlnx_host_t *ha, int hwfn_index, qlnx_trace_t *trace)
|
||||
}
|
||||
|
||||
if (rval != DBG_STATUS_OK) {
|
||||
QL_DPRINT1(ha, (ha->pci_dev, "%s : cmd = 0x%x failed [0x%x]\n",
|
||||
__func__, trace->cmd, rval));
|
||||
QL_DPRINT1(ha,"cmd = 0x%x failed [0x%x]\n", trace->cmd, rval);
|
||||
num_dwords = 0;
|
||||
}
|
||||
|
||||
@ -609,21 +598,18 @@ qlnx_write_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram, uint32_t cmd)
|
||||
|
||||
ret = copyin(nvram->data, buf, nvram->data_len);
|
||||
|
||||
QL_DPRINT9(ha,
|
||||
(ha->pci_dev, "%s: issue cmd = 0x%x data = %p "
|
||||
" data_len = 0x%x ret = 0x%x exit\n", __func__,
|
||||
cmd, nvram->data, nvram->data_len, ret));
|
||||
QL_DPRINT9(ha, "issue cmd = 0x%x data = %p \
|
||||
data_len = 0x%x ret = 0x%x exit\n",
|
||||
cmd, nvram->data, nvram->data_len, ret);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = ecore_mcp_nvm_write(&ha->cdev, cmd,
|
||||
nvram->offset, buf, nvram->data_len);
|
||||
}
|
||||
|
||||
QL_DPRINT9(ha,
|
||||
(ha->pci_dev, "%s: cmd = 0x%x data = %p "
|
||||
" data_len = 0x%x resp = 0x%x ret = 0x%x exit\n",
|
||||
__func__, cmd, nvram->data, nvram->data_len,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, "cmd = 0x%x data = %p \
|
||||
data_len = 0x%x resp = 0x%x ret = 0x%x exit\n",
|
||||
cmd, nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
|
||||
|
||||
free(buf, M_QLNXBUF);
|
||||
|
||||
@ -644,10 +630,9 @@ qlnx_read_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
|
||||
ret = ecore_mcp_nvm_read(&ha->cdev, nvram->offset, buf,
|
||||
nvram->data_len);
|
||||
|
||||
QL_DPRINT9(ha, (ha->pci_dev, "%s: data = %p data_len = 0x%x "
|
||||
" resp = 0x%x ret = 0x%x exit\n", __func__,
|
||||
nvram->data, nvram->data_len,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, " data = %p data_len = 0x%x \
|
||||
resp = 0x%x ret = 0x%x exit\n",
|
||||
nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = copyout(buf, nvram->data, nvram->data_len);
|
||||
@ -672,10 +657,9 @@ qlnx_get_nvram_resp(qlnx_host_t *ha, qlnx_nvram_t *nvram)
|
||||
|
||||
ret = ecore_mcp_nvm_resp(&ha->cdev, buf);
|
||||
|
||||
QL_DPRINT9(ha, (ha->pci_dev, "%s: data = %p data_len = 0x%x "
|
||||
" resp = 0x%x ret = 0x%x exit\n", __func__,
|
||||
nvram->data, nvram->data_len,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, "data = %p data_len = 0x%x \
|
||||
resp = 0x%x ret = 0x%x exit\n",
|
||||
nvram->data, nvram->data_len, ha->cdev.mcp_nvm_resp, ret);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = copyout(buf, nvram->data, nvram->data_len);
|
||||
@ -708,28 +692,25 @@ qlnx_nvram(qlnx_host_t *ha, qlnx_nvram_t *nvram)
|
||||
case QLNX_NVRAM_CMD_SET_SECURE_MODE:
|
||||
ret = ecore_mcp_nvm_set_secure_mode(&ha->cdev, nvram->offset);
|
||||
|
||||
QL_DPRINT9(ha, (ha->pci_dev,
|
||||
"%s: QLNX_NVRAM_CMD_SET_SECURE_MODE "
|
||||
" resp = 0x%x ret = 0x%x exit\n", __func__,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, "QLNX_NVRAM_CMD_SET_SECURE_MODE \
|
||||
resp = 0x%x ret = 0x%x exit\n",
|
||||
ha->cdev.mcp_nvm_resp, ret);
|
||||
break;
|
||||
|
||||
case QLNX_NVRAM_CMD_DEL_FILE:
|
||||
ret = ecore_mcp_nvm_del_file(&ha->cdev, nvram->offset);
|
||||
|
||||
QL_DPRINT9(ha, (ha->pci_dev,
|
||||
"%s: QLNX_NVRAM_CMD_DEL_FILE "
|
||||
" resp = 0x%x ret = 0x%x exit\n", __func__,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, "QLNX_NVRAM_CMD_DEL_FILE \
|
||||
resp = 0x%x ret = 0x%x exit\n",
|
||||
ha->cdev.mcp_nvm_resp, ret);
|
||||
break;
|
||||
|
||||
case QLNX_NVRAM_CMD_PUT_FILE_BEGIN:
|
||||
ret = ecore_mcp_nvm_put_file_begin(&ha->cdev, nvram->offset);
|
||||
|
||||
QL_DPRINT9(ha, (ha->pci_dev,
|
||||
"%s: QLNX_NVRAM_CMD_PUT_FILE_BEGIN "
|
||||
" resp = 0x%x ret = 0x%x exit\n", __func__,
|
||||
ha->cdev.mcp_nvm_resp, ret));
|
||||
QL_DPRINT9(ha, "QLNX_NVRAM_CMD_PUT_FILE_BEGIN \
|
||||
resp = 0x%x ret = 0x%x exit\n",
|
||||
ha->cdev.mcp_nvm_resp, ret);
|
||||
break;
|
||||
|
||||
case QLNX_NVRAM_CMD_GET_NVRAM_RESP:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -92,6 +92,7 @@
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/sched.h>
|
||||
|
||||
static __inline int qlnx_ms_to_hz(int ms)
|
||||
{
|
||||
@ -138,10 +139,6 @@ MALLOC_DECLARE(M_QLNXBUF);
|
||||
#define QLNX_LOCK(ha) mtx_lock(&ha->hw_lock)
|
||||
#define QLNX_UNLOCK(ha) mtx_unlock(&ha->hw_lock)
|
||||
|
||||
|
||||
#define QLNX_TX_LOCK(ha) mtx_lock(&ha->tx_lock);
|
||||
#define QLNX_TX_UNLOCK(ha) mtx_unlock(&ha->tx_lock);
|
||||
|
||||
/*
|
||||
* structure encapsulating a DMA buffer
|
||||
*/
|
||||
|
@ -1401,7 +1401,7 @@ int
|
||||
qla_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp,
|
||||
uint32_t jumbo)
|
||||
{
|
||||
register struct mbuf *mp = nmp;
|
||||
struct mbuf *mp = nmp;
|
||||
struct ifnet *ifp;
|
||||
int ret = 0;
|
||||
uint32_t offset;
|
||||
|
@ -1797,7 +1797,7 @@ qla_free_rcv_bufs(qla_host_t *ha)
|
||||
int
|
||||
ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
|
||||
{
|
||||
register struct mbuf *mp = nmp;
|
||||
struct mbuf *mp = nmp;
|
||||
struct ifnet *ifp;
|
||||
int ret = 0;
|
||||
uint32_t offset;
|
||||
|
@ -1396,7 +1396,7 @@ qls_alloc_rcv_bufs(qla_host_t *ha)
|
||||
int
|
||||
qls_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
|
||||
{
|
||||
register struct mbuf *mp = nmp;
|
||||
struct mbuf *mp = nmp;
|
||||
struct ifnet *ifp;
|
||||
int ret = 0;
|
||||
uint32_t offset;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user