mirror of
https://github.com/opnsense/src.git
synced 2026-06-12 10:10:24 -04:00
Revert "nvme: Separate total failures from I/O failures"
All kinds of crazy stuff was mixed into this commit. Revert
it and do it again.
This reverts commit d5507f9e43.
Sponsored by: Netflix
This commit is contained in:
parent
a233cb6914
commit
ce7fac64ba
24 changed files with 28 additions and 16219 deletions
|
|
@ -1,2 +0,0 @@
|
|||
include "GENERIC"
|
||||
options CAM_IOSCHED_DYNAMIC
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
include GENERIC
|
||||
|
||||
device mpi3mr
|
||||
# All the debugging options
|
||||
options DEADLKRES # Enable the deadlock resolver
|
||||
options INVARIANTS # Enable calls of extra sanity checking
|
||||
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
|
||||
options QUEUE_MACRO_DEBUG_TRASH # Trash queue(2) internal pointers on invalidation
|
||||
options WITNESS # Enable checks to detect deadlocks and cycles
|
||||
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
include "GENERIC"
|
||||
|
||||
ident GENERIC_16K
|
||||
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 2010 Isilon Systems, Inc.
|
||||
* Copyright (c) 2010 iX Systems, Inc.
|
||||
* Copyright (c) 2010 Panasas, Inc.
|
||||
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
|
||||
* Copyright (c) 2015 François Tigeot
|
||||
* 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 unmodified, 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 ``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 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 _LINUX_COMPILER_H_
|
||||
#define _LINUX_COMPILER_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define __user
|
||||
#define __kernel
|
||||
#define __safe
|
||||
#define __force
|
||||
#define __nocast
|
||||
#define __iomem
|
||||
#define __chk_user_ptr(x) ((void)0)
|
||||
#define __chk_io_ptr(x) ((void)0)
|
||||
#define __builtin_warning(x, y...) (1)
|
||||
#define __acquires(x)
|
||||
#define __releases(x)
|
||||
#define __acquire(x) do { } while (0)
|
||||
#define __release(x) do { } while (0)
|
||||
#define __cond_lock(x,c) (c)
|
||||
#define __bitwise
|
||||
#define __devinitdata
|
||||
#define __deprecated
|
||||
#define __init
|
||||
#define __initconst
|
||||
#define __devinit
|
||||
#define __devexit
|
||||
#define __exit
|
||||
#define __rcu
|
||||
#define __percpu
|
||||
#define __weak __weak_symbol
|
||||
#define __malloc
|
||||
#define ___stringify(...) #__VA_ARGS__
|
||||
#define __stringify(...) ___stringify(__VA_ARGS__)
|
||||
#define __attribute_const__ __attribute__((__const__))
|
||||
#undef __always_inline
|
||||
#define __always_inline inline
|
||||
#define noinline __noinline
|
||||
#define ____cacheline_aligned __aligned(CACHE_LINE_SIZE)
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#define typeof(x) __typeof(x)
|
||||
|
||||
#define uninitialized_var(x) x = x
|
||||
#define __maybe_unused __unused
|
||||
#define __always_unused __unused
|
||||
#define __must_check __result_use_check
|
||||
|
||||
#define __printf(a,b) __printflike(a,b)
|
||||
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 50000
|
||||
/* Moved from drm_os_freebsd.h */
|
||||
#define lower_32_bits(n) ((u32)(n))
|
||||
#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
|
||||
#endif
|
||||
|
||||
#define ___PASTE(a,b) a##b
|
||||
#define __PASTE(a,b) ___PASTE(a,b)
|
||||
|
||||
#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))
|
||||
|
||||
#define WRITE_ONCE(x,v) do { \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(x) = (v); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define READ_ONCE(x) ({ \
|
||||
__typeof(x) __var = ({ \
|
||||
barrier(); \
|
||||
ACCESS_ONCE(x); \
|
||||
}); \
|
||||
barrier(); \
|
||||
__var; \
|
||||
})
|
||||
|
||||
#define lockless_dereference(p) READ_ONCE(p)
|
||||
|
||||
#define _AT(T,X) ((T)(X))
|
||||
|
||||
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
||||
#define __must_be_array(a) __same_type(a, &(a)[0])
|
||||
|
||||
#endif /* _LINUX_COMPILER_H_ */
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2019-2020 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_fw_api_soc_h__
|
||||
#define __iwl_fw_api_soc_h__
|
||||
|
||||
#define SOC_CONFIG_CMD_FLAGS_DISCRETE BIT(0)
|
||||
#define SOC_CONFIG_CMD_FLAGS_LOW_LATENCY BIT(1)
|
||||
|
||||
#define SOC_FLAGS_LTR_APPLY_DELAY_MASK 0xc
|
||||
#define SOC_FLAGS_LTR_APPLY_DELAY_NONE 0
|
||||
#define SOC_FLAGS_LTR_APPLY_DELAY_200 1
|
||||
#define SOC_FLAGS_LTR_APPLY_DELAY_2500 2
|
||||
#define SOC_FLAGS_LTR_APPLY_DELAY_1820 3
|
||||
|
||||
/**
|
||||
* struct iwl_soc_configuration_cmd - Set device stabilization latency
|
||||
*
|
||||
* @flags: soc settings flags. In VER_1, we can only set the DISCRETE
|
||||
* flag, because the FW treats the whole value as an integer. In
|
||||
* VER_2, we can set the bits independently.
|
||||
* @latency: time for SOC to ensure stable power & XTAL
|
||||
*/
|
||||
struct iwl_soc_configuration_cmd {
|
||||
__le32 flags;
|
||||
__le32 latency;
|
||||
} __packed; /*
|
||||
* SOC_CONFIGURATION_CMD_S_VER_1 (see description above)
|
||||
* SOC_CONFIGURATION_CMD_S_VER_2
|
||||
*/
|
||||
|
||||
#endif /* __iwl_fw_api_soc_h__ */
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
This is a patched version of zlib, modified to use
|
||||
Pentium-Pro-optimized assembly code in the deflation algorithm. The
|
||||
files changed/added by this patch are:
|
||||
|
||||
README.686
|
||||
match.S
|
||||
|
||||
The speedup that this patch provides varies, depending on whether the
|
||||
compiler used to build the original version of zlib falls afoul of the
|
||||
PPro's speed traps. My own tests show a speedup of around 10-20% at
|
||||
the default compression level, and 20-30% using -9, against a version
|
||||
compiled using gcc 2.7.2.3. Your mileage may vary.
|
||||
|
||||
Note that this code has been tailored for the PPro/PII in particular,
|
||||
and will not perform particuarly well on a Pentium.
|
||||
|
||||
If you are using an assembler other than GNU as, you will have to
|
||||
translate match.S to use your assembler's syntax. (Have fun.)
|
||||
|
||||
Brian Raiter
|
||||
breadbox@muppetlabs.com
|
||||
April, 1998
|
||||
|
||||
|
||||
Added for zlib 1.1.3:
|
||||
|
||||
The patches come from
|
||||
http://www.muppetlabs.com/~breadbox/software/assembly.html
|
||||
|
||||
To compile zlib with this asm file, copy match.S to the zlib directory
|
||||
then do:
|
||||
|
||||
CFLAGS="-O3 -DASMV" ./configure
|
||||
make OBJA=match.o
|
||||
|
||||
|
||||
Update:
|
||||
|
||||
I've been ignoring these assembly routines for years, believing that
|
||||
gcc's generated code had caught up with it sometime around gcc 2.95
|
||||
and the major rearchitecting of the Pentium 4. However, I recently
|
||||
learned that, despite what I believed, this code still has some life
|
||||
in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
|
||||
faster than the code produced by gcc 4.1.
|
||||
|
||||
In acknowledgement of its continuing usefulness, I've altered the
|
||||
license to match that of the rest of zlib. Share and Enjoy!
|
||||
|
||||
Brian Raiter
|
||||
breadbox@muppetlabs.com
|
||||
April, 2007
|
||||
|
|
@ -1,357 +0,0 @@
|
|||
/* match.S -- x86 assembly version of the zlib longest_match() function.
|
||||
* Optimized for the Intel 686 chips (PPro and later).
|
||||
*
|
||||
* Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the author be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef NO_UNDERLINE
|
||||
#define match_init _match_init
|
||||
#define longest_match _longest_match
|
||||
#endif
|
||||
|
||||
#define MAX_MATCH (258)
|
||||
#define MIN_MATCH (3)
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
|
||||
#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
|
||||
|
||||
/* stack frame offsets */
|
||||
|
||||
#define chainlenwmask 0 /* high word: current chain len */
|
||||
/* low word: s->wmask */
|
||||
#define window 4 /* local copy of s->window */
|
||||
#define windowbestlen 8 /* s->window + bestlen */
|
||||
#define scanstart 16 /* first two bytes of string */
|
||||
#define scanend 12 /* last two bytes of string */
|
||||
#define scanalign 20 /* dword-misalignment of string */
|
||||
#define nicematch 24 /* a good enough match size */
|
||||
#define bestlen 28 /* size of best match so far */
|
||||
#define scan 32 /* ptr to string wanting match */
|
||||
|
||||
#define LocalVarsSize (36)
|
||||
/* saved ebx 36 */
|
||||
/* saved edi 40 */
|
||||
/* saved esi 44 */
|
||||
/* saved ebp 48 */
|
||||
/* return address 52 */
|
||||
#define deflatestate 56 /* the function arguments */
|
||||
#define curmatch 60
|
||||
|
||||
/* All the +zlib1222add offsets are due to the addition of fields
|
||||
* in zlib in the deflate_state structure since the asm code was first written
|
||||
* (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
|
||||
* (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
|
||||
* if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
|
||||
*/
|
||||
|
||||
#define zlib1222add (8)
|
||||
|
||||
#define dsWSize (36+zlib1222add)
|
||||
#define dsWMask (44+zlib1222add)
|
||||
#define dsWindow (48+zlib1222add)
|
||||
#define dsPrev (56+zlib1222add)
|
||||
#define dsMatchLen (88+zlib1222add)
|
||||
#define dsPrevMatch (92+zlib1222add)
|
||||
#define dsStrStart (100+zlib1222add)
|
||||
#define dsMatchStart (104+zlib1222add)
|
||||
#define dsLookahead (108+zlib1222add)
|
||||
#define dsPrevLen (112+zlib1222add)
|
||||
#define dsMaxChainLen (116+zlib1222add)
|
||||
#define dsGoodMatch (132+zlib1222add)
|
||||
#define dsNiceMatch (136+zlib1222add)
|
||||
|
||||
|
||||
.file "match.S"
|
||||
|
||||
.globl match_init, longest_match
|
||||
|
||||
.text
|
||||
|
||||
/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
|
||||
.cfi_sections .debug_frame
|
||||
|
||||
longest_match:
|
||||
|
||||
.cfi_startproc
|
||||
/* Save registers that the compiler may be using, and adjust %esp to */
|
||||
/* make room for our stack frame. */
|
||||
|
||||
pushl %ebp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset ebp, -8
|
||||
pushl %edi
|
||||
.cfi_def_cfa_offset 12
|
||||
pushl %esi
|
||||
.cfi_def_cfa_offset 16
|
||||
pushl %ebx
|
||||
.cfi_def_cfa_offset 20
|
||||
subl $LocalVarsSize, %esp
|
||||
.cfi_def_cfa_offset LocalVarsSize+20
|
||||
|
||||
/* Retrieve the function arguments. %ecx will hold cur_match */
|
||||
/* throughout the entire function. %edx will hold the pointer to the */
|
||||
/* deflate_state structure during the function's setup (before */
|
||||
/* entering the main loop). */
|
||||
|
||||
movl deflatestate(%esp), %edx
|
||||
movl curmatch(%esp), %ecx
|
||||
|
||||
/* uInt wmask = s->w_mask; */
|
||||
/* unsigned chain_length = s->max_chain_length; */
|
||||
/* if (s->prev_length >= s->good_match) { */
|
||||
/* chain_length >>= 2; */
|
||||
/* } */
|
||||
|
||||
movl dsPrevLen(%edx), %eax
|
||||
movl dsGoodMatch(%edx), %ebx
|
||||
cmpl %ebx, %eax
|
||||
movl dsWMask(%edx), %eax
|
||||
movl dsMaxChainLen(%edx), %ebx
|
||||
jl LastMatchGood
|
||||
shrl $2, %ebx
|
||||
LastMatchGood:
|
||||
|
||||
/* chainlen is decremented once beforehand so that the function can */
|
||||
/* use the sign flag instead of the zero flag for the exit test. */
|
||||
/* It is then shifted into the high word, to make room for the wmask */
|
||||
/* value, which it will always accompany. */
|
||||
|
||||
decl %ebx
|
||||
shll $16, %ebx
|
||||
orl %eax, %ebx
|
||||
movl %ebx, chainlenwmask(%esp)
|
||||
|
||||
/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
|
||||
|
||||
movl dsNiceMatch(%edx), %eax
|
||||
movl dsLookahead(%edx), %ebx
|
||||
cmpl %eax, %ebx
|
||||
jl LookaheadLess
|
||||
movl %eax, %ebx
|
||||
LookaheadLess: movl %ebx, nicematch(%esp)
|
||||
|
||||
/* register Bytef *scan = s->window + s->strstart; */
|
||||
|
||||
movl dsWindow(%edx), %esi
|
||||
movl %esi, window(%esp)
|
||||
movl dsStrStart(%edx), %ebp
|
||||
lea (%esi,%ebp), %edi
|
||||
movl %edi, scan(%esp)
|
||||
|
||||
/* Determine how many bytes the scan ptr is off from being */
|
||||
/* dword-aligned. */
|
||||
|
||||
movl %edi, %eax
|
||||
negl %eax
|
||||
andl $3, %eax
|
||||
movl %eax, scanalign(%esp)
|
||||
|
||||
/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
|
||||
/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
|
||||
|
||||
movl dsWSize(%edx), %eax
|
||||
subl $MIN_LOOKAHEAD, %eax
|
||||
subl %eax, %ebp
|
||||
jg LimitPositive
|
||||
xorl %ebp, %ebp
|
||||
LimitPositive:
|
||||
|
||||
/* int best_len = s->prev_length; */
|
||||
|
||||
movl dsPrevLen(%edx), %eax
|
||||
movl %eax, bestlen(%esp)
|
||||
|
||||
/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
|
||||
|
||||
addl %eax, %esi
|
||||
movl %esi, windowbestlen(%esp)
|
||||
|
||||
/* register ush scan_start = *(ushf*)scan; */
|
||||
/* register ush scan_end = *(ushf*)(scan+best_len-1); */
|
||||
/* Posf *prev = s->prev; */
|
||||
|
||||
movzwl (%edi), %ebx
|
||||
movl %ebx, scanstart(%esp)
|
||||
movzwl -1(%edi,%eax), %ebx
|
||||
movl %ebx, scanend(%esp)
|
||||
movl dsPrev(%edx), %edi
|
||||
|
||||
/* Jump into the main loop. */
|
||||
|
||||
movl chainlenwmask(%esp), %edx
|
||||
jmp LoopEntry
|
||||
|
||||
.balign 16
|
||||
|
||||
/* do {
|
||||
* match = s->window + cur_match;
|
||||
* if (*(ushf*)(match+best_len-1) != scan_end ||
|
||||
* *(ushf*)match != scan_start) continue;
|
||||
* [...]
|
||||
* } while ((cur_match = prev[cur_match & wmask]) > limit
|
||||
* && --chain_length != 0);
|
||||
*
|
||||
* Here is the inner loop of the function. The function will spend the
|
||||
* majority of its time in this loop, and majority of that time will
|
||||
* be spent in the first ten instructions.
|
||||
*
|
||||
* Within this loop:
|
||||
* %ebx = scanend
|
||||
* %ecx = curmatch
|
||||
* %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
|
||||
* %esi = windowbestlen - i.e., (window + bestlen)
|
||||
* %edi = prev
|
||||
* %ebp = limit
|
||||
*/
|
||||
LookupLoop:
|
||||
andl %edx, %ecx
|
||||
movzwl (%edi,%ecx,2), %ecx
|
||||
cmpl %ebp, %ecx
|
||||
jbe LeaveNow
|
||||
subl $0x00010000, %edx
|
||||
js LeaveNow
|
||||
LoopEntry: movzwl -1(%esi,%ecx), %eax
|
||||
cmpl %ebx, %eax
|
||||
jnz LookupLoop
|
||||
movl window(%esp), %eax
|
||||
movzwl (%eax,%ecx), %eax
|
||||
cmpl scanstart(%esp), %eax
|
||||
jnz LookupLoop
|
||||
|
||||
/* Store the current value of chainlen. */
|
||||
|
||||
movl %edx, chainlenwmask(%esp)
|
||||
|
||||
/* Point %edi to the string under scrutiny, and %esi to the string we */
|
||||
/* are hoping to match it up with. In actuality, %esi and %edi are */
|
||||
/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
|
||||
/* initialized to -(MAX_MATCH_8 - scanalign). */
|
||||
|
||||
movl window(%esp), %esi
|
||||
movl scan(%esp), %edi
|
||||
addl %ecx, %esi
|
||||
movl scanalign(%esp), %eax
|
||||
movl $(-MAX_MATCH_8), %edx
|
||||
lea MAX_MATCH_8(%edi,%eax), %edi
|
||||
lea MAX_MATCH_8(%esi,%eax), %esi
|
||||
|
||||
/* Test the strings for equality, 8 bytes at a time. At the end,
|
||||
* adjust %edx so that it is offset to the exact byte that mismatched.
|
||||
*
|
||||
* We already know at this point that the first three bytes of the
|
||||
* strings match each other, and they can be safely passed over before
|
||||
* starting the compare loop. So what this code does is skip over 0-3
|
||||
* bytes, as much as necessary in order to dword-align the %edi
|
||||
* pointer. (%esi will still be misaligned three times out of four.)
|
||||
*
|
||||
* It should be confessed that this loop usually does not represent
|
||||
* much of the total running time. Replacing it with a more
|
||||
* straightforward "rep cmpsb" would not drastically degrade
|
||||
* performance.
|
||||
*/
|
||||
LoopCmps:
|
||||
movl (%esi,%edx), %eax
|
||||
xorl (%edi,%edx), %eax
|
||||
jnz LeaveLoopCmps
|
||||
movl 4(%esi,%edx), %eax
|
||||
xorl 4(%edi,%edx), %eax
|
||||
jnz LeaveLoopCmps4
|
||||
addl $8, %edx
|
||||
jnz LoopCmps
|
||||
jmp LenMaximum
|
||||
LeaveLoopCmps4: addl $4, %edx
|
||||
LeaveLoopCmps: testl $0x0000FFFF, %eax
|
||||
jnz LenLower
|
||||
addl $2, %edx
|
||||
shrl $16, %eax
|
||||
LenLower: subb $1, %al
|
||||
adcl $0, %edx
|
||||
|
||||
/* Calculate the length of the match. If it is longer than MAX_MATCH, */
|
||||
/* then automatically accept it as the best possible match and leave. */
|
||||
|
||||
lea (%edi,%edx), %eax
|
||||
movl scan(%esp), %edi
|
||||
subl %edi, %eax
|
||||
cmpl $MAX_MATCH, %eax
|
||||
jge LenMaximum
|
||||
|
||||
/* If the length of the match is not longer than the best match we */
|
||||
/* have so far, then forget it and return to the lookup loop. */
|
||||
|
||||
movl deflatestate(%esp), %edx
|
||||
movl bestlen(%esp), %ebx
|
||||
cmpl %ebx, %eax
|
||||
jg LongerMatch
|
||||
movl windowbestlen(%esp), %esi
|
||||
movl dsPrev(%edx), %edi
|
||||
movl scanend(%esp), %ebx
|
||||
movl chainlenwmask(%esp), %edx
|
||||
jmp LookupLoop
|
||||
|
||||
/* s->match_start = cur_match; */
|
||||
/* best_len = len; */
|
||||
/* if (len >= nice_match) break; */
|
||||
/* scan_end = *(ushf*)(scan+best_len-1); */
|
||||
|
||||
LongerMatch: movl nicematch(%esp), %ebx
|
||||
movl %eax, bestlen(%esp)
|
||||
movl %ecx, dsMatchStart(%edx)
|
||||
cmpl %ebx, %eax
|
||||
jge LeaveNow
|
||||
movl window(%esp), %esi
|
||||
addl %eax, %esi
|
||||
movl %esi, windowbestlen(%esp)
|
||||
movzwl -1(%edi,%eax), %ebx
|
||||
movl dsPrev(%edx), %edi
|
||||
movl %ebx, scanend(%esp)
|
||||
movl chainlenwmask(%esp), %edx
|
||||
jmp LookupLoop
|
||||
|
||||
/* Accept the current string, with the maximum possible length. */
|
||||
|
||||
LenMaximum: movl deflatestate(%esp), %edx
|
||||
movl $MAX_MATCH, bestlen(%esp)
|
||||
movl %ecx, dsMatchStart(%edx)
|
||||
|
||||
/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
|
||||
/* return s->lookahead; */
|
||||
|
||||
LeaveNow:
|
||||
movl deflatestate(%esp), %edx
|
||||
movl bestlen(%esp), %ebx
|
||||
movl dsLookahead(%edx), %eax
|
||||
cmpl %eax, %ebx
|
||||
jg LookaheadRet
|
||||
movl %ebx, %eax
|
||||
LookaheadRet:
|
||||
|
||||
/* Restore the stack and return from whence we came. */
|
||||
|
||||
addl $LocalVarsSize, %esp
|
||||
.cfi_def_cfa_offset 20
|
||||
popl %ebx
|
||||
.cfi_def_cfa_offset 16
|
||||
popl %esi
|
||||
.cfi_def_cfa_offset 12
|
||||
popl %edi
|
||||
.cfi_def_cfa_offset 8
|
||||
popl %ebp
|
||||
.cfi_def_cfa_offset 4
|
||||
.cfi_endproc
|
||||
match_init: ret
|
||||
|
|
@ -1,595 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/* Copyright (c) 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 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 Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 "ice_common.h"
|
||||
#include "ice_sriov.h"
|
||||
|
||||
/**
|
||||
* ice_aq_send_msg_to_vf
|
||||
* @hw: pointer to the hardware structure
|
||||
* @vfid: VF ID to send msg
|
||||
* @v_opcode: opcodes for VF-PF communication
|
||||
* @v_retval: return error code
|
||||
* @msg: pointer to the msg buffer
|
||||
* @msglen: msg length
|
||||
* @cd: pointer to command details
|
||||
*
|
||||
* Send message to VF driver (0x0802) using mailbox
|
||||
* queue and asynchronously sending message via
|
||||
* ice_sq_send_cmd() function
|
||||
*/
|
||||
enum ice_status
|
||||
ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
|
||||
u8 *msg, u16 msglen, struct ice_sq_cd *cd)
|
||||
{
|
||||
struct ice_aqc_pf_vf_msg *cmd;
|
||||
struct ice_aq_desc desc;
|
||||
|
||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_mbx_opc_send_msg_to_vf);
|
||||
|
||||
cmd = &desc.params.virt;
|
||||
cmd->id = CPU_TO_LE32(vfid);
|
||||
|
||||
desc.cookie_high = CPU_TO_LE32(v_opcode);
|
||||
desc.cookie_low = CPU_TO_LE32(v_retval);
|
||||
|
||||
if (msglen)
|
||||
desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
|
||||
|
||||
return ice_sq_send_cmd(hw, &hw->mailboxq, &desc, msg, msglen, cd);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_aq_send_msg_to_pf
|
||||
* @hw: pointer to the hardware structure
|
||||
* @v_opcode: opcodes for VF-PF communication
|
||||
* @v_retval: return error code
|
||||
* @msg: pointer to the msg buffer
|
||||
* @msglen: msg length
|
||||
* @cd: pointer to command details
|
||||
*
|
||||
* Send message to PF driver using mailbox queue. By default, this
|
||||
* message is sent asynchronously, i.e. ice_sq_send_cmd()
|
||||
* does not wait for completion before returning.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_aq_send_msg_to_pf(struct ice_hw *hw, enum virtchnl_ops v_opcode,
|
||||
enum ice_status v_retval, u8 *msg, u16 msglen,
|
||||
struct ice_sq_cd *cd)
|
||||
{
|
||||
struct ice_aq_desc desc;
|
||||
|
||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_mbx_opc_send_msg_to_pf);
|
||||
desc.cookie_high = CPU_TO_LE32(v_opcode);
|
||||
desc.cookie_low = CPU_TO_LE32(v_retval);
|
||||
|
||||
if (msglen)
|
||||
desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
|
||||
|
||||
return ice_sq_send_cmd(hw, &hw->mailboxq, &desc, msg, msglen, cd);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_conv_link_speed_to_virtchnl
|
||||
* @adv_link_support: determines the format of the returned link speed
|
||||
* @link_speed: variable containing the link_speed to be converted
|
||||
*
|
||||
* Convert link speed supported by HW to link speed supported by virtchnl.
|
||||
* If adv_link_support is true, then return link speed in Mbps. Else return
|
||||
* link speed as a VIRTCHNL_LINK_SPEED_* casted to a u32. Note that the caller
|
||||
* needs to cast back to an enum virtchnl_link_speed in the case where
|
||||
* adv_link_support is false, but when adv_link_support is true the caller can
|
||||
* expect the speed in Mbps.
|
||||
*/
|
||||
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
|
||||
{
|
||||
u32 speed;
|
||||
|
||||
if (adv_link_support)
|
||||
switch (link_speed) {
|
||||
case ICE_AQ_LINK_SPEED_10MB:
|
||||
speed = ICE_LINK_SPEED_10MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_100MB:
|
||||
speed = ICE_LINK_SPEED_100MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_1000MB:
|
||||
speed = ICE_LINK_SPEED_1000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_2500MB:
|
||||
speed = ICE_LINK_SPEED_2500MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_5GB:
|
||||
speed = ICE_LINK_SPEED_5000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_10GB:
|
||||
speed = ICE_LINK_SPEED_10000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_20GB:
|
||||
speed = ICE_LINK_SPEED_20000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_25GB:
|
||||
speed = ICE_LINK_SPEED_25000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_40GB:
|
||||
speed = ICE_LINK_SPEED_40000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_50GB:
|
||||
speed = ICE_LINK_SPEED_50000MBPS;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_100GB:
|
||||
speed = ICE_LINK_SPEED_100000MBPS;
|
||||
break;
|
||||
default:
|
||||
speed = ICE_LINK_SPEED_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* Virtchnl speeds are not defined for every speed supported in
|
||||
* the hardware. To maintain compatibility with older AVF
|
||||
* drivers, while reporting the speed the new speed values are
|
||||
* resolved to the closest known virtchnl speeds
|
||||
*/
|
||||
switch (link_speed) {
|
||||
case ICE_AQ_LINK_SPEED_10MB:
|
||||
case ICE_AQ_LINK_SPEED_100MB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_100MB;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_1000MB:
|
||||
case ICE_AQ_LINK_SPEED_2500MB:
|
||||
case ICE_AQ_LINK_SPEED_5GB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_1GB;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_10GB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_10GB;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_20GB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_20GB;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_25GB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_25GB;
|
||||
break;
|
||||
case ICE_AQ_LINK_SPEED_40GB:
|
||||
case ICE_AQ_LINK_SPEED_50GB:
|
||||
case ICE_AQ_LINK_SPEED_100GB:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_40GB;
|
||||
break;
|
||||
default:
|
||||
speed = (u32)VIRTCHNL_LINK_SPEED_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
/* The mailbox overflow detection algorithm helps to check if there
|
||||
* is a possibility of a malicious VF transmitting too many MBX messages to the
|
||||
* PF.
|
||||
* 1. The mailbox snapshot structure, ice_mbx_snapshot, is initialized during
|
||||
* driver initialization in ice_init_hw() using ice_mbx_init_snapshot().
|
||||
* The struct ice_mbx_snapshot helps to track and traverse a static window of
|
||||
* messages within the mailbox queue while looking for a malicious VF.
|
||||
*
|
||||
* 2. When the caller starts processing its mailbox queue in response to an
|
||||
* interrupt, the structure ice_mbx_snapshot is expected to be cleared before
|
||||
* the algorithm can be run for the first time for that interrupt. This can be
|
||||
* done via ice_mbx_reset_snapshot().
|
||||
*
|
||||
* 3. For every message read by the caller from the MBX Queue, the caller must
|
||||
* call the detection algorithm's entry function ice_mbx_vf_state_handler().
|
||||
* Before every call to ice_mbx_vf_state_handler() the struct ice_mbx_data is
|
||||
* filled as it is required to be passed to the algorithm.
|
||||
*
|
||||
* 4. Every time a message is read from the MBX queue, a VFId is received which
|
||||
* is passed to the state handler. The boolean output is_malvf of the state
|
||||
* handler ice_mbx_vf_state_handler() serves as an indicator to the caller
|
||||
* whether this VF is malicious or not.
|
||||
*
|
||||
* 5. When a VF is identified to be malicious, the caller can send a message
|
||||
* to the system administrator. The caller can invoke ice_mbx_report_malvf()
|
||||
* to help determine if a malicious VF is to be reported or not. This function
|
||||
* requires the caller to maintain a global bitmap to track all malicious VFs
|
||||
* and pass that to ice_mbx_report_malvf() along with the VFID which was identified
|
||||
* to be malicious by ice_mbx_vf_state_handler().
|
||||
*
|
||||
* 6. The global bitmap maintained by PF can be cleared completely if PF is in
|
||||
* reset or the bit corresponding to a VF can be cleared if that VF is in reset.
|
||||
* When a VF is shut down and brought back up, we assume that the new VF
|
||||
* brought up is not malicious and hence report it if found malicious.
|
||||
*
|
||||
* 7. The function ice_mbx_reset_snapshot() is called to reset the information
|
||||
* in ice_mbx_snapshot for every new mailbox interrupt handled.
|
||||
*
|
||||
* 8. The memory allocated for variables in ice_mbx_snapshot is de-allocated
|
||||
* when driver is unloaded.
|
||||
*/
|
||||
#define ICE_RQ_DATA_MASK(rq_data) ((rq_data) & PF_MBX_ARQH_ARQH_M)
|
||||
/* Using the highest value for an unsigned 16-bit value 0xFFFF to indicate that
|
||||
* the max messages check must be ignored in the algorithm
|
||||
*/
|
||||
#define ICE_IGNORE_MAX_MSG_CNT 0xFFFF
|
||||
|
||||
/**
|
||||
* ice_mbx_traverse - Pass through mailbox snapshot
|
||||
* @hw: pointer to the HW struct
|
||||
* @new_state: new algorithm state
|
||||
*
|
||||
* Traversing the mailbox static snapshot without checking
|
||||
* for malicious VFs.
|
||||
*/
|
||||
static void
|
||||
ice_mbx_traverse(struct ice_hw *hw,
|
||||
enum ice_mbx_snapshot_state *new_state)
|
||||
{
|
||||
struct ice_mbx_snap_buffer_data *snap_buf;
|
||||
u32 num_iterations;
|
||||
|
||||
snap_buf = &hw->mbx_snapshot.mbx_buf;
|
||||
|
||||
/* As mailbox buffer is circular, applying a mask
|
||||
* on the incremented iteration count.
|
||||
*/
|
||||
num_iterations = ICE_RQ_DATA_MASK(++snap_buf->num_iterations);
|
||||
|
||||
/* Checking either of the below conditions to exit snapshot traversal:
|
||||
* Condition-1: If the number of iterations in the mailbox is equal to
|
||||
* the mailbox head which would indicate that we have reached the end
|
||||
* of the static snapshot.
|
||||
* Condition-2: If the maximum messages serviced in the mailbox for a
|
||||
* given interrupt is the highest possible value then there is no need
|
||||
* to check if the number of messages processed is equal to it. If not
|
||||
* check if the number of messages processed is greater than or equal
|
||||
* to the maximum number of mailbox entries serviced in current work item.
|
||||
*/
|
||||
if (num_iterations == snap_buf->head ||
|
||||
(snap_buf->max_num_msgs_mbx < ICE_IGNORE_MAX_MSG_CNT &&
|
||||
++snap_buf->num_msg_proc >= snap_buf->max_num_msgs_mbx))
|
||||
*new_state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_detect_malvf - Detect malicious VF in snapshot
|
||||
* @hw: pointer to the HW struct
|
||||
* @vf_id: relative virtual function ID
|
||||
* @new_state: new algorithm state
|
||||
* @is_malvf: boolean output to indicate if VF is malicious
|
||||
*
|
||||
* This function tracks the number of asynchronous messages
|
||||
* sent per VF and marks the VF as malicious if it exceeds
|
||||
* the permissible number of messages to send.
|
||||
*/
|
||||
static enum ice_status
|
||||
ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,
|
||||
enum ice_mbx_snapshot_state *new_state,
|
||||
bool *is_malvf)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
|
||||
if (vf_id >= snap->mbx_vf.vfcntr_len)
|
||||
return ICE_ERR_OUT_OF_RANGE;
|
||||
|
||||
/* increment the message count in the VF array */
|
||||
snap->mbx_vf.vf_cntr[vf_id]++;
|
||||
|
||||
if (snap->mbx_vf.vf_cntr[vf_id] >= ICE_ASYNC_VF_MSG_THRESHOLD)
|
||||
*is_malvf = true;
|
||||
|
||||
/* continue to iterate through the mailbox snapshot */
|
||||
ice_mbx_traverse(hw, new_state);
|
||||
|
||||
return ICE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_reset_snapshot - Reset mailbox snapshot structure
|
||||
* @snap: pointer to mailbox snapshot structure in the ice_hw struct
|
||||
*
|
||||
* Reset the mailbox snapshot structure and clear VF counter array.
|
||||
*/
|
||||
static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap)
|
||||
{
|
||||
u32 vfcntr_len;
|
||||
|
||||
if (!snap || !snap->mbx_vf.vf_cntr)
|
||||
return;
|
||||
|
||||
/* Clear VF counters. */
|
||||
vfcntr_len = snap->mbx_vf.vfcntr_len;
|
||||
if (vfcntr_len)
|
||||
ice_memset(snap->mbx_vf.vf_cntr, 0,
|
||||
(vfcntr_len * sizeof(*snap->mbx_vf.vf_cntr)),
|
||||
ICE_NONDMA_MEM);
|
||||
|
||||
/* Reset mailbox snapshot for a new capture. */
|
||||
ice_memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf),
|
||||
ICE_NONDMA_MEM);
|
||||
snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_vf_state_handler - Handle states of the overflow algorithm
|
||||
* @hw: pointer to the HW struct
|
||||
* @mbx_data: pointer to structure containing mailbox data
|
||||
* @vf_id: relative virtual function (VF) ID
|
||||
* @is_malvf: boolean output to indicate if VF is malicious
|
||||
*
|
||||
* The function serves as an entry point for the malicious VF
|
||||
* detection algorithm by handling the different states and state
|
||||
* transitions of the algorithm:
|
||||
* New snapshot: This state is entered when creating a new static
|
||||
* snapshot. The data from any previous mailbox snapshot is
|
||||
* cleared and a new capture of the mailbox head and tail is
|
||||
* logged. This will be the new static snapshot to detect
|
||||
* asynchronous messages sent by VFs. On capturing the snapshot
|
||||
* and depending on whether the number of pending messages in that
|
||||
* snapshot exceed the watermark value, the state machine enters
|
||||
* traverse or detect states.
|
||||
* Traverse: If pending message count is below watermark then iterate
|
||||
* through the snapshot without any action on VF.
|
||||
* Detect: If pending message count exceeds watermark traverse
|
||||
* the static snapshot and look for a malicious VF.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_mbx_vf_state_handler(struct ice_hw *hw,
|
||||
struct ice_mbx_data *mbx_data, u16 vf_id,
|
||||
bool *is_malvf)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
struct ice_mbx_snap_buffer_data *snap_buf;
|
||||
struct ice_ctl_q_info *cq = &hw->mailboxq;
|
||||
enum ice_mbx_snapshot_state new_state;
|
||||
enum ice_status status = ICE_SUCCESS;
|
||||
|
||||
if (!is_malvf || !mbx_data)
|
||||
return ICE_ERR_BAD_PTR;
|
||||
|
||||
/* When entering the mailbox state machine assume that the VF
|
||||
* is not malicious until detected.
|
||||
*/
|
||||
*is_malvf = false;
|
||||
|
||||
/* Checking if max messages allowed to be processed while servicing current
|
||||
* interrupt is not less than the defined AVF message threshold.
|
||||
*/
|
||||
if (mbx_data->max_num_msgs_mbx <= ICE_ASYNC_VF_MSG_THRESHOLD)
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
|
||||
/* The watermark value should not be lesser than the threshold limit
|
||||
* set for the number of asynchronous messages a VF can send to mailbox
|
||||
* nor should it be greater than the maximum number of messages in the
|
||||
* mailbox serviced in current interrupt.
|
||||
*/
|
||||
if (mbx_data->async_watermark_val < ICE_ASYNC_VF_MSG_THRESHOLD ||
|
||||
mbx_data->async_watermark_val > mbx_data->max_num_msgs_mbx)
|
||||
return ICE_ERR_PARAM;
|
||||
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
|
||||
snap_buf = &snap->mbx_buf;
|
||||
|
||||
switch (snap_buf->state) {
|
||||
case ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT:
|
||||
/* Clear any previously held data in mailbox snapshot structure. */
|
||||
ice_mbx_reset_snapshot(snap);
|
||||
|
||||
/* Collect the pending ARQ count, number of messages processed and
|
||||
* the maximum number of messages allowed to be processed from the
|
||||
* Mailbox for current interrupt.
|
||||
*/
|
||||
snap_buf->num_pending_arq = mbx_data->num_pending_arq;
|
||||
snap_buf->num_msg_proc = mbx_data->num_msg_proc;
|
||||
snap_buf->max_num_msgs_mbx = mbx_data->max_num_msgs_mbx;
|
||||
|
||||
/* Capture a new static snapshot of the mailbox by logging the
|
||||
* head and tail of snapshot and set num_iterations to the tail
|
||||
* value to mark the start of the iteration through the snapshot.
|
||||
*/
|
||||
snap_buf->head = ICE_RQ_DATA_MASK(cq->rq.next_to_clean +
|
||||
mbx_data->num_pending_arq);
|
||||
snap_buf->tail = ICE_RQ_DATA_MASK(cq->rq.next_to_clean - 1);
|
||||
snap_buf->num_iterations = snap_buf->tail;
|
||||
|
||||
/* Pending ARQ messages returned by ice_clean_rq_elem
|
||||
* is the difference between the head and tail of the
|
||||
* mailbox queue. Comparing this value against the watermark
|
||||
* helps to check if we potentially have malicious VFs.
|
||||
*/
|
||||
if (snap_buf->num_pending_arq >=
|
||||
mbx_data->async_watermark_val) {
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
|
||||
status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
|
||||
} else {
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
|
||||
ice_mbx_traverse(hw, &new_state);
|
||||
}
|
||||
break;
|
||||
|
||||
case ICE_MAL_VF_DETECT_STATE_TRAVERSE:
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
|
||||
ice_mbx_traverse(hw, &new_state);
|
||||
break;
|
||||
|
||||
case ICE_MAL_VF_DETECT_STATE_DETECT:
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
|
||||
status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
|
||||
break;
|
||||
|
||||
default:
|
||||
new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
|
||||
status = ICE_ERR_CFG;
|
||||
}
|
||||
|
||||
snap_buf->state = new_state;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_report_malvf - Track and note malicious VF
|
||||
* @hw: pointer to the HW struct
|
||||
* @all_malvfs: all malicious VFs tracked by PF
|
||||
* @bitmap_len: length of bitmap in bits
|
||||
* @vf_id: relative virtual function ID of the malicious VF
|
||||
* @report_malvf: boolean to indicate if malicious VF must be reported
|
||||
*
|
||||
* This function will update a bitmap that keeps track of the malicious
|
||||
* VFs attached to the PF. A malicious VF must be reported only once if
|
||||
* discovered between VF resets or loading so the function checks
|
||||
* the input vf_id against the bitmap to verify if the VF has been
|
||||
* detected in any previous mailbox iterations.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_mbx_report_malvf(struct ice_hw *hw, ice_bitmap_t *all_malvfs,
|
||||
u16 bitmap_len, u16 vf_id, bool *report_malvf)
|
||||
{
|
||||
if (!all_malvfs || !report_malvf)
|
||||
return ICE_ERR_PARAM;
|
||||
|
||||
*report_malvf = false;
|
||||
|
||||
if (bitmap_len < hw->mbx_snapshot.mbx_vf.vfcntr_len)
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
|
||||
if (vf_id >= bitmap_len)
|
||||
return ICE_ERR_OUT_OF_RANGE;
|
||||
|
||||
/* If the vf_id is found in the bitmap set bit and boolean to true */
|
||||
if (!ice_is_bit_set(all_malvfs, vf_id)) {
|
||||
ice_set_bit(vf_id, all_malvfs);
|
||||
ice_debug(hw, ICE_DBG_TRACE, "Malicious VF=%d found\n", vf_id);
|
||||
*report_malvf = true;
|
||||
}
|
||||
|
||||
return ICE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID
|
||||
* @snap: pointer to the mailbox snapshot structure
|
||||
* @all_malvfs: all malicious VFs tracked by PF
|
||||
* @bitmap_len: length of bitmap in bits
|
||||
* @vf_id: relative virtual function ID of the malicious VF
|
||||
*
|
||||
* In case of a VF reset, this function can be called to clear
|
||||
* the bit corresponding to the VF ID in the bitmap tracking all
|
||||
* malicious VFs attached to the PF. The function also clears the
|
||||
* VF counter array at the index of the VF ID. This is to ensure
|
||||
* that the new VF loaded is not considered malicious before going
|
||||
* through the overflow detection algorithm.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, ice_bitmap_t *all_malvfs,
|
||||
u16 bitmap_len, u16 vf_id)
|
||||
{
|
||||
if (!snap || !all_malvfs)
|
||||
return ICE_ERR_PARAM;
|
||||
|
||||
if (bitmap_len < snap->mbx_vf.vfcntr_len)
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
|
||||
/* Ensure VF ID value is not larger than bitmap or VF counter length */
|
||||
if (vf_id >= bitmap_len || vf_id >= snap->mbx_vf.vfcntr_len)
|
||||
return ICE_ERR_OUT_OF_RANGE;
|
||||
|
||||
/* Clear VF ID bit in the bitmap tracking malicious VFs attached to PF */
|
||||
ice_clear_bit(vf_id, all_malvfs);
|
||||
|
||||
/* Clear the VF counter in the mailbox snapshot structure for that VF ID.
|
||||
* This is to ensure that if a VF is unloaded and a new one brought back
|
||||
* up with the same VF ID for a snapshot currently in traversal or detect
|
||||
* state the counter for that VF ID does not increment on top of existing
|
||||
* values in the mailbox overflow detection algorithm.
|
||||
*/
|
||||
snap->mbx_vf.vf_cntr[vf_id] = 0;
|
||||
|
||||
return ICE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_init_snapshot - Initialize mailbox snapshot structure
|
||||
* @hw: pointer to the hardware structure
|
||||
* @vf_count: number of VFs allocated on a PF
|
||||
*
|
||||
* Clear the mailbox snapshot structure and allocate memory
|
||||
* for the VF counter array based on the number of VFs allocated
|
||||
* on that PF.
|
||||
*
|
||||
* Assumption: This function will assume ice_get_caps() has already been
|
||||
* called to ensure that the vf_count can be compared against the number
|
||||
* of VFs supported as defined in the functional capabilities of the device.
|
||||
*/
|
||||
enum ice_status ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
|
||||
/* Ensure that the number of VFs allocated is non-zero and
|
||||
* is not greater than the number of supported VFs defined in
|
||||
* the functional capabilities of the PF.
|
||||
*/
|
||||
if (!vf_count || vf_count > hw->func_caps.num_allocd_vfs)
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
|
||||
snap->mbx_vf.vf_cntr =
|
||||
(u32 *)ice_calloc(hw, vf_count,
|
||||
sizeof(*snap->mbx_vf.vf_cntr));
|
||||
if (!snap->mbx_vf.vf_cntr)
|
||||
return ICE_ERR_NO_MEMORY;
|
||||
|
||||
/* Setting the VF counter length to the number of allocated
|
||||
* VFs for given PF's functional capabilities.
|
||||
*/
|
||||
snap->mbx_vf.vfcntr_len = vf_count;
|
||||
|
||||
/* Clear mbx_buf in the mailbox snaphot structure and setting the
|
||||
* mailbox snapshot state to a new capture.
|
||||
*/
|
||||
ice_memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf), ICE_NONDMA_MEM);
|
||||
snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
|
||||
|
||||
return ICE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_mbx_deinit_snapshot - Free mailbox snapshot structure
|
||||
* @hw: pointer to the hardware structure
|
||||
*
|
||||
* Clear the mailbox snapshot structure and free the VF counter array.
|
||||
*/
|
||||
void ice_mbx_deinit_snapshot(struct ice_hw *hw)
|
||||
{
|
||||
struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
|
||||
|
||||
/* Free VF counter array and reset vf counter length */
|
||||
ice_free(hw, snap->mbx_vf.vf_cntr);
|
||||
snap->mbx_vf.vfcntr_len = 0;
|
||||
|
||||
/* Clear mbx_buf in the mailbox snaphot structure */
|
||||
ice_memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf), ICE_NONDMA_MEM);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/* Copyright (c) 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 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 Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef _ICE_SRIOV_H_
|
||||
#define _ICE_SRIOV_H_
|
||||
|
||||
#include "ice_type.h"
|
||||
#include "ice_controlq.h"
|
||||
|
||||
/* Defining the mailbox message threshold as 63 asynchronous
|
||||
* pending messages. Normal VF functionality does not require
|
||||
* sending more than 63 asynchronous pending message.
|
||||
*/
|
||||
#define ICE_ASYNC_VF_MSG_THRESHOLD 63
|
||||
|
||||
enum ice_status
|
||||
ice_aq_send_msg_to_pf(struct ice_hw *hw, enum virtchnl_ops v_opcode,
|
||||
enum ice_status v_retval, u8 *msg, u16 msglen,
|
||||
struct ice_sq_cd *cd);
|
||||
enum ice_status
|
||||
ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
|
||||
u8 *msg, u16 msglen, struct ice_sq_cd *cd);
|
||||
|
||||
u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed);
|
||||
enum ice_status
|
||||
ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
|
||||
u16 vf_id, bool *is_mal_vf);
|
||||
enum ice_status
|
||||
ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, ice_bitmap_t *all_malvfs,
|
||||
u16 bitmap_len, u16 vf_id);
|
||||
enum ice_status ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count);
|
||||
void ice_mbx_deinit_snapshot(struct ice_hw *hw);
|
||||
enum ice_status
|
||||
ice_mbx_report_malvf(struct ice_hw *hw, ice_bitmap_t *all_malvfs,
|
||||
u16 bitmap_len, u16 vf_id, bool *report_malvf);
|
||||
#endif /* _ICE_SRIOV_H_ */
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
/*-
|
||||
* Copyright 2000-2020 Broadcom 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.
|
||||
* 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.
|
||||
*
|
||||
* Broadcom Inc. (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2000-2020 Broadcom Inc. 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.03
|
||||
*
|
||||
* 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.
|
||||
* 07-22-18 02.00.03 Updted flags field for NVME Encapsulated req
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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_MASK_ERROR_RSP_ADDR_MASK (0x000C)
|
||||
#define MPI26_NVME_FLAGS_SYSTEM_RSP_ADDR (0x0000)
|
||||
#define MPI26_NVME_FLAGS_IOCCTL_RSP_ADDR (0x0008)
|
||||
/* 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
|
||||
|
|
@ -232,7 +232,7 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
|
|||
}
|
||||
|
||||
static void
|
||||
nvme_ctrlr_fail(struct nvme_controller *ctrlr, bool admin_also)
|
||||
nvme_ctrlr_fail(struct nvme_controller *ctrlr)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -242,10 +242,7 @@ nvme_ctrlr_fail(struct nvme_controller *ctrlr, bool admin_also)
|
|||
* a different error, though when we fail, that hardly matters).
|
||||
*/
|
||||
ctrlr->is_failed = true;
|
||||
if (admin_also) {
|
||||
ctrlr->is_failed_admin = true;
|
||||
nvme_qpair_fail(&ctrlr->adminq);
|
||||
}
|
||||
nvme_qpair_fail(&ctrlr->adminq);
|
||||
if (ctrlr->ioq != NULL) {
|
||||
for (i = 0; i < ctrlr->num_io_queues; i++) {
|
||||
nvme_qpair_fail(&ctrlr->ioq[i]);
|
||||
|
|
@ -418,7 +415,6 @@ nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr)
|
|||
|
||||
TSENTER();
|
||||
|
||||
ctrlr->is_failed_admin = true;
|
||||
nvme_ctrlr_disable_qpairs(ctrlr);
|
||||
|
||||
err = nvme_ctrlr_disable(ctrlr);
|
||||
|
|
@ -427,8 +423,6 @@ nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr)
|
|||
|
||||
err = nvme_ctrlr_enable(ctrlr);
|
||||
out:
|
||||
if (err == 0)
|
||||
ctrlr->is_failed_admin = false;
|
||||
|
||||
TSEXIT();
|
||||
return (err);
|
||||
|
|
@ -441,10 +435,11 @@ nvme_ctrlr_reset(struct nvme_controller *ctrlr)
|
|||
|
||||
cmpset = atomic_cmpset_32(&ctrlr->is_resetting, 0, 1);
|
||||
|
||||
if (cmpset == 0)
|
||||
if (cmpset == 0 || ctrlr->is_failed)
|
||||
/*
|
||||
* Controller is already resetting. Return immediately since
|
||||
* there is no need to kick off another reset.
|
||||
* Controller is already resetting or has failed. Return
|
||||
* immediately since there is no need to kick off another
|
||||
* reset in these cases.
|
||||
*/
|
||||
return;
|
||||
|
||||
|
|
@ -1095,7 +1090,7 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
|
|||
return;
|
||||
|
||||
if (resetting && nvme_ctrlr_identify(ctrlr) != 0) {
|
||||
nvme_ctrlr_fail(ctrlr, false);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1110,7 +1105,7 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
|
|||
if (resetting) {
|
||||
old_num_io_queues = ctrlr->num_io_queues;
|
||||
if (nvme_ctrlr_set_num_qpairs(ctrlr) != 0) {
|
||||
nvme_ctrlr_fail(ctrlr, false);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1128,12 +1123,12 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
|
|||
nvme_ctrlr_hmb_enable(ctrlr, true, true);
|
||||
|
||||
if (nvme_ctrlr_create_qpairs(ctrlr) != 0) {
|
||||
nvme_ctrlr_fail(ctrlr, false);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nvme_ctrlr_construct_namespaces(ctrlr) != 0) {
|
||||
nvme_ctrlr_fail(ctrlr, false);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1153,7 +1148,8 @@ nvme_ctrlr_start_config_hook(void *arg)
|
|||
TSENTER();
|
||||
|
||||
if (nvme_ctrlr_hw_reset(ctrlr) != 0) {
|
||||
nvme_ctrlr_fail(ctrlr, true);
|
||||
fail:
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
config_intrhook_disestablish(&ctrlr->config_hook);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1166,15 +1162,13 @@ nvme_ctrlr_start_config_hook(void *arg)
|
|||
nvme_ctrlr_construct_io_qpairs(ctrlr) == 0)
|
||||
nvme_ctrlr_start(ctrlr, false);
|
||||
else
|
||||
nvme_ctrlr_fail(ctrlr, false);
|
||||
goto fail;
|
||||
|
||||
nvme_sysctl_initialize_ctrlr(ctrlr);
|
||||
config_intrhook_disestablish(&ctrlr->config_hook);
|
||||
|
||||
if (!ctrlr->is_failed) {
|
||||
ctrlr->is_initialized = true;
|
||||
nvme_notify_new_controller(ctrlr);
|
||||
}
|
||||
ctrlr->is_initialized = true;
|
||||
nvme_notify_new_controller(ctrlr);
|
||||
TSEXIT();
|
||||
}
|
||||
|
||||
|
|
@ -1191,7 +1185,7 @@ nvme_ctrlr_reset_task(void *arg, int pending)
|
|||
nvme_ctrlr_start(ctrlr, true);
|
||||
} else {
|
||||
nvme_ctrlr_devctl_log(ctrlr, "RESET", "event=\"timed_out\"");
|
||||
nvme_ctrlr_fail(ctrlr, true);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
}
|
||||
|
||||
atomic_cmpset_32(&ctrlr->is_resetting, 1, 0);
|
||||
|
|
@ -1618,7 +1612,7 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev)
|
|||
*/
|
||||
gone = (nvme_mmio_read_4(ctrlr, csts) == NVME_GONE);
|
||||
if (gone)
|
||||
nvme_ctrlr_fail(ctrlr, true);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
else
|
||||
nvme_notify_fail_consumers(ctrlr);
|
||||
|
||||
|
|
@ -1748,9 +1742,7 @@ nvme_ctrlr_suspend(struct nvme_controller *ctrlr)
|
|||
int to = hz;
|
||||
|
||||
/*
|
||||
* Can't touch failed controllers, so it's already suspended. User will
|
||||
* need to do an explicit reset to bring it back, if that's even
|
||||
* possible.
|
||||
* Can't touch failed controllers, so it's already suspended.
|
||||
*/
|
||||
if (ctrlr->is_failed)
|
||||
return (0);
|
||||
|
|
@ -1817,7 +1809,7 @@ fail:
|
|||
* itself, due to questionable APIs.
|
||||
*/
|
||||
nvme_printf(ctrlr, "Failed to reset on resume, failing.\n");
|
||||
nvme_ctrlr_fail(ctrlr, true);
|
||||
nvme_ctrlr_fail(ctrlr);
|
||||
(void)atomic_cmpset_32(&ctrlr->is_resetting, 1, 0);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,7 +301,6 @@ struct nvme_controller {
|
|||
uint32_t notification_sent;
|
||||
|
||||
bool is_failed;
|
||||
bool is_failed_admin;
|
||||
bool is_dying;
|
||||
bool isr_warned;
|
||||
bool is_initialized;
|
||||
|
|
|
|||
|
|
@ -1046,7 +1046,6 @@ nvme_qpair_timeout(void *arg)
|
|||
struct nvme_tracker *tr;
|
||||
sbintime_t now;
|
||||
bool idle = true;
|
||||
bool is_admin = qpair == &ctrlr->adminq;
|
||||
bool fast;
|
||||
uint32_t csts;
|
||||
uint8_t cfs;
|
||||
|
|
@ -1058,10 +1057,9 @@ nvme_qpair_timeout(void *arg)
|
|||
* failure processing that races with the qpair timeout will fail
|
||||
* safely.
|
||||
*/
|
||||
if (is_admin ? qpair->ctrlr->is_failed_admin : qpair->ctrlr->is_failed) {
|
||||
if (qpair->ctrlr->is_failed) {
|
||||
nvme_printf(qpair->ctrlr,
|
||||
"%sFailed controller, stopping watchdog timeout.\n",
|
||||
is_admin ? "Complete " : "");
|
||||
"Failed controller, stopping watchdog timeout.\n");
|
||||
qpair->timer_armed = false;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1331,7 +1329,6 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
|
|||
{
|
||||
struct nvme_tracker *tr;
|
||||
int err = 0;
|
||||
bool is_admin = qpair == &qpair->ctrlr->adminq;
|
||||
|
||||
mtx_assert(&qpair->lock, MA_OWNED);
|
||||
|
||||
|
|
@ -1341,14 +1338,12 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
|
|||
/*
|
||||
* The controller has failed, so fail the request. Note, that this races
|
||||
* the recovery / timeout code. Since we hold the qpair lock, we know
|
||||
* it's safe to fail directly. is_failed is set when we fail the
|
||||
* controller. It is only ever reset in the ioctl reset controller
|
||||
* path, which is safe to race (for failed controllers, we make no
|
||||
* guarantees about bringing it out of failed state relative to other
|
||||
* commands). We try hard to allow admin commands when the entire
|
||||
* controller hasn't failed, only something related to I/O queues.
|
||||
* it's safe to fail directly. is_failed is set when we fail the controller.
|
||||
* It is only ever reset in the ioctl reset controller path, which is safe
|
||||
* to race (for failed controllers, we make no guarantees about bringing
|
||||
* it out of failed state relative to other commands).
|
||||
*/
|
||||
if (is_admin ? qpair->ctrlr->is_failed_admin : qpair->ctrlr->is_failed) {
|
||||
if (qpair->ctrlr->is_failed) {
|
||||
nvme_qpair_manual_complete_request(qpair, req,
|
||||
NVME_SCT_GENERIC, NVME_SC_ABORTED_BY_REQUEST, 1,
|
||||
ERROR_PRINT_NONE);
|
||||
|
|
@ -1415,13 +1410,11 @@ nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
|
|||
static void
|
||||
nvme_qpair_enable(struct nvme_qpair *qpair)
|
||||
{
|
||||
bool is_admin __unused = qpair == &qpair->ctrlr->adminq;
|
||||
|
||||
if (mtx_initialized(&qpair->recovery))
|
||||
mtx_assert(&qpair->recovery, MA_OWNED);
|
||||
if (mtx_initialized(&qpair->lock))
|
||||
mtx_assert(&qpair->lock, MA_OWNED);
|
||||
KASSERT(!(is_admin ? qpair->ctrlr->is_failed_admin : qpair->ctrlr->is_failed),
|
||||
KASSERT(!qpair->ctrlr->is_failed,
|
||||
("Enabling a failed qpair\n"));
|
||||
|
||||
qpair->recovery_state = RECOVERY_NONE;
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
|
|||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
break;
|
||||
case XPT_NVME_IO: /* Execute the requested I/O operation */
|
||||
case XPT_NVME_ADMIN: /* or Admin operation */
|
||||
if (ctrlr->is_failed) {
|
||||
/*
|
||||
* I/O came in while we were failing the drive, so drop
|
||||
|
|
@ -278,18 +279,6 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
|
|||
}
|
||||
nvme_sim_nvmeio(sim, ccb);
|
||||
return; /* no done */
|
||||
case XPT_NVME_ADMIN: /* or Admin operation */
|
||||
if (ctrlr->is_failed_admin) {
|
||||
/*
|
||||
* Admin request came in when we can't send admin
|
||||
* commands, so drop it. Once falure is complete, we'll
|
||||
* be destroyed.
|
||||
*/
|
||||
ccb->ccb_h.status = CAM_DEV_NOT_THERE;
|
||||
break;
|
||||
}
|
||||
nvme_sim_nvmeio(sim, ccb);
|
||||
return; /* no done */
|
||||
default:
|
||||
ccb->ccb_h.status = CAM_REQ_INVALID;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,686 +0,0 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_snd.h"
|
||||
#endif
|
||||
|
||||
#include <dev/sound/pcm/sound.h>
|
||||
#include <dev/sound/pcm/ac97.h>
|
||||
#include <dev/sound/pci/aureal.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
SND_DECLARE_FILE("");
|
||||
|
||||
/* PCI IDs of supported chips */
|
||||
#define AU8820_PCI_ID 0x000112eb
|
||||
|
||||
/* channel interface */
|
||||
static u_int32_t au_playfmt[] = {
|
||||
SND_FORMAT(AFMT_U8, 1, 0),
|
||||
SND_FORMAT(AFMT_U8, 2, 0),
|
||||
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
||||
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
||||
0
|
||||
};
|
||||
static struct pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0};
|
||||
|
||||
static u_int32_t au_recfmt[] = {
|
||||
SND_FORMAT(AFMT_U8, 1, 0),
|
||||
SND_FORMAT(AFMT_U8, 2, 0),
|
||||
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
||||
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
||||
0
|
||||
};
|
||||
static struct pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
struct au_info;
|
||||
|
||||
struct au_chinfo {
|
||||
struct au_info *parent;
|
||||
struct pcm_channel *channel;
|
||||
struct snd_dbuf *buffer;
|
||||
int dir;
|
||||
};
|
||||
|
||||
struct au_info {
|
||||
int unit;
|
||||
|
||||
bus_space_tag_t st[3];
|
||||
bus_space_handle_t sh[3];
|
||||
|
||||
bus_dma_tag_t parent_dmat;
|
||||
struct mtx *lock;
|
||||
|
||||
u_int32_t x[32], y[128];
|
||||
char z[128];
|
||||
u_int32_t routes[4], interrupts;
|
||||
struct au_chinfo pch;
|
||||
};
|
||||
|
||||
static int au_init(device_t dev, struct au_info *au);
|
||||
static void au_intr(void *);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static u_int32_t
|
||||
au_rd(struct au_info *au, int mapno, int regno, int size)
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
return bus_space_read_1(au->st[mapno], au->sh[mapno], regno);
|
||||
case 2:
|
||||
return bus_space_read_2(au->st[mapno], au->sh[mapno], regno);
|
||||
case 4:
|
||||
return bus_space_read_4(au->st[mapno], au->sh[mapno], regno);
|
||||
default:
|
||||
return 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
au_wr(struct au_info *au, int mapno, int regno, u_int32_t data, int size)
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
bus_space_write_1(au->st[mapno], au->sh[mapno], regno, data);
|
||||
break;
|
||||
case 2:
|
||||
bus_space_write_2(au->st[mapno], au->sh[mapno], regno, data);
|
||||
break;
|
||||
case 4:
|
||||
bus_space_write_4(au->st[mapno], au->sh[mapno], regno, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
au_rdcd(kobj_t obj, void *arg, int regno)
|
||||
{
|
||||
struct au_info *au = (struct au_info *)arg;
|
||||
int i=0, j=0;
|
||||
|
||||
regno<<=16;
|
||||
au_wr(au, 0, AU_REG_CODECIO, regno, 4);
|
||||
while (j<50) {
|
||||
i=au_rd(au, 0, AU_REG_CODECIO, 4);
|
||||
if ((i & 0x00ff0000) == (regno | 0x00800000)) break;
|
||||
DELAY(j * 200 + 2000);
|
||||
j++;
|
||||
}
|
||||
if (j==50) printf("pcm%d: codec timeout reading register %x (%x)\n",
|
||||
au->unit, (regno & AU_CDC_REGMASK)>>16, i);
|
||||
return i & AU_CDC_DATAMASK;
|
||||
}
|
||||
|
||||
static int
|
||||
au_wrcd(kobj_t obj, void *arg, int regno, u_int32_t data)
|
||||
{
|
||||
struct au_info *au = (struct au_info *)arg;
|
||||
int i, j, tries;
|
||||
i=j=tries=0;
|
||||
do {
|
||||
while (j<50 && (i & AU_CDC_WROK) == 0) {
|
||||
i=au_rd(au, 0, AU_REG_CODECST, 4);
|
||||
DELAY(2000);
|
||||
j++;
|
||||
}
|
||||
if (j==50) printf("codec timeout during write of register %x, data %x\n",
|
||||
regno, data);
|
||||
au_wr(au, 0, AU_REG_CODECIO, (regno<<16) | AU_CDC_REGSET | data, 4);
|
||||
/* DELAY(20000);
|
||||
i=au_rdcd(au, regno);
|
||||
*/ tries++;
|
||||
} while (0); /* (i != data && tries < 3); */
|
||||
/*
|
||||
if (tries == 3) printf("giving up writing 0x%4x to codec reg %2x\n", data, regno);
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static kobj_method_t au_ac97_methods[] = {
|
||||
KOBJMETHOD(ac97_read, au_rdcd),
|
||||
KOBJMETHOD(ac97_write, au_wrcd),
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
AC97_DECLARE(au_ac97);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
au_setbit(u_int32_t *p, char bit, u_int32_t value)
|
||||
{
|
||||
p += bit >> 5;
|
||||
bit &= 0x1f;
|
||||
*p &= ~ (1 << bit);
|
||||
*p |= (value << bit);
|
||||
}
|
||||
|
||||
static void
|
||||
au_addroute(struct au_info *au, int a, int b, int route)
|
||||
{
|
||||
int j = 0x1099c+(a<<2);
|
||||
if (au->x[a] != a+0x67) j = AU_REG_RTBASE+(au->x[a]<<2);
|
||||
|
||||
au_wr(au, 0, AU_REG_RTBASE+(route<<2), 0xffffffff, 4);
|
||||
au_wr(au, 0, j, route | (b<<7), 4);
|
||||
au->y[route]=au->x[a];
|
||||
au->x[a]=route;
|
||||
au->z[route]=a & 0x000000ff;
|
||||
au_setbit(au->routes, route, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
au_delroute(struct au_info *au, int route)
|
||||
{
|
||||
int i;
|
||||
int j=au->z[route];
|
||||
|
||||
au_setbit(au->routes, route, 0);
|
||||
au->z[route]=0x1f;
|
||||
i=au_rd(au, 0, AU_REG_RTBASE+(route<<2), 4);
|
||||
au_wr(au, 0, AU_REG_RTBASE+(au->y[route]<<2), i, 4);
|
||||
au->y[i & 0x7f]=au->y[route];
|
||||
au_wr(au, 0, AU_REG_RTBASE+(route<<2), 0xfffffffe, 4);
|
||||
if (au->x[j] == route) au->x[j]=au->y[route];
|
||||
au->y[route]=0x7f;
|
||||
}
|
||||
|
||||
static void
|
||||
au_encodec(struct au_info *au, char channel)
|
||||
{
|
||||
au_wr(au, 0, AU_REG_CODECEN,
|
||||
au_rd(au, 0, AU_REG_CODECEN, 4) | (1 << (channel + 8)), 4);
|
||||
}
|
||||
|
||||
static void
|
||||
au_clrfifo(struct au_info *au, u_int32_t c)
|
||||
{
|
||||
u_int32_t i;
|
||||
|
||||
for (i=0; i<32; i++) au_wr(au, 0, AU_REG_FIFOBASE+(c<<7)+(i<<2), 0, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
au_setadb(struct au_info *au, u_int32_t c, u_int32_t enable)
|
||||
{
|
||||
int x;
|
||||
|
||||
x = au_rd(au, 0, AU_REG_ADB, 4);
|
||||
x &= ~(1 << c);
|
||||
x |= (enable << c);
|
||||
au_wr(au, 0, AU_REG_ADB, x, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
au_prepareoutput(struct au_chinfo *ch, u_int32_t format)
|
||||
{
|
||||
struct au_info *au = ch->parent;
|
||||
int i, stereo = (AFMT_CHANNEL(format) > 1)? 1 : 0;
|
||||
u_int32_t baseaddr = sndbuf_getbufaddr(ch->buffer);
|
||||
|
||||
au_wr(au, 0, 0x1061c, 0, 4);
|
||||
au_wr(au, 0, 0x10620, 0, 4);
|
||||
au_wr(au, 0, 0x10624, 0, 4);
|
||||
switch(AFMT_ENCODING(format)) {
|
||||
case 1:
|
||||
i=0xb000;
|
||||
break;
|
||||
case 2:
|
||||
i=0xf000;
|
||||
break;
|
||||
case 8:
|
||||
i=0x7000;
|
||||
break;
|
||||
case 16:
|
||||
i=0x23000;
|
||||
break;
|
||||
default:
|
||||
i=0x3000;
|
||||
}
|
||||
au_wr(au, 0, 0x10200, baseaddr, 4);
|
||||
au_wr(au, 0, 0x10204, baseaddr+0x1000, 4);
|
||||
au_wr(au, 0, 0x10208, baseaddr+0x2000, 4);
|
||||
au_wr(au, 0, 0x1020c, baseaddr+0x3000, 4);
|
||||
|
||||
au_wr(au, 0, 0x10400, 0xdeffffff, 4);
|
||||
au_wr(au, 0, 0x10404, 0xfcffffff, 4);
|
||||
|
||||
au_wr(au, 0, 0x10580, i, 4);
|
||||
|
||||
au_wr(au, 0, 0x10210, baseaddr, 4);
|
||||
au_wr(au, 0, 0x10214, baseaddr+0x1000, 4);
|
||||
au_wr(au, 0, 0x10218, baseaddr+0x2000, 4);
|
||||
au_wr(au, 0, 0x1021c, baseaddr+0x3000, 4);
|
||||
|
||||
au_wr(au, 0, 0x10408, 0x00fff000 | 0x56000000 | 0x00000fff, 4);
|
||||
au_wr(au, 0, 0x1040c, 0x00fff000 | 0x74000000 | 0x00000fff, 4);
|
||||
|
||||
au_wr(au, 0, 0x10584, i, 4);
|
||||
|
||||
au_wr(au, 0, 0x0f800, stereo? 0x00030032 : 0x00030030, 4);
|
||||
au_wr(au, 0, 0x0f804, stereo? 0x00030032 : 0x00030030, 4);
|
||||
|
||||
au_addroute(au, 0x11, 0, 0x58);
|
||||
au_addroute(au, 0x11, stereo? 0 : 1, 0x59);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* channel interface */
|
||||
static void *
|
||||
auchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
|
||||
{
|
||||
struct au_info *au = devinfo;
|
||||
struct au_chinfo *ch = (dir == PCMDIR_PLAY)? &au->pch : NULL;
|
||||
|
||||
ch->parent = au;
|
||||
ch->channel = c;
|
||||
ch->buffer = b;
|
||||
ch->dir = dir;
|
||||
if (sndbuf_alloc(ch->buffer, au->parent_dmat, 0, AU_BUFFSIZE) != 0)
|
||||
return NULL;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static int
|
||||
auchan_setformat(kobj_t obj, void *data, u_int32_t format)
|
||||
{
|
||||
struct au_chinfo *ch = data;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) au_prepareoutput(ch, format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
auchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
|
||||
{
|
||||
struct au_chinfo *ch = data;
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
} else {
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
static int
|
||||
auchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
|
||||
{
|
||||
return blocksize;
|
||||
}
|
||||
|
||||
static int
|
||||
auchan_trigger(kobj_t obj, void *data, int go)
|
||||
{
|
||||
struct au_chinfo *ch = data;
|
||||
struct au_info *au = ch->parent;
|
||||
|
||||
if (!PCMTRIG_COMMON(go))
|
||||
return 0;
|
||||
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
au_setadb(au, 0x11, (go)? 1 : 0);
|
||||
if (go != PCMTRIG_START) {
|
||||
au_wr(au, 0, 0xf800, 0, 4);
|
||||
au_wr(au, 0, 0xf804, 0, 4);
|
||||
au_delroute(au, 0x58);
|
||||
au_delroute(au, 0x59);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
auchan_getptr(kobj_t obj, void *data)
|
||||
{
|
||||
struct au_chinfo *ch = data;
|
||||
struct au_info *au = ch->parent;
|
||||
if (ch->dir == PCMDIR_PLAY) {
|
||||
return au_rd(au, 0, AU_REG_UNK2, 4) & (AU_BUFFSIZE-1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct pcmchan_caps *
|
||||
auchan_getcaps(kobj_t obj, void *data)
|
||||
{
|
||||
struct au_chinfo *ch = data;
|
||||
return (ch->dir == PCMDIR_PLAY)? &au_playcaps : &au_reccaps;
|
||||
}
|
||||
|
||||
static kobj_method_t auchan_methods[] = {
|
||||
KOBJMETHOD(channel_init, auchan_init),
|
||||
KOBJMETHOD(channel_setformat, auchan_setformat),
|
||||
KOBJMETHOD(channel_setspeed, auchan_setspeed),
|
||||
KOBJMETHOD(channel_setblocksize, auchan_setblocksize),
|
||||
KOBJMETHOD(channel_trigger, auchan_trigger),
|
||||
KOBJMETHOD(channel_getptr, auchan_getptr),
|
||||
KOBJMETHOD(channel_getcaps, auchan_getcaps),
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
CHANNEL_DECLARE(auchan);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* The interrupt handler */
|
||||
static void
|
||||
au_intr (void *p)
|
||||
{
|
||||
struct au_info *au = p;
|
||||
u_int32_t intsrc, i;
|
||||
|
||||
au->interrupts++;
|
||||
intsrc=au_rd(au, 0, AU_REG_IRQSRC, 4);
|
||||
printf("pcm%d: interrupt with src %x\n", au->unit, intsrc);
|
||||
if (intsrc & AU_IRQ_FATAL) printf("pcm%d: fatal error irq\n", au->unit);
|
||||
if (intsrc & AU_IRQ_PARITY) printf("pcm%d: parity error irq\n", au->unit);
|
||||
if (intsrc & AU_IRQ_UNKNOWN) {
|
||||
(void)au_rd(au, 0, AU_REG_UNK1, 4);
|
||||
au_wr(au, 0, AU_REG_UNK1, 0, 4);
|
||||
au_wr(au, 0, AU_REG_UNK1, 0x10000, 4);
|
||||
}
|
||||
if (intsrc & AU_IRQ_PCMOUT) {
|
||||
i=au_rd(au, 0, AU_REG_UNK2, 4) & (AU_BUFFSIZE-1);
|
||||
chn_intr(au->pch.channel);
|
||||
(void)au_rd(au, 0, AU_REG_UNK3, 4);
|
||||
(void)au_rd(au, 0, AU_REG_UNK4, 4);
|
||||
(void)au_rd(au, 0, AU_REG_UNK5, 4);
|
||||
}
|
||||
/* don't support midi
|
||||
if (intsrc & AU_IRQ_MIDI) {
|
||||
i=au_rd(au, 0, 0x11004, 4);
|
||||
j=10;
|
||||
while (i & 0xff) {
|
||||
if (j-- <= 0) break;
|
||||
i=au_rd(au, 0, 0x11000, 4);
|
||||
if ((au->midi_stat & 1) && (au->midi_out))
|
||||
au->midi_out(au->midi_devno, i);
|
||||
i=au_rd(au, 0, 0x11004);
|
||||
}
|
||||
}
|
||||
*/
|
||||
au_wr(au, 0, AU_REG_IRQSRC, intsrc & 0x7ff, 4);
|
||||
au_rd(au, 0, AU_REG_IRQSRC, 4);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/* Probe and attach the card */
|
||||
|
||||
static int
|
||||
au_init(device_t dev, struct au_info *au)
|
||||
{
|
||||
u_int32_t i, j;
|
||||
|
||||
au_wr(au, 0, AU_REG_IRQGLOB, 0xffffffff, 4);
|
||||
DELAY(100000);
|
||||
|
||||
/* init codec */
|
||||
/* cold reset */
|
||||
for (i=0; i<32; i++) {
|
||||
au_wr(au, 0, AU_REG_CODECCHN+(i<<2), 0, 4);
|
||||
DELAY(10000);
|
||||
}
|
||||
if (1) {
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x8068, 4);
|
||||
DELAY(10000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x00e8, 4);
|
||||
DELAY(10000);
|
||||
} else {
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x00a8, 4);
|
||||
DELAY(100000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x80a8, 4);
|
||||
DELAY(100000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x80e8, 4);
|
||||
DELAY(100000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x80a8, 4);
|
||||
DELAY(100000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x00a8, 4);
|
||||
DELAY(100000);
|
||||
au_wr(au, 0, AU_REG_CODECST, 0x00e8, 4);
|
||||
DELAY(100000);
|
||||
}
|
||||
|
||||
/* init */
|
||||
for (i=0; i<32; i++) {
|
||||
au_wr(au, 0, AU_REG_CODECCHN+(i<<2), 0, 4);
|
||||
DELAY(10000);
|
||||
}
|
||||
au_wr(au, 0, AU_REG_CODECST, 0xe8, 4);
|
||||
DELAY(10000);
|
||||
au_wr(au, 0, AU_REG_CODECEN, 0, 4);
|
||||
|
||||
/* setup codec */
|
||||
i=j=0;
|
||||
while (j<100 && (i & AU_CDC_READY)==0) {
|
||||
i=au_rd(au, 0, AU_REG_CODECST, 4);
|
||||
DELAY(1000);
|
||||
j++;
|
||||
}
|
||||
if (j==100) device_printf(dev, "codec not ready, status 0x%x\n", i);
|
||||
|
||||
/* init adb */
|
||||
/*au->x5c=0;*/
|
||||
for (i=0; i<32; i++) au->x[i]=i+0x67;
|
||||
for (i=0; i<128; i++) au->y[i]=0x7f;
|
||||
for (i=0; i<128; i++) au->z[i]=0x1f;
|
||||
au_wr(au, 0, AU_REG_ADB, 0, 4);
|
||||
for (i=0; i<124; i++) au_wr(au, 0, AU_REG_RTBASE+(i<<2), 0xffffffff, 4);
|
||||
|
||||
/* test */
|
||||
i=au_rd(au, 0, 0x107c0, 4);
|
||||
if (i!=0xdeadbeef) device_printf(dev, "dma check failed: 0x%x\n", i);
|
||||
|
||||
/* install mixer */
|
||||
au_wr(au, 0, AU_REG_IRQGLOB,
|
||||
au_rd(au, 0, AU_REG_IRQGLOB, 4) | AU_IRQ_ENABLE, 4);
|
||||
/* braindead but it's what the oss/linux driver does
|
||||
* for (i=0; i<0x80000000; i++) au_wr(au, 0, i<<2, 0, 4);
|
||||
*/
|
||||
au->routes[0]=au->routes[1]=au->routes[2]=au->routes[3]=0;
|
||||
/*au->x1e4=0;*/
|
||||
|
||||
/* attach channel */
|
||||
au_addroute(au, 0x11, 0x48, 0x02);
|
||||
au_addroute(au, 0x11, 0x49, 0x03);
|
||||
au_encodec(au, 0);
|
||||
au_encodec(au, 1);
|
||||
|
||||
for (i=0; i<48; i++) au_wr(au, 0, 0xf800+(i<<2), 0x20, 4);
|
||||
for (i=2; i<6; i++) au_wr(au, 0, 0xf800+(i<<2), 0, 4);
|
||||
au_wr(au, 0, 0xf8c0, 0x0843, 4);
|
||||
for (i=0; i<4; i++) au_clrfifo(au, i);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
au_testirq(struct au_info *au)
|
||||
{
|
||||
au_wr(au, 0, AU_REG_UNK1, 0x80001000, 4);
|
||||
au_wr(au, 0, AU_REG_IRQEN, 0x00001030, 4);
|
||||
au_wr(au, 0, AU_REG_IRQSRC, 0x000007ff, 4);
|
||||
DELAY(1000000);
|
||||
if (au->interrupts==0) printf("pcm%d: irq test failed\n", au->unit);
|
||||
/* this apparently generates an irq */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
au_pci_probe(device_t dev)
|
||||
{
|
||||
if (pci_get_devid(dev) == AU8820_PCI_ID) {
|
||||
device_set_desc(dev, "Aureal Vortex 8820");
|
||||
return BUS_PROBE_DEFAULT;
|
||||
}
|
||||
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static int
|
||||
au_pci_attach(device_t dev)
|
||||
{
|
||||
struct au_info *au;
|
||||
int type[10];
|
||||
int regid[10];
|
||||
struct resource *reg[10];
|
||||
int i, j, mapped = 0;
|
||||
int irqid;
|
||||
struct resource *irq;
|
||||
void *ih;
|
||||
struct ac97_info *codec;
|
||||
char status[SND_STATUSLEN];
|
||||
|
||||
au = malloc(sizeof(*au), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
au->unit = device_get_unit(dev);
|
||||
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
irq = NULL;
|
||||
ih = NULL;
|
||||
j=0;
|
||||
/* XXX dfr: is this strictly necessary? */
|
||||
for (i=0; i<PCI_MAXMAPS_0; i++) {
|
||||
#if 0
|
||||
/* Slapped wrist: config_id and map are private structures */
|
||||
if (bootverbose) {
|
||||
printf("pcm%d: map %d - allocating ", unit, i+1);
|
||||
printf("0x%x bytes of ", 1<<config_id->map[i].ln2size);
|
||||
printf("%s space ", (config_id->map[i].type & PCI_MAPPORT)?
|
||||
"io" : "memory");
|
||||
printf("at 0x%x...", config_id->map[i].base);
|
||||
}
|
||||
#endif
|
||||
regid[j] = PCIR_BAR(i);
|
||||
type[j] = SYS_RES_MEMORY;
|
||||
reg[j] = bus_alloc_resource_any(dev, type[j], ®id[j],
|
||||
RF_ACTIVE);
|
||||
if (!reg[j]) {
|
||||
type[j] = SYS_RES_IOPORT;
|
||||
reg[j] = bus_alloc_resource_any(dev, type[j],
|
||||
®id[j], RF_ACTIVE);
|
||||
}
|
||||
if (reg[j]) {
|
||||
au->st[i] = rman_get_bustag(reg[j]);
|
||||
au->sh[i] = rman_get_bushandle(reg[j]);
|
||||
mapped++;
|
||||
}
|
||||
#if 0
|
||||
if (bootverbose) printf("%s\n", mapped? "ok" : "failed");
|
||||
#endif
|
||||
if (mapped) j++;
|
||||
if (j == 10) {
|
||||
/* XXX */
|
||||
device_printf(dev, "too many resources");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (j < config_id->nummaps) {
|
||||
printf("pcm%d: unable to map a required resource\n", unit);
|
||||
free(au, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
au_wr(au, 0, AU_REG_IRQEN, 0, 4);
|
||||
|
||||
irqid = 0;
|
||||
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqid,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
if (!irq || snd_setup_intr(dev, irq, 0, au_intr, au, &ih)) {
|
||||
device_printf(dev, "unable to map interrupt\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (au_testirq(au)) device_printf(dev, "irq test failed\n");
|
||||
|
||||
if (au_init(dev, au) == -1) {
|
||||
device_printf(dev, "unable to initialize the card\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
codec = AC97_CREATE(dev, au, au_ac97);
|
||||
if (codec == NULL) goto bad;
|
||||
if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
|
||||
|
||||
if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
|
||||
/*boundary*/0,
|
||||
/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
|
||||
/*highaddr*/BUS_SPACE_MAXADDR,
|
||||
/*filter*/NULL, /*filterarg*/NULL,
|
||||
/*maxsize*/AU_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff,
|
||||
/*flags*/0, /*lockfunc*/NULL, /*lockarg*/NULL,
|
||||
&au->parent_dmat) != 0) {
|
||||
device_printf(dev, "unable to create dma tag\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
snprintf(status, SND_STATUSLEN, "at %s 0x%jx irq %jd %s",
|
||||
(type[0] == SYS_RES_IOPORT)? "io" : "memory",
|
||||
rman_get_start(reg[0]), rman_get_start(irq),PCM_KLDSTRING(snd_aureal));
|
||||
|
||||
if (pcm_register(dev, au, 1, 1)) goto bad;
|
||||
/* pcm_addchan(dev, PCMDIR_REC, &au_chantemplate, au); */
|
||||
pcm_addchan(dev, PCMDIR_PLAY, &auchan_class, au);
|
||||
pcm_setstatus(dev, status);
|
||||
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
if (au) free(au, M_DEVBUF);
|
||||
for (i = 0; i < j; i++)
|
||||
bus_release_resource(dev, type[i], regid[i], reg[i]);
|
||||
if (ih) bus_teardown_intr(dev, irq, ih);
|
||||
if (irq) bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static device_method_t au_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, au_pci_probe),
|
||||
DEVMETHOD(device_attach, au_pci_attach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t au_driver = {
|
||||
"pcm",
|
||||
au_methods,
|
||||
PCM_SOFTC_SIZE,
|
||||
};
|
||||
|
||||
DRIVER_MODULE(snd_aureal, pci, au_driver, pcm_devclass, 0, 0);
|
||||
MODULE_DEPEND(snd_aureal, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
|
||||
MODULE_VERSION(snd_aureal, 1);
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AU8820_REG_H
|
||||
#define _AU8820_REG_H
|
||||
|
||||
#define AU_BUFFSIZE 0x4000
|
||||
|
||||
#define AU_REG_FIFOBASE 0x0e000
|
||||
|
||||
#define AU_REG_UNK2 0x105c0
|
||||
#define AU_REG_UNK3 0x10600
|
||||
#define AU_REG_UNK4 0x10604
|
||||
#define AU_REG_UNK5 0x10608
|
||||
|
||||
#define AU_REG_RTBASE 0x10800
|
||||
|
||||
#define AU_REG_ADB 0x10a00
|
||||
|
||||
#define AU_REG_CODECCHN 0x11880
|
||||
|
||||
#define AU_REG_CODECST 0x11984
|
||||
#define AU_CDC_RUN 0x00000040
|
||||
#define AU_CDC_WROK 0x00000100
|
||||
#define AU_CDC_RESET 0x00008000
|
||||
|
||||
#define AU_REG_CODECIO 0x11988
|
||||
#define AU_CDC_DATAMASK 0x0000ffff
|
||||
#define AU_CDC_REGMASK 0x007f0000
|
||||
#define AU_CDC_REGSET 0x00800000
|
||||
#define AU_CDC_READY 0x04000000
|
||||
|
||||
#define AU_REG_CODECEN 0x11990
|
||||
#define AU_CDC_CHAN1EN 0x00000100
|
||||
#define AU_CDC_CHAN2EN 0x00000200
|
||||
|
||||
#define AU_REG_UNK1 0x1199c
|
||||
|
||||
#define AU_REG_IRQSRC 0x12800
|
||||
#define AU_IRQ_FATAL 0x0001
|
||||
#define AU_IRQ_PARITY 0x0002
|
||||
#define AU_IRQ_PCMOUT 0x0020
|
||||
#define AU_IRQ_UNKNOWN 0x1000
|
||||
#define AU_IRQ_MIDI 0x2000
|
||||
#define AU_REG_IRQEN 0x12804
|
||||
|
||||
#define AU_REG_IRQGLOB 0x1280c
|
||||
#define AU_IRQ_ENABLE 0x4000
|
||||
|
||||
#define AC97_MUTE 0x8000
|
||||
#define AC97_REG_RESET 0x00
|
||||
#define AC97_MIX_MASTER 0x02
|
||||
#define AC97_MIX_PHONES 0x04
|
||||
#define AC97_MIX_MONO 0x06
|
||||
#define AC97_MIX_TONE 0x08
|
||||
#define AC97_MIX_BEEP 0x0a
|
||||
#define AC97_MIX_PHONE 0x0c
|
||||
#define AC97_MIX_MIC 0x0e
|
||||
#define AC97_MIX_LINE 0x10
|
||||
#define AC97_MIX_CD 0x12
|
||||
#define AC97_MIX_VIDEO 0x14
|
||||
#define AC97_MIX_AUX 0x16
|
||||
#define AC97_MIX_PCM 0x18
|
||||
#define AC97_REG_RECSEL 0x1a
|
||||
#define AC97_MIX_RGAIN 0x1c
|
||||
#define AC97_MIX_MGAIN 0x1e
|
||||
#define AC97_REG_GEN 0x20
|
||||
#define AC97_REG_3D 0x22
|
||||
#define AC97_REG_POWER 0x26
|
||||
#define AC97_REG_ID1 0x7c
|
||||
#define AC97_REG_ID2 0x7e
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* =======================================================================
|
||||
* title : define
|
||||
* company : YAMAHA
|
||||
* author : Taichi Sugiyama
|
||||
* create Data : 28/Sep/99
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
/* ----- YAMAHA DS-XG Devices -------------------------------------------- */
|
||||
#define YAMAHA 0x1073
|
||||
#define YMF724 0x0004
|
||||
#define YMF724F 0x000d
|
||||
#define YMF734 0x0005
|
||||
#define YMF737 0x0008
|
||||
#define YMF738 0x0020
|
||||
#define YMF740 0x000a
|
||||
#define YMF740C 0x000c
|
||||
#define YMF744 0x0010
|
||||
#define YMF754 0x0012
|
||||
#define YMF738_TEG 0x0006
|
||||
#define DEVICE4CH(x) ((x == YMF738) || (x == YMF744) || (x == YMF754))
|
||||
|
||||
#define PCIR_DSXGCTRL 0x48
|
||||
/* ----- interrupt flag -------------------------------------------------- */
|
||||
#define YDSXG_DEFINT 0x01
|
||||
#define YDSXG_TIMERINT 0x02
|
||||
|
||||
/* ----- AC97 ------------------------------------------------------------ */
|
||||
#define YDSXG_AC97TIMEOUT 1000
|
||||
#define YDSXG_AC97READCMD 0x8000
|
||||
#define YDSXG_AC97WRITECMD 0x0000
|
||||
#define YDSXG_AC97READFALSE 0xFFFF
|
||||
|
||||
/* ----- AC97 register map _---------------------------------------------- */
|
||||
#define AC97R_GPIOSTATUS 0x54
|
||||
|
||||
/* ----- work buffer ----------------------------------------------------- */
|
||||
#define DEF_WORKBUFFLENGTH 0x0400
|
||||
|
||||
/* ----- register size --------------------------------------------------- */
|
||||
#define YDSXG_MAPLENGTH 0x8000
|
||||
#define YDSXG_DSPLENGTH 0x0080
|
||||
#define YDSXG_CTRLLENGTH 0x3000
|
||||
|
||||
/* ----- register map ---------------------------------------------------- */
|
||||
#define YDSXGR_INTFLAG 0x0004
|
||||
#define YDSXGR_ACTIVITY 0x0006
|
||||
#define YDSXGR_GLOBALCTRL 0x0008
|
||||
#define YDSXGR_ZVCTRL 0x000A
|
||||
#define YDSXGR_TIMERCTRL 0x0010
|
||||
#define YDSXGR_TIMERCOUNT 0x0012
|
||||
#define YDSXGR_SPDIFOUTCTRL 0x0018
|
||||
#define YDSXGR_SPDIFOUTSTATUS 0x001C
|
||||
#define YDSXGR_EEPROMCTRL 0x0020
|
||||
#define YDSXGR_SPDIFINCTRL 0x0034
|
||||
#define YDSXGR_SPDIFINSTATUS 0x0038
|
||||
#define YDSXGR_DSPPROGRAMDL 0x0048
|
||||
#define YDSXGR_DLCNTRL 0x004C
|
||||
#define YDSXGR_GPIOININTFLAG 0x0050
|
||||
#define YDSXGR_GPIOININTENABLE 0x0052
|
||||
#define YDSXGR_GPIOINSTATUS 0x0054
|
||||
#define YDSXGR_GPIOOUTCTRL 0x0056
|
||||
#define YDSXGR_GPIOFUNCENABLE 0x0058
|
||||
#define YDSXGR_GPIOTYPECONFIG 0x005A
|
||||
#define YDSXGR_AC97CMDDATA 0x0060
|
||||
#define YDSXGR_AC97CMDADR 0x0062
|
||||
#define YDSXGR_PRISTATUSDATA 0x0064
|
||||
#define YDSXGR_PRISTATUSADR 0x0066
|
||||
#define YDSXGR_SECSTATUSDATA 0x0068
|
||||
#define YDSXGR_SECSTATUSADR 0x006A
|
||||
#define YDSXGR_SECCONFIG 0x0070
|
||||
#define YDSXGR_LEGACYOUTVOL 0x0080
|
||||
#define YDSXGR_LEGACYOUTVOLL 0x0080
|
||||
#define YDSXGR_LEGACYOUTVOLR 0x0082
|
||||
#define YDSXGR_NATIVEDACOUTVOL 0x0084
|
||||
#define YDSXGR_NATIVEDACOUTVOLL 0x0084
|
||||
#define YDSXGR_NATIVEDACOUTVOLR 0x0086
|
||||
#define YDSXGR_SPDIFOUTVOL 0x0088
|
||||
#define YDSXGR_SPDIFOUTVOLL 0x0088
|
||||
#define YDSXGR_SPDIFOUTVOLR 0x008A
|
||||
#define YDSXGR_AC3OUTVOL 0x008C
|
||||
#define YDSXGR_AC3OUTVOLL 0x008C
|
||||
#define YDSXGR_AC3OUTVOLR 0x008E
|
||||
#define YDSXGR_PRIADCOUTVOL 0x0090
|
||||
#define YDSXGR_PRIADCOUTVOLL 0x0090
|
||||
#define YDSXGR_PRIADCOUTVOLR 0x0092
|
||||
#define YDSXGR_LEGACYLOOPVOL 0x0094
|
||||
#define YDSXGR_LEGACYLOOPVOLL 0x0094
|
||||
#define YDSXGR_LEGACYLOOPVOLR 0x0096
|
||||
#define YDSXGR_NATIVEDACLOOPVOL 0x0098
|
||||
#define YDSXGR_NATIVEDACLOOPVOLL 0x0098
|
||||
#define YDSXGR_NATIVEDACLOOPVOLR 0x009A
|
||||
#define YDSXGR_SPDIFLOOPVOL 0x009C
|
||||
#define YDSXGR_SPDIFLOOPVOLL 0x009E
|
||||
#define YDSXGR_SPDIFLOOPVOLR 0x009E
|
||||
#define YDSXGR_AC3LOOPVOL 0x00A0
|
||||
#define YDSXGR_AC3LOOPVOLL 0x00A0
|
||||
#define YDSXGR_AC3LOOPVOLR 0x00A2
|
||||
#define YDSXGR_PRIADCLOOPVOL 0x00A4
|
||||
#define YDSXGR_PRIADCLOOPVOLL 0x00A4
|
||||
#define YDSXGR_PRIADCLOOPVOLR 0x00A6
|
||||
#define YDSXGR_NATIVEADCINVOL 0x00A8
|
||||
#define YDSXGR_NATIVEADCINVOLL 0x00A8
|
||||
#define YDSXGR_NATIVEADCINVOLR 0x00AA
|
||||
#define YDSXGR_NATIVEDACINVOL 0x00AC
|
||||
#define YDSXGR_NATIVEDACINVOLL 0x00AC
|
||||
#define YDSXGR_NATIVEDACINVOLR 0x00AE
|
||||
#define YDSXGR_BUF441OUTVOL 0x00B0
|
||||
#define YDSXGR_BUF441OUTVOLL 0x00B0
|
||||
#define YDSXGR_BUF441OUTVOLR 0x00B2
|
||||
#define YDSXGR_BUF441LOOPVOL 0x00B4
|
||||
#define YDSXGR_BUF441LOOPVOLL 0x00B4
|
||||
#define YDSXGR_BUF441LOOPVOLR 0x00B6
|
||||
#define YDSXGR_SPDIFOUTVOL2 0x00B8
|
||||
#define YDSXGR_SPDIFOUTVOL2L 0x00B8
|
||||
#define YDSXGR_SPDIFOUTVOL2R 0x00BA
|
||||
#define YDSXGR_SPDIFLOOPVOL2 0x00BC
|
||||
#define YDSXGR_SPDIFLOOPVOL2L 0x00BC
|
||||
#define YDSXGR_SPDIFLOOPVOL2R 0x00BE
|
||||
#define YDSXGR_ADCSLOTSR 0x00C0
|
||||
#define YDSXGR_RECSLOTSR 0x00C4
|
||||
#define YDSXGR_ADCFORMAT 0x00C8
|
||||
#define YDSXGR_RECFORMAT 0x00CC
|
||||
#define YDSXGR_P44SLOTSR 0x00D0
|
||||
#define YDSXGR_STATUS 0x0100
|
||||
#define YDSXGR_CTRLSELECT 0x0104
|
||||
#define YDSXGR_MODE 0x0108
|
||||
#define YDSXGR_SAMPLECOUNT 0x010C
|
||||
#define YDSXGR_NUMOFSAMPLES 0x0110
|
||||
#define YDSXGR_CONFIG 0x0114
|
||||
#define YDSXGR_PLAYCTRLSIZE 0x0140
|
||||
#define YDSXGR_RECCTRLSIZE 0x0144
|
||||
#define YDSXGR_EFFCTRLSIZE 0x0148
|
||||
#define YDSXGR_WORKSIZE 0x014C
|
||||
#define YDSXGR_MAPOFREC 0x0150
|
||||
#define YDSXGR_MAPOFEFFECT 0x0154
|
||||
#define YDSXGR_PLAYCTRLBASE 0x0158
|
||||
#define YDSXGR_RECCTRLBASE 0x015C
|
||||
#define YDSXGR_EFFCTRLBASE 0x0160
|
||||
#define YDSXGR_WORKBASE 0x0164
|
||||
#define YDSXGR_DSPINSTRAM 0x1000
|
||||
#define YDSXGR_CTRLINSTRAM 0x4000
|
||||
|
||||
/* ----- time out -------------------------------------------------------- */
|
||||
#define YDSXG_WORKBITTIMEOUT 250000
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,381 +0,0 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 1999-2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp>
|
||||
* 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.
|
||||
*
|
||||
* maestro_reg.h,v 1.13 2001/11/11 18:29:46 taku Exp
|
||||
*/
|
||||
|
||||
#ifndef MAESTRO_REG_H_INCLUDED
|
||||
#define MAESTRO_REG_H_INCLUDED
|
||||
|
||||
/* -----------------------------
|
||||
* PCI config registers
|
||||
*/
|
||||
|
||||
/* Legacy emulation */
|
||||
#define CONF_LEGACY 0x40
|
||||
|
||||
#define LEGACY_DISABLED 0x8000
|
||||
|
||||
/* Chip configurations */
|
||||
#define CONF_MAESTRO 0x50
|
||||
#define MAESTRO_PMC 0x08000000
|
||||
#define MAESTRO_SPDIF 0x01000000
|
||||
#define MAESTRO_HWVOL 0x00800000
|
||||
#define MAESTRO_CHIBUS 0x00100000
|
||||
#define MAESTRO_POSTEDWRITE 0x00000080
|
||||
#define MAESTRO_DMA_PCITIMING 0x00000040
|
||||
#define MAESTRO_SWAP_LR 0x00000020
|
||||
|
||||
/* ACPI configurations */
|
||||
#define CONF_ACPI_STOPCLOCK 0x54
|
||||
#define ACPI_PART_2ndC_CLOCK 15
|
||||
#define ACPI_PART_CODEC_CLOCK 14
|
||||
#define ACPI_PART_978 13 /* Docking station or something */
|
||||
#define ACPI_PART_SPDIF 12
|
||||
#define ACPI_PART_GLUE 11 /* What? */
|
||||
#define ACPI_PART_DAA 10
|
||||
#define ACPI_PART_PCI_IF 9
|
||||
#define ACPI_PART_HW_VOL 8
|
||||
#define ACPI_PART_GPIO 7
|
||||
#define ACPI_PART_ASSP 6
|
||||
#define ACPI_PART_SB 5
|
||||
#define ACPI_PART_FM 4
|
||||
#define ACPI_PART_RINGBUS 3
|
||||
#define ACPI_PART_MIDI 2
|
||||
#define ACPI_PART_GAME_PORT 1
|
||||
#define ACPI_PART_WP 0
|
||||
|
||||
/* Power management */
|
||||
#define CONF_PM_PTR 0x34 /* BYTE R */
|
||||
#define PM_CID 0 /* BYTE R */
|
||||
#define PPMI_CID 1
|
||||
#define PM_CTRL 4 /* BYTE RW */
|
||||
#define PPMI_D0 0 /* Full power */
|
||||
#define PPMI_D1 1 /* Medium power */
|
||||
#define PPMI_D2 2 /* Low power */
|
||||
#define PPMI_D3 3 /* Turned off */
|
||||
|
||||
/* -----------------------------
|
||||
* I/O ports
|
||||
*/
|
||||
|
||||
/* Direct Sound Processor (aka WP) */
|
||||
#define PORT_DSP_DATA 0x00 /* WORD RW */
|
||||
#define PORT_DSP_INDEX 0x02 /* WORD RW */
|
||||
#define PORT_INT_STAT 0x04 /* WORD RW */
|
||||
#define PORT_SAMPLE_CNT 0x06 /* WORD RO */
|
||||
|
||||
/* WaveCache */
|
||||
#define PORT_WAVCACHE_INDEX 0x10 /* WORD RW */
|
||||
#define PORT_WAVCACHE_DATA 0x12 /* WORD RW */
|
||||
#define WAVCACHE_PCMBAR 0x1fc
|
||||
#define WAVCACHE_WTBAR 0x1f0
|
||||
#define WAVCACHE_BASEADDR_SHIFT 12
|
||||
|
||||
#define WAVCACHE_CHCTL_ADDRTAG_MASK 0xfff8
|
||||
#define WAVCACHE_CHCTL_U8 0x0004
|
||||
#define WAVCACHE_CHCTL_STEREO 0x0002
|
||||
#define WAVCACHE_CHCTL_DECREMENTAL 0x0001
|
||||
|
||||
#define PORT_WAVCACHE_CTRL 0x14 /* WORD RW */
|
||||
#define WAVCACHE_EXTRA_CH_ENABLED 0x0200
|
||||
#define WAVCACHE_ENABLED 0x0100
|
||||
#define WAVCACHE_CH_60_ENABLED 0x0080
|
||||
#define WAVCACHE_WTSIZE_MASK 0x0060
|
||||
#define WAVCACHE_WTSIZE_1MB 0x0000
|
||||
#define WAVCACHE_WTSIZE_2MB 0x0020
|
||||
#define WAVCACHE_WTSIZE_4MB 0x0040
|
||||
#define WAVCACHE_WTSIZE_8MB 0x0060
|
||||
#define WAVCACHE_SGC_MASK 0x000c
|
||||
#define WAVCACHE_SGC_DISABLED 0x0000
|
||||
#define WAVCACHE_SGC_40_47 0x0004
|
||||
#define WAVCACHE_SGC_32_47 0x0008
|
||||
#define WAVCACHE_TESTMODE 0x0001
|
||||
|
||||
/* Host Interruption */
|
||||
#define PORT_HOSTINT_CTRL 0x18 /* WORD RW */
|
||||
#define HOSTINT_CTRL_SOFT_RESET 0x8000
|
||||
#define HOSTINT_CTRL_DSOUND_RESET 0x4000
|
||||
#define HOSTINT_CTRL_HW_VOL_TO_PME 0x0400
|
||||
#define HOSTINT_CTRL_CLKRUN_ENABLED 0x0100
|
||||
#define HOSTINT_CTRL_HWVOL_ENABLED 0x0040
|
||||
#define HOSTINT_CTRL_ASSP_INT_ENABLED 0x0010
|
||||
#define HOSTINT_CTRL_ISDN_INT_ENABLED 0x0008
|
||||
#define HOSTINT_CTRL_DSOUND_INT_ENABLED 0x0004
|
||||
#define HOSTINT_CTRL_MPU401_INT_ENABLED 0x0002
|
||||
#define HOSTINT_CTRL_SB_INT_ENABLED 0x0001
|
||||
|
||||
#define PORT_HOSTINT_STAT 0x1a /* BYTE RW */
|
||||
#define HOSTINT_STAT_HWVOL 0x40
|
||||
#define HOSTINT_STAT_ASSP 0x10
|
||||
#define HOSTINT_STAT_ISDN 0x08
|
||||
#define HOSTINT_STAT_DSOUND 0x04
|
||||
#define HOSTINT_STAT_MPU401 0x02
|
||||
#define HOSTINT_STAT_SB 0x01
|
||||
|
||||
/* Hardware volume */
|
||||
#define PORT_HWVOL_CTRL 0x1b /* BYTE RW */
|
||||
#define HWVOL_CTRL_SPLIT_SHADOW 0x01
|
||||
|
||||
#define PORT_HWVOL_VOICE_SHADOW 0x1c /* BYTE RW */
|
||||
#define PORT_HWVOL_VOICE 0x1d /* BYTE RW */
|
||||
#define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */
|
||||
#define PORT_HWVOL_MASTER 0x1f /* BYTE RW */
|
||||
#define HWVOL_NOP 0x88
|
||||
#define HWVOL_MUTE 0x11
|
||||
#define HWVOL_UP 0xaa
|
||||
#define HWVOL_DOWN 0x66
|
||||
|
||||
/* CODEC */
|
||||
#define PORT_CODEC_CMD 0x30 /* BYTE W */
|
||||
#define CODEC_CMD_READ 0x80
|
||||
#define CODEC_CMD_WRITE 0x00
|
||||
#define CODEC_CMD_ADDR_MASK 0x7f
|
||||
|
||||
#define PORT_CODEC_STAT 0x30 /* BYTE R */
|
||||
#define CODEC_STAT_MASK 0x01
|
||||
#define CODEC_STAT_RW_DONE 0x00
|
||||
#define CODEC_STAT_PROGLESS 0x01
|
||||
|
||||
#define PORT_CODEC_REG 0x32 /* WORD RW */
|
||||
|
||||
/* Ring bus control */
|
||||
#define PORT_RINGBUS_CTRL 0x34 /* DWORD RW */
|
||||
#define RINGBUS_CTRL_I2S_ENABLED 0x80000000
|
||||
#define RINGBUS_CTRL_RINGBUS_ENABLED 0x20000000
|
||||
#define RINGBUS_CTRL_ACLINK_ENABLED 0x10000000
|
||||
#define RINGBUS_CTRL_AC97_SWRESET 0x08000000
|
||||
|
||||
#define RINGBUS_SRC_MIC 20
|
||||
#define RINGBUS_SRC_I2S 16
|
||||
#define RINGBUS_SRC_ADC 12
|
||||
#define RINGBUS_SRC_MODEM 8
|
||||
#define RINGBUS_SRC_DSOUND 4
|
||||
#define RINGBUS_SRC_ASSP 0
|
||||
|
||||
#define RINGBUS_DEST_MONORAL 000
|
||||
#define RINGBUS_DEST_STEREO 010
|
||||
#define RINGBUS_DEST_NONE 0
|
||||
#define RINGBUS_DEST_DAC 1
|
||||
#define RINGBUS_DEST_MODEM_IN 2
|
||||
#define RINGBUS_DEST_RESERVED3 3
|
||||
#define RINGBUS_DEST_DSOUND_IN 4
|
||||
#define RINGBUS_DEST_ASSP_IN 5
|
||||
|
||||
/* Ring bus control B */
|
||||
#define PORT_RINGBUS_CTRL_B 0x38 /* BYTE RW */
|
||||
#define RINGBUS_CTRL_SSPE 0x40
|
||||
#define RINGBUS_CTRL_2ndCODEC 0x20
|
||||
#define RINGBUS_CTRL_SPDIF 0x10
|
||||
#define RINGBUS_CTRL_ITB_DISABLE 0x08
|
||||
#define RINGBUS_CTRL_CODEC_ID_MASK 0x03
|
||||
#define RINGBUS_CTRL_CODEC_ID_AC98 2
|
||||
|
||||
/* General Purpose I/O */
|
||||
#define PORT_GPIO_DATA 0x60 /* WORD RW */
|
||||
#define PORT_GPIO_MASK 0x64 /* WORD RW */
|
||||
#define PORT_GPIO_DIR 0x68 /* WORD RW */
|
||||
|
||||
/* Application Specific Signal Processor */
|
||||
#define PORT_ASSP_MEM_INDEX 0x80 /* DWORD RW */
|
||||
#define PORT_ASSP_MEM_DATA 0x84 /* WORD RW */
|
||||
#define PORT_ASSP_CTRL_A 0xa2 /* BYTE RW */
|
||||
#define PORT_ASSP_CTRL_B 0xa4 /* BYTE RW */
|
||||
#define PORT_ASSP_CTRL_C 0xa6 /* BYTE RW */
|
||||
#define PORT_ASSP_HOST_WR_INDEX 0xa8 /* BYTE W */
|
||||
#define PORT_ASSP_HOST_WR_DATA 0xaa /* BYTE RW */
|
||||
#define PORT_ASSP_INT_STAT 0xac /* BYTE RW */
|
||||
|
||||
/* -----------------------------
|
||||
* Wave Processor Indexed Data Registers.
|
||||
*/
|
||||
|
||||
#define WPREG_DATA_PORT 0
|
||||
#define WPREG_CRAM_PTR 1
|
||||
#define WPREG_CRAM_DATA 2
|
||||
#define WPREG_WAVE_DATA 3
|
||||
#define WPREG_WAVE_PTR_LOW 4
|
||||
#define WPREG_WAVE_PTR_HIGH 5
|
||||
|
||||
#define WPREG_TIMER_FREQ 6
|
||||
#define WP_TIMER_FREQ_PRESCALE_MASK 0x00e0 /* actual - 9 */
|
||||
#define WP_TIMER_FREQ_PRESCALE_SHIFT 5
|
||||
#define WP_TIMER_FREQ_DIVIDE_MASK 0x001f
|
||||
#define WP_TIMER_FREQ_DIVIDE_SHIFT 0
|
||||
|
||||
#define WPREG_WAVE_ROMRAM 7
|
||||
#define WP_WAVE_VIRTUAL_ENABLED 0x0400
|
||||
#define WP_WAVE_8BITRAM_ENABLED 0x0200
|
||||
#define WP_WAVE_DRAM_ENABLED 0x0100
|
||||
#define WP_WAVE_RAMSPLIT_MASK 0x00ff
|
||||
#define WP_WAVE_RAMSPLIT_SHIFT 0
|
||||
|
||||
#define WPREG_BASE 12
|
||||
#define WP_PARAOUT_BASE_MASK 0xf000
|
||||
#define WP_PARAOUT_BASE_SHIFT 12
|
||||
#define WP_PARAIN_BASE_MASK 0x0f00
|
||||
#define WP_PARAIN_BASE_SHIFT 8
|
||||
#define WP_SERIAL0_BASE_MASK 0x00f0
|
||||
#define WP_SERIAL0_BASE_SHIFT 4
|
||||
#define WP_SERIAL1_BASE_MASK 0x000f
|
||||
#define WP_SERIAL1_BASE_SHIFT 0
|
||||
|
||||
#define WPREG_TIMER_ENABLE 17
|
||||
#define WPREG_TIMER_START 23
|
||||
|
||||
/* -----------------------------
|
||||
* Audio Processing Unit.
|
||||
*/
|
||||
#define APUREG_APUTYPE 0
|
||||
#define APU_DMA_ENABLED 0x4000
|
||||
#define APU_INT_ON_LOOP 0x2000
|
||||
#define APU_ENDCURVE 0x1000
|
||||
#define APU_APUTYPE_MASK 0x00f0
|
||||
#define APU_FILTERTYPE_MASK 0x000c
|
||||
#define APU_FILTERQ_MASK 0x0003
|
||||
|
||||
/* APU types */
|
||||
#define APU_APUTYPE_SHIFT 4
|
||||
|
||||
#define APUTYPE_INACTIVE 0
|
||||
#define APUTYPE_16BITLINEAR 1
|
||||
#define APUTYPE_16BITSTEREO 2
|
||||
#define APUTYPE_8BITLINEAR 3
|
||||
#define APUTYPE_8BITSTEREO 4
|
||||
#define APUTYPE_8BITDIFF 5
|
||||
#define APUTYPE_DIGITALDELAY 6
|
||||
#define APUTYPE_DUALTAP_READER 7
|
||||
#define APUTYPE_CORRELATOR 8
|
||||
#define APUTYPE_INPUTMIXER 9
|
||||
#define APUTYPE_WAVETABLE 10
|
||||
#define APUTYPE_RATECONV 11
|
||||
#define APUTYPE_16BITPINGPONG 12
|
||||
/* APU type 13 through 15 are reserved. */
|
||||
|
||||
/* Filter types */
|
||||
#define APU_FILTERTYPE_SHIFT 2
|
||||
|
||||
#define FILTERTYPE_2POLE_LOPASS 0
|
||||
#define FILTERTYPE_2POLE_BANDPASS 1
|
||||
#define FILTERTYPE_2POLE_HIPASS 2
|
||||
#define FILTERTYPE_1POLE_LOPASS 3
|
||||
#define FILTERTYPE_1POLE_HIPASS 4
|
||||
#define FILTERTYPE_PASSTHROUGH 5
|
||||
|
||||
/* Filter Q */
|
||||
#define APU_FILTERQ_SHIFT 0
|
||||
|
||||
#define FILTERQ_LESSQ 0
|
||||
#define FILTERQ_MOREQ 3
|
||||
|
||||
/* APU register 2 */
|
||||
#define APUREG_FREQ_LOBYTE 2
|
||||
#define APU_FREQ_LOBYTE_MASK 0xff00
|
||||
#define APU_plus6dB 0x0010
|
||||
|
||||
/* APU register 3 */
|
||||
#define APUREG_FREQ_HIWORD 3
|
||||
#define APU_FREQ_HIWORD_MASK 0x0fff
|
||||
|
||||
/* Frequency */
|
||||
#define APU_FREQ_LOBYTE_SHIFT 8
|
||||
#define APU_FREQ_HIWORD_SHIFT 0
|
||||
#define FREQ_Hz2DIV(freq) (((u_int64_t)(freq) << 16) / 48000)
|
||||
|
||||
/* APU register 4 */
|
||||
#define APUREG_WAVESPACE 4
|
||||
#define APU_64KPAGE_MASK 0xff00
|
||||
|
||||
/* 64KW (==128KB) Page */
|
||||
#define APU_64KPAGE_SHIFT 8
|
||||
|
||||
/* Wave Processor Wavespace Address */
|
||||
#define WPWA_MAX ((1 << 22) - 1)
|
||||
#define WPWA_STEREO (1 << 23)
|
||||
#define WPWA_USE_SYSMEM (1 << 22)
|
||||
|
||||
#define WPWA_WTBAR_SHIFT(wtsz) WPWA_WTBAR_SHIFT_##wtsz
|
||||
#define WPWA_WTBAR_SHIFT_1 15
|
||||
#define WPWA_WTBAR_SHIFT_2 16
|
||||
#define WPWA_WTBAR_SHIFT_4 17
|
||||
#define WPWA_WTBAR_SHIFT_8 18
|
||||
|
||||
#define WPWA_PCMBAR_SHIFT 20
|
||||
|
||||
/* APU register 5 - 7 */
|
||||
#define APUREG_CURPTR 5
|
||||
#define APUREG_ENDPTR 6
|
||||
#define APUREG_LOOPLEN 7
|
||||
|
||||
/* APU register 8 */
|
||||
#define APUREG_EFFECT_GAIN 8
|
||||
|
||||
/* Effect gain? */
|
||||
#define APUREG_EFFECT_GAIN_MASK 0x00ff
|
||||
|
||||
/* APU register 9 */
|
||||
#define APUREG_AMPLITUDE 9
|
||||
#define APU_AMPLITUDE_NOW_MASK 0xff00
|
||||
#define APU_AMPLITUDE_DEST_MASK 0x00ff
|
||||
|
||||
/* Amplitude now? */
|
||||
#define APU_AMPLITUDE_NOW_SHIFT 8
|
||||
|
||||
/* APU register 10 */
|
||||
#define APUREG_POSITION 10
|
||||
#define APU_RADIUS_MASK 0x00c0
|
||||
#define APU_PAN_MASK 0x003f
|
||||
|
||||
/* Radius control. */
|
||||
#define APU_RADIUS_SHIFT 6
|
||||
#define RADIUS_CENTERCIRCLE 0
|
||||
#define RADIUS_MIDDLE 1
|
||||
#define RADIUS_OUTSIDE 2
|
||||
|
||||
/* Polar pan. */
|
||||
#define APU_PAN_SHIFT 0
|
||||
#define PAN_RIGHT 0x00
|
||||
#define PAN_FRONT 0x08
|
||||
#define PAN_LEFT 0x10
|
||||
|
||||
/* Source routing. */
|
||||
#define APUREG_ROUTING 11
|
||||
#define APU_INVERT_POLARITY_B 0x8000
|
||||
#define APU_DATASRC_B_MASK 0x7f00
|
||||
#define APU_INVERT_POLARITY_A 0x0080
|
||||
#define APU_DATASRC_A_MASK 0x007f
|
||||
|
||||
#define APU_DATASRC_A_SHIFT 0
|
||||
#define APU_DATASRC_B_SHIFT 8
|
||||
|
||||
/* -----------------------------
|
||||
* Limits.
|
||||
*/
|
||||
#define WPWA_MAXADDR ((1 << 23) - 1)
|
||||
#define MAESTRO_MAXADDR ((1 << 28) - 1)
|
||||
|
||||
#endif /* MAESTRO_REG_H_INCLUDED */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
.PATH: ${SRCTOP}/sys/dev/sound/pci
|
||||
|
||||
KMOD= snd_ds1
|
||||
SRCS= device_if.h bus_if.h pci_if.h
|
||||
SRCS+= ds1.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
.PATH: ${SRCTOP}/sys/dev/sound/pci
|
||||
|
||||
KMOD= snd_maestro
|
||||
SRCS= device_if.h bus_if.h pci_if.h
|
||||
SRCS+= maestro.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
Loading…
Reference in a new issue