diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-17 20:19:38 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-17 20:19:38 +0000 |
commit | a3906ca572a6be18d39883a1ce431f147918385a (patch) | |
tree | c9736dd18bc357aee191ebdb1fb7cfd2dbc0c408 /sys | |
parent | 2bcad0d8d6ddcdb3e8aff686ea467142b6f1d752 (diff) | |
parent | e9200a6cc226d6015597a4aa5e8ddf7e608e6113 (diff) | |
download | src-a3906ca572a6be18d39883a1ce431f147918385a.tar.gz src-a3906ca572a6be18d39883a1ce431f147918385a.zip |
Merge ^/head r313644 through r313895.
Notes
Notes:
svn path=/projects/clang400-import/; revision=313896
Diffstat (limited to 'sys')
237 files changed, 12138 insertions, 9428 deletions
diff --git a/sys/amd64/amd64/amd64_mem.c b/sys/amd64/amd64/amd64_mem.c index aa8dc5c807e3..315981dfcae2 100644 --- a/sys/amd64/amd64/amd64_mem.c +++ b/sys/amd64/amd64/amd64_mem.c @@ -609,6 +609,10 @@ amd64_mrinit(struct mem_range_softc *sc) u_int regs[4]; int i, nmdesc = 0, pabits; + if (sc->mr_desc != NULL) + /* Already initialized. */ + return; + mtrrcap = rdmsr(MSR_MTRRcap); mtrrdef = rdmsr(MSR_MTRRdefType); @@ -750,5 +754,6 @@ amd64_mem_drvinit(void *unused) return; } mem_range_softc.mr_op = &amd64_mrops; + amd64_mrinit(&mem_range_softc); } -SYSINIT(amd64memdev, SI_SUB_DRIVERS, SI_ORDER_FIRST, amd64_mem_drvinit, NULL); +SYSINIT(amd64memdev, SI_SUB_CPU, SI_ORDER_ANY, amd64_mem_drvinit, NULL); diff --git a/sys/amd64/linux/linux_dummy.c b/sys/amd64/linux/linux_dummy.c index efe18fd5fbad..b86fa4d8a2b2 100644 --- a/sys/amd64/linux/linux_dummy.c +++ b/sys/amd64/linux/linux_dummy.c @@ -45,7 +45,6 @@ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE); DUMMY(mincore); DUMMY(sendfile); -DUMMY(ptrace); DUMMY(syslog); DUMMY(setfsuid); DUMMY(setfsgid); diff --git a/sys/amd64/linux/linux_proto.h b/sys/amd64/linux/linux_proto.h index 16d00ad658a7..ebd43d98638a 100644 --- a/sys/amd64/linux/linux_proto.h +++ b/sys/amd64/linux/linux_proto.h @@ -423,8 +423,8 @@ struct linux_times_args { struct linux_ptrace_args { char req_l_[PADL_(l_long)]; l_long req; char req_r_[PADR_(l_long)]; char pid_l_[PADL_(l_long)]; l_long pid; char pid_r_[PADR_(l_long)]; - char addr_l_[PADL_(l_long)]; l_long addr; char addr_r_[PADR_(l_long)]; - char data_l_[PADL_(l_long)]; l_long data; char data_r_[PADR_(l_long)]; + char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; + char data_l_[PADL_(l_ulong)]; l_ulong data; char data_r_[PADR_(l_ulong)]; }; struct linux_getuid_args { register_t dummy; diff --git a/sys/amd64/linux/linux_ptrace.c b/sys/amd64/linux/linux_ptrace.c new file mode 100644 index 000000000000..e7d486705411 --- /dev/null +++ b/sys/amd64/linux/linux_ptrace.c @@ -0,0 +1,414 @@ +/*- + * Copyright (c) 2017 Edward Tomasz Napierala <trasz@FreeBSD.org> + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/ptrace.h> +#include <sys/syscallsubr.h> + +#include <machine/pcb.h> +#include <machine/reg.h> + +#include <amd64/linux/linux.h> +#include <amd64/linux/linux_proto.h> +#include <compat/linux/linux_signal.h> + +#define LINUX_PTRACE_TRACEME 0 +#define LINUX_PTRACE_PEEKTEXT 1 +#define LINUX_PTRACE_PEEKDATA 2 +#define LINUX_PTRACE_PEEKUSER 3 +#define LINUX_PTRACE_POKETEXT 4 +#define LINUX_PTRACE_POKEDATA 5 +#define LINUX_PTRACE_POKEUSER 6 +#define LINUX_PTRACE_CONT 7 +#define LINUX_PTRACE_KILL 8 +#define LINUX_PTRACE_SINGLESTEP 9 +#define LINUX_PTRACE_GETREGS 12 +#define LINUX_PTRACE_SETREGS 13 +#define LINUX_PTRACE_GETFPREGS 14 +#define LINUX_PTRACE_SETFPREGS 15 +#define LINUX_PTRACE_ATTACH 16 +#define LINUX_PTRACE_DETACH 17 +#define LINUX_PTRACE_SYSCALL 24 +#define LINUX_PTRACE_SETOPTIONS 0x4200 +#define LINUX_PTRACE_GETREGSET 0x4204 +#define LINUX_PTRACE_SEIZE 0x4206 + +#define LINUX_PTRACE_O_TRACESYSGOOD 1 +#define LINUX_PTRACE_O_TRACEFORK 2 +#define LINUX_PTRACE_O_TRACEVFORK 4 +#define LINUX_PTRACE_O_TRACECLONE 8 +#define LINUX_PTRACE_O_TRACEEXEC 16 +#define LINUX_PTRACE_O_TRACEVFORKDONE 32 +#define LINUX_PTRACE_O_TRACEEXIT 64 +#define LINUX_PTRACE_O_TRACESECCOMP 128 +#define LINUX_PTRACE_O_EXITKILL 1048576 +#define LINUX_PTRACE_O_SUSPEND_SECCOMP 2097152 + +#define LINUX_NT_PRSTATUS 1 + +#define LINUX_PTRACE_O_MASK (LINUX_PTRACE_O_TRACESYSGOOD | \ + LINUX_PTRACE_O_TRACEFORK | LINUX_PTRACE_O_TRACEVFORK | \ + LINUX_PTRACE_O_TRACECLONE | LINUX_PTRACE_O_TRACEEXEC | \ + LINUX_PTRACE_O_TRACEVFORKDONE | LINUX_PTRACE_O_TRACEEXIT | \ + LINUX_PTRACE_O_TRACESECCOMP | LINUX_PTRACE_O_EXITKILL | \ + LINUX_PTRACE_O_SUSPEND_SECCOMP) + +static int +map_signum(int lsig, int *bsigp) +{ + int bsig; + + if (lsig == 0) { + *bsigp = 0; + return (0); + } + + if (lsig < 0 || lsig > LINUX_SIGRTMAX) + return (EINVAL); + + bsig = linux_to_bsd_signal(lsig); + if (bsig == SIGSTOP) + bsig = 0; + + *bsigp = bsig; + return (0); +} + +struct linux_pt_reg { + l_ulong r15; + l_ulong r14; + l_ulong r13; + l_ulong r12; + l_ulong rbp; + l_ulong rbx; + l_ulong r11; + l_ulong r10; + l_ulong r9; + l_ulong r8; + l_ulong rax; + l_ulong rcx; + l_ulong rdx; + l_ulong rsi; + l_ulong rdi; + l_ulong orig_rax; + l_ulong rip; + l_ulong cs; + l_ulong eflags; + l_ulong rsp; + l_ulong ss; +}; + +/* + * Translate amd64 ptrace registers between Linux and FreeBSD formats. + * The translation is pretty straighforward, for all registers but + * orig_rax on Linux side and r_trapno and r_err in FreeBSD. + */ +static void +map_regs_to_linux(struct reg *b_reg, struct linux_pt_reg *l_reg) +{ + + l_reg->r15 = b_reg->r_r15; + l_reg->r14 = b_reg->r_r14; + l_reg->r13 = b_reg->r_r13; + l_reg->r12 = b_reg->r_r12; + l_reg->rbp = b_reg->r_rbp; + l_reg->rbx = b_reg->r_rbx; + l_reg->r11 = b_reg->r_r11; + l_reg->r10 = b_reg->r_r10; + l_reg->r9 = b_reg->r_r9; + l_reg->r8 = b_reg->r_r8; + l_reg->rax = b_reg->r_rax; + l_reg->rcx = b_reg->r_rcx; + l_reg->rdx = b_reg->r_rdx; + l_reg->rsi = b_reg->r_rsi; + l_reg->rdi = b_reg->r_rdi; + l_reg->orig_rax = b_reg->r_rax; + l_reg->rip = b_reg->r_rip; + l_reg->cs = b_reg->r_cs; + l_reg->eflags = b_reg->r_rflags; + l_reg->rsp = b_reg->r_rsp; + l_reg->ss = b_reg->r_ss; +} + +static void +map_regs_from_linux(struct reg *b_reg, struct linux_pt_reg *l_reg) +{ + b_reg->r_r15 = l_reg->r15; + b_reg->r_r14 = l_reg->r14; + b_reg->r_r13 = l_reg->r13; + b_reg->r_r12 = l_reg->r12; + b_reg->r_r11 = l_reg->r11; + b_reg->r_r10 = l_reg->r10; + b_reg->r_r9 = l_reg->r9; + b_reg->r_r8 = l_reg->r8; + b_reg->r_rdi = l_reg->rdi; + b_reg->r_rsi = l_reg->rsi; + b_reg->r_rbp = l_reg->rbp; + b_reg->r_rbx = l_reg->rbx; + b_reg->r_rdx = l_reg->rdx; + b_reg->r_rcx = l_reg->rcx; + b_reg->r_rax = l_reg->rax; + + /* + * XXX: Are zeroes the right thing to put here? + */ + b_reg->r_trapno = 0; + b_reg->r_fs = 0; + b_reg->r_gs = 0; + b_reg->r_err = 0; + b_reg->r_es = 0; + b_reg->r_ds = 0; + + b_reg->r_rip = l_reg->rip; + b_reg->r_cs = l_reg->cs; + b_reg->r_rflags = l_reg->eflags; + b_reg->r_rsp = l_reg->rsp; + b_reg->r_ss = l_reg->ss; +} + +static int +linux_ptrace_peek(struct thread *td, pid_t pid, void *addr, void *data) +{ + int error; + + error = kern_ptrace(td, PT_READ_I, pid, addr, 0); + if (error == 0) + error = copyout(td->td_retval, data, sizeof(l_int)); + td->td_retval[0] = error; + + return (error); +} + +static int +linux_ptrace_setoptions(struct thread *td, pid_t pid, l_ulong data) +{ + int mask; + + mask = 0; + + if (data & ~LINUX_PTRACE_O_MASK) { + printf("%s: unknown ptrace option %lx set; " + "returning EINVAL\n", + __func__, data & ~LINUX_PTRACE_O_MASK); + return (EINVAL); + } + + /* + * PTRACE_O_EXITKILL is ignored, we do that by default. + */ + + if (data & LINUX_PTRACE_O_TRACESYSGOOD) { + printf("%s: PTRACE_O_TRACESYSGOOD not implemented; " + "returning EINVAL\n", __func__); + return (EINVAL); + } + + if (data & LINUX_PTRACE_O_TRACEFORK) + mask |= PTRACE_FORK; + + if (data & LINUX_PTRACE_O_TRACEVFORK) + mask |= PTRACE_VFORK; + + if (data & LINUX_PTRACE_O_TRACECLONE) + mask |= PTRACE_VFORK; + + if (data & LINUX_PTRACE_O_TRACEEXEC) + mask |= PTRACE_EXEC; + + if (data & LINUX_PTRACE_O_TRACEVFORKDONE) + mask |= PTRACE_VFORK; /* XXX: Close enough? */ + + if (data & LINUX_PTRACE_O_TRACEEXIT) { + printf("%s: PTRACE_O_TRACEEXIT not implemented; " + "returning EINVAL\n", __func__); + return (EINVAL); + } + + return (kern_ptrace(td, PT_SET_EVENT_MASK, pid, &mask, sizeof(mask))); +} + +static int +linux_ptrace_getregs(struct thread *td, pid_t pid, void *data) +{ + struct ptrace_lwpinfo lwpinfo; + struct reg b_reg; + struct linux_pt_reg l_reg; + int error; + + error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0); + if (error != 0) + return (error); + + map_regs_to_linux(&b_reg, &l_reg); + + /* + * The strace(1) utility depends on RAX being set to -ENOSYS + * on syscall entry. + */ + error = kern_ptrace(td, PT_LWPINFO, pid, &lwpinfo, sizeof(lwpinfo)); + if (error != 0) { + printf("%s: PT_LWPINFO failed with error %d\n", __func__, error); + return (error); + } + if (lwpinfo.pl_flags & PL_FLAG_SCE) + l_reg.rax = -38; // XXX: Don't hardcode? + + error = copyout(&l_reg, (void *)data, sizeof(l_reg)); + return (error); +} + +static int +linux_ptrace_setregs(struct thread *td, pid_t pid, void *data) +{ + struct reg b_reg; + struct linux_pt_reg l_reg; + int error; + + error = copyin(data, &l_reg, sizeof(l_reg)); + if (error != 0) + return (error); + map_regs_from_linux(&b_reg, &l_reg); + error = kern_ptrace(td, PT_SETREGS, pid, &b_reg, 0); + return (error); +} + +static int +linux_ptrace_getregset(struct thread *td, pid_t pid, l_ulong addr, l_ulong data) +{ + + switch (addr) { + case LINUX_NT_PRSTATUS: + printf("%s: NT_PRSTATUS not implemented; returning EINVAL\n", + __func__); + return (EINVAL); + default: + printf("%s: PTRACE_GETREGSET request %ld not implemented; " + "returning EINVAL\n", __func__, addr); + return (EINVAL); + } +} + +static int +linux_ptrace_seize(struct thread *td, pid_t pid, l_ulong addr, l_ulong data) +{ + + printf("%s: PTRACE_SEIZE not implemented; returning EINVAL\n", __func__); + return (EINVAL); +} + +int +linux_ptrace(struct thread *td, struct linux_ptrace_args *uap) +{ + void *addr; + pid_t pid; + int error, sig; + + pid = (pid_t)uap->pid; + addr = (void *)uap->addr; + + switch (uap->req) { + case LINUX_PTRACE_TRACEME: + error = kern_ptrace(td, PT_TRACE_ME, 0, 0, 0); + break; + case LINUX_PTRACE_PEEKTEXT: + case LINUX_PTRACE_PEEKDATA: + error = linux_ptrace_peek(td, pid, addr, (void *)uap->data); + if (error != 0) + return (error); + /* + * Linux expects this syscall to read 64 bits, not 32. + */ + error = linux_ptrace_peek(td, pid, + (void *)(uap->addr + 4), (void *)(uap->data + 4)); + break; + case LINUX_PTRACE_POKETEXT: + error = kern_ptrace(td, PT_WRITE_I, pid, addr, uap->data); + break; + case LINUX_PTRACE_POKEDATA: + error = kern_ptrace(td, PT_WRITE_D, pid, addr, uap->data); + break; + case LINUX_PTRACE_CONT: + error = map_signum(uap->data, &sig); + if (error != 0) + break; + error = kern_ptrace(td, PT_CONTINUE, pid, (void *)1, sig); + break; + case LINUX_PTRACE_KILL: + error = kern_ptrace(td, PT_KILL, pid, addr, uap->data); + break; + case LINUX_PTRACE_SINGLESTEP: + error = map_signum(uap->data, &sig); + if (error != 0) + break; + error = kern_ptrace(td, PT_STEP, pid, (void *)1, sig); + break; + case LINUX_PTRACE_GETREGS: + error = linux_ptrace_getregs(td, pid, (void *)uap->data); + break; + case LINUX_PTRACE_SETREGS: + error = linux_ptrace_setregs(td, pid, (void *)uap->data); + break; + case LINUX_PTRACE_ATTACH: + error = kern_ptrace(td, PT_ATTACH, pid, addr, uap->data); + break; + case LINUX_PTRACE_DETACH: + error = map_signum(uap->data, &sig); + if (error != 0) + break; + error = kern_ptrace(td, PT_DETACH, pid, (void *)1, sig); + break; + case LINUX_PTRACE_SYSCALL: + error = map_signum(uap->data, &sig); + if (error != 0) + break; + error = kern_ptrace(td, PT_SYSCALL, pid, (void *)1, sig); + break; + case LINUX_PTRACE_SETOPTIONS: + error = linux_ptrace_setoptions(td, pid, uap->data); + break; + case LINUX_PTRACE_GETREGSET: + error = linux_ptrace_getregset(td, pid, uap->addr, uap->data); + break; + case LINUX_PTRACE_SEIZE: + error = linux_ptrace_seize(td, pid, uap->addr, uap->data); + break; + default: + printf("%s: ptrace(%ld, ...) not implemented; returning EINVAL\n", + __func__, uap->req); + error = EINVAL; + break; + } + + return (error); +} diff --git a/sys/amd64/linux/linux_systrace_args.c b/sys/amd64/linux/linux_systrace_args.c index 35cd5bd16e7b..e4ad84a33d31 100644 --- a/sys/amd64/linux/linux_systrace_args.c +++ b/sys/amd64/linux/linux_systrace_args.c @@ -874,8 +874,8 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) struct linux_ptrace_args *p = params; iarg[0] = p->req; /* l_long */ iarg[1] = p->pid; /* l_long */ - iarg[2] = p->addr; /* l_long */ - iarg[3] = p->data; /* l_long */ + iarg[2] = p->addr; /* l_ulong */ + iarg[3] = p->data; /* l_ulong */ *n_args = 4; break; } @@ -3971,10 +3971,10 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "l_long"; break; case 2: - p = "l_long"; + p = "l_ulong"; break; case 3: - p = "l_long"; + p = "l_ulong"; break; default: break; diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master index 291953bf3e66..405fd78cd0e6 100644 --- a/sys/amd64/linux/syscalls.master +++ b/sys/amd64/linux/syscalls.master @@ -219,7 +219,7 @@ 99 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); } 100 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } 101 AUE_PTRACE STD { int linux_ptrace(l_long req, l_long pid, \ - l_long addr, l_long data); } + l_ulong addr, l_ulong data); } 102 AUE_GETUID STD { int linux_getuid(void); } 103 AUE_NULL STD { int linux_syslog(l_int type, char *buf, \ l_int len); } diff --git a/sys/arm/arm/cpufunc_asm.S b/sys/arm/arm/cpufunc_asm.S index 792a1975b4e5..20f2efb91185 100644 --- a/sys/arm/arm/cpufunc_asm.S +++ b/sys/arm/arm/cpufunc_asm.S @@ -124,9 +124,6 @@ ENTRY(cpufunc_control) mov r0, r3 /* Return old value */ RET -.Lglou: - .asciz "plop %p\n" - .align 2 END(cpufunc_control) /* diff --git a/sys/arm/freescale/imx/imx6_usbphy.c b/sys/arm/freescale/imx/imx6_usbphy.c index a338737a63d3..806659bc64e2 100644 --- a/sys/arm/freescale/imx/imx6_usbphy.c +++ b/sys/arm/freescale/imx/imx6_usbphy.c @@ -143,6 +143,10 @@ usbphy_attach(device_t dev) bus_write_4(sc->mem_res, CTRL_SET_REG, CTRL_SFTRST); bus_write_4(sc->mem_res, CTRL_CLR_REG, CTRL_SFTRST | CTRL_CLKGATE); + /* Set UTMI+ level 2+3 bits to enable low and full speed devices. */ + bus_write_4(sc->mem_res, CTRL_SET_REG, + CTRL_ENUTMILEVEL2 | CTRL_ENUTMILEVEL3); + /* Power up: clear all bits in the powerdown register. */ bus_write_4(sc->mem_res, PWD_REG, 0); diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S index 1b501a4934ea..299e590ded09 100644 --- a/sys/arm64/arm64/swtch.S +++ b/sys/arm64/arm64/swtch.S @@ -241,11 +241,6 @@ ENTRY(fork_trampoline) mov fp, #0 /* Stack traceback stops here. */ bl _C_LABEL(fork_exit) - /* Restore sp and lr */ - ldp x0, x1, [sp] - msr sp_el0, x0 - mov lr, x1 - /* Restore the registers other than x0 and x1 */ ldp x2, x3, [sp, #TF_X + 2 * 8] ldp x4, x5, [sp, #TF_X + 4 * 8] @@ -261,14 +256,18 @@ ENTRY(fork_trampoline) ldp x24, x25, [sp, #TF_X + 24 * 8] ldp x26, x27, [sp, #TF_X + 26 * 8] ldp x28, x29, [sp, #TF_X + 28 * 8] - /* Skip x30 as it was restored above as lr */ /* * Disable interrupts to avoid - * overwriting spsr_el1 by an IRQ exception. + * overwriting spsr_el1 and sp_el0 by an IRQ exception. */ msr daifset, #2 + /* Restore sp and lr */ + ldp x0, x1, [sp] + msr sp_el0, x0 + mov lr, x1 + /* Restore elr and spsr */ ldp x0, x1, [sp, #16] msr elr_el1, x0 diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 790c02a2d369..c25304511def 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -119,6 +119,7 @@ options PCI_IOV # PCI SR-IOV support device mii device miibus # MII bus support device awg # Allwinner EMAC Gigabit Ethernet +device axgbe # AMD Opteron A1100 integrated NIC device em # Intel PRO/1000 Gigabit Ethernet Family device ix # Intel 10Gb Ethernet Family device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c index 5ba65a4a4446..e503a289a1c7 100644 --- a/sys/boot/common/ufsread.c +++ b/sys/boot/common/ufsread.c @@ -127,7 +127,7 @@ lookup(const char *path) ssize_t n; uint8_t dt; - ino = ROOTINO; + ino = UFS_ROOTINO; dt = DT_DIR; for (;;) { if (*path == '/') @@ -261,19 +261,19 @@ fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep) while (nb) { lbn = lblkno(&fs, fs_off); off = blkoff(&fs, fs_off); - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { addr2 = DIP(di_db[lbn]); - } else if (lbn < NDADDR + NINDIR(&fs)) { + } else if (lbn < UFS_NDADDR + NINDIR(&fs)) { n = INDIRPERVBLK(&fs); addr2 = DIP(di_ib[0]); - u = (u_int)(lbn - NDADDR) / n * DBPERVBLK; + u = (u_int)(lbn - UFS_NDADDR) / n * DBPERVBLK; vbaddr = fsbtodb(&fs, addr2) + u; if (indmap != vbaddr) { if (dskread(indbuf, vbaddr, DBPERVBLK)) return -1; indmap = vbaddr; } - n = (lbn - NDADDR) & (n - 1); + n = (lbn - UFS_NDADDR) & (n - 1); #if defined(UFS1_ONLY) memcpy(&addr1, (ufs1_daddr_t *)indbuf + n, sizeof(ufs1_daddr_t)); diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c index 790f41be6cbf..0bff2d24e530 100644 --- a/sys/boot/efi/libefi/efipart.c +++ b/sys/boot/efi/libefi/efipart.c @@ -254,7 +254,7 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias, } unit++; } - + cd = malloc(sizeof(pdinfo_t)); if (cd == NULL) { printf("Failed to add cd %d, out of memory\n", unit); @@ -290,7 +290,7 @@ efipart_updatecd(void) continue; if (efipart_floppy(node) != NULL) continue; - + status = BS->HandleProtocol(efipart_handles[i], &blkio_guid, (void **)&blkio); if (EFI_ERROR(status)) @@ -417,6 +417,89 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle) return (0); } +/* + * The MEDIA_FILEPATH_DP has device name. + * From U-Boot sources it looks like names are in the form + * of typeN:M, where type is interface type, N is disk id + * and M is partition id. + */ +static int +efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle) +{ + EFI_DEVICE_PATH *devpath; + FILEPATH_DEVICE_PATH *node; + char *pathname, *p; + int unit, len; + pdinfo_t *pd, *last; + + /* First collect and verify all the data */ + if ((devpath = efi_lookup_devpath(disk_handle)) == NULL) + return (ENOENT); + node = (FILEPATH_DEVICE_PATH *)efi_devpath_last_node(devpath); + if (node == NULL) + return (ENOENT); /* This should not happen. */ + + pd = malloc(sizeof(pdinfo_t)); + if (pd == NULL) { + printf("Failed to add disk, out of memory\n"); + return (ENOMEM); + } + memset(pd, 0, sizeof(pdinfo_t)); + STAILQ_INIT(&pd->pd_part); + last = STAILQ_LAST(&hdinfo, pdinfo, pd_link); + if (last != NULL) + unit = last->pd_unit + 1; + else + unit = 0; + + /* FILEPATH_DEVICE_PATH has 0 terminated string */ + for (len = 0; node->PathName[len] != 0; len++) + ; + if ((pathname = malloc(len + 1)) == NULL) { + printf("Failed to add disk, out of memory\n"); + free(pd); + return (ENOMEM); + } + cpy16to8(node->PathName, pathname, len + 1); + p = strchr(pathname, ':'); + + /* + * Assume we are receiving handles in order, first disk handle, + * then partitions for this disk. If this assumption proves + * false, this code would need update. + */ + if (p == NULL) { /* no colon, add the disk */ + pd->pd_handle = disk_handle; + pd->pd_unit = unit; + pd->pd_devpath = devpath; + STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link); + free(pathname); + return (0); + } + p++; /* skip the colon */ + unit = (int)strtol(p, NULL, 0); + + /* + * We should have disk registered, if not, we are receiving + * handles out of order, and this code should be reworked + * to create "blank" disk for partition, and to find the + * disk based on PathName compares. + */ + if (last == NULL) { + printf("BUG: No disk for partition \"%s\"\n", pathname); + free(pathname); + free(pd); + return (EINVAL); + } + /* Add the partition. */ + pd->pd_handle = disk_handle; + pd->pd_unit = unit; + pd->pd_devpath = devpath; + STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link); + free(pathname); + return (0); +} + static void efipart_updatehd(void) { @@ -467,6 +550,12 @@ efipart_updatehd(void) efipart_hdinfo_add(handle, efipart_handles[i]); continue; } + + if (DevicePathType(node) == MEDIA_DEVICE_PATH && + DevicePathSubType(node) == MEDIA_FILEPATH_DP) { + efipart_hdinfo_add_filepath(efipart_handles[i]); + continue; + } } } @@ -500,14 +589,14 @@ efipart_print_common(struct devsw *dev, pdinfo_list_t *pdlist, int verbose) if (STAILQ_EMPTY(pdlist)) return (0); - + printf("%s devices:", dev->dv_name); if ((ret = pager_output("\n")) != 0) return (ret); STAILQ_FOREACH(pd, pdlist, pd_link) { h = pd->pd_handle; - if (verbose) { /* Output the device path. */ + if (verbose) { /* Output the device path. */ text = efi_devpath_name(efi_lookup_devpath(h)); if (text != NULL) { printf(" %S", text); @@ -618,7 +707,7 @@ efipart_open(struct open_file *f, ...) pd = efiblk_get_pdinfo(pdi, dev->d_unit); if (pd == NULL) return (EIO); - + if (pd->pd_blkio == NULL) { status = BS->HandleProtocol(pd->pd_handle, &blkio_guid, (void **)&pd->pd_blkio); @@ -702,7 +791,7 @@ efipart_ioctl(struct open_file *f, u_long cmd, void *data) *(u_int *)data = pd->pd_blkio->Media->BlockSize; break; case DIOCGMEDIASIZE: - *(off_t *)data = pd->pd_blkio->Media->BlockSize * + *(uint64_t *)data = pd->pd_blkio->Media->BlockSize * (pd->pd_blkio->Media->LastBlock + 1); break; default: @@ -826,9 +915,9 @@ efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size, if (rsize != NULL) *rsize = size; - if ((size % blkio->Media->BlockSize == 0) && + if ((size % blkio->Media->BlockSize == 0) && ((blk * 512) % blkio->Media->BlockSize == 0)) - return (efipart_readwrite(blkio, rw, + return (efipart_readwrite(blkio, rw, blk * 512 / blkio->Media->BlockSize, size / blkio->Media->BlockSize, buf)); diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 74a780eb5572..4bf98ee80822 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -12405,6 +12405,9 @@ ctl_datamove(union ctl_io *io) if (io->io_hdr.flags & CTL_FLAG_DELAY_DONE) { io->io_hdr.flags &= ~CTL_FLAG_DELAY_DONE; } else { + struct ctl_lun *lun; + + lun = CTL_LUN(io); if ((lun != NULL) && (lun->delay_info.datamove_delay > 0)) { diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index b743bc6c66b6..ba3fa1c7c23e 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -1120,8 +1120,10 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, STAILQ_INIT(&be_lun->cont_queue); sx_init(&be_lun->page_lock, "cram page lock"); - if (be_lun->cap_bytes == 0) + if (be_lun->cap_bytes == 0) { + be_lun->indir = 0; be_lun->pages = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK); + } be_lun->zero_page = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK|M_ZERO); mtx_init(&be_lun->queue_lock, "cram queue lock", NULL, MTX_DEF); diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c index 9c222fa4286c..42331ea224f9 100644 --- a/sys/cam/ctl/ctl_error.c +++ b/sys/cam/ctl/ctl_error.c @@ -920,10 +920,7 @@ ctl_set_data_phase_error(struct ctl_scsiio *ctsio) void ctl_set_reservation_conflict(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; - sense = &ctsio->sense_data; - memset(sense, 0, sizeof(*sense)); ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; ctsio->sense_len = 0; ctsio->io_hdr.status = CTL_SCSI_ERROR; @@ -932,10 +929,7 @@ ctl_set_reservation_conflict(struct ctl_scsiio *ctsio) void ctl_set_queue_full(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; - sense = &ctsio->sense_data; - memset(sense, 0, sizeof(*sense)); ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL; ctsio->sense_len = 0; ctsio->io_hdr.status = CTL_SCSI_ERROR; @@ -944,10 +938,7 @@ ctl_set_queue_full(struct ctl_scsiio *ctsio) void ctl_set_busy(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; - sense = &ctsio->sense_data; - memset(sense, 0, sizeof(*sense)); ctsio->scsi_status = SCSI_STATUS_BUSY; ctsio->sense_len = 0; ctsio->io_hdr.status = CTL_SCSI_ERROR; @@ -956,10 +947,7 @@ ctl_set_busy(struct ctl_scsiio *ctsio) void ctl_set_task_aborted(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; - sense = &ctsio->sense_data; - memset(sense, 0, sizeof(*sense)); ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED; ctsio->sense_len = 0; ctsio->io_hdr.status = CTL_CMD_ABORTED; @@ -992,10 +980,7 @@ ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio) void ctl_set_success(struct ctl_scsiio *ctsio) { - struct scsi_sense_data *sense; - sense = &ctsio->sense_data; - memset(sense, 0, sizeof(*sense)); ctsio->scsi_status = SCSI_STATUS_OK; ctsio->sense_len = 0; ctsio->io_hdr.status = CTL_SUCCESS; diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 0992fdb1352c..c91d52d65962 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -95,10 +95,9 @@ SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, ping_timeout, CTLFLAG_RWTUN, static int login_timeout = 60; SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, login_timeout, CTLFLAG_RWTUN, &login_timeout, 60, "Time to wait for ctld(8) to finish Login Phase, in seconds"); -static int maxcmdsn_delta = 256; -SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxcmdsn_delta, CTLFLAG_RWTUN, - &maxcmdsn_delta, 256, "Number of commands the initiator can send " - "without confirmation"); +static int maxtags = 256; +SYSCTL_INT(_kern_cam_ctl_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, + &maxtags, 0, "Max number of requests queued by initiator"); #define CFISCSI_DEBUG(X, ...) \ do { \ @@ -244,7 +243,7 @@ cfiscsi_pdu_update_cmdsn(const struct icl_pdu *request) * outside of this range. */ if (ISCSI_SNLT(cmdsn, cs->cs_cmdsn) || - ISCSI_SNGT(cmdsn, cs->cs_cmdsn + maxcmdsn_delta)) { + ISCSI_SNGT(cmdsn, cs->cs_cmdsn - 1 + maxtags)) { CFISCSI_SESSION_UNLOCK(cs); CFISCSI_SESSION_WARN(cs, "received PDU with CmdSN %u, " "while expected %u", cmdsn, cs->cs_cmdsn); @@ -399,7 +398,8 @@ cfiscsi_pdu_prepare(struct icl_pdu *response) (bhssr->bhssr_flags & BHSDI_FLAGS_S)) bhssr->bhssr_statsn = htonl(cs->cs_statsn); bhssr->bhssr_expcmdsn = htonl(cs->cs_cmdsn); - bhssr->bhssr_maxcmdsn = htonl(cs->cs_cmdsn + maxcmdsn_delta); + bhssr->bhssr_maxcmdsn = htonl(cs->cs_cmdsn - 1 + + imax(0, maxtags - cs->cs_outstanding_ctl_pdus)); if (advance_statsn) cs->cs_statsn++; diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c index 4b739fdf7b3b..845da7a70801 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c @@ -1246,7 +1246,7 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) ASSERT(!(p->p_flag & SVFORK)); mutex_exit(&p->p_lock); #else - if ((p = pfind(probe->ftp_pid)) == NULL) + if (pget(probe->ftp_pid, PGET_HOLD | PGET_NOTWEXIT, &p) != 0) return; #endif @@ -1255,13 +1255,6 @@ fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) * the chance to execute the trap instruction we're about to place * in their process's text. */ -#ifdef __FreeBSD__ - /* - * pfind() returns a locked process. - */ - _PHOLD(p); - PROC_UNLOCK(p); -#endif fasttrap_enable_callbacks(); /* @@ -1333,17 +1326,8 @@ fasttrap_pid_disable(void *arg, dtrace_id_t id, void *parg) * provider lock as a point of mutual exclusion to prevent other * DTrace consumers from disabling this probe. */ - if ((p = pfind(probe->ftp_pid)) != NULL) { -#ifdef __FreeBSD__ - if (p->p_flag & P_WEXIT) { - PROC_UNLOCK(p); - p = NULL; - } else { - _PHOLD(p); - PROC_UNLOCK(p); - } -#endif - } + if (pget(probe->ftp_pid, PGET_HOLD | PGET_NOTWEXIT, &p) != 0) + p = NULL; /* * Disable all the associated tracepoints (for fully enabled probes). diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index b41b746d3687..2a7801e2cc1a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -711,7 +711,6 @@ typedef struct arc_stats { kstat_named_t arcstat_l2_size; kstat_named_t arcstat_l2_asize; kstat_named_t arcstat_l2_hdr_size; - kstat_named_t arcstat_l2_padding_needed; kstat_named_t arcstat_l2_write_trylock_fail; kstat_named_t arcstat_l2_write_passed_headroom; kstat_named_t arcstat_l2_write_spa_mismatch; @@ -809,7 +808,6 @@ static arc_stats_t arc_stats = { { "l2_size", KSTAT_DATA_UINT64 }, { "l2_asize", KSTAT_DATA_UINT64 }, { "l2_hdr_size", KSTAT_DATA_UINT64 }, - { "l2_padding_needed", KSTAT_DATA_UINT64 }, { "l2_write_trylock_fail", KSTAT_DATA_UINT64 }, { "l2_write_passed_headroom", KSTAT_DATA_UINT64 }, { "l2_write_spa_mismatch", KSTAT_DATA_UINT64 }, @@ -4088,7 +4086,6 @@ arc_reclaim_thread(void *dummy __unused) mutex_enter(&arc_reclaim_lock); while (!arc_reclaim_thread_exit) { - int64_t free_memory = arc_available_memory(); uint64_t evicted = 0; /* @@ -4107,6 +4104,14 @@ arc_reclaim_thread(void *dummy __unused) mutex_exit(&arc_reclaim_lock); + /* + * We call arc_adjust() before (possibly) calling + * arc_kmem_reap_now(), so that we can wake up + * arc_get_data_buf() sooner. + */ + evicted = arc_adjust(); + + int64_t free_memory = arc_available_memory(); if (free_memory < 0) { arc_no_grow = B_TRUE; @@ -4140,8 +4145,6 @@ arc_reclaim_thread(void *dummy __unused) arc_no_grow = B_FALSE; } - evicted = arc_adjust(); - mutex_enter(&arc_reclaim_lock); /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c index aad00863f814..40b217e4daad 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c @@ -49,12 +49,6 @@ uint_t zfs_dbuf_evict_key; -/* - * Number of times that zfs_free_range() took the slow path while doing - * a zfs receive. A nonzero value indicates a potential performance problem. - */ -uint64_t zfs_free_range_recv_miss; - static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx); static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx); @@ -1220,9 +1214,6 @@ dbuf_unoverride(dbuf_dirty_record_t *dr) * Evict (if its unreferenced) or clear (if its referenced) any level-0 * data blocks in the free range, so that any future readers will find * empty blocks. - * - * This is a no-op if the dataset is in the middle of an incremental - * receive; see comment below for details. */ void dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, @@ -1232,10 +1223,9 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, dmu_buf_impl_t *db, *db_next; uint64_t txg = tx->tx_txg; avl_index_t where; - boolean_t freespill = - (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID); - if (end_blkid > dn->dn_maxblkid && !freespill) + if (end_blkid > dn->dn_maxblkid && + !(start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID)) end_blkid = dn->dn_maxblkid; dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid); @@ -1244,29 +1234,9 @@ dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, db_search.db_state = DB_SEARCH; mutex_enter(&dn->dn_dbufs_mtx); - if (start_blkid >= dn->dn_unlisted_l0_blkid && !freespill) { - /* There can't be any dbufs in this range; no need to search. */ -#ifdef DEBUG - db = avl_find(&dn->dn_dbufs, &db_search, &where); - ASSERT3P(db, ==, NULL); - db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); - ASSERT(db == NULL || db->db_level > 0); -#endif - mutex_exit(&dn->dn_dbufs_mtx); - return; - } else if (dmu_objset_is_receiving(dn->dn_objset)) { - /* - * If we are receiving, we expect there to be no dbufs in - * the range to be freed, because receive modifies each - * block at most once, and in offset order. If this is - * not the case, it can lead to performance problems, - * so note that we unexpectedly took the slow path. - */ - atomic_inc_64(&zfs_free_range_recv_miss); - } - db = avl_find(&dn->dn_dbufs, &db_search, &where); ASSERT3P(db, ==, NULL); + db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); for (; db != NULL; db = db_next) { @@ -2283,9 +2253,7 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid, return (odb); } avl_add(&dn->dn_dbufs, db); - if (db->db_level == 0 && db->db_blkid >= - dn->dn_unlisted_l0_blkid) - dn->dn_unlisted_l0_blkid = db->db_blkid + 1; + db->db_state = DB_UNCACHED; mutex_exit(&dn->dn_dbufs_mtx); arc_space_consume(sizeof (dmu_buf_impl_t), ARC_SPACE_OTHER); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c index d599ed32b0d5..9c618d932755 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] */ @@ -153,7 +153,6 @@ dnode_cons(void *arg, void *unused, int kmflag) dn->dn_id_flags = 0; dn->dn_dbufs_count = 0; - dn->dn_unlisted_l0_blkid = 0; avl_create(&dn->dn_dbufs, dbuf_compare, sizeof (dmu_buf_impl_t), offsetof(dmu_buf_impl_t, db_link)); @@ -207,7 +206,6 @@ dnode_dest(void *arg, void *unused) ASSERT0(dn->dn_id_flags); ASSERT0(dn->dn_dbufs_count); - ASSERT0(dn->dn_unlisted_l0_blkid); avl_destroy(&dn->dn_dbufs); } @@ -525,7 +523,6 @@ dnode_destroy(dnode_t *dn) dn->dn_newuid = 0; dn->dn_newgid = 0; dn->dn_id_flags = 0; - dn->dn_unlisted_l0_blkid = 0; dmu_zfetch_fini(&dn->dn_zfetch); kmem_cache_free(dnode_cache, dn); @@ -761,7 +758,6 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) ASSERT(avl_is_empty(&ndn->dn_dbufs)); avl_swap(&ndn->dn_dbufs, &odn->dn_dbufs); ndn->dn_dbufs_count = odn->dn_dbufs_count; - ndn->dn_unlisted_l0_blkid = odn->dn_unlisted_l0_blkid; ndn->dn_bonus = odn->dn_bonus; ndn->dn_have_spill = odn->dn_have_spill; ndn->dn_zio = odn->dn_zio; @@ -794,7 +790,6 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn) avl_create(&odn->dn_dbufs, dbuf_compare, sizeof (dmu_buf_impl_t), offsetof(dmu_buf_impl_t, db_link)); odn->dn_dbufs_count = 0; - odn->dn_unlisted_l0_blkid = 0; odn->dn_bonus = NULL; odn->dn_zfetch.zf_dnode = NULL; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h index e55faf3fdb0a..a3538f52f965 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dnode.h @@ -195,8 +195,6 @@ struct dnode { /* protected by dn_dbufs_mtx; declared here to fill 32-bit hole */ uint32_t dn_dbufs_count; /* count of dn_dbufs */ - /* There are no level-0 blocks of this blkid or higher in dn_dbufs */ - uint64_t dn_unlisted_l0_blkid; /* protected by os_lock: */ list_node_t dn_dirty_link[TXG_SIZE]; /* next on dataset's dirty */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c index 9eaa7d2dd702..9ac5fc2aacdd 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c @@ -1604,16 +1604,21 @@ zfsctl_snapshot_vptocnp(struct vop_vptocnp_args *ap) } if (sep == NULL) { mutex_exit(&sdp->sd_lock); - error = ENOENT; + error = SET_ERROR(ENOENT); } else { size_t len; len = strlen(sep->se_name); - *ap->a_buflen -= len; - bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len); - mutex_exit(&sdp->sd_lock); - vref(dvp); - *ap->a_vpp = dvp; + if (*ap->a_buflen < len) { + mutex_exit(&sdp->sd_lock); + error = SET_ERROR(ENOMEM); + } else { + *ap->a_buflen -= len; + bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len); + mutex_exit(&sdp->sd_lock); + vref(dvp); + *ap->a_vpp = dvp; + } } VN_RELE(dvp); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 7993ef6d8704..2e0da41ef5db 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -5939,6 +5939,10 @@ zfs_vptocnp(struct vop_vptocnp_args *ap) error = zfs_znode_parent_and_name(zp, &dzp, name); if (error == 0) { len = strlen(name); + if (*ap->a_buflen < len) + error = SET_ERROR(ENOMEM); + } + if (error == 0) { *ap->a_buflen -= len; bcopy(name, ap->a_buf + *ap->a_buflen, len); *ap->a_vpp = ZTOV(dzp); diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c index df39d2ec1e92..717f4557a64d 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c @@ -41,7 +41,9 @@ #include <sys/dtrace_impl.h> #include <sys/dtrace_bsd.h> #include <machine/clock.h> +#include <machine/cpufunc.h> #include <machine/frame.h> +#include <machine/psl.h> #include <vm/pmap.h> extern void dtrace_getnanotime(struct timespec *tsp); @@ -384,6 +386,8 @@ dtrace_gethrestime(void) int dtrace_trap(struct trapframe *frame, u_int type) { + uint16_t nofault; + /* * A trap can occur while DTrace executes a probe. Before * executing the probe, DTrace blocks re-scheduling and sets @@ -393,7 +397,12 @@ dtrace_trap(struct trapframe *frame, u_int type) * * Check if DTrace has enabled 'no-fault' mode: */ - if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) { + sched_pin(); + nofault = cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT; + sched_unpin(); + if (nofault) { + KASSERT((read_rflags() & PSL_I) == 0, ("interrupts enabled")); + /* * There are only a couple of trap types that are expected. * All the rest will be handled in the usual way. diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c index b70eab964f10..3801c1ba772c 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c @@ -42,7 +42,9 @@ #include <sys/dtrace_impl.h> #include <sys/dtrace_bsd.h> #include <machine/clock.h> +#include <machine/cpufunc.h> #include <machine/frame.h> +#include <machine/psl.h> #include <vm/pmap.h> extern uintptr_t kernelbase; @@ -386,6 +388,8 @@ dtrace_gethrestime(void) int dtrace_trap(struct trapframe *frame, u_int type) { + uint16_t nofault; + /* * A trap can occur while DTrace executes a probe. Before * executing the probe, DTrace blocks re-scheduling and sets @@ -395,7 +399,12 @@ dtrace_trap(struct trapframe *frame, u_int type) * * Check if DTrace has enabled 'no-fault' mode: */ - if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) { + sched_pin(); + nofault = cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT; + sched_unpin(); + if (nofault) { + KASSERT((read_eflags() & PSL_I) == 0, ("interrupts enabled")); + /* * There are only a couple of trap types that are expected. * All the rest will be handled in the usual way. diff --git a/sys/compat/cloudabi/cloudabi_mem.c b/sys/compat/cloudabi/cloudabi_mem.c index 42234f9f99c5..30d9a6fee8ea 100644 --- a/sys/compat/cloudabi/cloudabi_mem.c +++ b/sys/compat/cloudabi/cloudabi_mem.c @@ -29,8 +29,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/mman.h> #include <sys/proc.h> - -#include <vm/vm_extern.h> +#include <sys/syscallsubr.h> #include <contrib/cloudabi/cloudabi_types_common.h> @@ -86,16 +85,16 @@ cloudabi_sys_mem_advise(struct thread *td, return (EINVAL); } - return (kern_vm_madvise(td, (vm_offset_t)uap->mapping, - uap->mapping_len, behav)); + return (kern_madvise(td, (uintptr_t)uap->mapping, uap->mapping_len, + behav)); } int cloudabi_sys_mem_lock(struct thread *td, struct cloudabi_sys_mem_lock_args *uap) { - return (vm_mlock(td->td_proc, td->td_ucred, uap->mapping, - uap->mapping_len)); + return (kern_mlock(td->td_proc, td->td_ucred, + __DECONST(uintptr_t, uap->mapping), uap->mapping_len)); } int @@ -119,8 +118,8 @@ cloudabi_sys_mem_map(struct thread *td, struct cloudabi_sys_mem_map_args *uap) if (error != 0) return (error); - return (kern_vm_mmap(td, (vm_offset_t)uap->addr, uap->len, prot, - flags, uap->fd, uap->off)); + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, flags, + uap->fd, uap->off)); } int @@ -134,8 +133,8 @@ cloudabi_sys_mem_protect(struct thread *td, if (error != 0) return (error); - return (kern_vm_mprotect(td, (vm_offset_t)uap->mapping, - uap->mapping_len, prot)); + return (kern_mprotect(td, (uintptr_t)uap->mapping, uap->mapping_len, + prot)); } int @@ -157,8 +156,8 @@ cloudabi_sys_mem_sync(struct thread *td, struct cloudabi_sys_mem_sync_args *uap) if ((uap->flags & CLOUDABI_MS_INVALIDATE) != 0) flags |= MS_INVALIDATE; - return (kern_vm_msync(td, (vm_offset_t)uap->mapping, - uap->mapping_len, flags)); + return (kern_msync(td, (uintptr_t)uap->mapping, uap->mapping_len, + flags)); } int @@ -166,7 +165,8 @@ cloudabi_sys_mem_unlock(struct thread *td, struct cloudabi_sys_mem_unlock_args *uap) { - return (kern_vm_munlock(td, (vm_offset_t)uap->mapping, uap->mapping_len)); + return (kern_munlock(td, __DECONST(uintptr_t, uap->mapping), + uap->mapping_len)); } int @@ -174,5 +174,5 @@ cloudabi_sys_mem_unmap(struct thread *td, struct cloudabi_sys_mem_unmap_args *uap) { - return (kern_vm_munmap(td, (vm_offset_t)uap->mapping, uap->mapping_len)); + return (kern_munmap(td, (uintptr_t)uap->mapping, uap->mapping_len)); } diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index d30c520b0e49..1c54d025a5e4 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -456,8 +456,8 @@ freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap) if (i386_read_exec && (prot & PROT_READ) != 0) prot |= PROT_EXEC; #endif - return (kern_vm_mprotect(td, (vm_offset_t)PTRIN(uap->addr), - uap->len, prot)); + return (kern_mprotect(td, (uintptr_t)PTRIN(uap->addr), uap->len, + prot)); } int @@ -471,25 +471,25 @@ freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) prot |= PROT_EXEC; #endif - return (kern_vm_mmap(td, (vm_offset_t)uap->addr, uap->len, prot, + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos))); } #ifdef COMPAT_FREEBSD6 int -freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap) +freebsd6_freebsd32_mmap(struct thread *td, + struct freebsd6_freebsd32_mmap_args *uap) { - struct freebsd32_mmap_args ap; + int prot; - ap.addr = uap->addr; - ap.len = uap->len; - ap.prot = uap->prot; - ap.flags = uap->flags; - ap.fd = uap->fd; - ap.pos1 = uap->pos1; - ap.pos2 = uap->pos2; + prot = uap->prot; +#if defined(__amd64__) + if (i386_read_exec && (prot & PROT_READ)) + prot |= PROT_EXEC; +#endif - return (freebsd32_mmap(td, &ap)); + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, + uap->flags, uap->fd, PAIR32TO64(off_t, uap->pos))); } #endif diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c index d1d787742c63..2846ad4935e5 100644 --- a/sys/compat/linux/linux.c +++ b/sys/compat/linux/linux.c @@ -128,7 +128,7 @@ int linux_to_bsd_signal(int sig) { - KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n")); + KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("invalid Linux signal %d\n", sig)); if (sig < LINUX_SIGRTMIN) return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]); diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 7c44009724b5..a7695f010cee 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -53,8 +53,6 @@ __FBSDID("$FreeBSD$"); #include <sys/unistd.h> #include <sys/vnode.h> -#include <security/mac/mac_framework.h> - #ifdef COMPAT_LINUX32 #include <machine/../linux32/linux.h> #include <machine/../linux32/linux32_proto.h> @@ -66,6 +64,10 @@ __FBSDID("$FreeBSD$"); #include <compat/linux/linux_util.h> #include <compat/linux/linux_file.h> +static int linux_common_open(struct thread *, int, char *, int, int); +static int linux_getdents_error(struct thread *, int, int); + + int linux_creat(struct thread *td, struct linux_creat_args *args) { @@ -244,28 +246,41 @@ linux_llseek(struct thread *td, struct linux_llseek_args *args) td->td_retval[0] = 0; return (0); } - -int -linux_readdir(struct thread *td, struct linux_readdir_args *args) -{ - struct linux_getdents_args lda; - - lda.fd = args->fd; - lda.dent = args->dent; - lda.count = 1; - return (linux_getdents(td, &lda)); -} #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ /* * Note that linux_getdents(2) and linux_getdents64(2) have the same * arguments. They only differ in the definition of struct dirent they - * operate on. We use this to common the code, with the exception of - * accessing struct dirent. Note that linux_readdir(2) is implemented - * by means of linux_getdents(2). In this case we never operate on - * struct dirent64 and thus don't need to handle it... + * operate on. + * Note that linux_readdir(2) is a special case of linux_getdents(2) + * where count is always equals 1, meaning that the buffer is one + * dirent-structure in size and that the code can't handle more anyway. + * Note that linux_readdir(2) can't be implemented by means of linux_getdents(2) + * as in case when the *dent buffer size is equal to 1 linux_getdents(2) will + * trash user stack. */ +static int +linux_getdents_error(struct thread *td, int fd, int err) +{ + cap_rights_t rights; + struct vnode *vp; + struct file *fp; + int error; + + /* Linux return ENOTDIR in case when fd is not a directory. */ + error = getvnode(td, fd, cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) + return (error); + vp = fp->f_vnode; + if (vp->v_type != VDIR) { + fdrop(fp, td); + return (ENOTDIR); + } + fdrop(fp, td); + return (err); +} + struct l_dirent { l_ulong d_ino; l_off_t d_off; @@ -292,242 +307,228 @@ struct l_dirent64 { roundup(offsetof(struct l_dirent64, d_name) + (namlen) + 1, \ sizeof(uint64_t)) -#define LINUX_MAXRECLEN max(LINUX_RECLEN(LINUX_NAME_MAX), \ - LINUX_RECLEN64(LINUX_NAME_MAX)) #define LINUX_DIRBLKSIZ 512 -static int -getdents_common(struct thread *td, struct linux_getdents64_args *args, - int is64bit) +/* + * Linux l_dirent is bigger than FreeBSD dirent, thus the buffer size + * passed to kern_getdirentries() must be smaller than the one passed + * to linux_getdents() by certain factor. + */ +#define LINUX_RECLEN_RATIO(X) X * offsetof(struct dirent, d_name) / \ + offsetof(struct l_dirent, d_name); +#define LINUX_RECLEN64_RATIO(X) X * offsetof(struct dirent, d_name) / \ + offsetof(struct l_dirent64, d_name); + +int +linux_getdents(struct thread *td, struct linux_getdents_args *args) { struct dirent *bdp; - struct vnode *vp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ - int resid, linuxreclen=0; /* Linux-format */ + int resid, linuxreclen; /* Linux-format */ caddr_t lbuf; /* Linux-format */ - cap_rights_t rights; - struct file *fp; - struct uio auio; - struct iovec aiov; - off_t off; + long base; struct l_dirent *linux_dirent; - struct l_dirent64 *linux_dirent64; - int buflen, error, eofflag, nbytes, justone; - u_long *cookies = NULL, *cookiep; - int ncookies; - - nbytes = args->count; - if (nbytes == 1) { - /* readdir(2) case. Always struct dirent. */ - if (is64bit) - return (EINVAL); - nbytes = sizeof(*linux_dirent); - justone = 1; - } else - justone = 0; + int buflen, error; + size_t retval; - error = getvnode(td, args->fd, cap_rights_init(&rights, CAP_READ), &fp); - if (error != 0) - return (error); - - if ((fp->f_flag & FREAD) == 0) { - fdrop(fp, td); - return (EBADF); - } +#ifdef DEBUG + if (ldebug(getdents)) + printf(ARGS(getdents, "%d, *, %d"), args->fd, args->count); +#endif + buflen = LINUX_RECLEN_RATIO(args->count); + buflen = min(buflen, MAXBSIZE); + buf = malloc(buflen, M_TEMP, M_WAITOK); - off = foffset_lock(fp, 0); - vp = fp->f_vnode; - if (vp->v_type != VDIR) { - foffset_unlock(fp, off, 0); - fdrop(fp, td); - return (EINVAL); + error = kern_getdirentries(td, args->fd, buf, buflen, + &base, NULL, UIO_SYSSPACE); + if (error != 0) { + error = linux_getdents_error(td, args->fd, error); + goto out1; } + lbuf = malloc(LINUX_RECLEN(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); - buflen = max(LINUX_DIRBLKSIZ, nbytes); - buflen = min(buflen, MAXBSIZE); - buf = malloc(buflen, M_LINUX, M_WAITOK); - lbuf = malloc(LINUX_MAXRECLEN, M_LINUX, M_WAITOK | M_ZERO); - vn_lock(vp, LK_SHARED | LK_RETRY); - - aiov.iov_base = buf; - aiov.iov_len = buflen; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_rw = UIO_READ; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_td = td; - auio.uio_resid = buflen; - auio.uio_offset = off; - -#ifdef MAC - /* - * Do directory search MAC check using non-cached credentials. - */ - if ((error = mac_vnode_check_readdir(td->td_ucred, vp))) - goto out; -#endif /* MAC */ - if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, - &cookies))) - goto out; - + len = td->td_retval[0]; inp = buf; - outp = (caddr_t)args->dirent; - resid = nbytes; - if ((len = buflen - auio.uio_resid) <= 0) - goto eof; - - cookiep = cookies; - - if (cookies) { - /* - * When using cookies, the vfs has the option of reading from - * a different offset than that supplied (UFS truncates the - * offset to a block boundary to make sure that it never reads - * partway through a directory entry, even if the directory - * has been compacted). - */ - while (len > 0 && ncookies > 0 && *cookiep <= off) { - bdp = (struct dirent *) inp; - len -= bdp->d_reclen; - inp += bdp->d_reclen; - cookiep++; - ncookies--; - } - } + outp = (caddr_t)args->dent; + resid = args->count; + retval = 0; while (len > 0) { - if (cookiep && ncookies == 0) - break; bdp = (struct dirent *) inp; reclen = bdp->d_reclen; - if (reclen & 3) { - error = EFAULT; + linuxreclen = LINUX_RECLEN(bdp->d_namlen); + /* + * No more space in the user supplied dirent buffer. + * Return EINVAL. + */ + if (resid < linuxreclen) { + error = EINVAL; goto out; } - if (bdp->d_fileno == 0) { - inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; - - len -= reclen; - continue; - } - - linuxreclen = (is64bit) - ? LINUX_RECLEN64(bdp->d_namlen) - : LINUX_RECLEN(bdp->d_namlen); - - if (reclen > len || resid < linuxreclen) { - outp++; - break; - } - - if (justone) { - /* readdir(2) case. */ - linux_dirent = (struct l_dirent*)lbuf; - linux_dirent->d_ino = bdp->d_fileno; - linux_dirent->d_off = (l_off_t)linuxreclen; - linux_dirent->d_reclen = (l_ushort)bdp->d_namlen; - strlcpy(linux_dirent->d_name, bdp->d_name, - linuxreclen - offsetof(struct l_dirent, d_name)); - error = copyout(linux_dirent, outp, linuxreclen); - } - if (is64bit) { - linux_dirent64 = (struct l_dirent64*)lbuf; - linux_dirent64->d_ino = bdp->d_fileno; - linux_dirent64->d_off = (cookiep) - ? (l_off_t)*cookiep - : (l_off_t)(off + reclen); - linux_dirent64->d_reclen = (l_ushort)linuxreclen; - linux_dirent64->d_type = bdp->d_type; - strlcpy(linux_dirent64->d_name, bdp->d_name, - linuxreclen - offsetof(struct l_dirent64, d_name)); - error = copyout(linux_dirent64, outp, linuxreclen); - } else if (!justone) { - linux_dirent = (struct l_dirent*)lbuf; - linux_dirent->d_ino = bdp->d_fileno; - linux_dirent->d_off = (cookiep) - ? (l_off_t)*cookiep - : (l_off_t)(off + reclen); - linux_dirent->d_reclen = (l_ushort)linuxreclen; - /* - * Copy d_type to last byte of l_dirent buffer - */ - lbuf[linuxreclen-1] = bdp->d_type; - strlcpy(linux_dirent->d_name, bdp->d_name, - linuxreclen - offsetof(struct l_dirent, d_name)-1); - error = copyout(linux_dirent, outp, linuxreclen); - } - - if (error) + linux_dirent = (struct l_dirent*)lbuf; + linux_dirent->d_ino = bdp->d_fileno; + linux_dirent->d_off = base + reclen; + linux_dirent->d_reclen = linuxreclen; + /* + * Copy d_type to last byte of l_dirent buffer + */ + lbuf[linuxreclen - 1] = bdp->d_type; + strlcpy(linux_dirent->d_name, bdp->d_name, + linuxreclen - offsetof(struct l_dirent, d_name)-1); + error = copyout(linux_dirent, outp, linuxreclen); + if (error != 0) goto out; inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; + base += reclen; + len -= reclen; + retval += linuxreclen; outp += linuxreclen; resid -= linuxreclen; - len -= reclen; - if (justone) - break; } - - if (outp == (caddr_t)args->dirent) { - nbytes = resid; - goto eof; - } - - if (justone) - nbytes = resid + linuxreclen; - -eof: - td->td_retval[0] = nbytes - resid; + td->td_retval[0] = retval; out: - free(cookies, M_TEMP); - - VOP_UNLOCK(vp, 0); - foffset_unlock(fp, off, 0); - fdrop(fp, td); - free(buf, M_LINUX); free(lbuf, M_LINUX); +out1: + free(buf, M_LINUX); return (error); } int -linux_getdents(struct thread *td, struct linux_getdents_args *args) +linux_getdents64(struct thread *td, struct linux_getdents64_args *args) { + struct dirent *bdp; + caddr_t inp, buf; /* BSD-format */ + int len, reclen; /* BSD-format */ + caddr_t outp; /* Linux-format */ + int resid, linuxreclen; /* Linux-format */ + caddr_t lbuf; /* Linux-format */ + long base; + struct l_dirent64 *linux_dirent64; + int buflen, error; + size_t retval; #ifdef DEBUG - if (ldebug(getdents)) - printf(ARGS(getdents, "%d, *, %d"), args->fd, args->count); + if (ldebug(getdents64)) + uprintf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count); #endif + buflen = LINUX_RECLEN64_RATIO(args->count); + buflen = min(buflen, MAXBSIZE); + buf = malloc(buflen, M_TEMP, M_WAITOK); - return (getdents_common(td, (struct linux_getdents64_args*)args, 0)); + error = kern_getdirentries(td, args->fd, buf, buflen, + &base, NULL, UIO_SYSSPACE); + if (error != 0) { + error = linux_getdents_error(td, args->fd, error); + goto out1; + } + + lbuf = malloc(LINUX_RECLEN64(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); + + len = td->td_retval[0]; + inp = buf; + outp = (caddr_t)args->dirent; + resid = args->count; + retval = 0; + + while (len > 0) { + bdp = (struct dirent *) inp; + reclen = bdp->d_reclen; + linuxreclen = LINUX_RECLEN64(bdp->d_namlen); + /* + * No more space in the user supplied dirent buffer. + * Return EINVAL. + */ + if (resid < linuxreclen) { + error = EINVAL; + goto out; + } + + linux_dirent64 = (struct l_dirent64*)lbuf; + linux_dirent64->d_ino = bdp->d_fileno; + linux_dirent64->d_off = base + reclen; + linux_dirent64->d_reclen = linuxreclen; + linux_dirent64->d_type = bdp->d_type; + strlcpy(linux_dirent64->d_name, bdp->d_name, + linuxreclen - offsetof(struct l_dirent64, d_name)); + error = copyout(linux_dirent64, outp, linuxreclen); + if (error != 0) + goto out; + + inp += reclen; + base += reclen; + len -= reclen; + + retval += linuxreclen; + outp += linuxreclen; + resid -= linuxreclen; + } + td->td_retval[0] = retval; + +out: + free(lbuf, M_TEMP); +out1: + free(buf, M_TEMP); + return (error); } +#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) int -linux_getdents64(struct thread *td, struct linux_getdents64_args *args) +linux_readdir(struct thread *td, struct linux_readdir_args *args) { + struct dirent *bdp; + caddr_t buf; /* BSD-format */ + int linuxreclen; /* Linux-format */ + caddr_t lbuf; /* Linux-format */ + long base; + struct l_dirent *linux_dirent; + int buflen, error; #ifdef DEBUG - if (ldebug(getdents64)) - printf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count); + if (ldebug(readdir)) + printf(ARGS(readdir, "%d, *"), args->fd); #endif + buflen = LINUX_RECLEN(LINUX_NAME_MAX); + buflen = LINUX_RECLEN_RATIO(buflen); + buf = malloc(buflen, M_TEMP, M_WAITOK); + + error = kern_getdirentries(td, args->fd, buf, buflen, + &base, NULL, UIO_SYSSPACE); + if (error != 0) { + error = linux_getdents_error(td, args->fd, error); + goto out; + } + if (td->td_retval[0] == 0) + goto out; - return (getdents_common(td, args, 1)); + lbuf = malloc(LINUX_RECLEN(LINUX_NAME_MAX), M_TEMP, M_WAITOK | M_ZERO); + + bdp = (struct dirent *) buf; + linuxreclen = LINUX_RECLEN(bdp->d_namlen); + + linux_dirent = (struct l_dirent*)lbuf; + linux_dirent->d_ino = bdp->d_fileno; + linux_dirent->d_off = linuxreclen; + linux_dirent->d_reclen = bdp->d_namlen; + strlcpy(linux_dirent->d_name, bdp->d_name, + linuxreclen - offsetof(struct l_dirent, d_name)); + error = copyout(linux_dirent, args->dent, linuxreclen); + if (error == 0) + td->td_retval[0] = linuxreclen; + + free(lbuf, M_LINUX); +out: + free(buf, M_LINUX); + return (error); } +#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ + /* * These exist mainly for hooks for doing /compat/linux translation. diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index b73e5d9146f8..c92df986ff70 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -623,7 +623,7 @@ linux_mremap(struct thread *td, struct linux_mremap_args *args) if (args->new_len < args->old_len) { addr = args->addr + args->new_len; len = args->old_len - args->new_len; - error = kern_vm_munmap(td, addr, len); + error = kern_munmap(td, addr, len); } td->td_retval[0] = error ? 0 : (uintptr_t)args->addr; @@ -638,7 +638,7 @@ int linux_msync(struct thread *td, struct linux_msync_args *args) { - return (kern_vm_msync(td, args->addr, args->len, + return (kern_msync(td, args->addr, args->len, args->fl & ~LINUX_MS_SYNC)); } diff --git a/sys/compat/linux/linux_mmap.c b/sys/compat/linux/linux_mmap.c index 0c3f7688db59..802917f5a064 100644 --- a/sys/compat/linux/linux_mmap.c +++ b/sys/compat/linux/linux_mmap.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mman.h> #include <sys/proc.h> #include <sys/resourcevar.h> +#include <sys/syscallsubr.h> #include <sys/sysent.h> #include <sys/sysproto.h> @@ -202,7 +203,7 @@ linux_mmap_common(struct thread *td, uintptr_t addr, size_t len, int prot, } } - error = kern_vm_mmap(td, addr, len, prot, bsd_flags, fd, pos); + error = kern_mmap(td, addr, len, prot, bsd_flags, fd, pos); LINUX_CTR2(mmap2, "return: %d (%p)", error, td->td_retval[0]); @@ -216,7 +217,7 @@ linux_mprotect_common(struct thread *td, uintptr_t addr, size_t len, int prot) #if defined(__amd64__) linux_fixup_prot(td, &prot); #endif - return (kern_vm_mprotect(td, addr, len, prot)); + return (kern_mprotect(td, addr, len, prot)); } #if defined(__amd64__) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index d9fabb79b592..615c3d97c441 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1683,39 +1683,45 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) /* Argument list sizes for linux_socketcall */ - -#define LINUX_AL(x) ((x) * sizeof(l_ulong)) - -static const unsigned char lxs_args[] = { - LINUX_AL(0) /* unused*/, LINUX_AL(3) /* socket */, - LINUX_AL(3) /* bind */, LINUX_AL(3) /* connect */, - LINUX_AL(2) /* listen */, LINUX_AL(3) /* accept */, - LINUX_AL(3) /* getsockname */, LINUX_AL(3) /* getpeername */, - LINUX_AL(4) /* socketpair */, LINUX_AL(4) /* send */, - LINUX_AL(4) /* recv */, LINUX_AL(6) /* sendto */, - LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */, - LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */, - LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */, - LINUX_AL(4) /* accept4 */, LINUX_AL(5) /* recvmmsg */, - LINUX_AL(4) /* sendmmsg */ +static const unsigned char lxs_args_cnt[] = { + 0 /* unused*/, 3 /* socket */, + 3 /* bind */, 3 /* connect */, + 2 /* listen */, 3 /* accept */, + 3 /* getsockname */, 3 /* getpeername */, + 4 /* socketpair */, 4 /* send */, + 4 /* recv */, 6 /* sendto */, + 6 /* recvfrom */, 2 /* shutdown */, + 5 /* setsockopt */, 5 /* getsockopt */, + 3 /* sendmsg */, 3 /* recvmsg */, + 4 /* accept4 */, 5 /* recvmmsg */, + 4 /* sendmmsg */ }; - -#define LINUX_AL_SIZE (nitems(lxs_args) - 1) +#define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1) +#define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong)) int linux_socketcall(struct thread *td, struct linux_socketcall_args *args) { l_ulong a[6]; +#if defined(__amd64__) && defined(COMPAT_LINUX32) + register_t l_args[6]; +#endif void *arg; int error; - if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE) + if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT) return (EINVAL); - error = copyin(PTRIN(args->args), a, lxs_args[args->what]); - if (error) + error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what)); + if (error != 0) return (error); +#if defined(__amd64__) && defined(COMPAT_LINUX32) + for (int i = 0; i < lxs_args_cnt[args->what]; ++i) + l_args[i] = a[i]; + arg = l_args; +#else arg = a; +#endif switch (args->what) { case LINUX_SOCKET: return (linux_socket(td, arg)); diff --git a/sys/compat/linuxkpi/common/include/asm/atomic-long.h b/sys/compat/linuxkpi/common/include/asm/atomic-long.h index b7ccba5fcba8..374f015e20b8 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic-long.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic-long.h @@ -75,6 +75,12 @@ atomic_long_dec(atomic_long_t *v) return atomic_fetchadd_long(&v->counter, -1) - 1; } +static inline long +atomic_long_xchg(atomic_long_t *v, long val) +{ + return atomic_swap_long(&v->counter, val); +} + static inline int atomic_long_add_unless(atomic_long_t *v, long a, long u) { diff --git a/sys/compat/linuxkpi/common/include/asm/atomic.h b/sys/compat/linuxkpi/common/include/asm/atomic.h index 4912eefd03b6..5f07d0b2ad72 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic.h @@ -75,15 +75,21 @@ atomic_set(atomic_t *v, int i) } static inline void +atomic_set_release(atomic_t *v, int i) +{ + atomic_store_rel_int(&v->counter, i); +} + +static inline void atomic_set_mask(unsigned int mask, atomic_t *v) { atomic_set_int(&v->counter, mask); } static inline int -atomic_read(atomic_t *v) +atomic_read(const atomic_t *v) { - return atomic_load_acq_int(&v->counter); + return atomic_load_acq_int(&__DECONST(atomic_t *, v)->counter); } static inline int @@ -187,8 +193,26 @@ static inline void atomic_##op(int i, atomic_t *v) \ c = old; \ } +#define LINUX_ATOMIC_FETCH_OP(op, c_op) \ +static inline int atomic_fetch_##op(int i, atomic_t *v) \ +{ \ + int c, old; \ + \ + c = v->counter; \ + while ((old = atomic_cmpxchg(v, c, c c_op i)) != c) \ + c = old; \ + \ + return (c); \ +} + LINUX_ATOMIC_OP(or, |) LINUX_ATOMIC_OP(and, &) +LINUX_ATOMIC_OP(andnot, &~) LINUX_ATOMIC_OP(xor, ^) +LINUX_ATOMIC_FETCH_OP(or, |) +LINUX_ATOMIC_FETCH_OP(and, &) +LINUX_ATOMIC_FETCH_OP(andnot, &~) +LINUX_ATOMIC_FETCH_OP(xor, ^) + #endif /* _ASM_ATOMIC_H_ */ diff --git a/sys/compat/linuxkpi/common/include/asm/atomic64.h b/sys/compat/linuxkpi/common/include/asm/atomic64.h index f8dd2bbf5833..783f6997dde2 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic64.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic64.h @@ -36,6 +36,8 @@ typedef struct { volatile int64_t counter; } atomic64_t; +#define ATOMIC64_INIT(x) { .counter = (x) } + /*------------------------------------------------------------------------* * 64-bit atomic operations *------------------------------------------------------------------------*/ diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index 19e9c6eddcc8..313a6318b922 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -413,7 +413,7 @@ class_create(struct module *owner, const char *name) class = kzalloc(sizeof(*class), M_WAITOK); class->owner = owner; - class->name= name; + class->name = name; class->class_release = linux_class_kfree; error = class_register(class); if (error) { diff --git a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h index 87bc25ed3906..1b486ec80908 100644 --- a/sys/compat/linuxkpi/common/include/linux/dma-mapping.h +++ b/sys/compat/linuxkpi/common/include/linux/dma-mapping.h @@ -129,8 +129,10 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, if (dev->dma_mask) high = *dev->dma_mask; - else + else if (flag & GFP_DMA32) high = BUS_SPACE_MAXADDR_32BIT; + else + high = BUS_SPACE_MAXADDR; align = PAGE_SIZE << get_order(size); mem = (void *)kmem_alloc_contig(kmem_arena, size, flag, 0, high, align, 0, VM_MEMATTR_DEFAULT); diff --git a/sys/compat/linuxkpi/common/include/linux/gfp.h b/sys/compat/linuxkpi/common/include/linux/gfp.h index 1c73022ff13f..7840919864ea 100644 --- a/sys/compat/linuxkpi/common/include/linux/gfp.h +++ b/sys/compat/linuxkpi/common/include/linux/gfp.h @@ -53,7 +53,7 @@ #define __GFP_IO 0 #define __GFP_NO_KSWAPD 0 #define __GFP_WAIT M_WAITOK -#define __GFP_DMA32 0 +#define __GFP_DMA32 (1U << 24) /* LinuxKPI only */ #define GFP_NOWAIT M_NOWAIT #define GFP_ATOMIC (M_NOWAIT | M_USE_RESERVE) @@ -63,8 +63,9 @@ #define GFP_HIGHUSER_MOVABLE M_WAITOK #define GFP_IOFS M_NOWAIT #define GFP_NOIO M_NOWAIT -#define GFP_DMA32 0 +#define GFP_DMA32 __GFP_DMA32 #define GFP_TEMPORARY M_NOWAIT +#define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO) static inline void * page_address(struct page *page) diff --git a/sys/compat/linuxkpi/common/include/linux/kernel.h b/sys/compat/linuxkpi/common/include/linux/kernel.h index b813bd4f95e4..ead6a8a72bfe 100644 --- a/sys/compat/linuxkpi/common/include/linux/kernel.h +++ b/sys/compat/linuxkpi/common/include/linux/kernel.h @@ -245,8 +245,8 @@ scnprintf(char *buf, size_t size, const char *fmt, ...) #define container_of(ptr, type, member) \ ({ \ - __typeof(((type *)0)->member) *_p = (ptr); \ - (type *)((char *)_p - offsetof(type, member)); \ + const __typeof(((type *)0)->member) *__p = (ptr); \ + (type *)((uintptr_t)__p - offsetof(type, member)); \ }) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) diff --git a/sys/conf/NOTES b/sys/conf/NOTES index a8a6d03d8924..c7dd5a039844 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1429,7 +1429,7 @@ options PCI_IOV # PCI SR-IOV support # HARDWARE DEVICE CONFIGURATION # For ISA the required hints are listed. -# EISA, MCA, PCI, CardBus, SD/MMC and pccard are self identifying buses, so +# PCI, CardBus, SD/MMC and pccard are self identifying buses, so # no hints are needed. # @@ -1530,7 +1530,6 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # adv: All Narrow SCSI bus AdvanSys controllers. # adw: Second Generation AdvanSys controllers including the ADV940UW. # aha: Adaptec 154x/1535/1640 -# ahb: Adaptec 174x EISA controllers # ahc: Adaptec 274x/284x/2910/293x/294x/394x/3950x/3960x/398X/4944/ # 19160x/29160x, aic7770/aic78xx # ahd: Adaptec 29320/39320 Controllers. @@ -1557,7 +1556,7 @@ options TERMINAL_KERN_ATTR=(FG_LIGHTRED|BG_BLACK) # trm: Tekram DC395U/UW/F DC315U adapters. # -# Note that the order is important in order for Buslogic ISA/EISA cards to be +# Note that the order is important in order for Buslogic ISA cards to be # probed correctly. # device bt @@ -1570,7 +1569,6 @@ device aha hint.aha.0.at="isa" device aic hint.aic.0.at="isa" -device ahb device ahc device ahd device esp @@ -1976,7 +1974,6 @@ device xmphy # XaQti XMAC II # ex: Intel EtherExpress Pro/10 and other i82595-based adapters, # Olicom Ethernet PC Card devices. # fe: Fujitsu MB86960A/MB86965A Ethernet -# fea: DEC DEFEA EISA FDDI adapter # fpa: Support for the Digital DEFPA PCI FDDI. `device fddi' is also needed. # fxp: Intel EtherExpress Pro/100B # (hint of prefer_iomap can be done to prefer I/O instead of Mem mapping) @@ -2077,7 +2074,7 @@ device xmphy # XaQti XMAC II # in Dell Latitude laptop docking stations. # Also supported: 3Com 3c980(C)-TX, 3Com 3cSOHO100-TX, 3Com 3c450-TX -# Order for ISA/EISA devices is important here +# Order for ISA devices is important here device cm hint.cm.0.at="isa" @@ -2089,7 +2086,6 @@ device ex device fe hint.fe.0.at="isa" hint.fe.0.port="0x300" -device fea device sn hint.sn.0.at="isa" hint.sn.0.port="0x300" diff --git a/sys/conf/config.mk b/sys/conf/config.mk index c519980d088e..1e315fca1347 100644 --- a/sys/conf/config.mk +++ b/sys/conf/config.mk @@ -23,10 +23,6 @@ opt_inet6.h: opt_ratelimit.h: @echo "#define RATELIMIT 1" > ${.TARGET} .endif -.if ${MK_EISA} != "no" -opt_eisa.h: - @echo "#define DEV_EISA 1" > ${.TARGET} -.endif opt_mrouting.h: echo "#define MROUTING 1" > ${.TARGET} opt_natm.h: @@ -49,9 +45,6 @@ KERN_OPTS+= INET TCP_OFFLOAD .if ${MK_INET6_SUPPORT} != "no" KERN_OPTS+= INET6 .endif -.if ${MK_EISA} != "no" -KERN_OPTS+= DEV_EISA -.endif .elif !defined(KERN_OPTS) KERN_OPTS!=cat ${KERNBUILDDIR}/opt*.h | awk '{print $$2;}' | sort -u .export KERN_OPTS diff --git a/sys/conf/files b/sys/conf/files index 79e00def63b6..a4f933c7303d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -679,7 +679,6 @@ dev/acpica/acpi_throttle.c optional acpi dev/acpica/acpi_video.c optional acpi_video acpi dev/acpica/acpi_dock.c optional acpi_dock acpi dev/adlink/adlink.c optional adlink -dev/advansys/adv_eisa.c optional adv eisa dev/advansys/adv_pci.c optional adv pci dev/advansys/advansys.c optional adv dev/advansys/advlib.c optional adv @@ -694,14 +693,11 @@ dev/agp/agp.c optional agp pci dev/agp/agp_if.m optional agp pci dev/aha/aha.c optional aha dev/aha/aha_isa.c optional aha isa -dev/aha/aha_mca.c optional aha mca -dev/ahb/ahb.c optional ahb eisa dev/ahci/ahci.c optional ahci dev/ahci/ahciem.c optional ahci dev/ahci/ahci_pci.c optional ahci pci dev/aic/aic.c optional aic dev/aic/aic_pccard.c optional aic pccard -dev/aic7xxx/ahc_eisa.c optional ahc eisa dev/aic7xxx/ahc_isa.c optional ahc isa dev/aic7xxx/ahc_pci.c optional ahc pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" @@ -1190,8 +1186,6 @@ dev/bge/if_bge.c optional bge dev/bhnd/bhnd.c optional bhnd dev/bhnd/bhnd_erom.c optional bhnd dev/bhnd/bhnd_erom_if.m optional bhnd -dev/bhnd/bhnd_nexus.c optional bhnd siba_nexus | \ - bhnd bcma_nexus dev/bhnd/bhnd_subr.c optional bhnd dev/bhnd/bhnd_bus_if.m optional bhnd dev/bhnd/bhndb/bhnd_bhndb.c optional bhndb bhnd @@ -1206,7 +1200,6 @@ dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb dev/bhnd/bcma/bcma_erom.c optional bcma bhnd -dev/bhnd/bcma/bcma_nexus.c optional bcma_nexus bcma bhnd dev/bhnd/bcma/bcma_subr.c optional bcma bhnd dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhnd dev/bhnd/cores/chipc/bhnd_sprom_chipc.c optional bhnd @@ -1252,7 +1245,6 @@ dev/bhnd/nvram/bhnd_sprom.c optional bhnd dev/bhnd/siba/siba.c optional siba bhnd dev/bhnd/siba/siba_bhndb.c optional siba bhnd bhndb dev/bhnd/siba/siba_erom.c optional siba bhnd -dev/bhnd/siba/siba_nexus.c optional siba_nexus siba bhnd dev/bhnd/siba/siba_subr.c optional siba bhnd # dev/bktr/bktr_audio.c optional bktr pci @@ -1267,9 +1259,7 @@ dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci dev/bnxt/bnxt_txrx.c optional bnxt iflib pci dev/bnxt/if_bnxt.c optional bnxt iflib pci dev/buslogic/bt.c optional bt -dev/buslogic/bt_eisa.c optional bt eisa dev/buslogic/bt_isa.c optional bt isa -dev/buslogic/bt_mca.c optional bt mca dev/buslogic/bt_pci.c optional bt pci dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi @@ -1447,7 +1437,6 @@ dev/dcons/dcons_crom.c optional dcons_crom dev/dcons/dcons_os.c optional dcons dev/de/if_de.c optional de pci dev/dme/if_dme.c optional dme -dev/dpt/dpt_eisa.c optional dpt eisa dev/dpt/dpt_pci.c optional dpt pci dev/dpt/dpt_scsi.c optional dpt dev/drm/ati_pcigart.c optional drm @@ -1565,8 +1554,6 @@ dev/ed/if_ed_rtl80x9.c optional ed dev/ed/if_ed_pccard.c optional ed pccard dev/ed/if_ed_pci.c optional ed pci dev/efidev/efidev.c optional efirt -dev/eisa/eisa_if.m standard -dev/eisa/eisaconf.c optional eisa dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/em_txrx.c optional em \ @@ -1611,9 +1598,7 @@ dev/et/if_et.c optional et dev/en/if_en_pci.c optional en pci dev/en/midway.c optional en dev/ep/if_ep.c optional ep -dev/ep/if_ep_eisa.c optional ep eisa dev/ep/if_ep_isa.c optional ep isa -dev/ep/if_ep_mca.c optional ep mca dev/ep/if_ep_pccard.c optional ep pccard dev/esp/esp_pci.c optional esp pci dev/esp/ncr53c9x.c optional esp @@ -1736,7 +1721,6 @@ dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida -dev/ida/ida_eisa.c optional ida eisa dev/ida/ida_pci.c optional ida pci dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ds1307.c optional ds1307 @@ -2180,7 +2164,6 @@ dev/malo/if_malo.c optional malo dev/malo/if_malohal.c optional malo dev/malo/if_malo_pci.c optional malo pci dev/mc146818/mc146818.c optional mc146818 -dev/mca/mca_bus.c optional mca dev/md/md.c optional md dev/mdio/mdio_if.m optional miiproxy | mdio dev/mdio/mdio.c optional miiproxy | mdio @@ -2404,7 +2387,6 @@ dev/pccbb/pccbb.c optional cbb dev/pccbb/pccbb_isa.c optional cbb isa dev/pccbb/pccbb_pci.c optional cbb pci dev/pcf/pcf.c optional pcf -dev/pci/eisa_pci.c optional pci eisa dev/pci/fixup_pci.c optional pci dev/pci/hostb_pci.c optional pci dev/pci/ignore_pci.c optional pci @@ -2421,10 +2403,9 @@ dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci dev/pcn/if_pcn.c optional pcn pci -dev/pdq/if_fea.c optional fea eisa dev/pdq/if_fpa.c optional fpa pci -dev/pdq/pdq.c optional nowerror fea eisa | fpa pci -dev/pdq/pdq_ifsubr.c optional nowerror fea eisa | fpa pci +dev/pdq/pdq.c optional nowerror fpa pci +dev/pdq/pdq_ifsubr.c optional nowerror fpa pci dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ @@ -3252,7 +3233,6 @@ dev/vt/vt_font.c optional vt dev/vt/vt_sysmouse.c optional vt dev/vte/if_vte.c optional vte pci dev/vx/if_vx.c optional vx -dev/vx/if_vx_eisa.c optional vx eisa dev/vx/if_vx_pci.c optional vx pci dev/vxge/vxge.c optional vxge dev/vxge/vxgehal/vxgehal-ifmsg.c optional vxge diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 94bc6e390ae5..cb2b84ca522e 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -146,6 +146,11 @@ crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb dev/acpica/acpi_if.m optional acpi dev/ahci/ahci_generic.c optional ahci +dev/axgbe/if_axgbe.c optional axgbe +dev/axgbe/xgbe-desc.c optional axgbe +dev/axgbe/xgbe-dev.c optional axgbe +dev/axgbe/xgbe-drv.c optional axgbe +dev/axgbe/xgbe-mdio.c optional axgbe dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index daebc227f427..177b3ae0c266 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -474,7 +474,6 @@ acpi_wakedata.h optional acpi \ clean "acpi_wakedata.h" # i386/bios/apm.c optional apm -i386/bios/mca_machdep.c optional mca i386/bios/smapi.c optional smapi i386/bios/smapi_bios.S optional smapi i386/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index c2b3ad727d79..094163157e07 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -45,7 +45,6 @@ __DEFAULT_YES_OPTIONS = \ ZFS __DEFAULT_NO_OPTIONS = \ - EISA \ EXTRA_TCP_STACKS \ NAND \ OFED \ @@ -77,10 +76,6 @@ BROKEN_OPTIONS+= ZFS # Things that don't work because the kernel doesn't have the support # for them. -.if ${MACHINE} != "i386" -BROKEN_OPTIONS+= EISA -.endif - .if ${MACHINE} != "i386" && ${MACHINE} != "amd64" BROKEN_OPTIONS+= OFED .endif diff --git a/sys/conf/options b/sys/conf/options index a857d9a216c8..ab9073e76972 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -723,7 +723,6 @@ ISAPNP opt_isa.h # various 'device presence' options. DEV_BPF opt_bpf.h DEV_CARP opt_carp.h -DEV_MCA opt_mca.h DEV_NETMAP opt_global.h DEV_PCI opt_pci.h DEV_PF opt_pf.h @@ -733,10 +732,6 @@ DEV_RANDOM opt_global.h DEV_SPLASH opt_splash.h DEV_VLAN opt_vlan.h -# EISA support -DEV_EISA opt_eisa.h -EISA_SLOTS opt_eisa.h - # ed driver ED_HPP opt_ed.h ED_3C503 opt_ed.h diff --git a/sys/dev/acpica/acpi_package.c b/sys/dev/acpica/acpi_package.c index 448d35ba733b..c7e79ab29e40 100644 --- a/sys/dev/acpica/acpi_package.c +++ b/sys/dev/acpica/acpi_package.c @@ -50,7 +50,7 @@ acpi_PkgInt(ACPI_OBJECT *res, int idx, UINT64 *dst) ACPI_OBJECT *obj; obj = &res->Package.Elements[idx]; - if (obj == NULL || obj->Type != ACPI_TYPE_INTEGER) + if (obj->Type != ACPI_TYPE_INTEGER) return (EINVAL); *dst = obj->Integer.Value; diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c index 190674a74623..9a66336e7c62 100644 --- a/sys/dev/acpica/acpi_pcib_acpi.c +++ b/sys/dev/acpica/acpi_pcib_acpi.c @@ -309,15 +309,19 @@ acpi_pcib_osc(struct acpi_hpcib_softc *sc) 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66 }; + /* Status Field */ + cap_set[PCI_OSC_STATUS] = 0; + /* Support Field: Extended PCI Config Space, MSI */ - cap_set[1] = 0x11; + cap_set[PCI_OSC_SUPPORT] = PCIM_OSC_SUPPORT_EXT_PCI_CONF | + PCIM_OSC_SUPPORT_MSI; /* Control Field */ - cap_set[2] = 0; + cap_set[PCI_OSC_CTL] = 0; #ifdef PCI_HP /* Control Field: PCI Express Native Hot Plug */ - cap_set[2] |= 0x1; + cap_set[PCI_OSC_CTL] |= PCIM_OSC_CTL_PCIE_HP; #endif status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1, @@ -330,10 +334,16 @@ acpi_pcib_osc(struct acpi_hpcib_softc *sc) return; } - if (cap_set[0] != 0) { + if (cap_set[PCI_OSC_STATUS] != 0) { device_printf(sc->ap_dev, "_OSC returned error %#x\n", cap_set[0]); } + +#ifdef PCI_HP + if ((cap_set[PCI_OSC_CTL] & PCIM_OSC_CTL_PCIE_HP) == 0 && bootverbose) { + device_printf(sc->ap_dev, "_OSC didn't allow HP control\n"); + } +#endif } static int diff --git a/sys/dev/advansys/adv_eisa.c b/sys/dev/advansys/adv_eisa.c deleted file mode 100644 index 7adb75fec902..000000000000 --- a/sys/dev/advansys/adv_eisa.c +++ /dev/null @@ -1,377 +0,0 @@ -/*- - * Device probe and attach routines for the following - * Advanced Systems Inc. SCSI controllers: - * - * Single Channel Products: - * ABP742 - Bus-Master EISA (240 CDB) - * - * Dual Channel Products: - * ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) - * - * Copyright (c) 1997 Justin Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/advansys/advansys.h> - -#define EISA_DEVICE_ID_ADVANSYS_740 0x04507400 -#define EISA_DEVICE_ID_ADVANSYS_750 0x04507500 - -#define ADV_EISA_SLOT_OFFSET 0xc00 -#define ADV_EISA_OFFSET_CHAN1 0x30 -#define ADV_EISA_OFFSET_CHAN2 0x50 -#define ADV_EISA_IOSIZE 0x100 - -#define ADV_EISA_ROM_BIOS_ADDR_REG 0x86 -#define ADV_EISA_IRQ_BURST_LEN_REG 0x87 -#define ADV_EISA_IRQ_MASK 0x07 -#define ADV_EISA_IRQ_10 0x00 -#define ADV_EISA_IRQ_11 0x01 -#define ADV_EISA_IRQ_12 0x02 -#define ADV_EISA_IRQ_14 0x04 -#define ADV_EISA_IRQ_15 0x05 - -#define ADV_EISA_MAX_DMA_ADDR (0x07FFFFFFL) -#define ADV_EISA_MAX_DMA_COUNT (0x07FFFFFFL) - -/* - * The overrun buffer shared amongst all EISA adapters. - */ -static void* overrun_buf; -static bus_dma_tag_t overrun_dmat; -static bus_dmamap_t overrun_dmamap; -static bus_addr_t overrun_physbase; - -static const char* -adv_eisa_match(eisa_id_t type) -{ - switch (type & ~0xF) { - case EISA_DEVICE_ID_ADVANSYS_740: - return ("AdvanSys ABP-740/742 SCSI adapter"); - break; - case EISA_DEVICE_ID_ADVANSYS_750: - return ("AdvanSys ABP-750/752 SCSI adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -adv_eisa_probe(device_t dev) -{ - const char *desc; - u_int32_t iobase; - u_int8_t irq; - - desc = adv_eisa_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + ADV_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, ADV_EISA_IOSIZE, RESVADDR_NONE); - irq = inb(iobase + ADV_EISA_IRQ_BURST_LEN_REG); - irq &= ADV_EISA_IRQ_MASK; - switch (irq) { - case 0: - case 1: - case 2: - case 4: - case 5: - break; - default: - printf("adv at slot %d: illegal " - "irq setting %d\n", eisa_get_slot(dev), - irq); - return ENXIO; - } - eisa_add_intr(dev, irq + 10, EISA_TRIGGER_LEVEL); - - return 0; -} - -/* - * The adv_b stuff to handle twin-channel cards will not work in its current - * incarnation. It tries to reuse the same softc since adv_alloc() doesn't - * actually allocate a softc. It also tries to reuse the same unit number - * for both sims. This can be re-enabled if someone fixes it properly. - */ -static int -adv_eisa_attach(device_t dev) -{ - struct adv_softc *adv; -#if 0 - struct adv_softc *adv_b; -#endif - struct resource *io; - struct resource *irq; - int rid, error; - void *ih; - -#if 0 - adv_b = NULL; -#endif - - rid = 0; - io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - return ENOMEM; - } - - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_SHAREABLE | RF_ACTIVE); - if (!irq) { - device_printf(dev, "No irq?!\n"); - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - return ENOMEM; - - } - - switch (eisa_get_id(dev) & ~0xF) { - case EISA_DEVICE_ID_ADVANSYS_750: -#if 0 - adv_b = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN2); - if (adv_b == NULL) - goto bad; - - /* - * Allocate a parent dmatag for all tags created - * by the MI portions of the advansys driver - */ - error = bus_dma_tag_create( - /* parent */ bus_get_dma_tag(dev), - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ ADV_EISA_MAX_DMA_ADDR, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ ADV_EISA_MAX_DMA_COUNT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &adv_b->parent_dmat); - - if (error != 0) { - device_printf(dev, "Could not allocate DMA tag - error %d\n", - error); - adv_free(adv_b); - goto bad; - } - - adv_b->init_level++; -#endif - - /* FALLTHROUGH */ - case EISA_DEVICE_ID_ADVANSYS_740: - adv = adv_alloc(dev, io, ADV_EISA_OFFSET_CHAN1); - if (adv == NULL) { -#if 0 - if (adv_b != NULL) - adv_free(adv_b); -#endif - goto bad; - } - - /* - * Allocate a parent dmatag for all tags created - * by the MI portions of the advansys driver - */ - error = bus_dma_tag_create( - /* parent */ bus_get_dma_tag(dev), - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ ADV_EISA_MAX_DMA_ADDR, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ ADV_EISA_MAX_DMA_COUNT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &adv->parent_dmat); - - if (error != 0) { - device_printf(dev, "Could not allocate DMA tag - error %d\n", - error); - adv_free(adv); - goto bad; - } - - adv->init_level++; - break; - default: - printf("adveisaattach: Unknown device type!\n"); - goto bad; - break; - } - - if (overrun_buf == NULL) { - /* Need to allocate our overrun buffer */ - if (bus_dma_tag_create( - /* parent */ bus_get_dma_tag(dev), - /* alignment */ 8, - /* boundary */ 0, - /* lowaddr */ ADV_EISA_MAX_DMA_ADDR, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ ADV_OVERRUN_BSIZE, - /* nsegments */ 1, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &overrun_dmat) != 0) { - adv_free(adv); - goto bad; - } - if (bus_dmamem_alloc(overrun_dmat, - &overrun_buf, - BUS_DMA_NOWAIT, - &overrun_dmamap) != 0) { - bus_dma_tag_destroy(overrun_dmat); - adv_free(adv); - goto bad; - } - /* And permanently map it in */ - bus_dmamap_load(overrun_dmat, overrun_dmamap, - overrun_buf, ADV_OVERRUN_BSIZE, - adv_map, &overrun_physbase, - /*flags*/0); - } - - /* - * Now that we know we own the resources we need, do the - * card initialization. - */ - - /* - * Stop the chip. - */ - ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); - ADV_OUTW(adv, ADV_CHIP_STATUS, 0); - - adv->chip_version = EISA_REVISION_ID(eisa_get_id(dev)) - + ADV_CHIP_MIN_VER_EISA - 1; - - if (adv_init(adv) != 0) { - adv_free(adv); -#if 0 - if (adv_b != NULL) - adv_free(adv_b); -#endif - goto bad; - } - - adv->max_dma_count = ADV_EISA_MAX_DMA_COUNT; - adv->max_dma_addr = ADV_EISA_MAX_DMA_ADDR; - -#if 0 - if (adv_b != NULL) { - /* - * Stop the chip. - */ - ADV_OUTB(adv_b, ADV_CHIP_CTRL, ADV_CC_HALT); - ADV_OUTW(adv_b, ADV_CHIP_STATUS, 0); - - adv_b->chip_version = EISA_REVISION_ID(eisa_get_id(dev)) - + ADV_CHIP_MIN_VER_EISA - 1; - - if (adv_init(adv_b) != 0) { - adv_free(adv_b); - } else { - adv_b->max_dma_count = ADV_EISA_MAX_DMA_COUNT; - adv_b->max_dma_addr = ADV_EISA_MAX_DMA_ADDR; - } - } -#endif - - /* - * Enable our interrupt handler. - */ - if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL, - adv_intr, adv, &ih) != 0) { - adv_free(adv); - goto bad; - } - - /* Attach sub-devices */ - if (adv_attach(adv) != 0) { - adv_free(adv); - goto bad; - } -#if 0 - if (adv_b != NULL) - adv_attach(adv_b); -#endif - - return 0; - - bad: - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - return ENXIO; -} - -static device_method_t adv_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, adv_eisa_probe), - DEVMETHOD(device_attach, adv_eisa_attach), - { 0, 0 } -}; - -static driver_t adv_eisa_driver = { - "adv", adv_eisa_methods, sizeof(struct adv_softc) -}; - -static devclass_t adv_eisa_devclass; -DRIVER_MODULE(adv, eisa, adv_eisa_driver, adv_eisa_devclass, 0, 0); -MODULE_DEPEND(adv, eisa, 1, 1, 1); diff --git a/sys/dev/advansys/advansys.c b/sys/dev/advansys/advansys.c index cb108f4804ae..8ca81ae55459 100644 --- a/sys/dev/advansys/advansys.c +++ b/sys/dev/advansys/advansys.c @@ -3,7 +3,6 @@ * Product specific probe and attach routines can be found in: * * i386/isa/adv_isa.c ABP5140, ABP542, ABP5150, ABP842, ABP852 - * i386/eisa/adv_eisa.c ABP742, ABP752 * pci/adv_pci.c ABP920, ABP930, ABP930U, ABP930UA, ABP940, ABP940U, * ABP940UA, ABP950, ABP960, ABP960U, ABP960UA, * ABP970, ABP970U @@ -1378,8 +1377,6 @@ adv_attach(adv) /* * Register the bus. - * - * XXX Twin Channel EISA Cards??? */ mtx_lock(&adv->lock); if (xpt_bus_register(adv->sim, adv->dev, 0) != CAM_SUCCESS) { diff --git a/sys/dev/advansys/advlib.c b/sys/dev/advansys/advlib.c index 75d6884b9131..5a448e4bf9f9 100644 --- a/sys/dev/advansys/advlib.c +++ b/sys/dev/advansys/advlib.c @@ -729,7 +729,7 @@ adv_execute_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq, panic("adv_execute_scsi_queue: " "Queue with too many segs."); - if ((adv->type & (ADV_ISA | ADV_VL | ADV_EISA)) != 0) { + if ((adv->type & (ADV_ISA | ADV_VL)) != 0) { int i; for (i = 0; i < sg_entry_cnt_minus_one; i++) { diff --git a/sys/dev/advansys/advlib.h b/sys/dev/advansys/advlib.h index 6952ca960c92..9fd6d1b2665f 100644 --- a/sys/dev/advansys/advlib.h +++ b/sys/dev/advansys/advlib.h @@ -66,9 +66,7 @@ typedef enum { ADV_ISA = 0x001, ADV_ISAPNP = 0x003, ADV_VL = 0x004, - ADV_EISA = 0x008, ADV_PCI = 0x010, - ADV_MCA = 0x020, ADV_PCMCIA = 0x040, ADV_ULTRA = 0x100, ADV_WIDE = 0x200, @@ -170,9 +168,6 @@ struct adv_ccb_info { #define ADV_CHIP_VER_ISA_BIT 0x30 #define ADV_CHIP_VER_ISAPNP_BIT 0x20 #define ADV_CHIP_VER_ASYN_BUG 0x21 -#define ADV_CHIP_MIN_VER_EISA 0x41 -#define ADV_CHIP_MAX_VER_EISA 0x47 -#define ADV_CHIP_VER_EISA_BIT 0x40 #define ADV_CONFIG_MSW 0x0004 #define ADV_CFG_MSW_SCSI_TARGET_ON 0x0080 diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c index 1fed39fb36d3..233339f8c434 100644 --- a/sys/dev/aha/aha.c +++ b/sys/dev/aha/aha.c @@ -1,9 +1,8 @@ /* - * Generic register and struct definitions for the Adaptech 154x/164x + * Generic register and struct definitions for the Adaptech 154x * SCSI host adapters. Product specific probe and attach routines can * be found in: * aha 1542A/1542B/1542C/1542CF/1542CP aha_isa.c - * aha 1640 aha_mca.c */ /*- * Copyright (c) 1998 M. Warner Losh. @@ -339,12 +338,6 @@ aha_fetch_adapter_info(struct aha_softc *aha) case BOARD_1542: snprintf(aha->model, sizeof(aha->model), "1540/1542 64 head BIOS"); break; - case BOARD_1640: - snprintf(aha->model, sizeof(aha->model), "1640"); - break; - case BOARD_1740: - snprintf(aha->model, sizeof(aha->model), "1740A/1742A/1744"); - break; case BOARD_1542C: snprintf(aha->model, sizeof(aha->model), "1542C"); break; diff --git a/sys/dev/aha/aha_mca.c b/sys/dev/aha/aha_mca.c deleted file mode 100644 index b954e07774ad..000000000000 --- a/sys/dev/aha/aha_mca.c +++ /dev/null @@ -1,231 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * 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. - * - * Based on aha_isa.c - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mutex.h> - -#include <sys/module.h> -#include <sys/bus.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <isa/isavar.h> - -#include <dev/mca/mca_busreg.h> -#include <dev/mca/mca_busvar.h> - -#include <dev/aha/ahareg.h> - -static struct mca_ident aha_mca_devs[] = { - { 0x0f1f, "Adaptec AHA-1640 SCSI Adapter" }, - { 0, NULL }, -}; - -#define AHA_MCA_IOPORT_POS MCA_ADP_POS(MCA_POS1) -# define AHA_MCA_IOPORT_MASK1 0x07 -# define AHA_MCA_IOPORT_MASK2 0xc0 -# define AHA_MCA_IOPORT_SIZE 0x03 -# define AHA_MCA_IOPORT(pos) (0x30 + \ - (((uint32_t)pos & \ - AHA_MCA_IOPORT_MASK1) << 8) + \ - (((uint32_t)pos & \ - AHA_MCA_IOPORT_MASK2) >> 4)) - -#define AHA_MCA_DRQ_POS MCA_ADP_POS(MCA_POS3) -# define AHA_MCA_DRQ_MASK 0x0f -# define AHA_MCA_DRQ(pos) (pos & AHA_MCA_DRQ_MASK) - -#define AHA_MCA_IRQ_POS MCA_ADP_POS(MCA_POS2) -# define AHA_MCA_IRQ_MASK 0x07 -# define AHA_MCA_IRQ(pos) ((pos & AHA_MCA_IRQ_MASK) + 8) - -/* - * Not needed as the board knows its config - * internally and the ID will be fetched - * via AOP_INQUIRE_SETUP_INFO command. - */ -#define AHA_MCA_SCSIID_POS MCA_ADP_POS(MCA_POS2) -#define AHA_MCA_SCSIID_MASK 0xe0 -#define AHA_MCA_SCSIID(pos) ((pos & AHA_MCA_SCSIID_MASK) >> 5) - -static int -aha_mca_probe (device_t dev) -{ - const char * desc; - mca_id_t id = mca_get_id(dev); - uint32_t iobase = 0; - uint32_t iosize = 0; - uint8_t drq = 0; - uint8_t irq = 0; - uint8_t pos; - - desc = mca_match_id(id, aha_mca_devs); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - pos = mca_pos_read(dev, AHA_MCA_IOPORT_POS); - iobase = AHA_MCA_IOPORT(pos); - iosize = AHA_MCA_IOPORT_SIZE; - - pos = mca_pos_read(dev, AHA_MCA_DRQ_POS); - drq = AHA_MCA_DRQ(pos); - - pos = mca_pos_read(dev, AHA_MCA_IRQ_POS); - irq = AHA_MCA_IRQ(pos); - - mca_add_iospace(dev, iobase, iosize); - mca_add_drq(dev, drq); - mca_add_irq(dev, irq); - - return (0); -} - -static int -aha_mca_attach (device_t dev) -{ - struct aha_softc * sc = device_get_softc(dev); - int error = ENOMEM; - - sc->portrid = 0; - sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid, - RF_ACTIVE); - if (sc->port == NULL) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - - sc->irqrid = 0; - sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqrid, - RF_ACTIVE); - if (sc->irq == NULL) { - device_printf(dev, "No IRQ?!\n"); - goto bad; - } - - sc->drqrid = 0; - sc->drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &sc->drqrid, - RF_ACTIVE); - if (sc->drq == NULL) { - device_printf(dev, "No DRQ?!\n"); - goto bad; - } - - aha_alloc(sc); - error = aha_probe(sc); - if (error) { - device_printf(dev, "aha_probe() failed!\n"); - goto bad; - } - - error = aha_fetch_adapter_info(sc); - if (error) { - device_printf(dev, "aha_fetch_adapter_info() failed!\n"); - goto bad; - } - - isa_dmacascade(rman_get_start(sc->drq)); - - error = bus_dma_tag_create( - /* parent */ bus_get_dma_tag(dev), - /* alignemnt */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_24BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_24BIT, - /* nsegments */ ~0, - /* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &sc->parent_dmat); - if (error) { - device_printf(dev, "bus_dma_tag_create() failed!\n"); - goto bad; - } - - error = aha_init(sc); - if (error) { - device_printf(dev, "aha_init() failed\n"); - goto bad; - } - - error = aha_attach(sc); - if (error) { - device_printf(dev, "aha_attach() failed\n"); - goto bad; - } - - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY | - INTR_MPSAFE, NULL, aha_intr, sc, &sc->ih); - if (error) { - device_printf(dev, "Unable to register interrupt handler\n"); - aha_detach(sc); - goto bad; - } - - return (0); - -bad: - aha_free(sc); - bus_free_resource(dev, SYS_RES_IOPORT, sc->port); - bus_free_resource(dev, SYS_RES_IRQ, sc->irq); - bus_free_resource(dev, SYS_RES_DRQ, sc->drq); - return (error); -} - -static device_method_t aha_mca_methods[] = { - DEVMETHOD(device_probe, aha_mca_probe), - DEVMETHOD(device_attach, aha_mca_attach), - - { 0, 0 } -}; - -static driver_t aha_mca_driver = { - "aha", - aha_mca_methods, - 1, -/* - sizeof(struct aha_softc *), - */ -}; - -static devclass_t aha_devclass; - -DRIVER_MODULE(aha, mca, aha_mca_driver, aha_devclass, 0, 0); -MODULE_DEPEND(aha, mca, 1, 1, 1); diff --git a/sys/dev/aha/ahareg.h b/sys/dev/aha/ahareg.h index 5c0f4cae9988..d85055a35610 100644 --- a/sys/dev/aha/ahareg.h +++ b/sys/dev/aha/ahareg.h @@ -1,8 +1,8 @@ /*- * Generic register and struct definitions for the Adaptech 1540, 1542, - * 1640, 1642 SCSI host adapters. Product specific probe and attach + * SCSI host adapters. Product specific probe and attach * routines can be found in: - * aha_isa.c, aha_mca.c + * aha_isa.c * * Derived from bt.c written by: * @@ -157,8 +157,6 @@ typedef struct { #define BOARD_1540_16HEAD_BIOS 0x00 #define BOARD_1540_64HEAD_BIOS 0x30 #define BOARD_1542 0x41 /* aha-1540/1542 w/64-h bios */ -#define BOARD_1640 0x42 /* aha-1640 */ -#define BOARD_1740 0x43 /* aha-1740A/1742A/1744 */ #define BOARD_1542C 0x44 /* aha-1542C */ #define BOARD_1542CF 0x45 /* aha-1542CF */ #define BOARD_1542CP 0x46 /* aha-1542CP, plug and play */ diff --git a/sys/dev/ahb/ahb.c b/sys/dev/ahb/ahb.c deleted file mode 100644 index b6665009d9af..000000000000 --- a/sys/dev/ahb/ahb.c +++ /dev/null @@ -1,1315 +0,0 @@ -/*- - * CAM SCSI device driver for the Adaptec 174X SCSI Host adapter - * - * Copyright (c) 1998 Justin T. Gibbs - * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <cam/cam.h> -#include <cam/cam_ccb.h> -#include <cam/cam_sim.h> -#include <cam/cam_xpt_sim.h> -#include <cam/cam_debug.h> - -#include <cam/scsi/scsi_message.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/ahb/ahbreg.h> - -#define ccb_ecb_ptr spriv_ptr0 -#define ccb_ahb_ptr spriv_ptr1 - -#define ahb_inb(ahb, port) \ - bus_read_1((ahb)->res, port) - -#define ahb_inl(ahb, port) \ - bus_read_4((ahb)->res, port) - -#define ahb_outb(ahb, port, value) \ - bus_write_1((ahb)->res, port, value) - -#define ahb_outl(ahb, port, value) \ - bus_write_4((ahb)->res, port, value) - -static const char *ahbmatch(eisa_id_t type); -static struct ahb_softc *ahballoc(device_t dev, struct resource *res); -static void ahbfree(struct ahb_softc *ahb); -static int ahbreset(struct ahb_softc *ahb); -static void ahbmapecbs(void *arg, bus_dma_segment_t *segs, - int nseg, int error); -static int ahbxptattach(struct ahb_softc *ahb); -static void ahbhandleimmed(struct ahb_softc *ahb, - u_int32_t mbox, u_int intstat); -static void ahbcalcresid(struct ahb_softc *ahb, - struct ecb *ecb, union ccb *ccb); -static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox, - u_int intstat); -static void ahbintr(void *arg); -static void ahbintr_locked(struct ahb_softc *ahb); -static bus_dmamap_callback_t ahbexecuteecb; -static void ahbaction(struct cam_sim *sim, union ccb *ccb); -static void ahbpoll(struct cam_sim *sim); - -/* Our timeout handler */ -static void ahbtimeout(void *arg); - -static __inline struct ecb* ahbecbget(struct ahb_softc *ahb); -static __inline void ahbecbfree(struct ahb_softc* ahb, - struct ecb* ecb); -static __inline u_int32_t ahbecbvtop(struct ahb_softc *ahb, - struct ecb *ecb); -static __inline struct ecb* ahbecbptov(struct ahb_softc *ahb, - u_int32_t ecb_addr); -static __inline u_int32_t ahbstatuspaddr(u_int32_t ecb_paddr); -static __inline u_int32_t ahbsensepaddr(u_int32_t ecb_paddr); -static __inline u_int32_t ahbsgpaddr(u_int32_t ecb_paddr); -static __inline void ahbqueuembox(struct ahb_softc *ahb, - u_int32_t mboxval, - u_int attn_code); - -static __inline struct ecb* -ahbecbget(struct ahb_softc *ahb) -{ - struct ecb* ecb; - - if (!dumping) - mtx_assert(&ahb->lock, MA_OWNED); - if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL) - SLIST_REMOVE_HEAD(&ahb->free_ecbs, links); - - return (ecb); -} - -static __inline void -ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb) -{ - - if (!dumping) - mtx_assert(&ahb->lock, MA_OWNED); - ecb->state = ECB_FREE; - SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links); -} - -static __inline u_int32_t -ahbecbvtop(struct ahb_softc *ahb, struct ecb *ecb) -{ - return (ahb->ecb_physbase - + (u_int32_t)((caddr_t)ecb - (caddr_t)ahb->ecb_array)); -} - -static __inline struct ecb* -ahbecbptov(struct ahb_softc *ahb, u_int32_t ecb_addr) -{ - return (ahb->ecb_array - + ((struct ecb*)(uintptr_t)ecb_addr - - (struct ecb*)(uintptr_t)ahb->ecb_physbase)); -} - -static __inline u_int32_t -ahbstatuspaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, status)); -} - -static __inline u_int32_t -ahbsensepaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, sense)); -} - -static __inline u_int32_t -ahbsgpaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, sg_list)); -} - -static __inline void -ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code) -{ - u_int loopmax = 300; - while (--loopmax) { - u_int status; - - status = ahb_inb(ahb, HOSTSTAT); - if ((status & (HOSTSTAT_MBOX_EMPTY|HOSTSTAT_BUSY)) - == HOSTSTAT_MBOX_EMPTY) - break; - DELAY(20); - } - if (loopmax == 0) - panic("%s: adapter not taking commands\n", - device_get_nameunit(ahb->dev)); - - ahb_outl(ahb, MBOXOUT0, mboxval); - ahb_outb(ahb, ATTN, attn_code); -} - -static const char * -ahbmatch(eisa_id_t type) -{ - switch(type & 0xfffffe00) { - case EISA_DEVICE_ID_ADAPTEC_1740: - return ("Adaptec 174x SCSI host adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -ahbprobe(device_t dev) -{ - const char *desc; - u_int32_t iobase; - u_int32_t irq; - u_int8_t intdef; - int shared; - - desc = ahbmatch(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + - AHB_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE); - - intdef = inb(INTDEF + iobase); - switch (intdef & 0x7) { - case INT9: - irq = 9; - break; - case INT10: - irq = 10; - break; - case INT11: - irq = 11; - break; - case INT12: - irq = 12; - break; - case INT14: - irq = 14; - break; - case INT15: - irq = 15; - break; - default: - printf("Adaptec 174X at slot %d: illegal " - "irq setting %d\n", eisa_get_slot(dev), - (intdef & 0x7)); - irq = 0; - break; - } - if (irq == 0) - return ENXIO; - - shared = (inb(INTDEF + iobase) & INTLEVEL) ? - EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; - - eisa_add_intr(dev, irq, shared); - - return 0; -} - -static int -ahbattach(device_t dev) -{ - /* - * find unit and check we have that many defined - */ - struct ahb_softc *ahb; - struct ecb* next_ecb; - struct resource *io; - struct resource *irq; - int rid; - void *ih; - - irq = NULL; - rid = 0; - io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (io == NULL) { - device_printf(dev, "No I/O space?!\n"); - return ENOMEM; - } - - ahb = ahballoc(dev, io); - - if (ahbreset(ahb) != 0) - goto error_exit; - - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (irq == NULL) { - device_printf(dev, "Can't allocate interrupt\n"); - goto error_exit; - } - - /* - * Create our DMA tags. These tags define the kinds of device - * accessible memory allocations and memory mappings we will - * need to perform during normal operation. - */ - /* DMA tag for mapping buffers into device visible space. */ - if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ DFLTPHYS, - /* nsegments */ AHB_NSEG, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ BUS_DMA_ALLOCNOW, - /* lockfunc */ busdma_lock_mutex, - /* lockarg */ &ahb->lock, - &ahb->buffer_dmat) != 0) - goto error_exit; - - ahb->init_level++; - - /* DMA tag for our ccb structures and ha inquiry data */ - if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ (AHB_NECB * - sizeof(struct ecb)) - + sizeof(*ahb->ha_inq_data), - /* nsegments */ 1, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &ahb->ecb_dmat) != 0) - goto error_exit; - - ahb->init_level++; - - /* Allocation for our ccbs */ - if (bus_dmamem_alloc(ahb->ecb_dmat, (void **)&ahb->ecb_array, - BUS_DMA_NOWAIT, &ahb->ecb_dmamap) != 0) - goto error_exit; - - ahb->ha_inq_data = (struct ha_inquiry_data *)&ahb->ecb_array[AHB_NECB]; - - ahb->init_level++; - - /* And permanently map them */ - bus_dmamap_load(ahb->ecb_dmat, ahb->ecb_dmamap, - ahb->ecb_array, AHB_NSEG * sizeof(struct ecb), - ahbmapecbs, ahb, /*flags*/0); - - ahb->init_level++; - - /* Allocate the buffer dmamaps for each of our ECBs */ - bzero(ahb->ecb_array, (AHB_NECB * sizeof(struct ecb)) - + sizeof(*ahb->ha_inq_data)); - next_ecb = ahb->ecb_array; - while (ahb->num_ecbs < AHB_NECB) { - u_int32_t ecb_paddr; - - if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0, - &next_ecb->dmamap)) - break; - callout_init_mtx(&next_ecb->timer, &ahb->lock, 0); - ecb_paddr = ahbecbvtop(ahb, next_ecb); - next_ecb->hecb.status_ptr = ahbstatuspaddr(ecb_paddr); - next_ecb->hecb.sense_ptr = ahbsensepaddr(ecb_paddr); - ahb->num_ecbs++; - ahbecbfree(ahb, next_ecb); - next_ecb++; - } - - ahb->init_level++; - - /* - * Now that we know we own the resources we need, register - * our bus with the XPT. - */ - if (ahbxptattach(ahb)) - goto error_exit; - - /* Enable our interrupt */ - if (bus_setup_intr(dev, irq, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, - NULL, ahbintr, ahb, &ih) != 0) - goto error_exit; - - return (0); - -error_exit: - /* - * The board's IRQ line will not be left enabled - * if we can't initialize correctly, so its safe - * to release the irq. - */ - ahbfree(ahb); - if (irq != NULL) - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - return (-1); -} - -static struct ahb_softc * -ahballoc(device_t dev, struct resource *res) -{ - struct ahb_softc *ahb; - - ahb = device_get_softc(dev); - SLIST_INIT(&ahb->free_ecbs); - LIST_INIT(&ahb->pending_ccbs); - ahb->res = res; - ahb->disc_permitted = ~0; - ahb->tags_permitted = ~0; - ahb->dev = dev; - mtx_init(&ahb->lock, "ahb", NULL, MTX_DEF); - - return (ahb); -} - -static void -ahbfree(struct ahb_softc *ahb) -{ - switch (ahb->init_level) { - default: - case 4: - bus_dmamap_unload(ahb->ecb_dmat, ahb->ecb_dmamap); - case 3: - bus_dmamem_free(ahb->ecb_dmat, ahb->ecb_array, - ahb->ecb_dmamap); - case 2: - bus_dma_tag_destroy(ahb->ecb_dmat); - case 1: - bus_dma_tag_destroy(ahb->buffer_dmat); - case 0: - break; - } - mtx_destroy(&ahb->lock); -} - -/* - * reset board, If it doesn't respond, return failure - */ -static int -ahbreset(struct ahb_softc *ahb) -{ - int wait = 1000; /* 1 sec enough? */ - int test; - - if ((ahb_inb(ahb, PORTADDR) & PORTADDR_ENHANCED) == 0) { - printf("ahb_reset: Controller not in enhanced mode\n"); - return (-1); - } - - ahb_outb(ahb, CONTROL, CNTRL_HARD_RST); - DELAY(1000); - ahb_outb(ahb, CONTROL, 0); - while (--wait) { - DELAY(1000); - if ((ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_BUSY) == 0) - break; - } - - if (wait == 0) { - printf("ahbreset: No answer from aha1742 board\n"); - return (-1); - } - if ((test = ahb_inb(ahb, MBOXIN0)) != 0) { - printf("ahb_reset: self test failed, val = 0x%x\n", test); - return (-1); - } - while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { - ahb_outb(ahb, CONTROL, CNTRL_CLRINT); - DELAY(10000); - } - return (0); -} - -static void -ahbmapecbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct ahb_softc* ahb; - - ahb = (struct ahb_softc*)arg; - ahb->ecb_physbase = segs->ds_addr; - /* - * Space for adapter inquiry information is on the - * tail of the ecb array. - */ - ahb->ha_inq_physbase = ahbecbvtop(ahb, &ahb->ecb_array[AHB_NECB]); -} - -static int -ahbxptattach(struct ahb_softc *ahb) -{ - struct cam_devq *devq; - struct ecb *ecb; - u_int i; - - mtx_lock(&ahb->lock); - - /* Remember who are we on the scsi bus */ - ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID; - - /* Use extended translation?? */ - ahb->extended_trans = ahb_inb(ahb, RESV1) & EXTENDED_TRANS; - - /* Fetch adapter inquiry data */ - ecb = ahbecbget(ahb); /* Always succeeds - no outstanding commands */ - ecb->hecb.opcode = ECBOP_READ_HA_INQDATA; - ecb->hecb.flag_word1 = FW1_SUPPRESS_URUN_ERR|FW1_ERR_STATUS_BLK_ONLY; - ecb->hecb.data_ptr = ahb->ha_inq_physbase; - ecb->hecb.data_len = sizeof(struct ha_inquiry_data); - ecb->hecb.sense_ptr = 0; - ecb->state = ECB_ACTIVE; - - /* Tell the adapter about this command */ - ahbqueuembox(ahb, ahbecbvtop(ahb, ecb), - ATTN_STARTECB|ahb->scsi_id); - - /* Poll for interrupt completion */ - for (i = 1000; ecb->state != ECB_FREE && i != 0; i--) { - ahbintr_locked(ahb); - DELAY(1000); - } - - ahb->num_ecbs = MIN(ahb->num_ecbs, - ahb->ha_inq_data->scsi_data.spc2_flags); - device_printf(ahb->dev, - "%.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n", - ahb->ha_inq_data->scsi_data.product, - (ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential" - : "Single Ended", - ahb->ha_inq_data->scsi_data.revision, - ahb->scsi_id, ahb->num_ecbs); - - /* Restore sense paddr for future CCB clients */ - ecb->hecb.sense_ptr = ahbsensepaddr(ahbecbvtop(ahb, ecb)); - - ahbecbfree(ahb, ecb); - - /* - * Create the device queue for our SIM. - */ - devq = cam_simq_alloc(ahb->num_ecbs); - if (devq == NULL) { - mtx_unlock(&ahb->lock); - return (ENOMEM); - } - - /* - * Construct our SIM entry - */ - ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb, - device_get_unit(ahb->dev), &ahb->lock, 2, ahb->num_ecbs, devq); - if (ahb->sim == NULL) { - cam_simq_free(devq); - mtx_unlock(&ahb->lock); - return (ENOMEM); - } - - if (xpt_bus_register(ahb->sim, ahb->dev, 0) != CAM_SUCCESS) { - cam_sim_free(ahb->sim, /*free_devq*/TRUE); - mtx_unlock(&ahb->lock); - return (ENXIO); - } - - if (xpt_create_path(&ahb->path, /*periph*/NULL, - cam_sim_path(ahb->sim), CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(ahb->sim)); - cam_sim_free(ahb->sim, /*free_devq*/TRUE); - mtx_unlock(&ahb->lock); - return (ENXIO); - } - - /* - * Allow the board to generate interrupts. - */ - ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN); - mtx_unlock(&ahb->lock); - - return (0); -} - -static void -ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) -{ - struct ccb_hdr *ccb_h; - u_int target_id; - - if (ahb->immed_cmd == 0) { - device_printf(ahb->dev, "Immediate Command complete with no " - " pending command\n"); - return; - } - - target_id = intstat & INTSTAT_TARGET_MASK; - - ccb_h = LIST_FIRST(&ahb->pending_ccbs); - while (ccb_h != NULL) { - struct ecb *pending_ecb; - union ccb *ccb; - - pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; - ccb = pending_ecb->ccb; - ccb_h = LIST_NEXT(ccb_h, sim_links.le); - if (ccb->ccb_h.target_id == target_id - || target_id == ahb->scsi_id) { - callout_stop(&pending_ecb->timer); - LIST_REMOVE(&ccb->ccb_h, sim_links.le); - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) - bus_dmamap_unload(ahb->buffer_dmat, - pending_ecb->dmamap); - if (pending_ecb == ahb->immed_ecb) - ccb->ccb_h.status = - CAM_CMD_TIMEOUT|CAM_RELEASE_SIMQ; - else if (target_id == ahb->scsi_id) - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - else - ccb->ccb_h.status = CAM_BDR_SENT; - ahbecbfree(ahb, pending_ecb); - xpt_done(ccb); - } else if (ahb->immed_ecb != NULL) { - /* Re-instate timeout */ - callout_reset_sbt(&pending_ecb->timer, - SBT_1MS * ccb->ccb_h.timeout, 0, ahbtimeout, - pending_ecb, 0); - } - } - - if (ahb->immed_ecb != NULL) { - ahb->immed_ecb = NULL; - device_printf(ahb->dev, "No longer in timeout\n"); - } else if (target_id == ahb->scsi_id) - device_printf(ahb->dev, "SCSI Bus Reset Delivered\n"); - else - device_printf(ahb->dev, - "Bus Device Reset Delivered to target %d\n", target_id); - - ahb->immed_cmd = 0; -} - -static void -ahbcalcresid(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) -{ - if (ecb->status.data_overrun != 0) { - /* - * Overrun Condition. The hardware doesn't - * provide a meaningful byte count in this case - * (the residual is always 0). Tell the XPT - * layer about the error. - */ - ccb->ccb_h.status = CAM_DATA_RUN_ERR; - } else { - ccb->csio.resid = ecb->status.resid_count; - - if ((ecb->hecb.flag_word1 & FW1_SG_ECB) != 0) { - /* - * For S/G transfers, the adapter provides a pointer - * to the address in the last S/G element used and a - * residual for that element. So, we need to sum up - * the elements that follow it in order to get a real - * residual number. If we have an overrun, the residual - * reported will be 0 and we already know that all S/G - * segments have been exhausted, so we can skip this - * step. - */ - ahb_sg_t *sg; - int num_sg; - - num_sg = ecb->hecb.data_len / sizeof(ahb_sg_t); - - /* Find the S/G the adapter was working on */ - for (sg = ecb->sg_list; - num_sg != 0 && sg->addr != ecb->status.resid_addr; - num_sg--, sg++) - ; - - /* Skip it */ - num_sg--; - sg++; - - /* Sum the rest */ - for (; num_sg != 0; num_sg--, sg++) - ccb->csio.resid += sg->len; - } - /* Underruns are not errors */ - ccb->ccb_h.status = CAM_REQ_CMP; - } -} - -static void -ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) -{ - struct hardware_ecb *hecb; - struct ecb_status *status; - - hecb = &ecb->hecb; - status = &ecb->status; - switch (status->ha_status) { - case HS_OK: - ccb->csio.scsi_status = status->scsi_status; - if (status->scsi_status != 0) { - ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; - if (status->sense_stored) { - ccb->ccb_h.status |= CAM_AUTOSNS_VALID; - ccb->csio.sense_resid = - ccb->csio.sense_len - status->sense_len; - bcopy(&ecb->sense, &ccb->csio.sense_data, - status->sense_len); - } - } - break; - case HS_TARGET_NOT_ASSIGNED: - ccb->ccb_h.status = CAM_PATH_INVALID; - break; - case HS_SEL_TIMEOUT: - ccb->ccb_h.status = CAM_SEL_TIMEOUT; - break; - case HS_DATA_RUN_ERR: - ahbcalcresid(ahb, ecb, ccb); - break; - case HS_UNEXPECTED_BUSFREE: - ccb->ccb_h.status = CAM_UNEXP_BUSFREE; - break; - case HS_INVALID_PHASE: - ccb->ccb_h.status = CAM_SEQUENCE_FAIL; - break; - case HS_REQUEST_SENSE_FAILED: - ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; - break; - case HS_TAG_MSG_REJECTED: - { - struct ccb_trans_settings neg; - struct ccb_trans_settings_scsi *scsi = &neg.proto_specific.scsi; - - xpt_print_path(ccb->ccb_h.path); - printf("refuses tagged commands. Performing " - "non-tagged I/O\n"); - memset(&neg, 0, sizeof (neg)); - neg.protocol = PROTO_SCSI; - neg.protocol_version = SCSI_REV_2; - neg.transport = XPORT_SPI; - neg.transport_version = 2; - scsi->flags = CTS_SCSI_VALID_TQ; - xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); - xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); - ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id); - ccb->ccb_h.status = CAM_MSG_REJECT_REC; - break; - } - case HS_FIRMWARE_LOAD_REQ: - case HS_HARDWARE_ERR: - /* - * Tell the system that the Adapter - * is no longer functional. - */ - ccb->ccb_h.status = CAM_NO_HBA; - break; - case HS_CMD_ABORTED_HOST: - case HS_CMD_ABORTED_ADAPTER: - case HS_ATN_TARGET_FAILED: - case HS_SCSI_RESET_ADAPTER: - case HS_SCSI_RESET_INCOMING: - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - break; - case HS_INVALID_ECB_PARAM: - device_printf(ahb->dev, - "opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n", - hecb->opcode, hecb->flag_word1, hecb->flag_word2); - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - break; - case HS_DUP_TCB_RECEIVED: - case HS_INVALID_OPCODE: - case HS_INVALID_CMD_LINK: - case HS_PROGRAM_CKSUM_ERROR: - panic("%s: Can't happen host status %x occurred", - device_get_nameunit(ahb->dev), status->ha_status); - break; - } - if (ccb->ccb_h.status != CAM_REQ_CMP) { - xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); - ccb->ccb_h.status |= CAM_DEV_QFRZN; - } -} - -static void -ahbdone(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) -{ - struct ecb *ecb; - union ccb *ccb; - - ecb = ahbecbptov(ahb, mbox); - - if ((ecb->state & ECB_ACTIVE) == 0) - panic("ecb not active"); - - ccb = ecb->ccb; - - if (ccb != NULL) { - callout_stop(&ecb->timer); - LIST_REMOVE(&ccb->ccb_h, sim_links.le); - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - bus_dmasync_op_t op; - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) - op = BUS_DMASYNC_POSTREAD; - else - op = BUS_DMASYNC_POSTWRITE; - bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); - bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); - } - - if ((intstat & INTSTAT_MASK) == INTSTAT_ECB_OK) { - ccb->ccb_h.status = CAM_REQ_CMP; - ccb->csio.resid = 0; - } else { - ahbprocesserror(ahb, ecb, ccb); - } - ahbecbfree(ahb, ecb); - xpt_done(ccb); - } else { - /* Non CCB Command */ - if ((intstat & INTSTAT_MASK) != INTSTAT_ECB_OK) { - device_printf(ahb->dev, "Command 0%x Failed %x:%x:%x\n", - ecb->hecb.opcode, - *((u_int16_t*)&ecb->status), - ecb->status.ha_status, ecb->status.resid_count); - } - /* Client owns this ECB and will release it. */ - } -} - -/* - * Catch an interrupt from the adaptor - */ -static void -ahbintr(void *arg) -{ - struct ahb_softc *ahb; - - ahb = arg; - mtx_lock(&ahb->lock); - ahbintr_locked(ahb); - mtx_unlock(&ahb->lock); -} - -static void -ahbintr_locked(struct ahb_softc *ahb) -{ - u_int intstat; - u_int32_t mbox; - - while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { - /* - * Fetch information about this interrupt. - */ - intstat = ahb_inb(ahb, INTSTAT); - mbox = ahb_inl(ahb, MBOXIN0); - - /* - * Reset interrupt latch. - */ - ahb_outb(ahb, CONTROL, CNTRL_CLRINT); - - /* - * Process the completed operation - */ - switch (intstat & INTSTAT_MASK) { - case INTSTAT_ECB_OK: - case INTSTAT_ECB_CMPWRETRY: - case INTSTAT_ECB_CMPWERR: - ahbdone(ahb, mbox, intstat); - break; - case INTSTAT_AEN_OCCURED: - if ((intstat & INTSTAT_TARGET_MASK) == ahb->scsi_id) { - /* Bus Reset */ - xpt_print_path(ahb->path); - switch (mbox) { - case HS_SCSI_RESET_ADAPTER: - printf("Host Adapter Initiated " - "Bus Reset occurred\n"); - break; - case HS_SCSI_RESET_INCOMING: - printf("Bus Reset Initiated " - "by another device occurred\n"); - break; - } - /* Notify the XPT */ - xpt_async(AC_BUS_RESET, ahb->path, NULL); - break; - } - printf("Unsupported initiator selection AEN occurred\n"); - break; - case INTSTAT_IMMED_OK: - case INTSTAT_IMMED_ERR: - ahbhandleimmed(ahb, mbox, intstat); - break; - case INTSTAT_HW_ERR: - panic("Unrecoverable hardware Error Occurred\n"); - } - } -} - -static void -ahbexecuteecb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) -{ - struct ecb *ecb; - union ccb *ccb; - struct ahb_softc *ahb; - u_int32_t ecb_paddr; - - ecb = (struct ecb *)arg; - ccb = ecb->ccb; - ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; - mtx_assert(&ahb->lock, MA_OWNED); - - if (error != 0) { - if (error != EFBIG) - device_printf(ahb->dev, - "Unexepected error 0x%x returned from " - "bus_dmamap_load\n", error); - if (ccb->ccb_h.status == CAM_REQ_INPROG) { - xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); - ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; - } - ahbecbfree(ahb, ecb); - xpt_done(ccb); - return; - } - - ecb_paddr = ahbecbvtop(ahb, ecb); - - if (nseg != 0) { - ahb_sg_t *sg; - bus_dma_segment_t *end_seg; - bus_dmasync_op_t op; - - end_seg = dm_segs + nseg; - - /* Copy the segments into our SG list */ - sg = ecb->sg_list; - while (dm_segs < end_seg) { - sg->addr = dm_segs->ds_addr; - sg->len = dm_segs->ds_len; - sg++; - dm_segs++; - } - - if (nseg > 1) { - ecb->hecb.flag_word1 |= FW1_SG_ECB; - ecb->hecb.data_ptr = ahbsgpaddr(ecb_paddr); - ecb->hecb.data_len = sizeof(ahb_sg_t) * nseg; - } else { - ecb->hecb.data_ptr = ecb->sg_list->addr; - ecb->hecb.data_len = ecb->sg_list->len; - } - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { -/* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */ - op = BUS_DMASYNC_PREREAD; - } else { - op = BUS_DMASYNC_PREWRITE; - } - /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */ - - bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); - - } else { - ecb->hecb.data_ptr = 0; - ecb->hecb.data_len = 0; - } - - /* - * Last time we need to check if this CCB needs to - * be aborted. - */ - if (ccb->ccb_h.status != CAM_REQ_INPROG) { - if (nseg != 0) - bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); - ahbecbfree(ahb, ecb); - xpt_done(ccb); - return; - } - - ecb->state = ECB_ACTIVE; - ccb->ccb_h.status |= CAM_SIM_QUEUED; - LIST_INSERT_HEAD(&ahb->pending_ccbs, &ccb->ccb_h, sim_links.le); - - /* Tell the adapter about this command */ - ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id); - - callout_reset_sbt(&ecb->timer, SBT_1MS * ccb->ccb_h.timeout, 0, - ahbtimeout, ecb, 0); -} - -static void -ahbaction(struct cam_sim *sim, union ccb *ccb) -{ - struct ahb_softc *ahb; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahbaction\n")); - - ahb = (struct ahb_softc *)cam_sim_softc(sim); - mtx_assert(&ahb->lock, MA_OWNED); - - switch (ccb->ccb_h.func_code) { - /* Common cases first */ - case XPT_SCSI_IO: /* Execute the requested I/O operation */ - { - struct ecb *ecb; - struct hardware_ecb *hecb; - int error; - - /* - * get an ecb to use. - */ - if ((ecb = ahbecbget(ahb)) == NULL) { - /* Should never occur */ - panic("Failed to get an ecb"); - } - - /* - * So we can find the ECB when an abort is requested - */ - ecb->ccb = ccb; - ccb->ccb_h.ccb_ecb_ptr = ecb; - ccb->ccb_h.ccb_ahb_ptr = ahb; - - /* - * Put all the arguments for the xfer in the ecb - */ - hecb = &ecb->hecb; - hecb->opcode = ECBOP_INITIATOR_SCSI_CMD; - hecb->flag_word1 = FW1_AUTO_REQUEST_SENSE - | FW1_ERR_STATUS_BLK_ONLY; - hecb->flag_word2 = ccb->ccb_h.target_lun - | FW2_NO_RETRY_ON_BUSY; - if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { - hecb->flag_word2 |= FW2_TAG_ENB - | ((ccb->csio.tag_action & 0x3) - << FW2_TAG_TYPE_SHIFT); - } - if ((ccb->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) - hecb->flag_word2 |= FW2_DISABLE_DISC; - hecb->sense_len = ccb->csio.sense_len; - hecb->cdb_len = ccb->csio.cdb_len; - if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { - if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { - bcopy(ccb->csio.cdb_io.cdb_ptr, - hecb->cdb, hecb->cdb_len); - } else { - /* I guess I could map it in... */ - ccb->ccb_h.status = CAM_REQ_INVALID; - ahbecbfree(ahb, ecb); - xpt_done(ccb); - return; - } - } else { - bcopy(ccb->csio.cdb_io.cdb_bytes, - hecb->cdb, hecb->cdb_len); - } - - error = bus_dmamap_load_ccb( - ahb->buffer_dmat, - ecb->dmamap, - ccb, - ahbexecuteecb, - ecb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, freeze the controller - * queue until our mapping is returned. - */ - xpt_freeze_simq(ahb->sim, 1); - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } - break; - } - case XPT_EN_LUN: /* Enable LUN as a target */ - case XPT_TARGET_IO: /* Execute target I/O request */ - case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ - case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ - case XPT_ABORT: /* Abort the specified CCB */ - /* XXX Implement */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - case XPT_SET_TRAN_SETTINGS: - { - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - xpt_done(ccb); - break; - } - case XPT_GET_TRAN_SETTINGS: - /* Get default/user set transfer settings for the target */ - { - struct ccb_trans_settings *cts = &ccb->cts; - u_int target_mask = 0x01 << ccb->ccb_h.target_id; - struct ccb_trans_settings_scsi *scsi = - &cts->proto_specific.scsi; - struct ccb_trans_settings_spi *spi = - &cts->xport_specific.spi; - - if (cts->type == CTS_TYPE_USER_SETTINGS) { - cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_2; - cts->transport = XPORT_SPI; - cts->transport_version = 2; - - scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; - spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; - if ((ahb->disc_permitted & target_mask) != 0) - spi->flags |= CTS_SPI_FLAGS_DISC_ENB; - if ((ahb->tags_permitted & target_mask) != 0) - scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; - spi->sync_period = 25; /* 10MHz */ - - if (spi->sync_period != 0) - spi->sync_offset = 15; - - spi->valid = CTS_SPI_VALID_SYNC_RATE - | CTS_SPI_VALID_SYNC_OFFSET - | CTS_SPI_VALID_BUS_WIDTH - | CTS_SPI_VALID_DISC; - scsi->valid = CTS_SCSI_VALID_TQ; - ccb->ccb_h.status = CAM_REQ_CMP; - } else { - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - } - xpt_done(ccb); - break; - } - case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ - { - int i; - - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); - /* Poll for interrupt completion */ - for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) { - DELAY(1000); - ahbintr_locked(cam_sim_softc(sim)); - } - break; - } - case XPT_CALC_GEOMETRY: - { - cam_calc_geometry(&ccb->ccg, ahb->extended_trans); - xpt_done(ccb); - break; - } - case XPT_RESET_BUS: /* Reset the specified SCSI bus */ - { - int i; - - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); - /* Poll for interrupt completion */ - for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) - DELAY(1000); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - case XPT_TERM_IO: /* Terminate the I/O process */ - /* XXX Implement */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - case XPT_PATH_INQ: /* Path routing inquiry */ - { - struct ccb_pathinq *cpi = &ccb->cpi; - - cpi->version_num = 1; /* XXX??? */ - cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = 7; - cpi->max_lun = 7; - cpi->initiator_id = ahb->scsi_id; - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strlcpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); - strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(sim); - cpi->transport = XPORT_SPI; - cpi->transport_version = 2; - cpi->protocol = PROTO_SCSI; - cpi->protocol_version = SCSI_REV_2; - cpi->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } -#if 0 - /* Need these??? */ - case XPT_IMMED_NOTIFY: /* Notify Host Target driver of event */ - case XPT_NOTIFY_ACK: /* Acknowledgement of event */ -#endif - default: - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - } -} - -static void -ahbpoll(struct cam_sim *sim) -{ - ahbintr(cam_sim_softc(sim)); -} - -static void -ahbtimeout(void *arg) -{ - struct ecb *ecb; - union ccb *ccb; - struct ahb_softc *ahb; - - ecb = (struct ecb *)arg; - ccb = ecb->ccb; - ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; - mtx_assert(&ahb->lock, MA_OWNED); - xpt_print_path(ccb->ccb_h.path); - printf("ECB %p - timed out\n", (void *)ecb); - - if ((ecb->state & ECB_ACTIVE) == 0) { - xpt_print_path(ccb->ccb_h.path); - printf("ECB %p - timed out ECB already completed\n", - (void *)ecb); - return; - } - /* - * In order to simplify the recovery process, we ask the XPT - * layer to halt the queue of new transactions and we traverse - * the list of pending CCBs and remove their timeouts. This - * means that the driver attempts to clear only one error - * condition at a time. In general, timeouts that occur - * close together are related anyway, so there is no benefit - * in attempting to handle errors in parallel. Timeouts will - * be reinstated when the recovery process ends. - */ - if ((ecb->state & ECB_DEVICE_RESET) == 0) { - struct ccb_hdr *ccb_h; - - if ((ecb->state & ECB_RELEASE_SIMQ) == 0) { - xpt_freeze_simq(ahb->sim, /*count*/1); - ecb->state |= ECB_RELEASE_SIMQ; - } - - LIST_FOREACH(ccb_h, &ahb->pending_ccbs, sim_links.le) { - struct ecb *pending_ecb; - - pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; - callout_stop(&pending_ecb->timer); - } - - /* Store for our interrupt handler */ - ahb->immed_ecb = ecb; - - /* - * Send a Bus Device Reset message: - * The target that is holding up the bus may not - * be the same as the one that triggered this timeout - * (different commands have different timeout lengths), - * but we have no way of determining this from our - * timeout handler. Our strategy here is to queue a - * BDR message to the target of the timed out command. - * If this fails, we'll get another timeout 2 seconds - * later which will attempt a bus reset. - */ - xpt_print_path(ccb->ccb_h.path); - printf("Queuing BDR\n"); - ecb->state |= ECB_DEVICE_RESET; - callout_reset(&ecb->timer, 2 * hz, ahbtimeout, ecb); - - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); - } else if ((ecb->state & ECB_SCSIBUS_RESET) != 0) { - /* - * Try a SCSI bus reset. We do this only if we - * have already attempted to clear the condition with a BDR. - */ - xpt_print_path(ccb->ccb_h.path); - printf("Attempting SCSI Bus reset\n"); - ecb->state |= ECB_SCSIBUS_RESET; - callout_reset(&ecb->timer, 2 * hz, ahbtimeout, ecb); - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); - } else { - /* Bring out the hammer... */ - ahbreset(ahb); - - /* Simulate the reset complete interrupt */ - ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK); - } -} - -static device_method_t ahb_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ahbprobe), - DEVMETHOD(device_attach, ahbattach), - - { 0, 0 } -}; - -static driver_t ahb_eisa_driver = { - "ahb", - ahb_eisa_methods, - sizeof(struct ahb_softc), -}; - -static devclass_t ahb_devclass; - -DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0); -MODULE_DEPEND(ahb, eisa, 1, 1, 1); -MODULE_DEPEND(ahb, cam, 1, 1, 1); diff --git a/sys/dev/ahb/ahbreg.h b/sys/dev/ahb/ahbreg.h deleted file mode 100644 index dabf409a3d8f..000000000000 --- a/sys/dev/ahb/ahbreg.h +++ /dev/null @@ -1,284 +0,0 @@ -/*- - * Hardware structure definitions for the Adaptec 174X CAM SCSI device driver. - * - * Copyright (c) 1998 Justin T. Gibbs - * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not 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. - * - * $FreeBSD$ - */ - -/* Resource Constatns */ -#define AHB_NECB 64 -#define AHB_NSEG 32 - -/* AHA1740 EISA ID, IO port range size, and offset from slot base */ -#define EISA_DEVICE_ID_ADAPTEC_1740 0x04900000 -#define AHB_EISA_IOSIZE 0x100 -#define AHB_EISA_SLOT_OFFSET 0xc00 - -/* AHA1740 EISA board control registers (Offset from slot base) */ -#define EBCTRL 0x084 -#define CDEN 0x01 - -/* - * AHA1740 EISA board mode registers (Offset from slot base) - */ -#define PORTADDR 0x0C0 -#define PORTADDR_ENHANCED 0x80 - -#define BIOSADDR 0x0C1 - -#define INTDEF 0x0C2 -#define INT9 0x00 -#define INT10 0x01 -#define INT11 0x02 -#define INT12 0x03 -#define INT14 0x05 -#define INT15 0x06 -#define INTLEVEL 0x08 -#define INTEN 0x10 - -#define SCSIDEF 0x0C3 -#define HSCSIID 0x0F /* our SCSI ID */ -#define RSTBUS 0x10 - -#define BUSDEF 0x0C4 -#define B0uS 0x00 /* give up bus immediately */ -#define B4uS 0x01 /* delay 4uSec. */ -#define B8uS 0x02 /* delay 8uSec. */ - -#define RESV0 0x0C5 - -#define RESV1 0x0C6 -#define EXTENDED_TRANS 0x01 - -#define RESV2 0x0C7 - -/* - * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base) - */ -#define MBOXOUT0 0x0D0 -#define MBOXOUT1 0x0D1 -#define MBOXOUT2 0x0D2 -#define MBOXOUT3 0x0D3 - -#define ATTN 0x0D4 -#define ATTN_TARGMASK 0x0F -#define ATTN_IMMED 0x10 -#define ATTN_STARTECB 0x40 -#define ATTN_ABORTECB 0x50 -#define ATTN_TARG_RESET 0x80 - -#define CONTROL 0x0D5 -#define CNTRL_SET_HRDY 0x20 -#define CNTRL_CLRINT 0x40 -#define CNTRL_HARD_RST 0x80 - -#define INTSTAT 0x0D6 -#define INTSTAT_TARGET_MASK 0x0F -#define INTSTAT_MASK 0xF0 -#define INTSTAT_ECB_OK 0x10 /* ECB Completed w/out error */ -#define INTSTAT_ECB_CMPWRETRY 0x50 /* ECB Completed w/retries */ -#define INTSTAT_HW_ERR 0x70 /* Adapter Hardware Failure */ -#define INTSTAT_IMMED_OK 0xA0 /* Immediate command complete */ -#define INTSTAT_ECB_CMPWERR 0xC0 /* ECB Completed w/error */ -#define INTSTAT_AEN_OCCURED 0xD0 /* Async Event Notification */ -#define INTSTAT_IMMED_ERR 0xE0 /* Immediate command failed */ - -#define HOSTSTAT 0x0D7 -#define HOSTSTAT_MBOX_EMPTY 0x04 -#define HOSTSTAT_INTPEND 0x02 -#define HOSTSTAT_BUSY 0x01 - - -#define MBOXIN0 0x0D8 -#define MBOXIN1 0x0D9 -#define MBOXIN2 0x0DA -#define MBOXIN3 0x0DB - -#define STATUS2 0x0DC -#define STATUS2_HOST_READY 0x01 - -typedef enum { - IMMED_RESET = 0x000080, - IMMED_DEVICE_CLEAR_QUEUE = 0x000480, - IMMED_ADAPTER_CLEAR_QUEUE = 0x000880, - IMMED_RESUME = 0x200090 -} immed_cmd; - -struct ecb_status { - /* Status Flags */ - u_int16_t no_error :1, /* Completed with no error */ - data_underrun :1, - :1, - ha_queue_full :1, - spec_check :1, - data_overrun :1, - chain_halted :1, - intr_issued :1, - status_avail :1, /* status bytes 14-31 are valid */ - sense_stored :1, - :1, - init_requied :1, - major_error :1, - :1, - extended_ca :1, - :1; - /* Host Status */ - u_int8_t ha_status; - u_int8_t scsi_status; - int32_t resid_count; - u_int32_t resid_addr; - u_int16_t addit_status; - u_int8_t sense_len; - u_int8_t unused[9]; - u_int8_t cdb[6]; -}; - -typedef enum { - HS_OK = 0x00, - HS_CMD_ABORTED_HOST = 0x04, - HS_CMD_ABORTED_ADAPTER = 0x05, - HS_FIRMWARE_LOAD_REQ = 0x08, - HS_TARGET_NOT_ASSIGNED = 0x0A, - HS_SEL_TIMEOUT = 0x11, - HS_DATA_RUN_ERR = 0x12, - HS_UNEXPECTED_BUSFREE = 0x13, - HS_INVALID_PHASE = 0x14, - HS_INVALID_OPCODE = 0x16, - HS_INVALID_CMD_LINK = 0x17, - HS_INVALID_ECB_PARAM = 0x18, - HS_DUP_TCB_RECEIVED = 0x19, - HS_REQUEST_SENSE_FAILED = 0x1A, - HS_TAG_MSG_REJECTED = 0x1C, - HS_HARDWARE_ERR = 0x20, - HS_ATN_TARGET_FAILED = 0x21, - HS_SCSI_RESET_ADAPTER = 0x22, - HS_SCSI_RESET_INCOMING = 0x23, - HS_PROGRAM_CKSUM_ERROR = 0x80 -} host_status; - -typedef enum { - ECBOP_NOP = 0x00, - ECBOP_INITIATOR_SCSI_CMD = 0x01, - ECBOP_RUN_DIAGNOSTICS = 0x05, - ECBOP_INITIALIZE_SCSI = 0x06, /* Set syncrate/disc/parity */ - ECBOP_READ_SENSE = 0x08, - ECBOP_DOWNLOAD_FIRMWARE = 0x09, - ECBOP_READ_HA_INQDATA = 0x0a, - ECBOP_TARGET_SCSI_CMD = 0x10 -} ecb_op; - -struct ha_inquiry_data { - struct scsi_inquiry_data scsi_data; - u_int8_t release_date[8]; - u_int8_t release_time[8]; - u_int16_t firmware_cksum; - u_int16_t reserved; - u_int16_t target_data[16]; -}; - -struct hardware_ecb { - u_int16_t opcode; - u_int16_t flag_word1; -#define FW1_LINKED_CMD 0x0001 -#define FW1_DISABLE_INTR 0x0080 -#define FW1_SUPPRESS_URUN_ERR 0x0400 -#define FW1_SG_ECB 0x1000 -#define FW1_ERR_STATUS_BLK_ONLY 0x4000 -#define FW1_AUTO_REQUEST_SENSE 0x8000 - u_int16_t flag_word2; -#define FW2_LUN_MASK 0x0007 -#define FW2_TAG_ENB 0x0008 -#define FW2_TAG_TYPE 0x0030 -#define FW2_TAG_TYPE_SHIFT 4 -#define FW2_DISABLE_DISC 0x0040 -#define FW2_CHECK_DATA_DIR 0x0100 -#define FW2_DATA_DIR_IN 0x0200 -#define FW2_SUPRESS_TRANSFER 0x0400 -#define FW2_CALC_CKSUM 0x0800 -#define FW2_RECOVERY_ECB 0x4000 -#define FW2_NO_RETRY_ON_BUSY 0x8000 - u_int16_t reserved; - u_int32_t data_ptr; - u_int32_t data_len; - u_int32_t status_ptr; - u_int32_t link_ptr; - u_int32_t reserved2; - u_int32_t sense_ptr; - u_int8_t sense_len; - u_int8_t cdb_len; - u_int16_t cksum; - u_int8_t cdb[12]; -}; - -typedef struct { - u_int32_t addr; - u_int32_t len; -} ahb_sg_t; - -typedef enum { - ECB_FREE = 0x0, - ECB_ACTIVE = 0x1, - ECB_DEVICE_RESET = 0x2, - ECB_SCSIBUS_RESET = 0x4, - ECB_RELEASE_SIMQ = 0x8 -} ecb_state; - -struct ecb { - struct hardware_ecb hecb; - struct ecb_status status; - struct scsi_sense_data sense; - ahb_sg_t sg_list[AHB_NSEG]; - SLIST_ENTRY(ecb) links; - ecb_state state; - union ccb *ccb; - bus_dmamap_t dmamap; - struct callout timer; -}; - -struct ahb_softc { - device_t dev; - struct resource *res; - struct mtx lock; - struct cam_sim *sim; - struct cam_path *path; - SLIST_HEAD(,ecb) free_ecbs; - LIST_HEAD(,ccb_hdr) pending_ccbs; - struct ecb *ecb_array; - u_int32_t ecb_physbase; - bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ - bus_dma_tag_t ecb_dmat; /* dmat for our ecb array */ - bus_dmamap_t ecb_dmamap; - volatile u_int32_t immed_cmd; - struct ecb *immed_ecb; - struct ha_inquiry_data *ha_inq_data; - u_int32_t ha_inq_physbase; - u_int init_level; - u_int scsi_id; - u_int num_ecbs; - u_int extended_trans; - u_int8_t disc_permitted; - u_int8_t tags_permitted; -}; diff --git a/sys/dev/aic7xxx/ahc_eisa.c b/sys/dev/aic7xxx/ahc_eisa.c deleted file mode 100644 index 05d262bbc72e..000000000000 --- a/sys/dev/aic7xxx/ahc_eisa.c +++ /dev/null @@ -1,178 +0,0 @@ -/*- - * FreeBSD, EISA product support functions - * - * - * Copyright (c) 1994-1998, 2000, 2001 Justin T. Gibbs. - * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not 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. - * - * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/ahc_eisa.c#13 $ - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <dev/aic7xxx/aic7xxx_osm.h> - -#include <dev/eisa/eisaconf.h> - -static int -aic7770_probe(device_t dev) -{ - struct aic7770_identity *entry; - struct resource *regs; - uint32_t iobase; - bus_space_handle_t bsh; - bus_space_tag_t tag; - u_int irq; - u_int intdef; - u_int hcntrl; - int shared; - int rid; - int error; - - entry = aic7770_find_device(eisa_get_id(dev)); - if (entry == NULL) - return (ENXIO); - device_set_desc(dev, entry->name); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + AHC_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE); - - rid = 0; - regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (regs == NULL) { - device_printf(dev, "Unable to map I/O space?!\n"); - return ENOMEM; - } - - tag = rman_get_bustag(regs); - bsh = rman_get_bushandle(regs); - error = 0; - - /* Pause the card preseving the IRQ type */ - hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS; - bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE); - while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0) - ; - - /* Make sure we have a valid interrupt vector */ - intdef = bus_space_read_1(tag, bsh, INTDEF); - shared = (intdef & EDGE_TRIG) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; - irq = intdef & VECTOR; - switch (irq) { - case 9: - case 10: - case 11: - case 12: - case 14: - case 15: - break; - default: - printf("aic7770 at slot %d: illegal irq setting %d\n", - eisa_get_slot(dev), intdef); - error = ENXIO; - } - - if (error == 0) - eisa_add_intr(dev, irq, shared); - - bus_release_resource(dev, SYS_RES_IOPORT, rid, regs); - return (error); -} - -static int -aic7770_attach(device_t dev) -{ - struct aic7770_identity *entry; - struct ahc_softc *ahc; - char *name; - int error; - - entry = aic7770_find_device(eisa_get_id(dev)); - if (entry == NULL) - return (ENXIO); - - /* - * Allocate a softc for this card and - * set it up for attachment by our - * common detect routine. - */ - name = malloc(strlen(device_get_nameunit(dev)) + 1, M_DEVBUF, M_NOWAIT); - if (name == NULL) - return (ENOMEM); - strcpy(name, device_get_nameunit(dev)); - ahc = ahc_alloc(dev, name); - if (ahc == NULL) - return (ENOMEM); - - ahc_set_unit(ahc, device_get_unit(dev)); - - /* Allocate a dmatag for our SCB DMA maps */ - error = aic_dma_tag_create(ahc, /*parent*/bus_get_dma_tag(dev), - /*alignment*/1, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/AHC_NSEG, - /*maxsegsz*/AHC_MAXTRANSFER_SIZE, - /*flags*/0, - &ahc->parent_dmat); - - if (error != 0) { - printf("ahc_eisa_attach: Could not allocate DMA tag " - "- error %d\n", error); - ahc_free(ahc); - return (ENOMEM); - } - ahc->dev_softc = dev; - error = aic7770_config(ahc, entry, /*unused ioport arg*/0); - if (error != 0) { - ahc_free(ahc); - return (error); - } - - ahc_attach(ahc); - return (0); -} - - -static device_method_t ahc_eisa_device_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aic7770_probe), - DEVMETHOD(device_attach, aic7770_attach), - DEVMETHOD(device_detach, ahc_detach), - { 0, 0 } -}; - -static driver_t ahc_eisa_driver = { - "ahc", - ahc_eisa_device_methods, - sizeof(struct ahc_softc) -}; - -DRIVER_MODULE(ahc_eisa, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); -MODULE_DEPEND(ahc_eisa, ahc, 1, 1, 1); -MODULE_VERSION(ahc_eisa, 1); diff --git a/sys/dev/aic7xxx/aic7770.c b/sys/dev/aic7xxx/aic7770.c index a5efb0b9dbfe..c7c4cbf449b7 100644 --- a/sys/dev/aic7xxx/aic7770.c +++ b/sys/dev/aic7xxx/aic7770.c @@ -64,7 +64,7 @@ static int aic7770_suspend(struct ahc_softc *ahc); static int aic7770_resume(struct ahc_softc *ahc); static int aha2840_load_seeprom(struct ahc_softc *ahc); static ahc_device_setup_t ahc_aic7770_VL_setup; -static ahc_device_setup_t ahc_aic7770_EISA_setup; +static ahc_device_setup_t ahc_aic7770_EISA_setup; /* Really just ISA */ static ahc_device_setup_t ahc_aic7770_setup; struct aic7770_identity aic7770_ident_table[] = diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h index a673bb599cbc..053de9ac9d61 100644 --- a/sys/dev/aic7xxx/aic7xxx.h +++ b/sys/dev/aic7xxx/aic7xxx.h @@ -207,7 +207,7 @@ typedef enum { AHC_AIC7892 = 0x000c, AHC_AIC7899 = 0x000d, AHC_VL = 0x0100, /* Bus type VL */ - AHC_EISA = 0x0200, /* Bus type EISA */ + AHC_EISA = 0x0200, /* Bus type EISA/ISA */ AHC_PCI = 0x0400, /* Bus type PCI */ AHC_BUS_MASK = 0x0F00 } ahc_chip; @@ -1170,7 +1170,7 @@ struct ahc_pci_identity { extern struct ahc_pci_identity ahc_pci_ident_table[]; extern const u_int ahc_num_pci_devs; -/***************************** VL/EISA Declarations ***************************/ +/*************************** VL/EISA/ISA Declarations *************************/ struct aic7770_identity { uint32_t full_id; uint32_t id_mask; @@ -1197,7 +1197,7 @@ int ahc_pci_config(struct ahc_softc *, struct ahc_pci_identity *); int ahc_pci_test_register_access(struct ahc_softc *); -/*************************** EISA/VL Front End ********************************/ +/*************************** ISA/EISA/VL Front End ****************************/ struct aic7770_identity *aic7770_find_device(uint32_t); int aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *, diff --git a/sys/dev/aic7xxx/aic7xxx_osm.h b/sys/dev/aic7xxx/aic7xxx_osm.h index 9a2939e9e9a2..054811e9d97f 100644 --- a/sys/dev/aic7xxx/aic7xxx_osm.h +++ b/sys/dev/aic7xxx/aic7xxx_osm.h @@ -224,7 +224,7 @@ int ahc_pci_map_registers(struct ahc_softc *ahc); #define ahc_pci_map_int ahc_map_int #endif /*AIC_PCI_CONFIG*/ -/******************************** VL/EISA *************************************/ +/******************************** VL/EISA/ISA *********************************/ int aic7770_map_registers(struct ahc_softc *ahc, u_int port); static __inline int aic7770_map_int(struct ahc_softc *, int); @@ -233,9 +233,9 @@ aic7770_map_int(struct ahc_softc *ahc, int irq) { /* * The IRQ is unused in the FreeBSD - * implementation since the EISA and - * ISA attachments register the IRQ - * with newbus before the core is called. + * implementation since the ISA attachment + * registers the IRQ with newbus before + * the core is called. */ return ahc_map_int(ahc); } diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c index 384e733280a4..0d1cba3f7df8 100644 --- a/sys/dev/asmc/asmc.c +++ b/sys/dev/asmc/asmc.c @@ -155,13 +155,13 @@ static struct asmc_model *asmc_match(device_t dev); asmc_mbp_sysctl_light_control struct asmc_model asmc_models[] = { - { + { "MacBook1,1", "Apple SMC MacBook Core Duo", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, ASMC_MB_TEMPS, ASMC_MB_TEMPNAMES, ASMC_MB_TEMPDESCS }, - { + { "MacBook2,1", "Apple SMC MacBook Core 2 Duo", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, ASMC_MB_TEMPS, ASMC_MB_TEMPNAMES, ASMC_MB_TEMPDESCS @@ -173,68 +173,74 @@ struct asmc_model asmc_models[] = { ASMC_MB31_TEMPS, ASMC_MB31_TEMPNAMES, ASMC_MB31_TEMPDESCS }, - { + { "MacBookPro1,1", "Apple SMC MacBook Pro Core Duo (15-inch)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - { + { "MacBookPro1,2", "Apple SMC MacBook Pro Core Duo (17-inch)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - { + { "MacBookPro2,1", "Apple SMC MacBook Pro Core 2 Duo (17-inch)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - { + { "MacBookPro2,2", "Apple SMC MacBook Pro Core 2 Duo (15-inch)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - { + { "MacBookPro3,1", "Apple SMC MacBook Pro Core 2 Duo (15-inch LED)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - { + { "MacBookPro3,2", "Apple SMC MacBook Pro Core 2 Duo (17-inch HD)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP_TEMPS, ASMC_MBP_TEMPNAMES, ASMC_MBP_TEMPDESCS }, - - { + + { "MacBookPro4,1", "Apple SMC MacBook Pro Core 2 Duo (Penryn)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP4_TEMPS, ASMC_MBP4_TEMPNAMES, ASMC_MBP4_TEMPDESCS }, - { + { "MacBookPro5,1", "Apple SMC MacBook Pro Core 2 Duo (2008/2009)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP5_TEMPS, ASMC_MBP5_TEMPNAMES, ASMC_MBP5_TEMPDESCS }, - { + { "MacBookPro8,2", "Apple SMC MacBook Pro (early 2011)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, ASMC_MBP8_TEMPS, ASMC_MBP8_TEMPNAMES, ASMC_MBP8_TEMPDESCS }, - { + { + "MacBookPro11,2", "Apple SMC MacBook Pro Retina Core i7 (2013/2014)", + ASMC_SMS_FUNCS_DISABLED, ASMC_FAN_FUNCS2, ASMC_LIGHT_FUNCS, + ASMC_MBP112_TEMPS, ASMC_MBP112_TEMPNAMES, ASMC_MBP112_TEMPDESCS + }, + + { "MacBookPro11,3", "Apple SMC MacBook Pro Retina Core i7 (2013/2014)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS, - ASMC_MBP11_TEMPS, ASMC_MBP11_TEMPNAMES, ASMC_MBP11_TEMPDESCS + ASMC_MBP113_TEMPS, ASMC_MBP113_TEMPNAMES, ASMC_MBP113_TEMPDESCS }, - + /* The Mac Mini has no SMS */ - { + { "Macmini1,1", "Apple SMC Mac Mini", NULL, NULL, NULL, ASMC_FAN_FUNCS, @@ -243,7 +249,7 @@ struct asmc_model asmc_models[] = { }, /* The Mac Mini 3,1 has no SMS */ - { + { "Macmini3,1", "Apple SMC Mac Mini 3,1", NULL, NULL, NULL, ASMC_FAN_FUNCS, @@ -273,31 +279,31 @@ struct asmc_model asmc_models[] = { "MacBookAir1,1", "Apple SMC MacBook Air", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, ASMC_MBA_TEMPS, ASMC_MBA_TEMPNAMES, ASMC_MBA_TEMPDESCS - }, + }, { "MacBookAir3,1", "Apple SMC MacBook Air Core 2 Duo (Late 2010)", ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, NULL, NULL, NULL, ASMC_MBA3_TEMPS, ASMC_MBA3_TEMPNAMES, ASMC_MBA3_TEMPDESCS - }, + }, { "MacBookAir5,1", "Apple SMC MacBook Air 11-inch (Mid 2012)", ASMC_SMS_FUNCS_DISABLED, - ASMC_FAN_FUNCS2, + ASMC_FAN_FUNCS2, ASMC_LIGHT_FUNCS, ASMC_MBA5_TEMPS, ASMC_MBA5_TEMPNAMES, ASMC_MBA5_TEMPDESCS - }, + }, { "MacBookAir5,2", "Apple SMC MacBook Air 13-inch (Mid 2012)", ASMC_SMS_FUNCS_DISABLED, - ASMC_FAN_FUNCS2, + ASMC_FAN_FUNCS2, ASMC_LIGHT_FUNCS, ASMC_MBA5_TEMPS, ASMC_MBA5_TEMPNAMES, ASMC_MBA5_TEMPDESCS - }, + }, + - { NULL, NULL } }; @@ -333,7 +339,7 @@ ACPI_MODULE_NAME("ASMC") #ifdef DEBUG #define ASMC_DPRINTF(str) device_printf(dev, str) #else -#define ASMC_DPRINTF(str) +#define ASMC_DPRINTF(str) #endif /* NB: can't be const */ @@ -376,7 +382,7 @@ asmc_probe(device_t dev) return (ENXIO); if (ACPI_ID_PROBE(device_get_parent(dev), dev, asmc_ids) == NULL) return (ENXIO); - + model = asmc_match(dev); if (!model) { device_printf(dev, "model not recognized\n"); @@ -404,10 +410,10 @@ asmc_attach(device_t dev) device_printf(dev, "unable to allocate IO port\n"); return (ENOMEM); } - + sysctlctx = device_get_sysctl_ctx(dev); sysctlnode = device_get_sysctl_tree(dev); - + model = asmc_match(dev); mtx_init(&sc->sc_mtx, "asmc", NULL, MTX_SPIN); @@ -495,13 +501,13 @@ asmc_attach(device_t dev) sc->sc_light_tree = SYSCTL_ADD_NODE(sysctlctx, SYSCTL_CHILDREN(sysctlnode), OID_AUTO, "light", CTLFLAG_RD, 0, "Keyboard backlight sensors"); - + SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_light_tree), OID_AUTO, "left", CTLTYPE_INT | CTLFLAG_RD, dev, 0, model->smc_light_left, "I", "Keyboard backlight left sensor"); - + SYSCTL_ADD_PROC(sysctlctx, SYSCTL_CHILDREN(sc->sc_light_tree), OID_AUTO, "right", CTLTYPE_INT | CTLFLAG_RD, @@ -574,7 +580,7 @@ asmc_attach(device_t dev) goto err2; } - ret = bus_setup_intr(dev, sc->sc_irq, + ret = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, #ifdef INTR_FILTER asmc_sms_intrfast, asmc_sms_handler, @@ -663,7 +669,7 @@ asmc_init(device_t dev) asmc_key_write(dev, ASMC_KEY_INTOK, buf, 1); DELAY(50); - /* + /* * Initiate the polling intervals. */ buf[0] = 20; /* msecs */ @@ -698,13 +704,13 @@ asmc_init(device_t dev) DELAY(100); sc->sc_sms_intr_works = 0; - + /* * Retry SMS initialization 1000 times * (takes approx. 2 seconds in worst case) */ for (i = 0; i < 1000; i++) { - if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 && + if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 && (buf[0] == ASMC_SMS_INIT1 && buf[1] == ASMC_SMS_INIT2)) { error = 0; sc->sc_sms_intr_works = 1; @@ -734,7 +740,7 @@ nosms: */ asmc_key_read(dev, ASMC_NKEYS, buf, 4); device_printf(dev, "number of keys: %d\n", ntohl(*(uint32_t*)buf)); - } + } #ifdef DEBUG asmc_dumpall(dev); @@ -782,10 +788,10 @@ asmc_wait(device_t dev, uint8_t val) #ifdef DEBUG device_printf(dev, "%s failed: 0x%x, 0x%x\n", __func__, val, ASMC_CMDPORT_READ(sc)); -#endif +#endif return (1); } - + /* * Send the given command, retrying up to 10 times if * the acknowledgement fails. @@ -919,7 +925,7 @@ out: maxlen = type[0]; type[0] = ' '; type[5] = 0; - if (maxlen > sizeof(v)) { + if (maxlen > sizeof(v)) { device_printf(dev, "WARNING: cropping maxlen from %d to %zu\n", maxlen, sizeof(v)); @@ -1189,7 +1195,7 @@ asmc_sms_read(device_t dev, const char *key, int16_t *val) uint8_t buf[2]; int error; - /* no need to do locking here as asmc_key_read() already does it */ + /* no need to do locking here as asmc_key_read() already does it */ switch (key[3]) { case 'X': case 'Y': @@ -1246,7 +1252,7 @@ static void asmc_sms_handler(void *arg) { struct asmc_softc *sc = device_get_softc(arg); - + asmc_sms_task(sc, 0); } #endif @@ -1293,7 +1299,7 @@ asmc_sms_task(void *arg, int pending) } snprintf(notify, sizeof(notify), " notify=0x%x", type); - devctl_notify("ACPI", "asmc", "SMS", notify); + devctl_notify("ACPI", "asmc", "SMS", notify); } static int @@ -1363,11 +1369,11 @@ asmc_mbp_sysctl_light_right(SYSCTL_HANDLER_ARGS) uint8_t buf[6]; int error; int32_t v; - + asmc_key_read(dev, ASMC_KEY_LIGHTRIGHT, buf, sizeof buf); v = buf[2]; error = sysctl_handle_int(oidp, &v, 0, req); - + return (error); } diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h index 26c62035a00c..cf7b7f3ae79a 100644 --- a/sys/dev/asmc/asmcvar.h +++ b/sys/dev/asmc/asmcvar.h @@ -76,7 +76,7 @@ struct asmc_softc { /* Number of keys */ -#define ASMC_NKEYS "#KEY" /* RO; 4 bytes */ +#define ASMC_NKEYS "#KEY" /* RO; 4 bytes */ /* * Fan control via SMC. @@ -154,7 +154,7 @@ struct asmc_softc { #define ASMC_MB31_TEMPDESCS { "Enclosure Bottomside", \ "Northbridge Point 1", \ "Heatsink 1","Heatsink 2" \ - "Memory Bank A", } + "Memory Bank A", } #define ASMC_MBP_TEMPS { "TB0T", "Th0H", "Th1H", "Tm0P", \ "TG0H", "TG0P", "TG0T", NULL } @@ -167,7 +167,7 @@ struct asmc_softc { "Heatsink 1", "Heatsink 2", \ "Memory Controller", \ "Graphics Chip", "Graphics Heatsink", \ - "Unknown", } + "Unknown", } #define ASMC_MBP4_TEMPS { "TB0T", "Th0H", "Th1H", "Th2H", "Tm0P", \ "TG0H", "TG0D", "TC0D", "TC0P", "Ts0P", \ @@ -186,13 +186,13 @@ struct asmc_softc { "Graphics Chip Diode", \ "CPU Temperature Diode", "CPU Point 2", \ "Unknown", "Unknown", \ - "Wireless Module", } + "Wireless Module", } #define ASMC_MBP5_TEMPS { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", \ "TC0F", "TC0P", "TG0D", "TG0F", "TG0H", \ "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", \ "TTF0", "Th2H", "Tm0P", "Ts0P", "Ts0S", \ - NULL } + NULL } #define ASMC_MBP5_TEMPNAMES { "enclosure_bottom_0", "enclosure_bottom_1", \ "enclosure_bottom_2", "enclosure_bottom_3", \ @@ -203,7 +203,7 @@ struct asmc_softc { "gpu_2_heatsink", "northbridge_diode", \ "northbridge_pin", "unknown", \ "heatsink_2", "memory_controller", \ - "pci_express_slot_pin", "pci_express_slot_unk" } + "pci_express_slot_pin", "pci_express_slot_unk" } #define ASMC_MBP5_TEMPDESCS { "Enclosure Bottom 0", "Enclosure Bottom 1", \ "Enclosure Bottom 2", "Enclosure Bottom 3", \ @@ -214,30 +214,57 @@ struct asmc_softc { "GPU 2 Heatsink", "Northbridge Diode", \ "Northbridge Pin", "Unknown", \ "Heatsink 2", "Memory Controller", \ - "PCI Express Slot Pin", "PCI Express Slot (unk)" } + "PCI Express Slot Pin", "PCI Express Slot (unk)" } #define ASMC_MBP8_TEMPS { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", \ "TC0E", "TC0F", "TC0P", "TC1C", "TC2C", \ "TC3C", "TC4C", "TCFC", "TCGC", "TCSA", \ "TCTD", "TG0D", "TG0P", "THSP", "TM0S", \ "TMBS", "TP0P", "TPCD", "TW0P", "Th1H", \ - "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL } + "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL } #define ASMC_MBP8_TEMPNAMES { "enclosure", "TB1T", "TB2T", "TC0C", "TC0D", \ "TC0E", "TC0F", "TC0P", "TC1C", "TC2C", \ "TC3C", "TC4C", "TCFC", "TCGC", "TCSA", \ "TCTD", "graphics", "TG0P", "THSP", "TM0S", \ "TMBS", "TP0P", "TPCD", "wireless", "Th1H", \ - "Th2H", "memory", "Ts0P", "Ts0S" } + "Th2H", "memory", "Ts0P", "Ts0S" } #define ASMC_MBP8_TEMPDESCS { "Enclosure Bottomside", "TB1T", "TB2T", "TC0C", "TC0D", \ "TC0E", "TC0F", "TC0P", "TC1C", "TC2C", \ "TC3C", "TC4C", "TCFC", "TCGC", "TCSA", \ "TCTD", "TG0D", "TG0P", "THSP", "TM0S", \ "TMBS", "TP0P", "TPCD", "TW0P", "Th1H", \ - "Th2H", "Tm0P", "Ts0P", "Ts0S" } + "Th2H", "Tm0P", "Ts0P", "Ts0S" } + +#define ASMC_MBP112_TEMPS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ + "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ + "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ + "TCXC", "TH0A", "TH0B", "TH0F", "TH0R", \ + "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ + "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ + "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ + "Ts1S", NULL } + +#define ASMC_MBP112_TEMPNAMES { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ + "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ + "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ + "TCXC", "TH0A", "TH0B", "TH0F", "TH0R", \ + "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ + "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ + "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ + "Ts1S" } + +#define ASMC_MBP112_TEMPDESCS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ + "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ + "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ + "TCXC", "TH0A", "TH0B", "TH0F", "TH0R", \ + "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ + "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ + "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ + "Ts1S" } -#define ASMC_MBP11_TEMPS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ +#define ASMC_MBP113_TEMPS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ "TCXC", "TG0D", "TG0P", "TG1D", "TG1F", \ @@ -245,9 +272,9 @@ struct asmc_softc { "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ - "Ts1S", NULL } + "Ts1S", NULL } -#define ASMC_MBP11_TEMPNAMES { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ +#define ASMC_MBP113_TEMPNAMES { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ "TCXC", "TG0D", "TG0P", "TG1D", "TG1F", \ @@ -255,9 +282,9 @@ struct asmc_softc { "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ - "Ts1S" } + "Ts1S" } -#define ASMC_MBP11_TEMPDESCS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ +#define ASMC_MBP113_TEMPDESCS { "TB0T", "TB1T", "TB2T", "TBXT", "TC0E", \ "TC0F", "TC0P", "TC1C", "TC2C", "TC3C", \ "TC4C", "TCFC", "TCGC", "TCSA", "TCTD", \ "TCXC", "TG0D", "TG0P", "TG1D", "TG1F", \ @@ -265,7 +292,8 @@ struct asmc_softc { "TH0V", "TH0a", "TH0b", "TH0c", "TM0P", \ "TM0S", "TP0P", "TPCD", "TW0P", "Ta0P", \ "TaSP", "Th1H", "Th2H", "Ts0P", "Ts0S", \ - "Ts1S" } + "Ts1S" } + #define ASMC_MM_TEMPS { "TN0P", "TN1P", NULL } #define ASMC_MM_TEMPNAMES { "northbridge1", "northbridge2" } diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index e5462fae7b48..807f2ff1cf1c 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -3194,7 +3194,7 @@ psmgestures(struct psm_softc *sc, finger_t *fingers, int nfingers, if (sc->synhw.capClickPad && ms->button & MOUSE_BUTTON1DOWN) { y_ok = sc->syninfo.softbuttons_y >= 0 ? start_y < sc->syninfo.softbuttons_y : - start_y > max_y - sc->syninfo.softbuttons_y; + start_y > max_y + sc->syninfo.softbuttons_y; center_button = MOUSE_BUTTON2DOWN; center_x = sc->syninfo.softbutton2_x; diff --git a/sys/dev/axgbe/if_axgbe.c b/sys/dev/axgbe/if_axgbe.c new file mode 100644 index 000000000000..9544394fd3e8 --- /dev/null +++ b/sys/dev/axgbe/if_axgbe.c @@ -0,0 +1,619 @@ +/*- + * Copyright (c) 2016,2017 SoftIron Inc. + * All rights reserved. + * + * This software was developed by Andrew Turner under + * the sponsorship of SoftIron Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/queue.h> +#include <sys/rman.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/sx.h> +#include <sys/taskqueue.h> + +#include <net/ethernet.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> + +#include "miibus_if.h" + +#include "xgbe.h" +#include "xgbe-common.h" + +static device_probe_t axgbe_probe; +static device_attach_t axgbe_attach; + +struct axgbe_softc { + /* Must be first */ + struct xgbe_prv_data prv; + + uint8_t mac_addr[ETHER_ADDR_LEN]; + struct ifmedia media; +}; + +static struct ofw_compat_data compat_data[] = { + { "amd,xgbe-seattle-v1a", true }, + { NULL, false } +}; + +static struct resource_spec old_phy_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Rx/Tx regs */ + { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* Integration regs */ + { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* Integration regs */ + { SYS_RES_IRQ, 0, RF_ACTIVE }, /* Interrupt */ + { -1, 0 } +}; + +static struct resource_spec old_mac_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* MAC regs */ + { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* PCS regs */ + { SYS_RES_IRQ, 0, RF_ACTIVE }, /* Device interrupt */ + /* Per-channel interrupts */ + { SYS_RES_IRQ, 1, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL }, + { -1, 0 } +}; + +static struct resource_spec mac_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* MAC regs */ + { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* PCS regs */ + { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* Rx/Tx regs */ + { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* Integration regs */ + { SYS_RES_MEMORY, 4, RF_ACTIVE }, /* Integration regs */ + { SYS_RES_IRQ, 0, RF_ACTIVE }, /* Device interrupt */ + /* Per-channel and auto-negotiation interrupts */ + { SYS_RES_IRQ, 1, RF_ACTIVE }, + { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 4, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_IRQ, 5, RF_ACTIVE | RF_OPTIONAL }, + { -1, 0 } +}; + +MALLOC_DEFINE(M_AXGBE, "axgbe", "axgbe data"); + +static void +axgbe_init(void *p) +{ + struct axgbe_softc *sc; + struct ifnet *ifp; + + sc = p; + ifp = sc->prv.netdev; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + return; + + ifp->if_drv_flags |= IFF_DRV_RUNNING; +} + +static int +axgbe_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) +{ + struct axgbe_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *)data; + int error; + + switch(command) { + case SIOCSIFMTU: + if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU_JUMBO) + error = EINVAL; + else + error = xgbe_change_mtu(ifp, ifr->ifr_mtu); + break; + case SIOCSIFFLAGS: + error = 0; + break; + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &sc->media, command); + break; + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + +static void +axgbe_qflush(struct ifnet *ifp) +{ + + if_qflush(ifp); +} + +static int +axgbe_media_change(struct ifnet *ifp) +{ + struct axgbe_softc *sc; + int cur_media; + + sc = ifp->if_softc; + + sx_xlock(&sc->prv.an_mutex); + cur_media = sc->media.ifm_cur->ifm_media; + + switch (IFM_SUBTYPE(cur_media)) { + case IFM_10G_KR: + sc->prv.phy.speed = SPEED_10000; + sc->prv.phy.autoneg = AUTONEG_DISABLE; + break; + case IFM_2500_KX: + sc->prv.phy.speed = SPEED_2500; + sc->prv.phy.autoneg = AUTONEG_DISABLE; + break; + case IFM_1000_KX: + sc->prv.phy.speed = SPEED_1000; + sc->prv.phy.autoneg = AUTONEG_DISABLE; + break; + case IFM_AUTO: + sc->prv.phy.autoneg = AUTONEG_ENABLE; + break; + } + sx_xunlock(&sc->prv.an_mutex); + + return (-sc->prv.phy_if.phy_config_aneg(&sc->prv)); +} + +static void +axgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct axgbe_softc *sc; + + sc = ifp->if_softc; + + ifmr->ifm_status = IFM_AVALID; + if (!sc->prv.phy.link) + return; + + ifmr->ifm_status |= IFM_ACTIVE; + ifmr->ifm_active = IFM_ETHER; + + if (sc->prv.phy.duplex == DUPLEX_FULL) + ifmr->ifm_active |= IFM_FDX; + else + ifmr->ifm_active |= IFM_HDX; + + switch (sc->prv.phy.speed) { + case SPEED_10000: + ifmr->ifm_active |= IFM_10G_KR; + break; + case SPEED_2500: + ifmr->ifm_active |= IFM_2500_KX; + break; + case SPEED_1000: + ifmr->ifm_active |= IFM_1000_KX; + break; + } +} + +static uint64_t +axgbe_get_counter(struct ifnet *ifp, ift_counter c) +{ + struct xgbe_prv_data *pdata = ifp->if_softc; + struct xgbe_mmc_stats *pstats = &pdata->mmc_stats; + + DBGPR("-->%s\n", __func__); + + pdata->hw_if.read_mmc_stats(pdata); + + switch(c) { + case IFCOUNTER_IPACKETS: + return (pstats->rxframecount_gb); + case IFCOUNTER_IERRORS: + return (pstats->rxframecount_gb - + pstats->rxbroadcastframes_g - + pstats->rxmulticastframes_g - + pstats->rxunicastframes_g); + case IFCOUNTER_OPACKETS: + return (pstats->txframecount_gb); + case IFCOUNTER_OERRORS: + return (pstats->txframecount_gb - pstats->txframecount_g); + case IFCOUNTER_IBYTES: + return (pstats->rxoctetcount_gb); + case IFCOUNTER_OBYTES: + return (pstats->txoctetcount_gb); + default: + return (if_get_counter_default(ifp, c)); + } +} + +static int +axgbe_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "AMD 10 Gigabit Ethernet"); + return (BUS_PROBE_DEFAULT); +} + +static int +axgbe_get_optional_prop(device_t dev, phandle_t node, const char *name, + int *data, size_t len) +{ + + if (!OF_hasprop(node, name)) + return (-1); + + if (OF_getencprop(node, name, data, len) <= 0) { + device_printf(dev,"%s property is invalid\n", name); + return (ENXIO); + } + + return (0); +} + +static int +axgbe_attach(device_t dev) +{ + struct axgbe_softc *sc; + struct ifnet *ifp; + pcell_t phy_handle; + device_t phydev; + phandle_t node, phy_node; + struct resource *mac_res[11]; + struct resource *phy_res[4]; + ssize_t len; + int error, i, j; + + sc = device_get_softc(dev); + + node = ofw_bus_get_node(dev); + if (OF_getencprop(node, "phy-handle", &phy_handle, + sizeof(phy_handle)) <= 0) { + phy_node = node; + + if (bus_alloc_resources(dev, mac_spec, mac_res)) { + device_printf(dev, + "could not allocate phy resources\n"); + return (ENXIO); + } + + sc->prv.xgmac_res = mac_res[0]; + sc->prv.xpcs_res = mac_res[1]; + sc->prv.rxtx_res = mac_res[2]; + sc->prv.sir0_res = mac_res[3]; + sc->prv.sir1_res = mac_res[4]; + + sc->prv.dev_irq_res = mac_res[5]; + sc->prv.per_channel_irq = OF_hasprop(node, + XGBE_DMA_IRQS_PROPERTY); + for (i = 0, j = 6; j < nitems(mac_res) - 1 && + mac_res[j + 1] != NULL; i++, j++) { + if (sc->prv.per_channel_irq) { + sc->prv.chan_irq_res[i] = mac_res[j]; + } + } + + /* The last entry is the auto-negotiation interrupt */ + sc->prv.an_irq_res = mac_res[j]; + } else { + phydev = OF_device_from_xref(phy_handle); + phy_node = ofw_bus_get_node(phydev); + + if (bus_alloc_resources(phydev, old_phy_spec, phy_res)) { + device_printf(dev, + "could not allocate phy resources\n"); + return (ENXIO); + } + + if (bus_alloc_resources(dev, old_mac_spec, mac_res)) { + device_printf(dev, + "could not allocate mac resources\n"); + return (ENXIO); + } + + sc->prv.rxtx_res = phy_res[0]; + sc->prv.sir0_res = phy_res[1]; + sc->prv.sir1_res = phy_res[2]; + sc->prv.an_irq_res = phy_res[3]; + + sc->prv.xgmac_res = mac_res[0]; + sc->prv.xpcs_res = mac_res[1]; + sc->prv.dev_irq_res = mac_res[2]; + sc->prv.per_channel_irq = OF_hasprop(node, + XGBE_DMA_IRQS_PROPERTY); + if (sc->prv.per_channel_irq) { + for (i = 0, j = 3; i < nitems(sc->prv.chan_irq_res) && + mac_res[j] != NULL; i++, j++) { + sc->prv.chan_irq_res[i] = mac_res[j]; + } + } + } + + if ((len = OF_getproplen(node, "mac-address")) < 0) { + device_printf(dev, "No mac-address property\n"); + return (EINVAL); + } + + if (len != ETHER_ADDR_LEN) + return (EINVAL); + + OF_getprop(node, "mac-address", sc->mac_addr, ETHER_ADDR_LEN); + + sc->prv.netdev = ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "Cannot alloc ifnet\n"); + return (ENXIO); + } + + sc->prv.dev = dev; + sc->prv.dmat = bus_get_dma_tag(dev); + sc->prv.phy.advertising = ADVERTISED_10000baseKR_Full | + ADVERTISED_1000baseKX_Full; + + + /* + * Read the needed properties from the phy node. + */ + + /* This is documented as optional, but Linux requires it */ + if (OF_getencprop(phy_node, XGBE_SPEEDSET_PROPERTY, &sc->prv.speed_set, + sizeof(sc->prv.speed_set)) <= 0) { + device_printf(dev, "%s property is missing\n", + XGBE_SPEEDSET_PROPERTY); + return (EINVAL); + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_BLWC_PROPERTY, + sc->prv.serdes_blwc, sizeof(sc->prv.serdes_blwc)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_blwc[0] = XGBE_SPEED_1000_BLWC; + sc->prv.serdes_blwc[1] = XGBE_SPEED_2500_BLWC; + sc->prv.serdes_blwc[2] = XGBE_SPEED_10000_BLWC; + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_CDR_RATE_PROPERTY, + sc->prv.serdes_cdr_rate, sizeof(sc->prv.serdes_cdr_rate)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_cdr_rate[0] = XGBE_SPEED_1000_CDR; + sc->prv.serdes_cdr_rate[1] = XGBE_SPEED_2500_CDR; + sc->prv.serdes_cdr_rate[2] = XGBE_SPEED_10000_CDR; + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_PQ_SKEW_PROPERTY, + sc->prv.serdes_pq_skew, sizeof(sc->prv.serdes_pq_skew)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_pq_skew[0] = XGBE_SPEED_1000_PQ; + sc->prv.serdes_pq_skew[1] = XGBE_SPEED_2500_PQ; + sc->prv.serdes_pq_skew[2] = XGBE_SPEED_10000_PQ; + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_TX_AMP_PROPERTY, + sc->prv.serdes_tx_amp, sizeof(sc->prv.serdes_tx_amp)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_tx_amp[0] = XGBE_SPEED_1000_TXAMP; + sc->prv.serdes_tx_amp[1] = XGBE_SPEED_2500_TXAMP; + sc->prv.serdes_tx_amp[2] = XGBE_SPEED_10000_TXAMP; + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_DFE_CFG_PROPERTY, + sc->prv.serdes_dfe_tap_cfg, sizeof(sc->prv.serdes_dfe_tap_cfg)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_dfe_tap_cfg[0] = XGBE_SPEED_1000_DFE_TAP_CONFIG; + sc->prv.serdes_dfe_tap_cfg[1] = XGBE_SPEED_2500_DFE_TAP_CONFIG; + sc->prv.serdes_dfe_tap_cfg[2] = XGBE_SPEED_10000_DFE_TAP_CONFIG; + } + + error = axgbe_get_optional_prop(dev, phy_node, XGBE_DFE_ENA_PROPERTY, + sc->prv.serdes_dfe_tap_ena, sizeof(sc->prv.serdes_dfe_tap_ena)); + if (error > 0) { + return (error); + } else if (error < 0) { + sc->prv.serdes_dfe_tap_ena[0] = XGBE_SPEED_1000_DFE_TAP_ENABLE; + sc->prv.serdes_dfe_tap_ena[1] = XGBE_SPEED_2500_DFE_TAP_ENABLE; + sc->prv.serdes_dfe_tap_ena[2] = XGBE_SPEED_10000_DFE_TAP_ENABLE; + } + + /* Check if the NIC is DMA coherent */ + sc->prv.coherent = OF_hasprop(node, "dma-coherent"); + if (sc->prv.coherent) { + sc->prv.axdomain = XGBE_DMA_OS_AXDOMAIN; + sc->prv.arcache = XGBE_DMA_OS_ARCACHE; + sc->prv.awcache = XGBE_DMA_OS_AWCACHE; + } else { + sc->prv.axdomain = XGBE_DMA_SYS_AXDOMAIN; + sc->prv.arcache = XGBE_DMA_SYS_ARCACHE; + sc->prv.awcache = XGBE_DMA_SYS_AWCACHE; + } + + /* Create the lock & workqueues */ + spin_lock_init(&sc->prv.xpcs_lock); + sc->prv.dev_workqueue = taskqueue_create("axgbe", M_WAITOK, + taskqueue_thread_enqueue, &sc->prv.dev_workqueue); + taskqueue_start_threads(&sc->prv.dev_workqueue, 1, PI_NET, + "axgbe taskq"); + + /* Set the needed pointers */ + xgbe_init_function_ptrs_phy(&sc->prv.phy_if); + xgbe_init_function_ptrs_dev(&sc->prv.hw_if); + xgbe_init_function_ptrs_desc(&sc->prv.desc_if); + + /* Reset the hardware */ + sc->prv.hw_if.exit(&sc->prv); + + /* Read the hardware features */ + xgbe_get_all_hw_features(&sc->prv); + + /* Set default values */ + sc->prv.pblx8 = DMA_PBL_X8_ENABLE; + sc->prv.tx_desc_count = XGBE_TX_DESC_CNT; + sc->prv.tx_sf_mode = MTL_TSF_ENABLE; + sc->prv.tx_threshold = MTL_TX_THRESHOLD_64; + sc->prv.tx_pbl = DMA_PBL_16; + sc->prv.tx_osp_mode = DMA_OSP_ENABLE; + sc->prv.rx_desc_count = XGBE_RX_DESC_CNT; + sc->prv.rx_sf_mode = MTL_RSF_DISABLE; + sc->prv.rx_threshold = MTL_RX_THRESHOLD_64; + sc->prv.rx_pbl = DMA_PBL_16; + sc->prv.pause_autoneg = 1; + sc->prv.tx_pause = 1; + sc->prv.rx_pause = 1; + sc->prv.phy_speed = SPEED_UNKNOWN; + sc->prv.power_down = 0; + + /* TODO: Limit to min(ncpus, hw rings) */ + sc->prv.tx_ring_count = 1; + sc->prv.tx_q_count = 1; + sc->prv.rx_ring_count = 1; + sc->prv.rx_q_count = sc->prv.hw_feat.rx_q_cnt; + + /* Init the PHY */ + sc->prv.phy_if.phy_init(&sc->prv); + + /* Set the coalescing */ + xgbe_init_rx_coalesce(&sc->prv); + xgbe_init_tx_coalesce(&sc->prv); + + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_init = axgbe_init; + ifp->if_softc = sc; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = axgbe_ioctl; + ifp->if_transmit = xgbe_xmit; + ifp->if_qflush = axgbe_qflush; + ifp->if_get_counter = axgbe_get_counter; + + /* TODO: Support HW offload */ + ifp->if_capabilities = 0; + ifp->if_capenable = 0; + ifp->if_hwassist = 0; + + ether_ifattach(ifp, sc->mac_addr); + + ifmedia_init(&sc->media, IFM_IMASK, axgbe_media_change, + axgbe_media_status); +#ifdef notyet + ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_KR, 0, NULL); +#endif + ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_KX, 0, NULL); + ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO); + + set_bit(XGBE_DOWN, &sc->prv.dev_state); + + if (xgbe_open(ifp) < 0) { + device_printf(dev, "ndo_open failed\n"); + return (ENXIO); + } + + return (0); +} + +static device_method_t axgbe_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, axgbe_probe), + DEVMETHOD(device_attach, axgbe_attach), + + { 0, 0 } +}; + +static devclass_t axgbe_devclass; + +DEFINE_CLASS_0(axgbe, axgbe_driver, axgbe_methods, + sizeof(struct axgbe_softc)); +DRIVER_MODULE(axgbe, simplebus, axgbe_driver, axgbe_devclass, 0, 0); + + +static struct ofw_compat_data phy_compat_data[] = { + { "amd,xgbe-phy-seattle-v1a", true }, + { NULL, false } +}; + +static int +axgbephy_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, phy_compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "AMD 10 Gigabit Ethernet"); + return (BUS_PROBE_DEFAULT); +} + +static int +axgbephy_attach(device_t dev) +{ + phandle_t node; + + node = ofw_bus_get_node(dev); + OF_device_register_xref(OF_xref_from_node(node), dev); + + return (0); +} + +static device_method_t axgbephy_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, axgbephy_probe), + DEVMETHOD(device_attach, axgbephy_attach), + + { 0, 0 } +}; + +static devclass_t axgbephy_devclass; + +DEFINE_CLASS_0(axgbephy, axgbephy_driver, axgbephy_methods, 0); +EARLY_DRIVER_MODULE(axgbephy, simplebus, axgbephy_driver, axgbephy_devclass, + 0, 0, BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/dev/axgbe/xgbe-common.h b/sys/dev/axgbe/xgbe-common.h new file mode 100644 index 000000000000..bc081352bf53 --- /dev/null +++ b/sys/dev/axgbe/xgbe-common.h @@ -0,0 +1,1310 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014-2016 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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 __XGBE_COMMON_H__ +#define __XGBE_COMMON_H__ + +#include <sys/bus.h> +#include <sys/rman.h> + +/* DMA register offsets */ +#define DMA_MR 0x3000 +#define DMA_SBMR 0x3004 +#define DMA_ISR 0x3008 +#define DMA_AXIARCR 0x3010 +#define DMA_AXIAWCR 0x3018 +#define DMA_DSR0 0x3020 +#define DMA_DSR1 0x3024 + +/* DMA register entry bit positions and sizes */ +#define DMA_AXIARCR_DRC_INDEX 0 +#define DMA_AXIARCR_DRC_WIDTH 4 +#define DMA_AXIARCR_DRD_INDEX 4 +#define DMA_AXIARCR_DRD_WIDTH 2 +#define DMA_AXIARCR_TEC_INDEX 8 +#define DMA_AXIARCR_TEC_WIDTH 4 +#define DMA_AXIARCR_TED_INDEX 12 +#define DMA_AXIARCR_TED_WIDTH 2 +#define DMA_AXIARCR_THC_INDEX 16 +#define DMA_AXIARCR_THC_WIDTH 4 +#define DMA_AXIARCR_THD_INDEX 20 +#define DMA_AXIARCR_THD_WIDTH 2 +#define DMA_AXIAWCR_DWC_INDEX 0 +#define DMA_AXIAWCR_DWC_WIDTH 4 +#define DMA_AXIAWCR_DWD_INDEX 4 +#define DMA_AXIAWCR_DWD_WIDTH 2 +#define DMA_AXIAWCR_RPC_INDEX 8 +#define DMA_AXIAWCR_RPC_WIDTH 4 +#define DMA_AXIAWCR_RPD_INDEX 12 +#define DMA_AXIAWCR_RPD_WIDTH 2 +#define DMA_AXIAWCR_RHC_INDEX 16 +#define DMA_AXIAWCR_RHC_WIDTH 4 +#define DMA_AXIAWCR_RHD_INDEX 20 +#define DMA_AXIAWCR_RHD_WIDTH 2 +#define DMA_AXIAWCR_TDC_INDEX 24 +#define DMA_AXIAWCR_TDC_WIDTH 4 +#define DMA_AXIAWCR_TDD_INDEX 28 +#define DMA_AXIAWCR_TDD_WIDTH 2 +#define DMA_ISR_MACIS_INDEX 17 +#define DMA_ISR_MACIS_WIDTH 1 +#define DMA_ISR_MTLIS_INDEX 16 +#define DMA_ISR_MTLIS_WIDTH 1 +#define DMA_MR_SWR_INDEX 0 +#define DMA_MR_SWR_WIDTH 1 +#define DMA_SBMR_EAME_INDEX 11 +#define DMA_SBMR_EAME_WIDTH 1 +#define DMA_SBMR_BLEN_256_INDEX 7 +#define DMA_SBMR_BLEN_256_WIDTH 1 +#define DMA_SBMR_UNDEF_INDEX 0 +#define DMA_SBMR_UNDEF_WIDTH 1 + +/* DMA register values */ +#define DMA_DSR_RPS_WIDTH 4 +#define DMA_DSR_TPS_WIDTH 4 +#define DMA_DSR_Q_WIDTH (DMA_DSR_RPS_WIDTH + DMA_DSR_TPS_WIDTH) +#define DMA_DSR0_RPS_START 8 +#define DMA_DSR0_TPS_START 12 +#define DMA_DSRX_FIRST_QUEUE 3 +#define DMA_DSRX_INC 4 +#define DMA_DSRX_QPR 4 +#define DMA_DSRX_RPS_START 0 +#define DMA_DSRX_TPS_START 4 +#define DMA_TPS_STOPPED 0x00 +#define DMA_TPS_SUSPENDED 0x06 + +/* DMA channel register offsets + * Multiple channels can be active. The first channel has registers + * that begin at 0x3100. Each subsequent channel has registers that + * are accessed using an offset of 0x80 from the previous channel. + */ +#define DMA_CH_BASE 0x3100 +#define DMA_CH_INC 0x80 + +#define DMA_CH_CR 0x00 +#define DMA_CH_TCR 0x04 +#define DMA_CH_RCR 0x08 +#define DMA_CH_TDLR_HI 0x10 +#define DMA_CH_TDLR_LO 0x14 +#define DMA_CH_RDLR_HI 0x18 +#define DMA_CH_RDLR_LO 0x1c +#define DMA_CH_TDTR_LO 0x24 +#define DMA_CH_RDTR_LO 0x2c +#define DMA_CH_TDRLR 0x30 +#define DMA_CH_RDRLR 0x34 +#define DMA_CH_IER 0x38 +#define DMA_CH_RIWT 0x3c +#define DMA_CH_CATDR_LO 0x44 +#define DMA_CH_CARDR_LO 0x4c +#define DMA_CH_CATBR_HI 0x50 +#define DMA_CH_CATBR_LO 0x54 +#define DMA_CH_CARBR_HI 0x58 +#define DMA_CH_CARBR_LO 0x5c +#define DMA_CH_SR 0x60 + +/* DMA channel register entry bit positions and sizes */ +#define DMA_CH_CR_PBLX8_INDEX 16 +#define DMA_CH_CR_PBLX8_WIDTH 1 +#define DMA_CH_CR_SPH_INDEX 24 +#define DMA_CH_CR_SPH_WIDTH 1 +#define DMA_CH_IER_AIE_INDEX 15 +#define DMA_CH_IER_AIE_WIDTH 1 +#define DMA_CH_IER_FBEE_INDEX 12 +#define DMA_CH_IER_FBEE_WIDTH 1 +#define DMA_CH_IER_NIE_INDEX 16 +#define DMA_CH_IER_NIE_WIDTH 1 +#define DMA_CH_IER_RBUE_INDEX 7 +#define DMA_CH_IER_RBUE_WIDTH 1 +#define DMA_CH_IER_RIE_INDEX 6 +#define DMA_CH_IER_RIE_WIDTH 1 +#define DMA_CH_IER_RSE_INDEX 8 +#define DMA_CH_IER_RSE_WIDTH 1 +#define DMA_CH_IER_TBUE_INDEX 2 +#define DMA_CH_IER_TBUE_WIDTH 1 +#define DMA_CH_IER_TIE_INDEX 0 +#define DMA_CH_IER_TIE_WIDTH 1 +#define DMA_CH_IER_TXSE_INDEX 1 +#define DMA_CH_IER_TXSE_WIDTH 1 +#define DMA_CH_RCR_PBL_INDEX 16 +#define DMA_CH_RCR_PBL_WIDTH 6 +#define DMA_CH_RCR_RBSZ_INDEX 1 +#define DMA_CH_RCR_RBSZ_WIDTH 14 +#define DMA_CH_RCR_SR_INDEX 0 +#define DMA_CH_RCR_SR_WIDTH 1 +#define DMA_CH_RIWT_RWT_INDEX 0 +#define DMA_CH_RIWT_RWT_WIDTH 8 +#define DMA_CH_SR_FBE_INDEX 12 +#define DMA_CH_SR_FBE_WIDTH 1 +#define DMA_CH_SR_RBU_INDEX 7 +#define DMA_CH_SR_RBU_WIDTH 1 +#define DMA_CH_SR_RI_INDEX 6 +#define DMA_CH_SR_RI_WIDTH 1 +#define DMA_CH_SR_RPS_INDEX 8 +#define DMA_CH_SR_RPS_WIDTH 1 +#define DMA_CH_SR_TBU_INDEX 2 +#define DMA_CH_SR_TBU_WIDTH 1 +#define DMA_CH_SR_TI_INDEX 0 +#define DMA_CH_SR_TI_WIDTH 1 +#define DMA_CH_SR_TPS_INDEX 1 +#define DMA_CH_SR_TPS_WIDTH 1 +#define DMA_CH_TCR_OSP_INDEX 4 +#define DMA_CH_TCR_OSP_WIDTH 1 +#define DMA_CH_TCR_PBL_INDEX 16 +#define DMA_CH_TCR_PBL_WIDTH 6 +#define DMA_CH_TCR_ST_INDEX 0 +#define DMA_CH_TCR_ST_WIDTH 1 +#define DMA_CH_TCR_TSE_INDEX 12 +#define DMA_CH_TCR_TSE_WIDTH 1 + +/* DMA channel register values */ +#define DMA_OSP_DISABLE 0x00 +#define DMA_OSP_ENABLE 0x01 +#define DMA_PBL_1 1 +#define DMA_PBL_2 2 +#define DMA_PBL_4 4 +#define DMA_PBL_8 8 +#define DMA_PBL_16 16 +#define DMA_PBL_32 32 +#define DMA_PBL_64 64 /* 8 x 8 */ +#define DMA_PBL_128 128 /* 8 x 16 */ +#define DMA_PBL_256 256 /* 8 x 32 */ +#define DMA_PBL_X8_DISABLE 0x00 +#define DMA_PBL_X8_ENABLE 0x01 + +/* MAC register offsets */ +#define MAC_TCR 0x0000 +#define MAC_RCR 0x0004 +#define MAC_PFR 0x0008 +#define MAC_WTR 0x000c +#define MAC_HTR0 0x0010 +#define MAC_VLANTR 0x0050 +#define MAC_VLANHTR 0x0058 +#define MAC_VLANIR 0x0060 +#define MAC_IVLANIR 0x0064 +#define MAC_RETMR 0x006c +#define MAC_Q0TFCR 0x0070 +#define MAC_RFCR 0x0090 +#define MAC_RQC0R 0x00a0 +#define MAC_RQC1R 0x00a4 +#define MAC_RQC2R 0x00a8 +#define MAC_RQC3R 0x00ac +#define MAC_ISR 0x00b0 +#define MAC_IER 0x00b4 +#define MAC_RTSR 0x00b8 +#define MAC_PMTCSR 0x00c0 +#define MAC_RWKPFR 0x00c4 +#define MAC_LPICSR 0x00d0 +#define MAC_LPITCR 0x00d4 +#define MAC_VR 0x0110 +#define MAC_DR 0x0114 +#define MAC_HWF0R 0x011c +#define MAC_HWF1R 0x0120 +#define MAC_HWF2R 0x0124 +#define MAC_GPIOCR 0x0278 +#define MAC_GPIOSR 0x027c +#define MAC_MACA0HR 0x0300 +#define MAC_MACA0LR 0x0304 +#define MAC_MACA1HR 0x0308 +#define MAC_MACA1LR 0x030c +#define MAC_RSSCR 0x0c80 +#define MAC_RSSAR 0x0c88 +#define MAC_RSSDR 0x0c8c +#define MAC_TSCR 0x0d00 +#define MAC_SSIR 0x0d04 +#define MAC_STSR 0x0d08 +#define MAC_STNR 0x0d0c +#define MAC_STSUR 0x0d10 +#define MAC_STNUR 0x0d14 +#define MAC_TSAR 0x0d18 +#define MAC_TSSR 0x0d20 +#define MAC_TXSNR 0x0d30 +#define MAC_TXSSR 0x0d34 + +#define MAC_QTFCR_INC 4 +#define MAC_MACA_INC 4 +#define MAC_HTR_INC 4 + +#define MAC_RQC2_INC 4 +#define MAC_RQC2_Q_PER_REG 4 + +/* MAC register entry bit positions and sizes */ +#define MAC_HWF0R_ADDMACADRSEL_INDEX 18 +#define MAC_HWF0R_ADDMACADRSEL_WIDTH 5 +#define MAC_HWF0R_ARPOFFSEL_INDEX 9 +#define MAC_HWF0R_ARPOFFSEL_WIDTH 1 +#define MAC_HWF0R_EEESEL_INDEX 13 +#define MAC_HWF0R_EEESEL_WIDTH 1 +#define MAC_HWF0R_GMIISEL_INDEX 1 +#define MAC_HWF0R_GMIISEL_WIDTH 1 +#define MAC_HWF0R_MGKSEL_INDEX 7 +#define MAC_HWF0R_MGKSEL_WIDTH 1 +#define MAC_HWF0R_MMCSEL_INDEX 8 +#define MAC_HWF0R_MMCSEL_WIDTH 1 +#define MAC_HWF0R_RWKSEL_INDEX 6 +#define MAC_HWF0R_RWKSEL_WIDTH 1 +#define MAC_HWF0R_RXCOESEL_INDEX 16 +#define MAC_HWF0R_RXCOESEL_WIDTH 1 +#define MAC_HWF0R_SAVLANINS_INDEX 27 +#define MAC_HWF0R_SAVLANINS_WIDTH 1 +#define MAC_HWF0R_SMASEL_INDEX 5 +#define MAC_HWF0R_SMASEL_WIDTH 1 +#define MAC_HWF0R_TSSEL_INDEX 12 +#define MAC_HWF0R_TSSEL_WIDTH 1 +#define MAC_HWF0R_TSSTSSEL_INDEX 25 +#define MAC_HWF0R_TSSTSSEL_WIDTH 2 +#define MAC_HWF0R_TXCOESEL_INDEX 14 +#define MAC_HWF0R_TXCOESEL_WIDTH 1 +#define MAC_HWF0R_VLHASH_INDEX 4 +#define MAC_HWF0R_VLHASH_WIDTH 1 +#define MAC_HWF1R_ADDR64_INDEX 14 +#define MAC_HWF1R_ADDR64_WIDTH 2 +#define MAC_HWF1R_ADVTHWORD_INDEX 13 +#define MAC_HWF1R_ADVTHWORD_WIDTH 1 +#define MAC_HWF1R_DBGMEMA_INDEX 19 +#define MAC_HWF1R_DBGMEMA_WIDTH 1 +#define MAC_HWF1R_DCBEN_INDEX 16 +#define MAC_HWF1R_DCBEN_WIDTH 1 +#define MAC_HWF1R_HASHTBLSZ_INDEX 24 +#define MAC_HWF1R_HASHTBLSZ_WIDTH 3 +#define MAC_HWF1R_L3L4FNUM_INDEX 27 +#define MAC_HWF1R_L3L4FNUM_WIDTH 4 +#define MAC_HWF1R_NUMTC_INDEX 21 +#define MAC_HWF1R_NUMTC_WIDTH 3 +#define MAC_HWF1R_RSSEN_INDEX 20 +#define MAC_HWF1R_RSSEN_WIDTH 1 +#define MAC_HWF1R_RXFIFOSIZE_INDEX 0 +#define MAC_HWF1R_RXFIFOSIZE_WIDTH 5 +#define MAC_HWF1R_SPHEN_INDEX 17 +#define MAC_HWF1R_SPHEN_WIDTH 1 +#define MAC_HWF1R_TSOEN_INDEX 18 +#define MAC_HWF1R_TSOEN_WIDTH 1 +#define MAC_HWF1R_TXFIFOSIZE_INDEX 6 +#define MAC_HWF1R_TXFIFOSIZE_WIDTH 5 +#define MAC_HWF2R_AUXSNAPNUM_INDEX 28 +#define MAC_HWF2R_AUXSNAPNUM_WIDTH 3 +#define MAC_HWF2R_PPSOUTNUM_INDEX 24 +#define MAC_HWF2R_PPSOUTNUM_WIDTH 3 +#define MAC_HWF2R_RXCHCNT_INDEX 12 +#define MAC_HWF2R_RXCHCNT_WIDTH 4 +#define MAC_HWF2R_RXQCNT_INDEX 0 +#define MAC_HWF2R_RXQCNT_WIDTH 4 +#define MAC_HWF2R_TXCHCNT_INDEX 18 +#define MAC_HWF2R_TXCHCNT_WIDTH 4 +#define MAC_HWF2R_TXQCNT_INDEX 6 +#define MAC_HWF2R_TXQCNT_WIDTH 4 +#define MAC_IER_TSIE_INDEX 12 +#define MAC_IER_TSIE_WIDTH 1 +#define MAC_ISR_MMCRXIS_INDEX 9 +#define MAC_ISR_MMCRXIS_WIDTH 1 +#define MAC_ISR_MMCTXIS_INDEX 10 +#define MAC_ISR_MMCTXIS_WIDTH 1 +#define MAC_ISR_PMTIS_INDEX 4 +#define MAC_ISR_PMTIS_WIDTH 1 +#define MAC_ISR_TSIS_INDEX 12 +#define MAC_ISR_TSIS_WIDTH 1 +#define MAC_MACA1HR_AE_INDEX 31 +#define MAC_MACA1HR_AE_WIDTH 1 +#define MAC_PFR_HMC_INDEX 2 +#define MAC_PFR_HMC_WIDTH 1 +#define MAC_PFR_HPF_INDEX 10 +#define MAC_PFR_HPF_WIDTH 1 +#define MAC_PFR_HUC_INDEX 1 +#define MAC_PFR_HUC_WIDTH 1 +#define MAC_PFR_PM_INDEX 4 +#define MAC_PFR_PM_WIDTH 1 +#define MAC_PFR_PR_INDEX 0 +#define MAC_PFR_PR_WIDTH 1 +#define MAC_PFR_VTFE_INDEX 16 +#define MAC_PFR_VTFE_WIDTH 1 +#define MAC_PMTCSR_MGKPKTEN_INDEX 1 +#define MAC_PMTCSR_MGKPKTEN_WIDTH 1 +#define MAC_PMTCSR_PWRDWN_INDEX 0 +#define MAC_PMTCSR_PWRDWN_WIDTH 1 +#define MAC_PMTCSR_RWKFILTRST_INDEX 31 +#define MAC_PMTCSR_RWKFILTRST_WIDTH 1 +#define MAC_PMTCSR_RWKPKTEN_INDEX 2 +#define MAC_PMTCSR_RWKPKTEN_WIDTH 1 +#define MAC_Q0TFCR_PT_INDEX 16 +#define MAC_Q0TFCR_PT_WIDTH 16 +#define MAC_Q0TFCR_TFE_INDEX 1 +#define MAC_Q0TFCR_TFE_WIDTH 1 +#define MAC_RCR_ACS_INDEX 1 +#define MAC_RCR_ACS_WIDTH 1 +#define MAC_RCR_CST_INDEX 2 +#define MAC_RCR_CST_WIDTH 1 +#define MAC_RCR_DCRCC_INDEX 3 +#define MAC_RCR_DCRCC_WIDTH 1 +#define MAC_RCR_HDSMS_INDEX 12 +#define MAC_RCR_HDSMS_WIDTH 3 +#define MAC_RCR_IPC_INDEX 9 +#define MAC_RCR_IPC_WIDTH 1 +#define MAC_RCR_JE_INDEX 8 +#define MAC_RCR_JE_WIDTH 1 +#define MAC_RCR_LM_INDEX 10 +#define MAC_RCR_LM_WIDTH 1 +#define MAC_RCR_RE_INDEX 0 +#define MAC_RCR_RE_WIDTH 1 +#define MAC_RFCR_PFCE_INDEX 8 +#define MAC_RFCR_PFCE_WIDTH 1 +#define MAC_RFCR_RFE_INDEX 0 +#define MAC_RFCR_RFE_WIDTH 1 +#define MAC_RFCR_UP_INDEX 1 +#define MAC_RFCR_UP_WIDTH 1 +#define MAC_RQC0R_RXQ0EN_INDEX 0 +#define MAC_RQC0R_RXQ0EN_WIDTH 2 +#define MAC_RSSAR_ADDRT_INDEX 2 +#define MAC_RSSAR_ADDRT_WIDTH 1 +#define MAC_RSSAR_CT_INDEX 1 +#define MAC_RSSAR_CT_WIDTH 1 +#define MAC_RSSAR_OB_INDEX 0 +#define MAC_RSSAR_OB_WIDTH 1 +#define MAC_RSSAR_RSSIA_INDEX 8 +#define MAC_RSSAR_RSSIA_WIDTH 8 +#define MAC_RSSCR_IP2TE_INDEX 1 +#define MAC_RSSCR_IP2TE_WIDTH 1 +#define MAC_RSSCR_RSSE_INDEX 0 +#define MAC_RSSCR_RSSE_WIDTH 1 +#define MAC_RSSCR_TCP4TE_INDEX 2 +#define MAC_RSSCR_TCP4TE_WIDTH 1 +#define MAC_RSSCR_UDP4TE_INDEX 3 +#define MAC_RSSCR_UDP4TE_WIDTH 1 +#define MAC_RSSDR_DMCH_INDEX 0 +#define MAC_RSSDR_DMCH_WIDTH 4 +#define MAC_SSIR_SNSINC_INDEX 8 +#define MAC_SSIR_SNSINC_WIDTH 8 +#define MAC_SSIR_SSINC_INDEX 16 +#define MAC_SSIR_SSINC_WIDTH 8 +#define MAC_TCR_SS_INDEX 29 +#define MAC_TCR_SS_WIDTH 2 +#define MAC_TCR_TE_INDEX 0 +#define MAC_TCR_TE_WIDTH 1 +#define MAC_TSCR_AV8021ASMEN_INDEX 28 +#define MAC_TSCR_AV8021ASMEN_WIDTH 1 +#define MAC_TSCR_SNAPTYPSEL_INDEX 16 +#define MAC_TSCR_SNAPTYPSEL_WIDTH 2 +#define MAC_TSCR_TSADDREG_INDEX 5 +#define MAC_TSCR_TSADDREG_WIDTH 1 +#define MAC_TSCR_TSCFUPDT_INDEX 1 +#define MAC_TSCR_TSCFUPDT_WIDTH 1 +#define MAC_TSCR_TSCTRLSSR_INDEX 9 +#define MAC_TSCR_TSCTRLSSR_WIDTH 1 +#define MAC_TSCR_TSENA_INDEX 0 +#define MAC_TSCR_TSENA_WIDTH 1 +#define MAC_TSCR_TSENALL_INDEX 8 +#define MAC_TSCR_TSENALL_WIDTH 1 +#define MAC_TSCR_TSEVNTENA_INDEX 14 +#define MAC_TSCR_TSEVNTENA_WIDTH 1 +#define MAC_TSCR_TSINIT_INDEX 2 +#define MAC_TSCR_TSINIT_WIDTH 1 +#define MAC_TSCR_TSIPENA_INDEX 11 +#define MAC_TSCR_TSIPENA_WIDTH 1 +#define MAC_TSCR_TSIPV4ENA_INDEX 13 +#define MAC_TSCR_TSIPV4ENA_WIDTH 1 +#define MAC_TSCR_TSIPV6ENA_INDEX 12 +#define MAC_TSCR_TSIPV6ENA_WIDTH 1 +#define MAC_TSCR_TSMSTRENA_INDEX 15 +#define MAC_TSCR_TSMSTRENA_WIDTH 1 +#define MAC_TSCR_TSVER2ENA_INDEX 10 +#define MAC_TSCR_TSVER2ENA_WIDTH 1 +#define MAC_TSCR_TXTSSTSM_INDEX 24 +#define MAC_TSCR_TXTSSTSM_WIDTH 1 +#define MAC_TSSR_TXTSC_INDEX 15 +#define MAC_TSSR_TXTSC_WIDTH 1 +#define MAC_TXSNR_TXTSSTSMIS_INDEX 31 +#define MAC_TXSNR_TXTSSTSMIS_WIDTH 1 +#define MAC_VLANHTR_VLHT_INDEX 0 +#define MAC_VLANHTR_VLHT_WIDTH 16 +#define MAC_VLANIR_VLTI_INDEX 20 +#define MAC_VLANIR_VLTI_WIDTH 1 +#define MAC_VLANIR_CSVL_INDEX 19 +#define MAC_VLANIR_CSVL_WIDTH 1 +#define MAC_VLANTR_DOVLTC_INDEX 20 +#define MAC_VLANTR_DOVLTC_WIDTH 1 +#define MAC_VLANTR_ERSVLM_INDEX 19 +#define MAC_VLANTR_ERSVLM_WIDTH 1 +#define MAC_VLANTR_ESVL_INDEX 18 +#define MAC_VLANTR_ESVL_WIDTH 1 +#define MAC_VLANTR_ETV_INDEX 16 +#define MAC_VLANTR_ETV_WIDTH 1 +#define MAC_VLANTR_EVLS_INDEX 21 +#define MAC_VLANTR_EVLS_WIDTH 2 +#define MAC_VLANTR_EVLRXS_INDEX 24 +#define MAC_VLANTR_EVLRXS_WIDTH 1 +#define MAC_VLANTR_VL_INDEX 0 +#define MAC_VLANTR_VL_WIDTH 16 +#define MAC_VLANTR_VTHM_INDEX 25 +#define MAC_VLANTR_VTHM_WIDTH 1 +#define MAC_VLANTR_VTIM_INDEX 17 +#define MAC_VLANTR_VTIM_WIDTH 1 +#define MAC_VR_DEVID_INDEX 8 +#define MAC_VR_DEVID_WIDTH 8 +#define MAC_VR_SNPSVER_INDEX 0 +#define MAC_VR_SNPSVER_WIDTH 8 +#define MAC_VR_USERVER_INDEX 16 +#define MAC_VR_USERVER_WIDTH 8 + +/* MMC register offsets */ +#define MMC_CR 0x0800 +#define MMC_RISR 0x0804 +#define MMC_TISR 0x0808 +#define MMC_RIER 0x080c +#define MMC_TIER 0x0810 +#define MMC_TXOCTETCOUNT_GB_LO 0x0814 +#define MMC_TXOCTETCOUNT_GB_HI 0x0818 +#define MMC_TXFRAMECOUNT_GB_LO 0x081c +#define MMC_TXFRAMECOUNT_GB_HI 0x0820 +#define MMC_TXBROADCASTFRAMES_G_LO 0x0824 +#define MMC_TXBROADCASTFRAMES_G_HI 0x0828 +#define MMC_TXMULTICASTFRAMES_G_LO 0x082c +#define MMC_TXMULTICASTFRAMES_G_HI 0x0830 +#define MMC_TX64OCTETS_GB_LO 0x0834 +#define MMC_TX64OCTETS_GB_HI 0x0838 +#define MMC_TX65TO127OCTETS_GB_LO 0x083c +#define MMC_TX65TO127OCTETS_GB_HI 0x0840 +#define MMC_TX128TO255OCTETS_GB_LO 0x0844 +#define MMC_TX128TO255OCTETS_GB_HI 0x0848 +#define MMC_TX256TO511OCTETS_GB_LO 0x084c +#define MMC_TX256TO511OCTETS_GB_HI 0x0850 +#define MMC_TX512TO1023OCTETS_GB_LO 0x0854 +#define MMC_TX512TO1023OCTETS_GB_HI 0x0858 +#define MMC_TX1024TOMAXOCTETS_GB_LO 0x085c +#define MMC_TX1024TOMAXOCTETS_GB_HI 0x0860 +#define MMC_TXUNICASTFRAMES_GB_LO 0x0864 +#define MMC_TXUNICASTFRAMES_GB_HI 0x0868 +#define MMC_TXMULTICASTFRAMES_GB_LO 0x086c +#define MMC_TXMULTICASTFRAMES_GB_HI 0x0870 +#define MMC_TXBROADCASTFRAMES_GB_LO 0x0874 +#define MMC_TXBROADCASTFRAMES_GB_HI 0x0878 +#define MMC_TXUNDERFLOWERROR_LO 0x087c +#define MMC_TXUNDERFLOWERROR_HI 0x0880 +#define MMC_TXOCTETCOUNT_G_LO 0x0884 +#define MMC_TXOCTETCOUNT_G_HI 0x0888 +#define MMC_TXFRAMECOUNT_G_LO 0x088c +#define MMC_TXFRAMECOUNT_G_HI 0x0890 +#define MMC_TXPAUSEFRAMES_LO 0x0894 +#define MMC_TXPAUSEFRAMES_HI 0x0898 +#define MMC_TXVLANFRAMES_G_LO 0x089c +#define MMC_TXVLANFRAMES_G_HI 0x08a0 +#define MMC_RXFRAMECOUNT_GB_LO 0x0900 +#define MMC_RXFRAMECOUNT_GB_HI 0x0904 +#define MMC_RXOCTETCOUNT_GB_LO 0x0908 +#define MMC_RXOCTETCOUNT_GB_HI 0x090c +#define MMC_RXOCTETCOUNT_G_LO 0x0910 +#define MMC_RXOCTETCOUNT_G_HI 0x0914 +#define MMC_RXBROADCASTFRAMES_G_LO 0x0918 +#define MMC_RXBROADCASTFRAMES_G_HI 0x091c +#define MMC_RXMULTICASTFRAMES_G_LO 0x0920 +#define MMC_RXMULTICASTFRAMES_G_HI 0x0924 +#define MMC_RXCRCERROR_LO 0x0928 +#define MMC_RXCRCERROR_HI 0x092c +#define MMC_RXRUNTERROR 0x0930 +#define MMC_RXJABBERERROR 0x0934 +#define MMC_RXUNDERSIZE_G 0x0938 +#define MMC_RXOVERSIZE_G 0x093c +#define MMC_RX64OCTETS_GB_LO 0x0940 +#define MMC_RX64OCTETS_GB_HI 0x0944 +#define MMC_RX65TO127OCTETS_GB_LO 0x0948 +#define MMC_RX65TO127OCTETS_GB_HI 0x094c +#define MMC_RX128TO255OCTETS_GB_LO 0x0950 +#define MMC_RX128TO255OCTETS_GB_HI 0x0954 +#define MMC_RX256TO511OCTETS_GB_LO 0x0958 +#define MMC_RX256TO511OCTETS_GB_HI 0x095c +#define MMC_RX512TO1023OCTETS_GB_LO 0x0960 +#define MMC_RX512TO1023OCTETS_GB_HI 0x0964 +#define MMC_RX1024TOMAXOCTETS_GB_LO 0x0968 +#define MMC_RX1024TOMAXOCTETS_GB_HI 0x096c +#define MMC_RXUNICASTFRAMES_G_LO 0x0970 +#define MMC_RXUNICASTFRAMES_G_HI 0x0974 +#define MMC_RXLENGTHERROR_LO 0x0978 +#define MMC_RXLENGTHERROR_HI 0x097c +#define MMC_RXOUTOFRANGETYPE_LO 0x0980 +#define MMC_RXOUTOFRANGETYPE_HI 0x0984 +#define MMC_RXPAUSEFRAMES_LO 0x0988 +#define MMC_RXPAUSEFRAMES_HI 0x098c +#define MMC_RXFIFOOVERFLOW_LO 0x0990 +#define MMC_RXFIFOOVERFLOW_HI 0x0994 +#define MMC_RXVLANFRAMES_GB_LO 0x0998 +#define MMC_RXVLANFRAMES_GB_HI 0x099c +#define MMC_RXWATCHDOGERROR 0x09a0 + +/* MMC register entry bit positions and sizes */ +#define MMC_CR_CR_INDEX 0 +#define MMC_CR_CR_WIDTH 1 +#define MMC_CR_CSR_INDEX 1 +#define MMC_CR_CSR_WIDTH 1 +#define MMC_CR_ROR_INDEX 2 +#define MMC_CR_ROR_WIDTH 1 +#define MMC_CR_MCF_INDEX 3 +#define MMC_CR_MCF_WIDTH 1 +#define MMC_CR_MCT_INDEX 4 +#define MMC_CR_MCT_WIDTH 2 +#define MMC_RIER_ALL_INTERRUPTS_INDEX 0 +#define MMC_RIER_ALL_INTERRUPTS_WIDTH 23 +#define MMC_RISR_RXFRAMECOUNT_GB_INDEX 0 +#define MMC_RISR_RXFRAMECOUNT_GB_WIDTH 1 +#define MMC_RISR_RXOCTETCOUNT_GB_INDEX 1 +#define MMC_RISR_RXOCTETCOUNT_GB_WIDTH 1 +#define MMC_RISR_RXOCTETCOUNT_G_INDEX 2 +#define MMC_RISR_RXOCTETCOUNT_G_WIDTH 1 +#define MMC_RISR_RXBROADCASTFRAMES_G_INDEX 3 +#define MMC_RISR_RXBROADCASTFRAMES_G_WIDTH 1 +#define MMC_RISR_RXMULTICASTFRAMES_G_INDEX 4 +#define MMC_RISR_RXMULTICASTFRAMES_G_WIDTH 1 +#define MMC_RISR_RXCRCERROR_INDEX 5 +#define MMC_RISR_RXCRCERROR_WIDTH 1 +#define MMC_RISR_RXRUNTERROR_INDEX 6 +#define MMC_RISR_RXRUNTERROR_WIDTH 1 +#define MMC_RISR_RXJABBERERROR_INDEX 7 +#define MMC_RISR_RXJABBERERROR_WIDTH 1 +#define MMC_RISR_RXUNDERSIZE_G_INDEX 8 +#define MMC_RISR_RXUNDERSIZE_G_WIDTH 1 +#define MMC_RISR_RXOVERSIZE_G_INDEX 9 +#define MMC_RISR_RXOVERSIZE_G_WIDTH 1 +#define MMC_RISR_RX64OCTETS_GB_INDEX 10 +#define MMC_RISR_RX64OCTETS_GB_WIDTH 1 +#define MMC_RISR_RX65TO127OCTETS_GB_INDEX 11 +#define MMC_RISR_RX65TO127OCTETS_GB_WIDTH 1 +#define MMC_RISR_RX128TO255OCTETS_GB_INDEX 12 +#define MMC_RISR_RX128TO255OCTETS_GB_WIDTH 1 +#define MMC_RISR_RX256TO511OCTETS_GB_INDEX 13 +#define MMC_RISR_RX256TO511OCTETS_GB_WIDTH 1 +#define MMC_RISR_RX512TO1023OCTETS_GB_INDEX 14 +#define MMC_RISR_RX512TO1023OCTETS_GB_WIDTH 1 +#define MMC_RISR_RX1024TOMAXOCTETS_GB_INDEX 15 +#define MMC_RISR_RX1024TOMAXOCTETS_GB_WIDTH 1 +#define MMC_RISR_RXUNICASTFRAMES_G_INDEX 16 +#define MMC_RISR_RXUNICASTFRAMES_G_WIDTH 1 +#define MMC_RISR_RXLENGTHERROR_INDEX 17 +#define MMC_RISR_RXLENGTHERROR_WIDTH 1 +#define MMC_RISR_RXOUTOFRANGETYPE_INDEX 18 +#define MMC_RISR_RXOUTOFRANGETYPE_WIDTH 1 +#define MMC_RISR_RXPAUSEFRAMES_INDEX 19 +#define MMC_RISR_RXPAUSEFRAMES_WIDTH 1 +#define MMC_RISR_RXFIFOOVERFLOW_INDEX 20 +#define MMC_RISR_RXFIFOOVERFLOW_WIDTH 1 +#define MMC_RISR_RXVLANFRAMES_GB_INDEX 21 +#define MMC_RISR_RXVLANFRAMES_GB_WIDTH 1 +#define MMC_RISR_RXWATCHDOGERROR_INDEX 22 +#define MMC_RISR_RXWATCHDOGERROR_WIDTH 1 +#define MMC_TIER_ALL_INTERRUPTS_INDEX 0 +#define MMC_TIER_ALL_INTERRUPTS_WIDTH 18 +#define MMC_TISR_TXOCTETCOUNT_GB_INDEX 0 +#define MMC_TISR_TXOCTETCOUNT_GB_WIDTH 1 +#define MMC_TISR_TXFRAMECOUNT_GB_INDEX 1 +#define MMC_TISR_TXFRAMECOUNT_GB_WIDTH 1 +#define MMC_TISR_TXBROADCASTFRAMES_G_INDEX 2 +#define MMC_TISR_TXBROADCASTFRAMES_G_WIDTH 1 +#define MMC_TISR_TXMULTICASTFRAMES_G_INDEX 3 +#define MMC_TISR_TXMULTICASTFRAMES_G_WIDTH 1 +#define MMC_TISR_TX64OCTETS_GB_INDEX 4 +#define MMC_TISR_TX64OCTETS_GB_WIDTH 1 +#define MMC_TISR_TX65TO127OCTETS_GB_INDEX 5 +#define MMC_TISR_TX65TO127OCTETS_GB_WIDTH 1 +#define MMC_TISR_TX128TO255OCTETS_GB_INDEX 6 +#define MMC_TISR_TX128TO255OCTETS_GB_WIDTH 1 +#define MMC_TISR_TX256TO511OCTETS_GB_INDEX 7 +#define MMC_TISR_TX256TO511OCTETS_GB_WIDTH 1 +#define MMC_TISR_TX512TO1023OCTETS_GB_INDEX 8 +#define MMC_TISR_TX512TO1023OCTETS_GB_WIDTH 1 +#define MMC_TISR_TX1024TOMAXOCTETS_GB_INDEX 9 +#define MMC_TISR_TX1024TOMAXOCTETS_GB_WIDTH 1 +#define MMC_TISR_TXUNICASTFRAMES_GB_INDEX 10 +#define MMC_TISR_TXUNICASTFRAMES_GB_WIDTH 1 +#define MMC_TISR_TXMULTICASTFRAMES_GB_INDEX 11 +#define MMC_TISR_TXMULTICASTFRAMES_GB_WIDTH 1 +#define MMC_TISR_TXBROADCASTFRAMES_GB_INDEX 12 +#define MMC_TISR_TXBROADCASTFRAMES_GB_WIDTH 1 +#define MMC_TISR_TXUNDERFLOWERROR_INDEX 13 +#define MMC_TISR_TXUNDERFLOWERROR_WIDTH 1 +#define MMC_TISR_TXOCTETCOUNT_G_INDEX 14 +#define MMC_TISR_TXOCTETCOUNT_G_WIDTH 1 +#define MMC_TISR_TXFRAMECOUNT_G_INDEX 15 +#define MMC_TISR_TXFRAMECOUNT_G_WIDTH 1 +#define MMC_TISR_TXPAUSEFRAMES_INDEX 16 +#define MMC_TISR_TXPAUSEFRAMES_WIDTH 1 +#define MMC_TISR_TXVLANFRAMES_G_INDEX 17 +#define MMC_TISR_TXVLANFRAMES_G_WIDTH 1 + +/* MTL register offsets */ +#define MTL_OMR 0x1000 +#define MTL_FDCR 0x1008 +#define MTL_FDSR 0x100c +#define MTL_FDDR 0x1010 +#define MTL_ISR 0x1020 +#define MTL_RQDCM0R 0x1030 +#define MTL_TCPM0R 0x1040 +#define MTL_TCPM1R 0x1044 + +#define MTL_RQDCM_INC 4 +#define MTL_RQDCM_Q_PER_REG 4 +#define MTL_TCPM_INC 4 +#define MTL_TCPM_TC_PER_REG 4 + +/* MTL register entry bit positions and sizes */ +#define MTL_OMR_ETSALG_INDEX 5 +#define MTL_OMR_ETSALG_WIDTH 2 +#define MTL_OMR_RAA_INDEX 2 +#define MTL_OMR_RAA_WIDTH 1 + +/* MTL queue register offsets + * Multiple queues can be active. The first queue has registers + * that begin at 0x1100. Each subsequent queue has registers that + * are accessed using an offset of 0x80 from the previous queue. + */ +#define MTL_Q_BASE 0x1100 +#define MTL_Q_INC 0x80 + +#define MTL_Q_TQOMR 0x00 +#define MTL_Q_TQUR 0x04 +#define MTL_Q_TQDR 0x08 +#define MTL_Q_RQOMR 0x40 +#define MTL_Q_RQMPOCR 0x44 +#define MTL_Q_RQDR 0x48 +#define MTL_Q_RQFCR 0x50 +#define MTL_Q_IER 0x70 +#define MTL_Q_ISR 0x74 + +/* MTL queue register entry bit positions and sizes */ +#define MTL_Q_RQDR_PRXQ_INDEX 16 +#define MTL_Q_RQDR_PRXQ_WIDTH 14 +#define MTL_Q_RQDR_RXQSTS_INDEX 4 +#define MTL_Q_RQDR_RXQSTS_WIDTH 2 +#define MTL_Q_RQFCR_RFA_INDEX 1 +#define MTL_Q_RQFCR_RFA_WIDTH 6 +#define MTL_Q_RQFCR_RFD_INDEX 17 +#define MTL_Q_RQFCR_RFD_WIDTH 6 +#define MTL_Q_RQOMR_EHFC_INDEX 7 +#define MTL_Q_RQOMR_EHFC_WIDTH 1 +#define MTL_Q_RQOMR_RQS_INDEX 16 +#define MTL_Q_RQOMR_RQS_WIDTH 9 +#define MTL_Q_RQOMR_RSF_INDEX 5 +#define MTL_Q_RQOMR_RSF_WIDTH 1 +#define MTL_Q_RQOMR_RTC_INDEX 0 +#define MTL_Q_RQOMR_RTC_WIDTH 2 +#define MTL_Q_TQOMR_FTQ_INDEX 0 +#define MTL_Q_TQOMR_FTQ_WIDTH 1 +#define MTL_Q_TQOMR_Q2TCMAP_INDEX 8 +#define MTL_Q_TQOMR_Q2TCMAP_WIDTH 3 +#define MTL_Q_TQOMR_TQS_INDEX 16 +#define MTL_Q_TQOMR_TQS_WIDTH 10 +#define MTL_Q_TQOMR_TSF_INDEX 1 +#define MTL_Q_TQOMR_TSF_WIDTH 1 +#define MTL_Q_TQOMR_TTC_INDEX 4 +#define MTL_Q_TQOMR_TTC_WIDTH 3 +#define MTL_Q_TQOMR_TXQEN_INDEX 2 +#define MTL_Q_TQOMR_TXQEN_WIDTH 2 + +/* MTL queue register value */ +#define MTL_RSF_DISABLE 0x00 +#define MTL_RSF_ENABLE 0x01 +#define MTL_TSF_DISABLE 0x00 +#define MTL_TSF_ENABLE 0x01 + +#define MTL_RX_THRESHOLD_64 0x00 +#define MTL_RX_THRESHOLD_96 0x02 +#define MTL_RX_THRESHOLD_128 0x03 +#define MTL_TX_THRESHOLD_32 0x01 +#define MTL_TX_THRESHOLD_64 0x00 +#define MTL_TX_THRESHOLD_96 0x02 +#define MTL_TX_THRESHOLD_128 0x03 +#define MTL_TX_THRESHOLD_192 0x04 +#define MTL_TX_THRESHOLD_256 0x05 +#define MTL_TX_THRESHOLD_384 0x06 +#define MTL_TX_THRESHOLD_512 0x07 + +#define MTL_ETSALG_WRR 0x00 +#define MTL_ETSALG_WFQ 0x01 +#define MTL_ETSALG_DWRR 0x02 +#define MTL_RAA_SP 0x00 +#define MTL_RAA_WSP 0x01 + +#define MTL_Q_DISABLED 0x00 +#define MTL_Q_ENABLED 0x02 + +/* MTL traffic class register offsets + * Multiple traffic classes can be active. The first class has registers + * that begin at 0x1100. Each subsequent queue has registers that + * are accessed using an offset of 0x80 from the previous queue. + */ +#define MTL_TC_BASE MTL_Q_BASE +#define MTL_TC_INC MTL_Q_INC + +#define MTL_TC_ETSCR 0x10 +#define MTL_TC_ETSSR 0x14 +#define MTL_TC_QWR 0x18 + +/* MTL traffic class register entry bit positions and sizes */ +#define MTL_TC_ETSCR_TSA_INDEX 0 +#define MTL_TC_ETSCR_TSA_WIDTH 2 +#define MTL_TC_QWR_QW_INDEX 0 +#define MTL_TC_QWR_QW_WIDTH 21 + +/* MTL traffic class register value */ +#define MTL_TSA_SP 0x00 +#define MTL_TSA_ETS 0x02 + +/* PCS MMD select register offset + * The MMD select register is used for accessing PCS registers + * when the underlying APB3 interface is using indirect addressing. + * Indirect addressing requires accessing registers in two phases, + * an address phase and a data phase. The address phases requires + * writing an address selection value to the MMD select regiesters. + */ +#define PCS_MMD_SELECT 0xff + +/* SerDes integration register offsets */ +#define SIR0_KR_RT_1 0x002c +#define SIR0_STATUS 0x0040 +#define SIR1_SPEED 0x0000 + +/* SerDes integration register entry bit positions and sizes */ +#define SIR0_KR_RT_1_RESET_INDEX 11 +#define SIR0_KR_RT_1_RESET_WIDTH 1 +#define SIR0_STATUS_RX_READY_INDEX 0 +#define SIR0_STATUS_RX_READY_WIDTH 1 +#define SIR0_STATUS_TX_READY_INDEX 8 +#define SIR0_STATUS_TX_READY_WIDTH 1 +#define SIR1_SPEED_CDR_RATE_INDEX 12 +#define SIR1_SPEED_CDR_RATE_WIDTH 4 +#define SIR1_SPEED_DATARATE_INDEX 4 +#define SIR1_SPEED_DATARATE_WIDTH 2 +#define SIR1_SPEED_PLLSEL_INDEX 3 +#define SIR1_SPEED_PLLSEL_WIDTH 1 +#define SIR1_SPEED_RATECHANGE_INDEX 6 +#define SIR1_SPEED_RATECHANGE_WIDTH 1 +#define SIR1_SPEED_TXAMP_INDEX 8 +#define SIR1_SPEED_TXAMP_WIDTH 4 +#define SIR1_SPEED_WORDMODE_INDEX 0 +#define SIR1_SPEED_WORDMODE_WIDTH 3 + +/* SerDes RxTx register offsets */ +#define RXTX_REG6 0x0018 +#define RXTX_REG20 0x0050 +#define RXTX_REG22 0x0058 +#define RXTX_REG114 0x01c8 +#define RXTX_REG129 0x0204 + +/* SerDes RxTx register entry bit positions and sizes */ +#define RXTX_REG6_RESETB_RXD_INDEX 8 +#define RXTX_REG6_RESETB_RXD_WIDTH 1 +#define RXTX_REG20_BLWC_ENA_INDEX 2 +#define RXTX_REG20_BLWC_ENA_WIDTH 1 +#define RXTX_REG114_PQ_REG_INDEX 9 +#define RXTX_REG114_PQ_REG_WIDTH 7 +#define RXTX_REG129_RXDFE_CONFIG_INDEX 14 +#define RXTX_REG129_RXDFE_CONFIG_WIDTH 2 + +/* Descriptor/Packet entry bit positions and sizes */ +#define RX_PACKET_ERRORS_CRC_INDEX 2 +#define RX_PACKET_ERRORS_CRC_WIDTH 1 +#define RX_PACKET_ERRORS_FRAME_INDEX 3 +#define RX_PACKET_ERRORS_FRAME_WIDTH 1 +#define RX_PACKET_ERRORS_LENGTH_INDEX 0 +#define RX_PACKET_ERRORS_LENGTH_WIDTH 1 +#define RX_PACKET_ERRORS_OVERRUN_INDEX 1 +#define RX_PACKET_ERRORS_OVERRUN_WIDTH 1 + +#define RX_PACKET_ATTRIBUTES_CSUM_DONE_INDEX 0 +#define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 1 +#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2 +#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX 3 +#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX 4 +#define RX_PACKET_ATTRIBUTES_CONTEXT_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_INDEX 5 +#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1 +#define RX_PACKET_ATTRIBUTES_RSS_HASH_INDEX 6 +#define RX_PACKET_ATTRIBUTES_RSS_HASH_WIDTH 1 + +#define RX_NORMAL_DESC0_OVT_INDEX 0 +#define RX_NORMAL_DESC0_OVT_WIDTH 16 +#define RX_NORMAL_DESC2_HL_INDEX 0 +#define RX_NORMAL_DESC2_HL_WIDTH 10 +#define RX_NORMAL_DESC3_CDA_INDEX 27 +#define RX_NORMAL_DESC3_CDA_WIDTH 1 +#define RX_NORMAL_DESC3_CTXT_INDEX 30 +#define RX_NORMAL_DESC3_CTXT_WIDTH 1 +#define RX_NORMAL_DESC3_ES_INDEX 15 +#define RX_NORMAL_DESC3_ES_WIDTH 1 +#define RX_NORMAL_DESC3_ETLT_INDEX 16 +#define RX_NORMAL_DESC3_ETLT_WIDTH 4 +#define RX_NORMAL_DESC3_FD_INDEX 29 +#define RX_NORMAL_DESC3_FD_WIDTH 1 +#define RX_NORMAL_DESC3_INTE_INDEX 30 +#define RX_NORMAL_DESC3_INTE_WIDTH 1 +#define RX_NORMAL_DESC3_L34T_INDEX 20 +#define RX_NORMAL_DESC3_L34T_WIDTH 4 +#define RX_NORMAL_DESC3_LD_INDEX 28 +#define RX_NORMAL_DESC3_LD_WIDTH 1 +#define RX_NORMAL_DESC3_OWN_INDEX 31 +#define RX_NORMAL_DESC3_OWN_WIDTH 1 +#define RX_NORMAL_DESC3_PL_INDEX 0 +#define RX_NORMAL_DESC3_PL_WIDTH 14 +#define RX_NORMAL_DESC3_RSV_INDEX 26 +#define RX_NORMAL_DESC3_RSV_WIDTH 1 + +#define RX_DESC3_L34T_IPV4_TCP 1 +#define RX_DESC3_L34T_IPV4_UDP 2 +#define RX_DESC3_L34T_IPV4_ICMP 3 +#define RX_DESC3_L34T_IPV6_TCP 9 +#define RX_DESC3_L34T_IPV6_UDP 10 +#define RX_DESC3_L34T_IPV6_ICMP 11 + +#define RX_CONTEXT_DESC3_TSA_INDEX 4 +#define RX_CONTEXT_DESC3_TSA_WIDTH 1 +#define RX_CONTEXT_DESC3_TSD_INDEX 6 +#define RX_CONTEXT_DESC3_TSD_WIDTH 1 + +#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_INDEX 0 +#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_WIDTH 1 +#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_INDEX 1 +#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_WIDTH 1 +#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 2 +#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1 +#define TX_PACKET_ATTRIBUTES_PTP_INDEX 3 +#define TX_PACKET_ATTRIBUTES_PTP_WIDTH 1 + +#define TX_CONTEXT_DESC2_MSS_INDEX 0 +#define TX_CONTEXT_DESC2_MSS_WIDTH 15 +#define TX_CONTEXT_DESC3_CTXT_INDEX 30 +#define TX_CONTEXT_DESC3_CTXT_WIDTH 1 +#define TX_CONTEXT_DESC3_TCMSSV_INDEX 26 +#define TX_CONTEXT_DESC3_TCMSSV_WIDTH 1 +#define TX_CONTEXT_DESC3_VLTV_INDEX 16 +#define TX_CONTEXT_DESC3_VLTV_WIDTH 1 +#define TX_CONTEXT_DESC3_VT_INDEX 0 +#define TX_CONTEXT_DESC3_VT_WIDTH 16 + +#define TX_NORMAL_DESC2_HL_B1L_INDEX 0 +#define TX_NORMAL_DESC2_HL_B1L_WIDTH 14 +#define TX_NORMAL_DESC2_IC_INDEX 31 +#define TX_NORMAL_DESC2_IC_WIDTH 1 +#define TX_NORMAL_DESC2_TTSE_INDEX 30 +#define TX_NORMAL_DESC2_TTSE_WIDTH 1 +#define TX_NORMAL_DESC2_VTIR_INDEX 14 +#define TX_NORMAL_DESC2_VTIR_WIDTH 2 +#define TX_NORMAL_DESC3_CIC_INDEX 16 +#define TX_NORMAL_DESC3_CIC_WIDTH 2 +#define TX_NORMAL_DESC3_CPC_INDEX 26 +#define TX_NORMAL_DESC3_CPC_WIDTH 2 +#define TX_NORMAL_DESC3_CTXT_INDEX 30 +#define TX_NORMAL_DESC3_CTXT_WIDTH 1 +#define TX_NORMAL_DESC3_FD_INDEX 29 +#define TX_NORMAL_DESC3_FD_WIDTH 1 +#define TX_NORMAL_DESC3_FL_INDEX 0 +#define TX_NORMAL_DESC3_FL_WIDTH 15 +#define TX_NORMAL_DESC3_LD_INDEX 28 +#define TX_NORMAL_DESC3_LD_WIDTH 1 +#define TX_NORMAL_DESC3_OWN_INDEX 31 +#define TX_NORMAL_DESC3_OWN_WIDTH 1 +#define TX_NORMAL_DESC3_TCPHDRLEN_INDEX 19 +#define TX_NORMAL_DESC3_TCPHDRLEN_WIDTH 4 +#define TX_NORMAL_DESC3_TCPPL_INDEX 0 +#define TX_NORMAL_DESC3_TCPPL_WIDTH 18 +#define TX_NORMAL_DESC3_TSE_INDEX 18 +#define TX_NORMAL_DESC3_TSE_WIDTH 1 + +#define TX_NORMAL_DESC2_VLAN_INSERT 0x2 + +/* MDIO undefined or vendor specific registers */ +#ifndef MDIO_PMA_10GBR_PMD_CTRL +#define MDIO_PMA_10GBR_PMD_CTRL 0x0096 +#endif + +#ifndef MDIO_PMA_10GBR_FECCTRL +#define MDIO_PMA_10GBR_FECCTRL 0x00ab +#endif + +#ifndef MDIO_AN_XNP +#define MDIO_AN_XNP 0x0016 +#endif + +#ifndef MDIO_AN_LPX +#define MDIO_AN_LPX 0x0019 +#endif + +#ifndef MDIO_AN_COMP_STAT +#define MDIO_AN_COMP_STAT 0x0030 +#endif + +#ifndef MDIO_AN_INTMASK +#define MDIO_AN_INTMASK 0x8001 +#endif + +#ifndef MDIO_AN_INT +#define MDIO_AN_INT 0x8002 +#endif + +#ifndef MDIO_CTRL1_SPEED1G +#define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) +#endif + +/* MDIO mask values */ +#define XGBE_XNP_MCF_NULL_MESSAGE 0x001 +#define XGBE_XNP_ACK_PROCESSED BIT(12) +#define XGBE_XNP_MP_FORMATTED BIT(13) +#define XGBE_XNP_NP_EXCHANGE BIT(15) + +#define XGBE_KR_TRAINING_START BIT(0) +#define XGBE_KR_TRAINING_ENABLE BIT(1) + +/* Bit setting and getting macros + * The get macro will extract the current bit field value from within + * the variable + * + * The set macro will clear the current bit field value within the + * variable and then set the bit field of the variable to the + * specified value + */ +#define GET_BITS(_var, _index, _width) \ + (((_var) >> (_index)) & ((0x1 << (_width)) - 1)) + +#define SET_BITS(_var, _index, _width, _val) \ +do { \ + (_var) &= ~(((0x1 << (_width)) - 1) << (_index)); \ + (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \ +} while (0) + +#define GET_BITS_LE(_var, _index, _width) \ + ((le32_to_cpu((_var)) >> (_index)) & ((0x1 << (_width)) - 1)) + +#define SET_BITS_LE(_var, _index, _width, _val) \ +do { \ + (_var) &= cpu_to_le32(~(((0x1 << (_width)) - 1) << (_index))); \ + (_var) |= cpu_to_le32((((_val) & \ + ((0x1 << (_width)) - 1)) << (_index))); \ +} while (0) + +/* Bit setting and getting macros based on register fields + * The get macro uses the bit field definitions formed using the input + * names to extract the current bit field value from within the + * variable + * + * The set macro uses the bit field definitions formed using the input + * names to set the bit field of the variable to the specified value + */ +#define XGMAC_GET_BITS(_var, _prefix, _field) \ + GET_BITS((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH) + +#define XGMAC_SET_BITS(_var, _prefix, _field, _val) \ + SET_BITS((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH, (_val)) + +#define XGMAC_GET_BITS_LE(_var, _prefix, _field) \ + GET_BITS_LE((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH) + +#define XGMAC_SET_BITS_LE(_var, _prefix, _field, _val) \ + SET_BITS_LE((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH, (_val)) + +/* Macros for reading or writing registers + * The ioread macros will get bit fields or full values using the + * register definitions formed using the input names + * + * The iowrite macros will set bit fields or full values using the + * register definitions formed using the input names + */ +#define XGMAC_IOREAD(_pdata, _reg) \ + bus_read_4((_pdata)->xgmac_res, _reg) + +#define XGMAC_IOREAD_BITS(_pdata, _reg, _field) \ + GET_BITS(XGMAC_IOREAD((_pdata), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XGMAC_IOWRITE(_pdata, _reg, _val) \ + bus_write_4((_pdata)->xgmac_res, _reg, (_val)) + +#define XGMAC_IOWRITE_BITS(_pdata, _reg, _field, _val) \ +do { \ + u32 reg_val = XGMAC_IOREAD((_pdata), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XGMAC_IOWRITE((_pdata), _reg, reg_val); \ +} while (0) + +/* Macros for reading or writing MTL queue or traffic class registers + * Similar to the standard read and write macros except that the + * base register value is calculated by the queue or traffic class number + */ +#define XGMAC_MTL_IOREAD(_pdata, _n, _reg) \ + bus_read_4((_pdata)->xgmac_res, \ + MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg) + +#define XGMAC_MTL_IOREAD_BITS(_pdata, _n, _reg, _field) \ + GET_BITS(XGMAC_MTL_IOREAD((_pdata), (_n), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XGMAC_MTL_IOWRITE(_pdata, _n, _reg, _val) \ + bus_write_4((_pdata)->xgmac_res, \ + MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg, (_val)) + +#define XGMAC_MTL_IOWRITE_BITS(_pdata, _n, _reg, _field, _val) \ +do { \ + u32 reg_val = XGMAC_MTL_IOREAD((_pdata), (_n), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XGMAC_MTL_IOWRITE((_pdata), (_n), _reg, reg_val); \ +} while (0) + +/* Macros for reading or writing DMA channel registers + * Similar to the standard read and write macros except that the + * base register value is obtained from the ring + */ +#define XGMAC_DMA_IOREAD(_channel, _reg) \ + bus_space_read_4((_channel)->dma_tag, (_channel)->dma_handle, _reg) + +#define XGMAC_DMA_IOREAD_BITS(_channel, _reg, _field) \ + GET_BITS(XGMAC_DMA_IOREAD((_channel), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XGMAC_DMA_IOWRITE(_channel, _reg, _val) \ + bus_space_write_4((_channel)->dma_tag, (_channel)->dma_handle, \ + _reg, (_val)) + +#define XGMAC_DMA_IOWRITE_BITS(_channel, _reg, _field, _val) \ +do { \ + u32 reg_val = XGMAC_DMA_IOREAD((_channel), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XGMAC_DMA_IOWRITE((_channel), _reg, reg_val); \ +} while (0) + +/* Macros for building, reading or writing register values or bits + * within the register values of XPCS registers. + */ +#define XPCS_IOWRITE(_pdata, _off, _val) \ + bus_write_4((_pdata)->xpcs_res, (_off), _val) + +#define XPCS_IOREAD(_pdata, _off) \ + bus_read_4((_pdata)->xpcs_res, (_off)) + +/* Macros for building, reading or writing register values or bits + * within the register values of SerDes integration registers. + */ +#define XSIR_GET_BITS(_var, _prefix, _field) \ + GET_BITS((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH) + +#define XSIR_SET_BITS(_var, _prefix, _field, _val) \ + SET_BITS((_var), \ + _prefix##_##_field##_INDEX, \ + _prefix##_##_field##_WIDTH, (_val)) + +#define XSIR0_IOREAD(_pdata, _reg) \ + bus_read_2((_pdata)->sir0_res, _reg) + +#define XSIR0_IOREAD_BITS(_pdata, _reg, _field) \ + GET_BITS(XSIR0_IOREAD((_pdata), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XSIR0_IOWRITE(_pdata, _reg, _val) \ + bus_write_2((_pdata)->sir0_res, _reg, (_val)) + +#define XSIR0_IOWRITE_BITS(_pdata, _reg, _field, _val) \ +do { \ + u16 reg_val = XSIR0_IOREAD((_pdata), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XSIR0_IOWRITE((_pdata), _reg, reg_val); \ +} while (0) + +#define XSIR1_IOREAD(_pdata, _reg) \ + bus_read_2((_pdata)->sir1_res, _reg) + +#define XSIR1_IOREAD_BITS(_pdata, _reg, _field) \ + GET_BITS(XSIR1_IOREAD((_pdata), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XSIR1_IOWRITE(_pdata, _reg, _val) \ + bus_write_2((_pdata)->sir1_res, _reg, (_val)) + +#define XSIR1_IOWRITE_BITS(_pdata, _reg, _field, _val) \ +do { \ + u16 reg_val = XSIR1_IOREAD((_pdata), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XSIR1_IOWRITE((_pdata), _reg, reg_val); \ +} while (0) + +/* Macros for building, reading or writing register values or bits + * within the register values of SerDes RxTx registers. + */ +#define XRXTX_IOREAD(_pdata, _reg) \ + bus_read_2((_pdata)->rxtx_res, _reg) + +#define XRXTX_IOREAD_BITS(_pdata, _reg, _field) \ + GET_BITS(XRXTX_IOREAD((_pdata), _reg), \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH) + +#define XRXTX_IOWRITE(_pdata, _reg, _val) \ + bus_write_2((_pdata)->rxtx_res, _reg, (_val)) + +#define XRXTX_IOWRITE_BITS(_pdata, _reg, _field, _val) \ +do { \ + u16 reg_val = XRXTX_IOREAD((_pdata), _reg); \ + SET_BITS(reg_val, \ + _reg##_##_field##_INDEX, \ + _reg##_##_field##_WIDTH, (_val)); \ + XRXTX_IOWRITE((_pdata), _reg, reg_val); \ +} while (0) + +/* Macros for building, reading or writing register values or bits + * using MDIO. Different from above because of the use of standardized + * Linux include values. No shifting is performed with the bit + * operations, everything works on mask values. + */ +#define XMDIO_READ(_pdata, _mmd, _reg) \ + ((_pdata)->hw_if.read_mmd_regs((_pdata), 0, \ + MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff))) + +#define XMDIO_READ_BITS(_pdata, _mmd, _reg, _mask) \ + (XMDIO_READ((_pdata), _mmd, _reg) & _mask) + +#define XMDIO_WRITE(_pdata, _mmd, _reg, _val) \ + ((_pdata)->hw_if.write_mmd_regs((_pdata), 0, \ + MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff), (_val))) + +#define XMDIO_WRITE_BITS(_pdata, _mmd, _reg, _mask, _val) \ +do { \ + u32 mmd_val = XMDIO_READ((_pdata), _mmd, _reg); \ + mmd_val &= ~_mask; \ + mmd_val |= (_val); \ + XMDIO_WRITE((_pdata), _mmd, _reg, mmd_val); \ +} while (0) + +#endif diff --git a/sys/dev/axgbe/xgbe-desc.c b/sys/dev/axgbe/xgbe-desc.c new file mode 100644 index 000000000000..a2f1f98881e9 --- /dev/null +++ b/sys/dev/axgbe/xgbe-desc.c @@ -0,0 +1,539 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "xgbe.h" +#include "xgbe-common.h" + +static void xgbe_unmap_rdata(struct xgbe_prv_data *, struct xgbe_ring_data *); + +static void xgbe_free_ring(struct xgbe_prv_data *pdata, + struct xgbe_ring *ring) +{ + struct xgbe_ring_data *rdata; + unsigned int i; + + if (!ring) + return; + + bus_dmamap_destroy(ring->mbuf_dmat, ring->mbuf_map); + bus_dma_tag_destroy(ring->mbuf_dmat); + + ring->mbuf_map = NULL; + ring->mbuf_dmat = NULL; + + if (ring->rdata) { + for (i = 0; i < ring->rdesc_count; i++) { + rdata = XGBE_GET_DESC_DATA(ring, i); + xgbe_unmap_rdata(pdata, rdata); + } + + free(ring->rdata, M_AXGBE); + ring->rdata = NULL; + } + + bus_dmamap_unload(ring->rdesc_dmat, ring->rdesc_map); + bus_dmamem_free(ring->rdesc_dmat, ring->rdesc, ring->rdesc_map); + bus_dma_tag_destroy(ring->rdesc_dmat); + + ring->rdesc_map = NULL; + ring->rdesc_dmat = NULL; + ring->rdesc = NULL; +} + +static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + DBGPR("-->xgbe_free_ring_resources\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + xgbe_free_ring(pdata, channel->tx_ring); + xgbe_free_ring(pdata, channel->rx_ring); + } + + DBGPR("<--xgbe_free_ring_resources\n"); +} + +static void xgbe_ring_dmamap_cb(void *arg, bus_dma_segment_t * segs, int nseg, + int error) +{ + if (error) + return; + *(bus_addr_t *) arg = segs->ds_addr; +} + +static int xgbe_init_ring(struct xgbe_prv_data *pdata, + struct xgbe_ring *ring, unsigned int rdesc_count) +{ + bus_size_t len; + int err, flags; + + DBGPR("-->xgbe_init_ring\n"); + + if (!ring) + return 0; + + flags = 0; + if (pdata->coherent) + flags = BUS_DMA_COHERENT; + + /* Descriptors */ + ring->rdesc_count = rdesc_count; + len = sizeof(struct xgbe_ring_desc) * rdesc_count; + err = bus_dma_tag_create(pdata->dmat, 512, 0, BUS_SPACE_MAXADDR, + BUS_SPACE_MAXADDR, NULL, NULL, len, 1, len, flags, NULL, NULL, + &ring->rdesc_dmat); + if (err != 0) { + printf("Unable to create the DMA tag: %d\n", err); + return -err; + } + + err = bus_dmamem_alloc(ring->rdesc_dmat, (void **)&ring->rdesc, + BUS_DMA_WAITOK | BUS_DMA_COHERENT, &ring->rdesc_map); + if (err != 0) { + bus_dma_tag_destroy(ring->rdesc_dmat); + printf("Unable to allocate DMA memory: %d\n", err); + return -err; + } + err = bus_dmamap_load(ring->rdesc_dmat, ring->rdesc_map, ring->rdesc, + len, xgbe_ring_dmamap_cb, &ring->rdesc_paddr, 0); + if (err != 0) { + bus_dmamem_free(ring->rdesc_dmat, ring->rdesc, ring->rdesc_map); + bus_dma_tag_destroy(ring->rdesc_dmat); + printf("Unable to load DMA memory\n"); + return -err; + } + + /* Descriptor information */ + ring->rdata = malloc(rdesc_count * sizeof(struct xgbe_ring_data), + M_AXGBE, M_WAITOK | M_ZERO); + + /* Create the space DMA tag for mbufs */ + err = bus_dma_tag_create(pdata->dmat, 1, 0, BUS_SPACE_MAXADDR, + BUS_SPACE_MAXADDR, NULL, NULL, XGBE_TX_MAX_BUF_SIZE * rdesc_count, + rdesc_count, XGBE_TX_MAX_BUF_SIZE, flags, NULL, NULL, + &ring->mbuf_dmat); + if (err != 0) + return -err; + + err = bus_dmamap_create(ring->mbuf_dmat, 0, &ring->mbuf_map); + if (err != 0) + return -err; + + DBGPR("<--xgbe_init_ring\n"); + + return 0; +} + +static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + int ret; + + DBGPR("-->xgbe_alloc_ring_resources\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ret = xgbe_init_ring(pdata, channel->tx_ring, + pdata->tx_desc_count); + if (ret) { + printf("error initializing Tx ring\n"); + goto err_ring; + } + + ret = xgbe_init_ring(pdata, channel->rx_ring, + pdata->rx_desc_count); + if (ret) { + printf("error initializing Rx ring\n"); + goto err_ring; + } + } + + DBGPR("<--xgbe_alloc_ring_resources\n"); + + return 0; + +err_ring: + xgbe_free_ring_resources(pdata); + + return ret; +} + +static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata, + struct xgbe_ring *ring, + struct xgbe_ring_data *rdata) +{ + bus_dmamap_t mbuf_map; + bus_dma_segment_t segs[2]; + struct mbuf *m0, *m1; + int err, nsegs; + + m0 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MCLBYTES); + if (m0 == NULL) + return (-ENOBUFS); + + m1 = m_getjcl(M_NOWAIT, MT_DATA, 0, MCLBYTES); + if (m1 == NULL) { + m_freem(m0); + return (-ENOBUFS); + } + + m0->m_next = m1; + m0->m_flags |= M_PKTHDR; + m0->m_len = MHLEN; + m0->m_pkthdr.len = MHLEN + MCLBYTES; + + m1->m_len = MCLBYTES; + m1->m_next = NULL; + m1->m_pkthdr.len = MCLBYTES; + + err = bus_dmamap_create(ring->mbuf_dmat, 0, &mbuf_map); + if (err != 0) { + m_freem(m0); + return (-err); + } + + err = bus_dmamap_load_mbuf_sg(ring->mbuf_dmat, mbuf_map, m0, segs, + &nsegs, BUS_DMA_NOWAIT); + if (err != 0) { + m_freem(m0); + bus_dmamap_destroy(ring->mbuf_dmat, mbuf_map); + return (-err); + } + + KASSERT(nsegs == 2, + ("xgbe_map_rx_buffer: Unable to handle multiple segments %d", + nsegs)); + + rdata->mb = m0; + rdata->mbuf_free = 0; + rdata->mbuf_dmat = ring->mbuf_dmat; + rdata->mbuf_map = mbuf_map; + rdata->mbuf_hdr_paddr = segs[0].ds_addr; + rdata->mbuf_data_paddr = segs[1].ds_addr; + + return 0; +} + +static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_channel *channel; + struct xgbe_ring *ring; + struct xgbe_ring_data *rdata; + struct xgbe_ring_desc *rdesc; + bus_addr_t rdesc_paddr; + unsigned int i, j; + + DBGPR("-->xgbe_wrapper_tx_descriptor_init\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ring = channel->tx_ring; + if (!ring) + break; + + rdesc = ring->rdesc; + rdesc_paddr = ring->rdesc_paddr; + + for (j = 0; j < ring->rdesc_count; j++) { + rdata = XGBE_GET_DESC_DATA(ring, j); + + rdata->rdesc = rdesc; + rdata->rdata_paddr = rdesc_paddr; + + rdesc++; + rdesc_paddr += sizeof(struct xgbe_ring_desc); + } + + ring->cur = 0; + ring->dirty = 0; + memset(&ring->tx, 0, sizeof(ring->tx)); + + hw_if->tx_desc_init(channel); + } + + DBGPR("<--xgbe_wrapper_tx_descriptor_init\n"); +} + +static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_channel *channel; + struct xgbe_ring *ring; + struct xgbe_ring_desc *rdesc; + struct xgbe_ring_data *rdata; + bus_addr_t rdesc_paddr; + unsigned int i, j; + + DBGPR("-->xgbe_wrapper_rx_descriptor_init\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ring = channel->rx_ring; + if (!ring) + break; + + rdesc = ring->rdesc; + rdesc_paddr = ring->rdesc_paddr; + + for (j = 0; j < ring->rdesc_count; j++) { + rdata = XGBE_GET_DESC_DATA(ring, j); + + rdata->rdesc = rdesc; + rdata->rdata_paddr = rdesc_paddr; + + if (xgbe_map_rx_buffer(pdata, ring, rdata)) + break; + + rdesc++; + rdesc_paddr += sizeof(struct xgbe_ring_desc); + } + + ring->cur = 0; + ring->dirty = 0; + + hw_if->rx_desc_init(channel); + } +} + +static void xgbe_unmap_rdata(struct xgbe_prv_data *pdata, + struct xgbe_ring_data *rdata) +{ + + if (rdata->mbuf_map != NULL) + bus_dmamap_destroy(rdata->mbuf_dmat, rdata->mbuf_map); + + if (rdata->mbuf_free) + m_freem(rdata->mb); + + rdata->mb = NULL; + rdata->mbuf_free = 0; + rdata->mbuf_hdr_paddr = 0; + rdata->mbuf_data_paddr = 0; + rdata->mbuf_len = 0; + + memset(&rdata->tx, 0, sizeof(rdata->tx)); + memset(&rdata->rx, 0, sizeof(rdata->rx)); +} + +struct xgbe_map_tx_skb_data { + struct xgbe_ring *ring; + struct xgbe_packet_data *packet; + unsigned int cur_index; +}; + +static void xgbe_map_tx_skb_cb(void *callback_arg, bus_dma_segment_t *segs, + int nseg, bus_size_t mapsize, int error) +{ + struct xgbe_map_tx_skb_data *data; + struct xgbe_ring_data *rdata; + struct xgbe_ring *ring; + int i; + + if (error != 0) + return; + + data = callback_arg; + ring = data->ring; + + for (i = 0; i < nseg; i++) { + rdata = XGBE_GET_DESC_DATA(ring, data->cur_index); + + KASSERT(segs[i].ds_len <= XGBE_TX_MAX_BUF_SIZE, + ("%s: Segment size is too large %ld > %d", __func__, + segs[i].ds_len, XGBE_TX_MAX_BUF_SIZE)); + + if (i == 0) { + rdata->mbuf_dmat = ring->mbuf_dmat; + bus_dmamap_create(ring->mbuf_dmat, 0, &ring->mbuf_map); + } + + rdata->mbuf_hdr_paddr = 0; + rdata->mbuf_data_paddr = segs[i].ds_addr; + rdata->mbuf_len = segs[i].ds_len; + + data->packet->length += rdata->mbuf_len; + + data->cur_index++; + } +} + +static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct mbuf *m) +{ + struct xgbe_ring *ring = channel->tx_ring; + struct xgbe_map_tx_skb_data cbdata; + struct xgbe_ring_data *rdata; + struct xgbe_packet_data *packet; + unsigned int start_index, cur_index; + int err; + + DBGPR("-->xgbe_map_tx_skb: cur = %d\n", ring->cur); + + start_index = ring->cur; + cur_index = ring->cur; + + packet = &ring->packet_data; + packet->rdesc_count = 0; + packet->length = 0; + + cbdata.ring = ring; + cbdata.packet = packet; + cbdata.cur_index = cur_index; + + err = bus_dmamap_load_mbuf(ring->mbuf_dmat, ring->mbuf_map, m, + xgbe_map_tx_skb_cb, &cbdata, BUS_DMA_NOWAIT); + if (err != 0) /* TODO: Undo the mapping */ + return (-err); + + cur_index = cbdata.cur_index; + + /* Save the mbuf address in the last entry. We always have some data + * that has been mapped so rdata is always advanced past the last + * piece of mapped data - use the entry pointed to by cur_index - 1. + */ + rdata = XGBE_GET_DESC_DATA(ring, cur_index - 1); + rdata->mb = m; + rdata->mbuf_free = 1; + + /* Save the number of descriptor entries used */ + packet->rdesc_count = cur_index - start_index; + + DBGPR("<--xgbe_map_tx_skb: count=%u\n", packet->rdesc_count); + + return packet->rdesc_count; +} + +void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if) +{ + DBGPR("-->xgbe_init_function_ptrs_desc\n"); + + desc_if->alloc_ring_resources = xgbe_alloc_ring_resources; + desc_if->free_ring_resources = xgbe_free_ring_resources; + desc_if->map_tx_skb = xgbe_map_tx_skb; + desc_if->map_rx_buffer = xgbe_map_rx_buffer; + desc_if->unmap_rdata = xgbe_unmap_rdata; + desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init; + desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init; + + DBGPR("<--xgbe_init_function_ptrs_desc\n"); +} diff --git a/sys/dev/axgbe/xgbe-dev.c b/sys/dev/axgbe/xgbe-dev.c new file mode 100644 index 000000000000..3a0c65cfa7c9 --- /dev/null +++ b/sys/dev/axgbe/xgbe-dev.c @@ -0,0 +1,2307 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014-2016 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> + +#include "xgbe.h" +#include "xgbe-common.h" + +#include <net/if_dl.h> +#include <net/if_var.h> + +static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata, + unsigned int usec) +{ + unsigned long rate; + unsigned int ret; + + DBGPR("-->xgbe_usec_to_riwt\n"); + + rate = pdata->sysclk_rate; + + /* + * Convert the input usec value to the watchdog timer value. Each + * watchdog timer value is equivalent to 256 clock cycles. + * Calculate the required value as: + * ( usec * ( system_clock_mhz / 10^6 ) / 256 + */ + ret = (usec * (rate / 1000000)) / 256; + + DBGPR("<--xgbe_usec_to_riwt\n"); + + return ret; +} + +static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata, + unsigned int riwt) +{ + unsigned long rate; + unsigned int ret; + + DBGPR("-->xgbe_riwt_to_usec\n"); + + rate = pdata->sysclk_rate; + + /* + * Convert the input watchdog timer value to the usec value. Each + * watchdog timer value is equivalent to 256 clock cycles. + * Calculate the required value as: + * ( riwt * 256 ) / ( system_clock_mhz / 10^6 ) + */ + ret = (riwt * 256) / (rate / 1000000); + + DBGPR("<--xgbe_riwt_to_usec\n"); + + return ret; +} + +static int xgbe_config_pblx8(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, PBLX8, + pdata->pblx8); + + return 0; +} + +static int xgbe_get_tx_pbl_val(struct xgbe_prv_data *pdata) +{ + return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_TCR, PBL); +} + +static int xgbe_config_tx_pbl_val(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, PBL, + pdata->tx_pbl); + } + + return 0; +} + +static int xgbe_get_rx_pbl_val(struct xgbe_prv_data *pdata) +{ + return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_RCR, PBL); +} + +static int xgbe_config_rx_pbl_val(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, PBL, + pdata->rx_pbl); + } + + return 0; +} + +static int xgbe_config_osp_mode(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, OSP, + pdata->tx_osp_mode); + } + + return 0; +} + +static int xgbe_config_rsf_mode(struct xgbe_prv_data *pdata, unsigned int val) +{ + unsigned int i; + + for (i = 0; i < pdata->rx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RSF, val); + + return 0; +} + +static int xgbe_config_tsf_mode(struct xgbe_prv_data *pdata, unsigned int val) +{ + unsigned int i; + + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TSF, val); + + return 0; +} + +static int xgbe_config_rx_threshold(struct xgbe_prv_data *pdata, + unsigned int val) +{ + unsigned int i; + + for (i = 0; i < pdata->rx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RTC, val); + + return 0; +} + +static int xgbe_config_tx_threshold(struct xgbe_prv_data *pdata, + unsigned int val) +{ + unsigned int i; + + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TTC, val); + + return 0; +} + +static int xgbe_config_rx_coalesce(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RIWT, RWT, + pdata->rx_riwt); + } + + return 0; +} + +static int xgbe_config_tx_coalesce(struct xgbe_prv_data *pdata) +{ + return 0; +} + +static void xgbe_config_rx_buffer_size(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, RBSZ, + pdata->rx_buf_size); + } +} + +static void xgbe_config_tso_mode(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, TSE, 1); + } +} + +static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, SPH, 1); + } + + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE); +} + +static int xgbe_disable_rss(struct xgbe_prv_data *pdata) +{ + if (!pdata->hw_feat.rss) + return -EOPNOTSUPP; + + XGMAC_IOWRITE_BITS(pdata, MAC_RSSCR, RSSE, 0); + + return 0; +} + +static void xgbe_config_rss(struct xgbe_prv_data *pdata) +{ + + if (!pdata->hw_feat.rss) + return; + + xgbe_disable_rss(pdata); +} + +static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) +{ + unsigned int max_q_count, q_count; + unsigned int reg, reg_val; + unsigned int i; + + /* Clear MTL flow control */ + for (i = 0; i < pdata->rx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0); + + /* Clear MAC flow control */ + max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; + q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + reg = MAC_Q0TFCR; + for (i = 0; i < q_count; i++) { + reg_val = XGMAC_IOREAD(pdata, reg); + XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 0); + XGMAC_IOWRITE(pdata, reg, reg_val); + + reg += MAC_QTFCR_INC; + } + + return 0; +} + +static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata) +{ + unsigned int max_q_count, q_count; + unsigned int reg, reg_val; + unsigned int i; + + /* Set MTL flow control */ + for (i = 0; i < pdata->rx_q_count; i++) { + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 1); + } + + /* Set MAC flow control */ + max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; + q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + reg = MAC_Q0TFCR; + for (i = 0; i < q_count; i++) { + reg_val = XGMAC_IOREAD(pdata, reg); + + /* Enable transmit flow control */ + XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 1); + /* Set pause time */ + XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, 0xffff); + + XGMAC_IOWRITE(pdata, reg, reg_val); + + reg += MAC_QTFCR_INC; + } + + return 0; +} + +static int xgbe_disable_rx_flow_control(struct xgbe_prv_data *pdata) +{ + XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 0); + + return 0; +} + +static int xgbe_enable_rx_flow_control(struct xgbe_prv_data *pdata) +{ + XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 1); + + return 0; +} + +static int xgbe_config_tx_flow_control(struct xgbe_prv_data *pdata) +{ + + if (pdata->tx_pause) + xgbe_enable_tx_flow_control(pdata); + else + xgbe_disable_tx_flow_control(pdata); + + return 0; +} + +static int xgbe_config_rx_flow_control(struct xgbe_prv_data *pdata) +{ + + if (pdata->rx_pause) + xgbe_enable_rx_flow_control(pdata); + else + xgbe_disable_rx_flow_control(pdata); + + return 0; +} + +static void xgbe_config_flow_control(struct xgbe_prv_data *pdata) +{ + + xgbe_config_tx_flow_control(pdata); + xgbe_config_rx_flow_control(pdata); + + XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0); +} + +static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int dma_ch_isr, dma_ch_ier; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + /* Clear all the interrupts which are set */ + dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR); + XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr); + + /* Clear all interrupt enable bits */ + dma_ch_ier = 0; + + /* Enable following interrupts + * NIE - Normal Interrupt Summary Enable + * AIE - Abnormal Interrupt Summary Enable + * FBEE - Fatal Bus Error Enable + */ + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, NIE, 1); + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, AIE, 1); + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1); + + if (channel->tx_ring) { + /* Enable the following Tx interrupts + * TIE - Transmit Interrupt Enable (unless using + * per channel interrupts) + */ + if (!pdata->per_channel_irq) + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1); + } + if (channel->rx_ring) { + /* Enable following Rx interrupts + * RBUE - Receive Buffer Unavailable Enable + * RIE - Receive Interrupt Enable (unless using + * per channel interrupts) + */ + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1); + if (!pdata->per_channel_irq) + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1); + } + + XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier); + } +} + +static void xgbe_enable_mtl_interrupts(struct xgbe_prv_data *pdata) +{ + unsigned int mtl_q_isr; + unsigned int q_count, i; + + q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt); + for (i = 0; i < q_count; i++) { + /* Clear all the interrupts which are set */ + mtl_q_isr = XGMAC_MTL_IOREAD(pdata, i, MTL_Q_ISR); + XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, mtl_q_isr); + + /* No MTL interrupts to be enabled */ + XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_IER, 0); + } +} + +static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata) +{ + unsigned int mac_ier = 0; + + /* Enable Timestamp interrupt */ + XGMAC_SET_BITS(mac_ier, MAC_IER, TSIE, 1); + + XGMAC_IOWRITE(pdata, MAC_IER, mac_ier); + + /* Enable all counter interrupts */ + XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff); + XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff); +} + +static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata) +{ + if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x3) + return 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3); + + return 0; +} + +static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata) +{ + if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x2) + return 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2); + + return 0; +} + +static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata) +{ + if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0) + return 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0); + + return 0; +} + +static int xgbe_enable_rx_vlan_stripping(struct xgbe_prv_data *pdata) +{ + /* Put the VLAN tag in the Rx descriptor */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1); + + /* Don't check the VLAN type */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1); + + /* Check only C-TAG (0x8100) packets */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0); + + /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0); + + /* Enable VLAN tag stripping */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3); + + return 0; +} + +static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata) +{ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0); + + return 0; +} + +static int xgbe_enable_rx_vlan_filtering(struct xgbe_prv_data *pdata) +{ + /* Enable VLAN filtering */ + XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1); + + /* Enable VLAN Hash Table filtering */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1); + + /* Disable VLAN tag inverse matching */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0); + + /* Only filter on the lower 12-bits of the VLAN tag */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1); + + /* In order for the VLAN Hash Table filtering to be effective, + * the VLAN tag identifier in the VLAN Tag Register must not + * be zero. Set the VLAN tag identifier to "1" to enable the + * VLAN Hash Table filtering. This implies that a VLAN tag of + * 1 will always pass filtering. + */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1); + + return 0; +} + +static int xgbe_disable_rx_vlan_filtering(struct xgbe_prv_data *pdata) +{ + /* Disable VLAN filtering */ + XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0); + + return 0; +} + +static int xgbe_update_vlan_hash_table(struct xgbe_prv_data *pdata) +{ + u16 vlan_hash_table = 0; + + /* Set the VLAN Hash Table filtering register */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table); + + return 0; +} + +static int xgbe_set_promiscuous_mode(struct xgbe_prv_data *pdata, + unsigned int enable) +{ + unsigned int val = enable ? 1 : 0; + + if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PR) == val) + return 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, val); + + /* Hardware will still perform VLAN filtering in promiscuous mode */ + xgbe_disable_rx_vlan_filtering(pdata); + + return 0; +} + +static int xgbe_set_all_multicast_mode(struct xgbe_prv_data *pdata, + unsigned int enable) +{ + unsigned int val = enable ? 1 : 0; + + if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PM) == val) + return 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, val); + + return 0; +} + +static void xgbe_set_mac_reg(struct xgbe_prv_data *pdata, + char *addr, unsigned int *mac_reg) +{ + unsigned int mac_addr_hi, mac_addr_lo; + u8 *mac_addr; + + mac_addr_lo = 0; + mac_addr_hi = 0; + + if (addr) { + mac_addr = (u8 *)&mac_addr_lo; + mac_addr[0] = addr[0]; + mac_addr[1] = addr[1]; + mac_addr[2] = addr[2]; + mac_addr[3] = addr[3]; + mac_addr = (u8 *)&mac_addr_hi; + mac_addr[0] = addr[4]; + mac_addr[1] = addr[5]; + + XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1); + } + + XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_hi); + *mac_reg += MAC_MACA_INC; + XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_lo); + *mac_reg += MAC_MACA_INC; +} + +static void xgbe_set_mac_addn_addrs(struct xgbe_prv_data *pdata) +{ + unsigned int mac_reg; + unsigned int addn_macs; + + mac_reg = MAC_MACA1HR; + addn_macs = pdata->hw_feat.addn_mac; + + xgbe_set_mac_reg(pdata, pdata->mac_addr, &mac_reg); + addn_macs--; + + /* Clear remaining additional MAC address entries */ + while (addn_macs--) + xgbe_set_mac_reg(pdata, NULL, &mac_reg); +} + +static int xgbe_add_mac_addresses(struct xgbe_prv_data *pdata) +{ + xgbe_set_mac_addn_addrs(pdata); + + return 0; +} + +static int xgbe_set_mac_address(struct xgbe_prv_data *pdata, u8 *addr) +{ + unsigned int mac_addr_hi, mac_addr_lo; + + mac_addr_hi = (addr[5] << 8) | (addr[4] << 0); + mac_addr_lo = (addr[3] << 24) | (addr[2] << 16) | + (addr[1] << 8) | (addr[0] << 0); + + XGMAC_IOWRITE(pdata, MAC_MACA0HR, mac_addr_hi); + XGMAC_IOWRITE(pdata, MAC_MACA0LR, mac_addr_lo); + + return 0; +} + +static int xgbe_config_rx_mode(struct xgbe_prv_data *pdata) +{ + unsigned int pr_mode, am_mode; + + /* XXX */ + pr_mode = 0; + am_mode = 0; + + xgbe_set_promiscuous_mode(pdata, pr_mode); + xgbe_set_all_multicast_mode(pdata, am_mode); + + xgbe_add_mac_addresses(pdata); + + return 0; +} + +static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad, + int mmd_reg) +{ + unsigned long flags; + unsigned int mmd_address; + int mmd_data; + + if (mmd_reg & MII_ADDR_C45) + mmd_address = mmd_reg & ~MII_ADDR_C45; + else + mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff); + + /* The PCS registers are accessed using mmio. The underlying APB3 + * management interface uses indirect addressing to access the MMD + * register sets. This requires accessing of the PCS register in two + * phases, an address phase and a data phase. + * + * The mmio interface is based on 32-bit offsets and values. All + * register offsets must therefore be adjusted by left shifting the + * offset 2 bits and reading 32 bits of data. + */ + spin_lock_irqsave(&pdata->xpcs_lock, flags); + XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8); + mmd_data = XPCS_IOREAD(pdata, (mmd_address & 0xff) << 2); + spin_unlock_irqrestore(&pdata->xpcs_lock, flags); + + return mmd_data; +} + +static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad, + int mmd_reg, int mmd_data) +{ + unsigned int mmd_address; + unsigned long flags; + + if (mmd_reg & MII_ADDR_C45) + mmd_address = mmd_reg & ~MII_ADDR_C45; + else + mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff); + + /* The PCS registers are accessed using mmio. The underlying APB3 + * management interface uses indirect addressing to access the MMD + * register sets. This requires accessing of the PCS register in two + * phases, an address phase and a data phase. + * + * The mmio interface is based on 32-bit offsets and values. All + * register offsets must therefore be adjusted by left shifting the + * offset 2 bits and reading 32 bits of data. + */ + spin_lock_irqsave(&pdata->xpcs_lock, flags); + XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8); + XPCS_IOWRITE(pdata, (mmd_address & 0xff) << 2, mmd_data); + spin_unlock_irqrestore(&pdata->xpcs_lock, flags); +} + +static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc) +{ + return !XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN); +} + +static int xgbe_disable_rx_csum(struct xgbe_prv_data *pdata) +{ + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 0); + + return 0; +} + +static int xgbe_enable_rx_csum(struct xgbe_prv_data *pdata) +{ + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 1); + + return 0; +} + +static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata) +{ + struct xgbe_ring_desc *rdesc = rdata->rdesc; + + /* Reset the Tx descriptor + * Set buffer 1 (lo) address to zero + * Set buffer 1 (hi) address to zero + * Reset all other control bits (IC, TTSE, B2L & B1L) + * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC, etc) + */ + rdesc->desc0 = 0; + rdesc->desc1 = 0; + rdesc->desc2 = 0; + rdesc->desc3 = 0; + + dsb(sy); +} + +static void xgbe_tx_desc_init(struct xgbe_channel *channel) +{ + struct xgbe_ring *ring = channel->tx_ring; + struct xgbe_ring_data *rdata; + int i; + int start_index = ring->cur; + + DBGPR("-->tx_desc_init\n"); + + /* Initialze all descriptors */ + for (i = 0; i < ring->rdesc_count; i++) { + rdata = XGBE_GET_DESC_DATA(ring, i); + + /* Initialize Tx descriptor */ + xgbe_tx_desc_reset(rdata); + } + + /* Update the total number of Tx descriptors */ + XGMAC_DMA_IOWRITE(channel, DMA_CH_TDRLR, ring->rdesc_count - 1); + + /* Update the starting address of descriptor ring */ + rdata = XGBE_GET_DESC_DATA(ring, start_index); + XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_HI, + upper_32_bits(rdata->rdata_paddr)); + XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_LO, + lower_32_bits(rdata->rdata_paddr)); + + DBGPR("<--tx_desc_init\n"); +} + +static void xgbe_rx_desc_reset(struct xgbe_prv_data *pdata, + struct xgbe_ring_data *rdata, unsigned int index) +{ + struct xgbe_ring_desc *rdesc = rdata->rdesc; + unsigned int inte; + + inte = 1; + + /* Reset the Rx descriptor + * Set buffer 1 (lo) address to header dma address (lo) + * Set buffer 1 (hi) address to header dma address (hi) + * Set buffer 2 (lo) address to buffer dma address (lo) + * Set buffer 2 (hi) address to buffer dma address (hi) and + * set control bits OWN and INTE + */ + rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->mbuf_hdr_paddr)); + rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->mbuf_hdr_paddr)); + rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->mbuf_data_paddr)); + rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->mbuf_data_paddr)); + + XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE, inte); + + dsb(sy); + + XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN, 1); + + dsb(sy); +} + +static void xgbe_rx_desc_init(struct xgbe_channel *channel) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_ring *ring = channel->rx_ring; + struct xgbe_ring_data *rdata; + unsigned int start_index = ring->cur; + unsigned int i; + + DBGPR("-->rx_desc_init\n"); + + /* Initialize all descriptors */ + for (i = 0; i < ring->rdesc_count; i++) { + rdata = XGBE_GET_DESC_DATA(ring, i); + + /* Initialize Rx descriptor */ + xgbe_rx_desc_reset(pdata, rdata, i); + } + + bus_dmamap_sync(ring->rdesc_dmat, ring->rdesc_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* Update the total number of Rx descriptors */ + XGMAC_DMA_IOWRITE(channel, DMA_CH_RDRLR, ring->rdesc_count - 1); + + /* Update the starting address of descriptor ring */ + rdata = XGBE_GET_DESC_DATA(ring, start_index); + XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_HI, + upper_32_bits(rdata->rdata_paddr)); + XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_LO, + lower_32_bits(rdata->rdata_paddr)); + + /* Update the Rx Descriptor Tail Pointer */ + rdata = XGBE_GET_DESC_DATA(ring, start_index + ring->rdesc_count - 1); + XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO, + lower_32_bits(rdata->rdata_paddr)); + + DBGPR("<--rx_desc_init\n"); +} + +static void xgbe_tx_start_xmit(struct xgbe_channel *channel, + struct xgbe_ring *ring) +{ + struct xgbe_ring_data *rdata; + + /* Issue a poll command to Tx DMA by writing address + * of next immediate free descriptor */ + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO, + lower_32_bits(rdata->rdata_paddr)); + + ring->tx.xmit_more = 0; +} + +static void xgbe_dev_xmit(struct xgbe_channel *channel) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_ring *ring = channel->tx_ring; + struct xgbe_ring_data *rdata; + struct xgbe_ring_desc *rdesc; + struct xgbe_packet_data *packet = &ring->packet_data; + unsigned int tx_set_ic; + int start_index = ring->cur; + int cur_index = ring->cur; + int i; + + DBGPR("-->xgbe_dev_xmit\n"); + + /* Determine if an interrupt should be generated for this Tx: + * Interrupt: + * - Tx frame count exceeds the frame count setting + * - Addition of Tx frame count to the frame count since the + * last interrupt was set exceeds the frame count setting + * No interrupt: + * - No frame count setting specified (ethtool -C ethX tx-frames 0) + * - Addition of Tx frame count to the frame count since the + * last interrupt was set does not exceed the frame count setting + */ + ring->coalesce_count += packet->tx_packets; + if (!pdata->tx_frames) + tx_set_ic = 0; + else if (packet->tx_packets > pdata->tx_frames) + tx_set_ic = 1; + else if ((ring->coalesce_count % pdata->tx_frames) < + packet->tx_packets) + tx_set_ic = 1; + else + tx_set_ic = 0; + tx_set_ic = 1; + + rdata = XGBE_GET_DESC_DATA(ring, cur_index); + rdesc = rdata->rdesc; + + /* Update buffer address (for TSO this is the header) */ + rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->mbuf_data_paddr)); + rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->mbuf_data_paddr)); + + /* Update the buffer length */ + XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L, + rdata->mbuf_len); + + /* Timestamp enablement check */ + if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) + XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1); + + /* Mark it as First Descriptor */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1); + + /* Mark it as a NORMAL descriptor */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0); + + /* Set OWN bit if not the first descriptor */ + if (cur_index != start_index) + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); + + /* Enable CRC and Pad Insertion */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CPC, 0); + + /* Set the total length to be transmitted */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FL, + packet->length); + + for (i = cur_index - start_index + 1; i < packet->rdesc_count; i++) { + cur_index++; + rdata = XGBE_GET_DESC_DATA(ring, cur_index); + rdesc = rdata->rdesc; + + /* Update buffer address */ + rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->mbuf_data_paddr)); + rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->mbuf_data_paddr)); + + /* Update the buffer length */ + XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L, + rdata->mbuf_len); + + /* Set OWN bit */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); + + /* Mark it as NORMAL descriptor */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0); + } + + /* Set LAST bit for the last descriptor */ + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1); + + /* Set IC bit based on Tx coalescing settings */ + if (tx_set_ic) + XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); + + /* Save the Tx info to report back during cleanup */ + rdata->tx.packets = packet->tx_packets; + rdata->tx.bytes = packet->tx_bytes; + + /* Sync the DMA buffers */ + bus_dmamap_sync(ring->rdesc_dmat, ring->rdesc_map, + BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(ring->mbuf_dmat, ring->mbuf_map, + BUS_DMASYNC_PREWRITE); + + /* In case the Tx DMA engine is running, make sure everything + * is written to the descriptor(s) before setting the OWN bit + * for the first descriptor + */ + + /* Set OWN bit for the first descriptor */ + rdata = XGBE_GET_DESC_DATA(ring, start_index); + rdesc = rdata->rdesc; + XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); + + /* Sync to ensure the OWN bit was seen */ + bus_dmamap_sync(ring->rdesc_dmat, ring->rdesc_map, + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + ring->cur = cur_index + 1; + xgbe_tx_start_xmit(channel, ring); + + DBGPR(" %s: descriptors %u to %u written\n", + channel->name, start_index & (ring->rdesc_count - 1), + (ring->cur - 1) & (ring->rdesc_count - 1)); + + DBGPR("<--xgbe_dev_xmit\n"); +} + +static int xgbe_dev_read(struct xgbe_channel *channel) +{ + struct xgbe_ring *ring = channel->rx_ring; + struct xgbe_ring_data *rdata; + struct xgbe_ring_desc *rdesc; + struct xgbe_packet_data *packet = &ring->packet_data; + unsigned int err, etlt; + + DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur); + + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + rdesc = rdata->rdesc; + + bus_dmamap_sync(ring->rdesc_dmat, ring->rdesc_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + dsb(sy); + + /* Check for data availability */ + if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN)) + return 1; + + dsb(sy); + + /* Normal Descriptor, be sure Context Descriptor bit is off */ + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, CONTEXT, 0); + + /* Indicate if a Context Descriptor is next */ + if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, CDA)) + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, + CONTEXT_NEXT, 1); + + /* Get the header length */ + if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, FD)) { + rdata->rx.hdr_len = XGMAC_GET_BITS_LE(rdesc->desc2, + RX_NORMAL_DESC2, HL); + } + + /* Get the packet length */ + rdata->rx.len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL); + + if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) { + /* Not all the data has been transferred for this packet */ + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, + INCOMPLETE, 1); + return 0; + } + + /* This is the last of the data for this packet */ + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, + INCOMPLETE, 0); + + /* Check for errors (only valid in last descriptor) */ + err = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ES); + etlt = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ETLT); + + if (err && etlt) { + if ((etlt == 0x05) || (etlt == 0x06)) + XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, + CSUM_DONE, 0); + else + XGMAC_SET_BITS(packet->errors, RX_PACKET_ERRORS, + FRAME, 1); + } + + bus_dmamap_sync(ring->mbuf_dmat, rdata->mbuf_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + + DBGPR("<--xgbe_dev_read: %s - descriptor=%u (cur=%d)\n", channel->name, + ring->cur & (ring->rdesc_count - 1), ring->cur); + + return 0; +} + +static int xgbe_is_context_desc(struct xgbe_ring_desc *rdesc) +{ + /* Rx and Tx share CTXT bit, so check TDES3.CTXT bit */ + return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT); +} + +static int xgbe_is_last_desc(struct xgbe_ring_desc *rdesc) +{ + /* Rx and Tx share LD bit, so check TDES3.LD bit */ + return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD); +} + +static int xgbe_enable_int(struct xgbe_channel *channel, + enum xgbe_int int_id) +{ + unsigned int dma_ch_ier; + + dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER); + + switch (int_id) { + case XGMAC_INT_DMA_CH_SR_TI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1); + break; + case XGMAC_INT_DMA_CH_SR_TPS: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 1); + break; + case XGMAC_INT_DMA_CH_SR_TBU: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 1); + break; + case XGMAC_INT_DMA_CH_SR_RI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1); + break; + case XGMAC_INT_DMA_CH_SR_RBU: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1); + break; + case XGMAC_INT_DMA_CH_SR_RPS: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 1); + break; + case XGMAC_INT_DMA_CH_SR_TI_RI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1); + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1); + break; + case XGMAC_INT_DMA_CH_SR_FBE: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1); + break; + case XGMAC_INT_DMA_ALL: + dma_ch_ier |= channel->saved_ier; + break; + default: + return -1; + } + + XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier); + + return 0; +} + +static int xgbe_disable_int(struct xgbe_channel *channel, + enum xgbe_int int_id) +{ + unsigned int dma_ch_ier; + + dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER); + + switch (int_id) { + case XGMAC_INT_DMA_CH_SR_TI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0); + break; + case XGMAC_INT_DMA_CH_SR_TPS: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 0); + break; + case XGMAC_INT_DMA_CH_SR_TBU: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 0); + break; + case XGMAC_INT_DMA_CH_SR_RI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0); + break; + case XGMAC_INT_DMA_CH_SR_RBU: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 0); + break; + case XGMAC_INT_DMA_CH_SR_RPS: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 0); + break; + case XGMAC_INT_DMA_CH_SR_TI_RI: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0); + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0); + break; + case XGMAC_INT_DMA_CH_SR_FBE: + XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 0); + break; + case XGMAC_INT_DMA_ALL: + channel->saved_ier = dma_ch_ier & XGBE_DMA_INTERRUPT_MASK; + dma_ch_ier &= ~XGBE_DMA_INTERRUPT_MASK; + break; + default: + return -1; + } + + XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier); + + return 0; +} + +static int xgbe_exit(struct xgbe_prv_data *pdata) +{ + unsigned int count = 2000; + + DBGPR("-->xgbe_exit\n"); + + /* Issue a software reset */ + XGMAC_IOWRITE_BITS(pdata, DMA_MR, SWR, 1); + DELAY(10); + + /* Poll Until Poll Condition */ + while (--count && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR)) + DELAY(500); + + if (!count) + return -EBUSY; + + DBGPR("<--xgbe_exit\n"); + + return 0; +} + +static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata) +{ + unsigned int i, count; + + if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) < 0x21) + return 0; + + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1); + + /* Poll Until Poll Condition */ + for (i = 0; i < pdata->tx_q_count; i++) { + count = 2000; + while (--count && XGMAC_MTL_IOREAD_BITS(pdata, i, + MTL_Q_TQOMR, FTQ)) + DELAY(500); + + if (!count) + return -EBUSY; + } + + return 0; +} + +static void xgbe_config_dma_bus(struct xgbe_prv_data *pdata) +{ + /* Set enhanced addressing mode */ + XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, EAME, 1); + + /* Set the System Bus mode */ + XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, UNDEF, 1); + XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, BLEN_256, 1); +} + +static void xgbe_config_dma_cache(struct xgbe_prv_data *pdata) +{ + unsigned int arcache, awcache; + + arcache = 0; + XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, pdata->arcache); + XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRD, pdata->axdomain); + XGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, pdata->arcache); + XGMAC_SET_BITS(arcache, DMA_AXIARCR, TED, pdata->axdomain); + XGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, pdata->arcache); + XGMAC_SET_BITS(arcache, DMA_AXIARCR, THD, pdata->axdomain); + XGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache); + + awcache = 0; + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, pdata->awcache); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWD, pdata->axdomain); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, pdata->awcache); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, pdata->axdomain); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, pdata->awcache); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, pdata->axdomain); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDC, pdata->awcache); + XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDD, pdata->axdomain); + XGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache); +} + +static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata) +{ + unsigned int i; + + /* Set Tx to weighted round robin scheduling algorithm */ + XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_WRR); + + /* Set Tx traffic classes to use WRR algorithm with equal weights */ + for (i = 0; i < pdata->hw_feat.tc_cnt; i++) { + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA, + MTL_TSA_ETS); + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW, 1); + } + + /* Set Rx to strict priority algorithm */ + XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP); +} + +static unsigned int xgbe_calculate_per_queue_fifo(unsigned int fifo_size, + unsigned int queue_count) +{ + unsigned int q_fifo_size; + unsigned int p_fifo; + + /* Calculate the configured fifo size */ + q_fifo_size = 1 << (fifo_size + 7); + + /* The configured value may not be the actual amount of fifo RAM */ + q_fifo_size = min_t(unsigned int, XGBE_FIFO_MAX, q_fifo_size); + + q_fifo_size = q_fifo_size / queue_count; + + /* Each increment in the queue fifo size represents 256 bytes of + * fifo, with 0 representing 256 bytes. Distribute the fifo equally + * between the queues. + */ + p_fifo = q_fifo_size / 256; + if (p_fifo) + p_fifo--; + + return p_fifo; +} + +static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata) +{ + unsigned int fifo_size; + unsigned int i; + + fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size, + pdata->tx_q_count); + + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, fifo_size); +} + +static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata) +{ + unsigned int fifo_size; + unsigned int i; + + fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.rx_fifo_size, + pdata->rx_q_count); + + for (i = 0; i < pdata->rx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, fifo_size); +} + +static void xgbe_config_queue_mapping(struct xgbe_prv_data *pdata) +{ + unsigned int qptc, qptc_extra, queue; + unsigned int prio_queues; + unsigned int ppq, ppq_extra, prio; + unsigned int mask; + unsigned int i, j, reg, reg_val; + + /* Map the MTL Tx Queues to Traffic Classes + * Note: Tx Queues >= Traffic Classes + */ + qptc = pdata->tx_q_count / pdata->hw_feat.tc_cnt; + qptc_extra = pdata->tx_q_count % pdata->hw_feat.tc_cnt; + + for (i = 0, queue = 0; i < pdata->hw_feat.tc_cnt; i++) { + for (j = 0; j < qptc; j++) { + XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR, + Q2TCMAP, i); + pdata->q2tc_map[queue++] = i; + } + + if (i < qptc_extra) { + XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR, + Q2TCMAP, i); + pdata->q2tc_map[queue++] = i; + } + } + + /* Map the 8 VLAN priority values to available MTL Rx queues */ + prio_queues = min_t(unsigned int, IEEE_8021QAZ_MAX_TCS, + pdata->rx_q_count); + ppq = IEEE_8021QAZ_MAX_TCS / prio_queues; + ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues; + + reg = MAC_RQC2R; + reg_val = 0; + for (i = 0, prio = 0; i < prio_queues;) { + mask = 0; + for (j = 0; j < ppq; j++) { + mask |= (1 << prio); + pdata->prio2q_map[prio++] = i; + } + + if (i < ppq_extra) { + mask |= (1 << prio); + pdata->prio2q_map[prio++] = i; + } + + reg_val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3)); + + if ((i % MAC_RQC2_Q_PER_REG) && (i != prio_queues)) + continue; + + XGMAC_IOWRITE(pdata, reg, reg_val); + reg += MAC_RQC2_INC; + reg_val = 0; + } + + /* Select dynamic mapping of MTL Rx queue to DMA Rx channel */ + reg = MTL_RQDCM0R; + reg_val = 0; + for (i = 0; i < pdata->rx_q_count;) { + reg_val |= (0x80 << ((i++ % MTL_RQDCM_Q_PER_REG) << 3)); + + if ((i % MTL_RQDCM_Q_PER_REG) && (i != pdata->rx_q_count)) + continue; + + XGMAC_IOWRITE(pdata, reg, reg_val); + + reg += MTL_RQDCM_INC; + reg_val = 0; + } +} + +static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata) +{ + unsigned int i; + + for (i = 0; i < pdata->rx_q_count; i++) { + /* Activate flow control when less than 4k left in fifo */ + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA, 2); + + /* De-activate flow control when more than 6k left in fifo */ + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD, 4); + } +} + +static void xgbe_config_mac_address(struct xgbe_prv_data *pdata) +{ + + xgbe_set_mac_address(pdata, IF_LLADDR(pdata->netdev)); +} + +static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata) +{ + unsigned int val; + + val = (if_getmtu(pdata->netdev) > XGMAC_STD_PACKET_MTU) ? 1 : 0; + + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val); +} + +static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata) +{ + switch (pdata->phy_speed) { + case SPEED_10000: + xgbe_set_xgmii_speed(pdata); + break; + + case SPEED_2500: + xgbe_set_gmii_2500_speed(pdata); + break; + + case SPEED_1000: + xgbe_set_gmii_speed(pdata); + break; + case SPEED_UNKNOWN: + break; + default: + panic("TODO %s:%d\n", __FILE__, __LINE__); + } +} + +static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata) +{ + if ((if_getcapenable(pdata->netdev) & IFCAP_RXCSUM) != 0) + xgbe_enable_rx_csum(pdata); + else + xgbe_disable_rx_csum(pdata); +} + +static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata) +{ + /* Indicate that VLAN Tx CTAGs come from context descriptors */ + XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 0); + XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, VLTI, 1); + + /* Set the current VLAN Hash Table register value */ + xgbe_update_vlan_hash_table(pdata); + + xgbe_disable_rx_vlan_filtering(pdata); + xgbe_disable_rx_vlan_stripping(pdata); +} + +static u64 xgbe_mmc_read(struct xgbe_prv_data *pdata, unsigned int reg_lo) +{ + bool read_hi; + u64 val; + + switch (reg_lo) { + /* These registers are always 64 bit */ + case MMC_TXOCTETCOUNT_GB_LO: + case MMC_TXOCTETCOUNT_G_LO: + case MMC_RXOCTETCOUNT_GB_LO: + case MMC_RXOCTETCOUNT_G_LO: + read_hi = true; + break; + + default: + read_hi = false; + } + + val = XGMAC_IOREAD(pdata, reg_lo); + + if (read_hi) + val |= ((u64)XGMAC_IOREAD(pdata, reg_lo + 4) << 32); + + return val; +} + +static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata) +{ + struct xgbe_mmc_stats *stats = &pdata->mmc_stats; + unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_TISR); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB)) + stats->txoctetcount_gb += + xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB)) + stats->txframecount_gb += + xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G)) + stats->txbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G)) + stats->txmulticastframes_g += + xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB)) + stats->tx64octets_gb += + xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB)) + stats->tx65to127octets_gb += + xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB)) + stats->tx128to255octets_gb += + xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB)) + stats->tx256to511octets_gb += + xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB)) + stats->tx512to1023octets_gb += + xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB)) + stats->tx1024tomaxoctets_gb += + xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB)) + stats->txunicastframes_gb += + xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB)) + stats->txmulticastframes_gb += + xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB)) + stats->txbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR)) + stats->txunderflowerror += + xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G)) + stats->txoctetcount_g += + xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G)) + stats->txframecount_g += + xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES)) + stats->txpauseframes += + xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G)) + stats->txvlanframes_g += + xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO); +} + +static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata) +{ + struct xgbe_mmc_stats *stats = &pdata->mmc_stats; + unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_RISR); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB)) + stats->rxframecount_gb += + xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB)) + stats->rxoctetcount_gb += + xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G)) + stats->rxoctetcount_g += + xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G)) + stats->rxbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G)) + stats->rxmulticastframes_g += + xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR)) + stats->rxcrcerror += + xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR)) + stats->rxrunterror += + xgbe_mmc_read(pdata, MMC_RXRUNTERROR); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR)) + stats->rxjabbererror += + xgbe_mmc_read(pdata, MMC_RXJABBERERROR); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G)) + stats->rxundersize_g += + xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G)) + stats->rxoversize_g += + xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB)) + stats->rx64octets_gb += + xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB)) + stats->rx65to127octets_gb += + xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB)) + stats->rx128to255octets_gb += + xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB)) + stats->rx256to511octets_gb += + xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB)) + stats->rx512to1023octets_gb += + xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB)) + stats->rx1024tomaxoctets_gb += + xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G)) + stats->rxunicastframes_g += + xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR)) + stats->rxlengtherror += + xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE)) + stats->rxoutofrangetype += + xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES)) + stats->rxpauseframes += + xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW)) + stats->rxfifooverflow += + xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB)) + stats->rxvlanframes_gb += + xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO); + + if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR)) + stats->rxwatchdogerror += + xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR); +} + +static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata) +{ + struct xgbe_mmc_stats *stats = &pdata->mmc_stats; + + /* Freeze counters */ + XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1); + + stats->txoctetcount_gb += + xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO); + + stats->txframecount_gb += + xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO); + + stats->txbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO); + + stats->txmulticastframes_g += + xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO); + + stats->tx64octets_gb += + xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO); + + stats->tx65to127octets_gb += + xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO); + + stats->tx128to255octets_gb += + xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO); + + stats->tx256to511octets_gb += + xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO); + + stats->tx512to1023octets_gb += + xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO); + + stats->tx1024tomaxoctets_gb += + xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); + + stats->txunicastframes_gb += + xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO); + + stats->txmulticastframes_gb += + xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO); + + stats->txbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO); + + stats->txunderflowerror += + xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO); + + stats->txoctetcount_g += + xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO); + + stats->txframecount_g += + xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO); + + stats->txpauseframes += + xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO); + + stats->txvlanframes_g += + xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO); + + stats->rxframecount_gb += + xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO); + + stats->rxoctetcount_gb += + xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO); + + stats->rxoctetcount_g += + xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO); + + stats->rxbroadcastframes_g += + xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO); + + stats->rxmulticastframes_g += + xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO); + + stats->rxcrcerror += + xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO); + + stats->rxrunterror += + xgbe_mmc_read(pdata, MMC_RXRUNTERROR); + + stats->rxjabbererror += + xgbe_mmc_read(pdata, MMC_RXJABBERERROR); + + stats->rxundersize_g += + xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G); + + stats->rxoversize_g += + xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G); + + stats->rx64octets_gb += + xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO); + + stats->rx65to127octets_gb += + xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO); + + stats->rx128to255octets_gb += + xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO); + + stats->rx256to511octets_gb += + xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO); + + stats->rx512to1023octets_gb += + xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO); + + stats->rx1024tomaxoctets_gb += + xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); + + stats->rxunicastframes_g += + xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO); + + stats->rxlengtherror += + xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO); + + stats->rxoutofrangetype += + xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO); + + stats->rxpauseframes += + xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO); + + stats->rxfifooverflow += + xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO); + + stats->rxvlanframes_gb += + xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO); + + stats->rxwatchdogerror += + xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR); + + /* Un-freeze counters */ + XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0); +} + +static void xgbe_config_mmc(struct xgbe_prv_data *pdata) +{ + /* Set counters to reset on read */ + XGMAC_IOWRITE_BITS(pdata, MMC_CR, ROR, 1); + + /* Reset the counters */ + XGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1); +} + +static void xgbe_prepare_tx_stop(struct xgbe_prv_data *pdata, + struct xgbe_channel *channel) +{ + unsigned int tx_dsr, tx_pos, tx_qidx; + unsigned int tx_status; + unsigned long tx_timeout; + + /* Calculate the status register to read and the position within */ + if (channel->queue_index < DMA_DSRX_FIRST_QUEUE) { + tx_dsr = DMA_DSR0; + tx_pos = (channel->queue_index * DMA_DSR_Q_WIDTH) + + DMA_DSR0_TPS_START; + } else { + tx_qidx = channel->queue_index - DMA_DSRX_FIRST_QUEUE; + + tx_dsr = DMA_DSR1 + ((tx_qidx / DMA_DSRX_QPR) * DMA_DSRX_INC); + tx_pos = ((tx_qidx % DMA_DSRX_QPR) * DMA_DSR_Q_WIDTH) + + DMA_DSRX_TPS_START; + } + + /* The Tx engine cannot be stopped if it is actively processing + * descriptors. Wait for the Tx engine to enter the stopped or + * suspended state. Don't wait forever though... + */ + tx_timeout = ticks + (XGBE_DMA_STOP_TIMEOUT * hz); + while (ticks < tx_timeout) { + tx_status = XGMAC_IOREAD(pdata, tx_dsr); + tx_status = GET_BITS(tx_status, tx_pos, DMA_DSR_TPS_WIDTH); + if ((tx_status == DMA_TPS_STOPPED) || + (tx_status == DMA_TPS_SUSPENDED)) + break; + + DELAY(500); + } +} + +static void xgbe_enable_tx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Enable each Tx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1); + } + + /* Enable each Tx queue */ + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, + MTL_Q_ENABLED); + + /* Enable MAC Tx */ + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1); +} + +static void xgbe_disable_tx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Prepare for Tx DMA channel stop */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + xgbe_prepare_tx_stop(pdata, channel); + } + + /* Disable MAC Tx */ + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0); + + /* Disable each Tx queue */ + for (i = 0; i < pdata->tx_q_count; i++) + XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, 0); + + /* Disable each Tx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0); + } +} + +static void xgbe_prepare_rx_stop(struct xgbe_prv_data *pdata, + unsigned int queue) +{ + unsigned int rx_status; + unsigned long rx_timeout; + + /* The Rx engine cannot be stopped if it is actively processing + * packets. Wait for the Rx queue to empty the Rx fifo. Don't + * wait forever though... + */ + rx_timeout = ticks + (XGBE_DMA_STOP_TIMEOUT * hz); + while (ticks < rx_timeout) { + rx_status = XGMAC_MTL_IOREAD(pdata, queue, MTL_Q_RQDR); + if ((XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, PRXQ) == 0) && + (XGMAC_GET_BITS(rx_status, MTL_Q_RQDR, RXQSTS) == 0)) + break; + + DELAY(500); + } +} + +static void xgbe_enable_rx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int reg_val, i; + + /* Enable each Rx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1); + } + + /* Enable each Rx queue */ + reg_val = 0; + for (i = 0; i < pdata->rx_q_count; i++) + reg_val |= (0x02 << (i << 1)); + XGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val); + + /* Enable MAC Rx */ + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 1); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 1); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 1); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 1); +} + +static void xgbe_disable_rx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Disable MAC Rx */ + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 0); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0); + XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0); + + /* Prepare for Rx DMA channel stop */ + for (i = 0; i < pdata->rx_q_count; i++) + xgbe_prepare_rx_stop(pdata, i); + + /* Disable each Rx queue */ + XGMAC_IOWRITE(pdata, MAC_RQC0R, 0); + + /* Disable each Rx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0); + } +} + +static void xgbe_powerup_tx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Enable each Tx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1); + } + + /* Enable MAC Tx */ + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1); +} + +static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Prepare for Tx DMA channel stop */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + xgbe_prepare_tx_stop(pdata, channel); + } + + /* Disable MAC Tx */ + XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0); + + /* Disable each Tx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->tx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0); + } +} + +static void xgbe_powerup_rx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Enable each Rx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1); + } +} + +static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + /* Disable each Rx DMA channel */ + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (!channel->rx_ring) + break; + + XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0); + } +} + +static int xgbe_init(struct xgbe_prv_data *pdata) +{ + struct xgbe_desc_if *desc_if = &pdata->desc_if; + int ret; + + DBGPR("-->xgbe_init\n"); + + /* Flush Tx queues */ + ret = xgbe_flush_tx_queues(pdata); + if (ret) + return ret; + + /* + * Initialize DMA related features + */ + xgbe_config_dma_bus(pdata); + xgbe_config_dma_cache(pdata); + xgbe_config_osp_mode(pdata); + xgbe_config_pblx8(pdata); + xgbe_config_tx_pbl_val(pdata); + xgbe_config_rx_pbl_val(pdata); + xgbe_config_rx_coalesce(pdata); + xgbe_config_tx_coalesce(pdata); + xgbe_config_rx_buffer_size(pdata); + xgbe_config_tso_mode(pdata); + xgbe_config_sph_mode(pdata); + xgbe_config_rss(pdata); + desc_if->wrapper_tx_desc_init(pdata); + desc_if->wrapper_rx_desc_init(pdata); + xgbe_enable_dma_interrupts(pdata); + + /* + * Initialize MTL related features + */ + xgbe_config_mtl_mode(pdata); + xgbe_config_queue_mapping(pdata); + xgbe_config_tsf_mode(pdata, pdata->tx_sf_mode); + xgbe_config_rsf_mode(pdata, pdata->rx_sf_mode); + xgbe_config_tx_threshold(pdata, pdata->tx_threshold); + xgbe_config_rx_threshold(pdata, pdata->rx_threshold); + xgbe_config_tx_fifo_size(pdata); + xgbe_config_rx_fifo_size(pdata); + xgbe_config_flow_control_threshold(pdata); + /*TODO: Error Packet and undersized good Packet forwarding enable + (FEP and FUP) + */ + xgbe_enable_mtl_interrupts(pdata); + + /* + * Initialize MAC related features + */ + xgbe_config_mac_address(pdata); + xgbe_config_rx_mode(pdata); + xgbe_config_jumbo_enable(pdata); + xgbe_config_flow_control(pdata); + xgbe_config_mac_speed(pdata); + xgbe_config_checksum_offload(pdata); + xgbe_config_vlan_support(pdata); + xgbe_config_mmc(pdata); + xgbe_enable_mac_interrupts(pdata); + + DBGPR("<--xgbe_init\n"); + + return 0; +} + +void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if) +{ + DBGPR("-->xgbe_init_function_ptrs\n"); + + hw_if->tx_complete = xgbe_tx_complete; + + hw_if->set_mac_address = xgbe_set_mac_address; + hw_if->config_rx_mode = xgbe_config_rx_mode; + + hw_if->enable_rx_csum = xgbe_enable_rx_csum; + hw_if->disable_rx_csum = xgbe_disable_rx_csum; + + hw_if->enable_rx_vlan_stripping = xgbe_enable_rx_vlan_stripping; + hw_if->disable_rx_vlan_stripping = xgbe_disable_rx_vlan_stripping; + hw_if->enable_rx_vlan_filtering = xgbe_enable_rx_vlan_filtering; + hw_if->disable_rx_vlan_filtering = xgbe_disable_rx_vlan_filtering; + hw_if->update_vlan_hash_table = xgbe_update_vlan_hash_table; + + hw_if->read_mmd_regs = xgbe_read_mmd_regs; + hw_if->write_mmd_regs = xgbe_write_mmd_regs; + + hw_if->set_gmii_speed = xgbe_set_gmii_speed; + hw_if->set_gmii_2500_speed = xgbe_set_gmii_2500_speed; + hw_if->set_xgmii_speed = xgbe_set_xgmii_speed; + + hw_if->enable_tx = xgbe_enable_tx; + hw_if->disable_tx = xgbe_disable_tx; + hw_if->enable_rx = xgbe_enable_rx; + hw_if->disable_rx = xgbe_disable_rx; + + hw_if->powerup_tx = xgbe_powerup_tx; + hw_if->powerdown_tx = xgbe_powerdown_tx; + hw_if->powerup_rx = xgbe_powerup_rx; + hw_if->powerdown_rx = xgbe_powerdown_rx; + + hw_if->dev_xmit = xgbe_dev_xmit; + hw_if->dev_read = xgbe_dev_read; + hw_if->enable_int = xgbe_enable_int; + hw_if->disable_int = xgbe_disable_int; + hw_if->init = xgbe_init; + hw_if->exit = xgbe_exit; + + /* Descriptor related Sequences have to be initialized here */ + hw_if->tx_desc_init = xgbe_tx_desc_init; + hw_if->rx_desc_init = xgbe_rx_desc_init; + hw_if->tx_desc_reset = xgbe_tx_desc_reset; + hw_if->rx_desc_reset = xgbe_rx_desc_reset; + hw_if->is_last_desc = xgbe_is_last_desc; + hw_if->is_context_desc = xgbe_is_context_desc; + hw_if->tx_start_xmit = xgbe_tx_start_xmit; + + /* For FLOW ctrl */ + hw_if->config_tx_flow_control = xgbe_config_tx_flow_control; + hw_if->config_rx_flow_control = xgbe_config_rx_flow_control; + + /* For RX coalescing */ + hw_if->config_rx_coalesce = xgbe_config_rx_coalesce; + hw_if->config_tx_coalesce = xgbe_config_tx_coalesce; + hw_if->usec_to_riwt = xgbe_usec_to_riwt; + hw_if->riwt_to_usec = xgbe_riwt_to_usec; + + /* For RX and TX threshold config */ + hw_if->config_rx_threshold = xgbe_config_rx_threshold; + hw_if->config_tx_threshold = xgbe_config_tx_threshold; + + /* For RX and TX Store and Forward Mode config */ + hw_if->config_rsf_mode = xgbe_config_rsf_mode; + hw_if->config_tsf_mode = xgbe_config_tsf_mode; + + /* For TX DMA Operating on Second Frame config */ + hw_if->config_osp_mode = xgbe_config_osp_mode; + + /* For RX and TX PBL config */ + hw_if->config_rx_pbl_val = xgbe_config_rx_pbl_val; + hw_if->get_rx_pbl_val = xgbe_get_rx_pbl_val; + hw_if->config_tx_pbl_val = xgbe_config_tx_pbl_val; + hw_if->get_tx_pbl_val = xgbe_get_tx_pbl_val; + hw_if->config_pblx8 = xgbe_config_pblx8; + + /* For MMC statistics support */ + hw_if->tx_mmc_int = xgbe_tx_mmc_int; + hw_if->rx_mmc_int = xgbe_rx_mmc_int; + hw_if->read_mmc_stats = xgbe_read_mmc_stats; + + /* For Receive Side Scaling */ + hw_if->disable_rss = xgbe_disable_rss; + + DBGPR("<--xgbe_init_function_ptrs\n"); +} diff --git a/sys/dev/axgbe/xgbe-drv.c b/sys/dev/axgbe/xgbe-drv.c new file mode 100644 index 000000000000..32a6cfe239c1 --- /dev/null +++ b/sys/dev/axgbe/xgbe-drv.c @@ -0,0 +1,1079 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014-2016 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> + +#include "xgbe.h" +#include "xgbe-common.h" + +static int xgbe_one_poll(struct xgbe_channel *channel, int budget); +static int xgbe_all_poll(struct xgbe_prv_data *pdata, int budget); + +static int xgbe_alloc_channels(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel_mem, *channel; + struct xgbe_ring *tx_ring, *rx_ring; + unsigned int count, i; + int ret = -ENOMEM; + + count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count); + + channel_mem = malloc(count * sizeof(struct xgbe_channel), M_AXGBE, + M_WAITOK | M_ZERO); + tx_ring = malloc(pdata->tx_ring_count * sizeof(struct xgbe_ring), + M_AXGBE, M_WAITOK | M_ZERO); + rx_ring = malloc(pdata->rx_ring_count * sizeof(struct xgbe_ring), + M_AXGBE, M_WAITOK | M_ZERO); + + for (i = 0, channel = channel_mem; i < count; i++, channel++) { + snprintf(channel->name, sizeof(channel->name), "channel-%d", i); + channel->pdata = pdata; + channel->queue_index = i; + channel->dma_tag = rman_get_bustag(pdata->xgmac_res); + bus_space_subregion(channel->dma_tag, + rman_get_bushandle(pdata->xgmac_res), + DMA_CH_BASE + (DMA_CH_INC * i), DMA_CH_INC, + &channel->dma_handle); + + if (pdata->per_channel_irq) { + if (pdata->chan_irq_res[i] == NULL) + goto err_irq; + + channel->dma_irq_res = pdata->chan_irq_res[i]; + } + + if (i < pdata->tx_ring_count) { + spin_lock_init(&tx_ring->lock); + channel->tx_ring = tx_ring++; + } + + if (i < pdata->rx_ring_count) { + spin_lock_init(&rx_ring->lock); + channel->rx_ring = rx_ring++; + } + } + + pdata->channel = channel_mem; + pdata->channel_count = count; + + return 0; + +err_irq: + free(rx_ring, M_AXGBE); + free(tx_ring, M_AXGBE); + free(channel_mem, M_AXGBE); + + return ret; +} + +static void xgbe_free_channels(struct xgbe_prv_data *pdata) +{ + if (!pdata->channel) + return; + + free(pdata->channel->rx_ring, M_AXGBE); + free(pdata->channel->tx_ring, M_AXGBE); + free(pdata->channel, M_AXGBE); + + pdata->channel = NULL; + pdata->channel_count = 0; +} + +static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring) +{ + return (ring->rdesc_count - (ring->cur - ring->dirty)); +} + +static inline unsigned int xgbe_rx_dirty_desc(struct xgbe_ring *ring) +{ + return (ring->cur - ring->dirty); +} + +static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel, + struct xgbe_ring *ring, unsigned int count) +{ + struct xgbe_prv_data *pdata = channel->pdata; + + if (count > xgbe_tx_avail_desc(ring)) { + /* If we haven't notified the hardware because of xmit_more + * support, tell it now + */ + if (ring->tx.xmit_more) + pdata->hw_if.tx_start_xmit(channel, ring); + + return EFBIG; + } + + return 0; +} + +static int xgbe_calc_rx_buf_size(struct ifnet *netdev, unsigned int mtu) +{ + unsigned int rx_buf_size; + + if (mtu > XGMAC_JUMBO_PACKET_MTU) { + return -EINVAL; + } + + rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + rx_buf_size = MIN(XGBE_RX_MIN_BUF_SIZE, PAGE_SIZE); + + rx_buf_size = (rx_buf_size + XGBE_RX_BUF_ALIGN - 1) & + ~(XGBE_RX_BUF_ALIGN - 1); + + return rx_buf_size; +} + +static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_channel *channel; + enum xgbe_int int_id; + unsigned int i; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + if (channel->tx_ring && channel->rx_ring) + int_id = XGMAC_INT_DMA_CH_SR_TI_RI; + else if (channel->tx_ring) + int_id = XGMAC_INT_DMA_CH_SR_TI; + else if (channel->rx_ring) + int_id = XGMAC_INT_DMA_CH_SR_RI; + else + continue; + + hw_if->enable_int(channel, int_id); + } +} + +static void xgbe_isr(void *data) +{ + struct xgbe_prv_data *pdata = data; + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_channel *channel; + unsigned int dma_isr, dma_ch_isr; + unsigned int mac_isr; + unsigned int i; + + /* The DMA interrupt status register also reports MAC and MTL + * interrupts. So for polling mode, we just need to check for + * this register to be non-zero + */ + dma_isr = XGMAC_IOREAD(pdata, DMA_ISR); + if (!dma_isr) + return; + + for (i = 0; i < pdata->channel_count; i++) { + if (!(dma_isr & (1 << i))) + continue; + + channel = pdata->channel + i; + + dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR); + + /* The TI or RI interrupt bits may still be set even if using + * per channel DMA interrupts. Check to be sure those are not + * enabled before using the private data napi structure. + */ + if (!pdata->per_channel_irq && + (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) || + XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI))) { + xgbe_all_poll(pdata, 16); + } + + if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU)) + pdata->ext_stats.rx_buffer_unavailable++; + + /* Restart the device on a Fatal Bus Error */ + if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE)) + taskqueue_enqueue(taskqueue_thread, + &pdata->restart_work); + + /* Clear all interrupt signals */ + XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr); + } + + if (XGMAC_GET_BITS(dma_isr, DMA_ISR, MACIS)) { + mac_isr = XGMAC_IOREAD(pdata, MAC_ISR); + + if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS)) + hw_if->tx_mmc_int(pdata); + + if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS)) + hw_if->rx_mmc_int(pdata); + } +} + +static void xgbe_dma_isr(void *data) +{ + struct xgbe_channel *channel = data; + + xgbe_one_poll(channel, 16); +} + +static void xgbe_service(void *ctx, int pending) +{ + struct xgbe_prv_data *pdata = ctx; + + pdata->phy_if.phy_status(pdata); +} + +static void xgbe_service_timer(void *data) +{ + struct xgbe_prv_data *pdata = data; + + DBGPR("--> xgbe_service_timer\n"); + taskqueue_enqueue(pdata->dev_workqueue, &pdata->service_work); + + callout_reset(&pdata->service_timer, hz, xgbe_service_timer, pdata); + DBGPR("<-- xgbe_service_timer\n"); +} + +static void xgbe_init_timers(struct xgbe_prv_data *pdata) +{ + + callout_init(&pdata->service_timer, 1); +} + +static void xgbe_start_timers(struct xgbe_prv_data *pdata) +{ + callout_reset(&pdata->service_timer, hz, xgbe_service_timer, pdata); +} + +static void xgbe_stop_timers(struct xgbe_prv_data *pdata) +{ + + callout_drain(&pdata->service_timer); +} + +void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata) +{ + unsigned int mac_hfr0, mac_hfr1, mac_hfr2; + struct xgbe_hw_features *hw_feat = &pdata->hw_feat; + + DBGPR("-->xgbe_get_all_hw_features\n"); + + mac_hfr0 = XGMAC_IOREAD(pdata, MAC_HWF0R); + mac_hfr1 = XGMAC_IOREAD(pdata, MAC_HWF1R); + mac_hfr2 = XGMAC_IOREAD(pdata, MAC_HWF2R); + + memset(hw_feat, 0, sizeof(*hw_feat)); + + hw_feat->version = XGMAC_IOREAD(pdata, MAC_VR); + + /* Hardware feature register 0 */ + hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL); + hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH); + hw_feat->sma = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL); + hw_feat->rwk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL); + hw_feat->mgk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL); + hw_feat->mmc = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL); + hw_feat->aoe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL); + hw_feat->ts = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL); + hw_feat->eee = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL); + hw_feat->tx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL); + hw_feat->rx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL); + hw_feat->addn_mac = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, + ADDMACADRSEL); + hw_feat->ts_src = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL); + hw_feat->sa_vlan_ins = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS); + + /* Hardware feature register 1 */ + hw_feat->rx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, + RXFIFOSIZE); + hw_feat->tx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, + TXFIFOSIZE); + hw_feat->adv_ts_hi = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADVTHWORD); + hw_feat->dma_width = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64); + hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN); + hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN); + hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN); + hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA); + hw_feat->rss = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN); + hw_feat->tc_cnt = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC); + hw_feat->hash_table_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, + HASHTBLSZ); + hw_feat->l3l4_filter_num = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, + L3L4FNUM); + + /* Hardware feature register 2 */ + hw_feat->rx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT); + hw_feat->tx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT); + hw_feat->rx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT); + hw_feat->tx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT); + hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM); + hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM); + + /* Translate the Hash Table size into actual number */ + switch (hw_feat->hash_table_size) { + case 0: + break; + case 1: + hw_feat->hash_table_size = 64; + break; + case 2: + hw_feat->hash_table_size = 128; + break; + case 3: + hw_feat->hash_table_size = 256; + break; + } + + /* Translate the address width setting into actual number */ + switch (hw_feat->dma_width) { + case 0: + hw_feat->dma_width = 32; + break; + case 1: + hw_feat->dma_width = 40; + break; + case 2: + hw_feat->dma_width = 48; + break; + default: + hw_feat->dma_width = 32; + } + + /* The Queue, Channel and TC counts are zero based so increment them + * to get the actual number + */ + hw_feat->rx_q_cnt++; + hw_feat->tx_q_cnt++; + hw_feat->rx_ch_cnt++; + hw_feat->tx_ch_cnt++; + hw_feat->tc_cnt++; + + DBGPR("<--xgbe_get_all_hw_features\n"); +} + +static int xgbe_request_irqs(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + int ret; + + ret = bus_setup_intr(pdata->dev, pdata->dev_irq_res, + INTR_MPSAFE | INTR_TYPE_NET, NULL, xgbe_isr, pdata, + &pdata->dev_irq_tag); + if (ret) { + return ret; + } + + if (!pdata->per_channel_irq) + return 0; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ret = bus_setup_intr(pdata->dev, channel->dma_irq_res, + INTR_MPSAFE | INTR_TYPE_NET, NULL, xgbe_dma_isr, channel, + &channel->dma_irq_tag); + if (ret != 0) { + goto err_irq; + } + } + + return 0; + +err_irq: + /* Using an unsigned int, 'i' will go to UINT_MAX and exit */ + for (i--, channel--; i < pdata->channel_count; i--, channel--) + bus_teardown_intr(pdata->dev, channel->dma_irq_res, + channel->dma_irq_tag); + + bus_teardown_intr(pdata->dev, pdata->dev_irq_res, pdata->dev_irq_tag); + + return -ret; +} + +static void xgbe_free_irqs(struct xgbe_prv_data *pdata) +{ + struct xgbe_channel *channel; + unsigned int i; + + bus_teardown_intr(pdata->dev, pdata->dev_irq_res, pdata->dev_irq_tag); + + if (!pdata->per_channel_irq) + return; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) + bus_teardown_intr(pdata->dev, channel->dma_irq_res, + channel->dma_irq_tag); +} + +void xgbe_init_tx_coalesce(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + + DBGPR("-->xgbe_init_tx_coalesce\n"); + + pdata->tx_usecs = XGMAC_INIT_DMA_TX_USECS; + pdata->tx_frames = XGMAC_INIT_DMA_TX_FRAMES; + + hw_if->config_tx_coalesce(pdata); + + DBGPR("<--xgbe_init_tx_coalesce\n"); +} + +void xgbe_init_rx_coalesce(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + + DBGPR("-->xgbe_init_rx_coalesce\n"); + + pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS); + pdata->rx_usecs = XGMAC_INIT_DMA_RX_USECS; + pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES; + + hw_if->config_rx_coalesce(pdata); + + DBGPR("<--xgbe_init_rx_coalesce\n"); +} + +static void xgbe_free_tx_data(struct xgbe_prv_data *pdata) +{ + struct xgbe_desc_if *desc_if = &pdata->desc_if; + struct xgbe_channel *channel; + struct xgbe_ring *ring; + struct xgbe_ring_data *rdata; + unsigned int i, j; + + DBGPR("-->xgbe_free_tx_data\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ring = channel->tx_ring; + if (!ring) + break; + + for (j = 0; j < ring->rdesc_count; j++) { + rdata = XGBE_GET_DESC_DATA(ring, j); + desc_if->unmap_rdata(pdata, rdata); + } + } + + DBGPR("<--xgbe_free_tx_data\n"); +} + +static void xgbe_free_rx_data(struct xgbe_prv_data *pdata) +{ + struct xgbe_desc_if *desc_if = &pdata->desc_if; + struct xgbe_channel *channel; + struct xgbe_ring *ring; + struct xgbe_ring_data *rdata; + unsigned int i, j; + + DBGPR("-->xgbe_free_rx_data\n"); + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + ring = channel->rx_ring; + if (!ring) + break; + + for (j = 0; j < ring->rdesc_count; j++) { + rdata = XGBE_GET_DESC_DATA(ring, j); + desc_if->unmap_rdata(pdata, rdata); + } + } + + DBGPR("<--xgbe_free_rx_data\n"); +} + +static int xgbe_phy_init(struct xgbe_prv_data *pdata) +{ + pdata->phy_link = -1; + pdata->phy_speed = SPEED_UNKNOWN; + + return pdata->phy_if.phy_reset(pdata); +} + +static int xgbe_start(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_phy_if *phy_if = &pdata->phy_if; + int ret; + + DBGPR("-->xgbe_start\n"); + + hw_if->init(pdata); + + ret = phy_if->phy_start(pdata); + if (ret) + goto err_phy; + + ret = xgbe_request_irqs(pdata); + if (ret) + goto err_napi; + + hw_if->enable_tx(pdata); + hw_if->enable_rx(pdata); + + xgbe_enable_rx_tx_ints(pdata); + + xgbe_start_timers(pdata); + taskqueue_enqueue(pdata->dev_workqueue, &pdata->service_work); + + DBGPR("<--xgbe_start\n"); + + return 0; + +err_napi: + phy_if->phy_stop(pdata); + +err_phy: + hw_if->exit(pdata); + + return ret; +} + +static void xgbe_stop(struct xgbe_prv_data *pdata) +{ + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_phy_if *phy_if = &pdata->phy_if; + + DBGPR("-->xgbe_stop\n"); + + xgbe_stop_timers(pdata); + taskqueue_drain_all(pdata->dev_workqueue); + + hw_if->disable_tx(pdata); + hw_if->disable_rx(pdata); + + xgbe_free_irqs(pdata); + + phy_if->phy_stop(pdata); + + hw_if->exit(pdata); + + DBGPR("<--xgbe_stop\n"); +} + +static void xgbe_restart_dev(struct xgbe_prv_data *pdata) +{ + DBGPR("-->xgbe_restart_dev\n"); + + /* If not running, "restart" will happen on open */ + if ((pdata->netdev->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + + xgbe_stop(pdata); + + xgbe_free_tx_data(pdata); + xgbe_free_rx_data(pdata); + + xgbe_start(pdata); + + DBGPR("<--xgbe_restart_dev\n"); +} + +static void xgbe_restart(void *ctx, int pending) +{ + struct xgbe_prv_data *pdata = ctx; + + xgbe_restart_dev(pdata); +} + +static void xgbe_packet_info(struct xgbe_prv_data *pdata, + struct xgbe_ring *ring, struct mbuf *m0, + struct xgbe_packet_data *packet) +{ + struct mbuf *m; + unsigned int len; + + packet->m = m0; + + packet->rdesc_count = 0; + + packet->tx_packets = 1; + packet->tx_bytes = m_length(m0, NULL); + + for (m = m0; m != NULL; m = m->m_next) { + for (len = m->m_len; len != 0;) { + packet->rdesc_count++; + len -= MIN(len, XGBE_TX_MAX_BUF_SIZE); + } + } +} + +int xgbe_open(struct ifnet *netdev) +{ + struct xgbe_prv_data *pdata = netdev->if_softc; + struct xgbe_desc_if *desc_if = &pdata->desc_if; + int ret; + + DBGPR("-->xgbe_open\n"); + + /* Initialize the phy */ + ret = xgbe_phy_init(pdata); + if (ret) + return ret; + + /* Calculate the Rx buffer size before allocating rings */ + ret = xgbe_calc_rx_buf_size(netdev, if_getmtu(netdev)); + if (ret < 0) { + goto err_ptpclk; + } + pdata->rx_buf_size = ret; + + /* Allocate the channel and ring structures */ + ret = xgbe_alloc_channels(pdata); + if (ret) { + printf("xgbe_alloc_channels failed\n"); + goto err_ptpclk; + } + + /* Allocate the ring descriptors and buffers */ + ret = desc_if->alloc_ring_resources(pdata); + if (ret) { + printf("desc_if->alloc_ring_resources failed\n"); + goto err_channels; + } + + TASK_INIT(&pdata->service_work, 0, xgbe_service, pdata); + TASK_INIT(&pdata->restart_work, 0, xgbe_restart, pdata); + xgbe_init_timers(pdata); + + ret = xgbe_start(pdata); + if (ret) + goto err_rings; + + clear_bit(XGBE_DOWN, &pdata->dev_state); + + DBGPR("<--xgbe_open\n"); + + return 0; + +err_rings: + desc_if->free_ring_resources(pdata); + +err_channels: + xgbe_free_channels(pdata); + +err_ptpclk: + + return ret; +} + +int xgbe_close(struct ifnet *netdev) +{ + struct xgbe_prv_data *pdata = netdev->if_softc; + struct xgbe_desc_if *desc_if = &pdata->desc_if; + + DBGPR("-->xgbe_close\n"); + + /* Stop the device */ + xgbe_stop(pdata); + + /* Free the ring descriptors and buffers */ + desc_if->free_ring_resources(pdata); + + /* Free the channel and ring structures */ + xgbe_free_channels(pdata); + + set_bit(XGBE_DOWN, &pdata->dev_state); + + DBGPR("<--xgbe_close\n"); + + return 0; +} + +int xgbe_xmit(struct ifnet *ifp, struct mbuf *m) +{ + struct xgbe_prv_data *pdata = ifp->if_softc; + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_desc_if *desc_if = &pdata->desc_if; + struct xgbe_channel *channel; + struct xgbe_ring *ring; + struct xgbe_packet_data *packet; + int ret; + + M_ASSERTPKTHDR(m); + MPASS(m->m_nextpkt == NULL); + + if (__predict_false(test_bit(XGBE_DOWN, &pdata->dev_state) || + !pdata->phy.link)) { + m_freem(m); + return (ENETDOWN); + } + + channel = pdata->channel; + ring = channel->tx_ring; + packet = &ring->packet_data; + + /* Calculate preliminary packet info */ + memset(packet, 0, sizeof(*packet)); + xgbe_packet_info(pdata, ring, m, packet); + + /* Check that there are enough descriptors available */ + ret = xgbe_maybe_stop_tx_queue(channel, ring, packet->rdesc_count); + if (ret) + goto tx_netdev_return; + + if (!desc_if->map_tx_skb(channel, m)) { + goto tx_netdev_return; + } + + /* Configure required descriptor fields for transmission */ + hw_if->dev_xmit(channel); + + return 0; + +tx_netdev_return: + m_free(m); + + return 0; +} + +int xgbe_change_mtu(struct ifnet *netdev, int mtu) +{ + struct xgbe_prv_data *pdata = netdev->if_softc; + int ret; + + DBGPR("-->xgbe_change_mtu\n"); + + ret = xgbe_calc_rx_buf_size(netdev, mtu); + if (ret < 0) + return -ret; + + pdata->rx_buf_size = ret; + netdev->if_mtu = mtu; + + xgbe_restart_dev(pdata); + + DBGPR("<--xgbe_change_mtu\n"); + + return 0; +} + +static void xgbe_rx_refresh(struct xgbe_channel *channel) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_desc_if *desc_if = &pdata->desc_if; + struct xgbe_ring *ring = channel->rx_ring; + struct xgbe_ring_data *rdata; + + while (ring->dirty != ring->cur) { + rdata = XGBE_GET_DESC_DATA(ring, ring->dirty); + + /* Reset rdata values */ + desc_if->unmap_rdata(pdata, rdata); + + if (desc_if->map_rx_buffer(pdata, ring, rdata)) + break; + + hw_if->rx_desc_reset(pdata, rdata, ring->dirty); + + ring->dirty++; + } + + /* Make sure everything is written before the register write */ + dsb(sy); + + /* Update the Rx Tail Pointer Register with address of + * the last cleaned entry */ + rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1); + XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO, + lower_32_bits(rdata->rdata_paddr)); +} + +static int xgbe_tx_poll(struct xgbe_channel *channel) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_desc_if *desc_if = &pdata->desc_if; + struct xgbe_ring *ring = channel->tx_ring; + struct xgbe_ring_data *rdata; + struct xgbe_ring_desc *rdesc; + int processed = 0; + unsigned int cur; + + DBGPR("-->xgbe_tx_poll\n"); + + /* Nothing to do if there isn't a Tx ring for this channel */ + if (!ring) + return 0; + + cur = ring->cur; + + /* Be sure we get ring->cur before accessing descriptor data */ + dsb(sy); + + while ((processed < XGBE_TX_DESC_MAX_PROC) && + (ring->dirty != cur)) { + rdata = XGBE_GET_DESC_DATA(ring, ring->dirty); + rdesc = rdata->rdesc; + + if (!hw_if->tx_complete(rdesc)) + break; + + /* Make sure descriptor fields are read after reading the OWN + * bit */ + dsb(sy); + + /* Free the SKB and reset the descriptor for re-use */ + desc_if->unmap_rdata(pdata, rdata); + hw_if->tx_desc_reset(rdata); + + processed++; + ring->dirty++; + } + + if (!processed) + return 0; + + DBGPR("<--xgbe_tx_poll: processed=%d\n", processed); + + return processed; +} + +static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) +{ + struct xgbe_prv_data *pdata = channel->pdata; + struct xgbe_hw_if *hw_if = &pdata->hw_if; + struct xgbe_ring *ring = channel->rx_ring; + struct xgbe_ring_data *rdata; + struct xgbe_packet_data *packet; + struct ifnet *ifp = pdata->netdev; + struct mbuf *m; + unsigned int incomplete, context_next, context; + unsigned int received = 0; + int packet_count = 0; + + DBGPR("-->xgbe_rx_poll: budget=%d\n", budget); + + /* Nothing to do if there isn't a Rx ring for this channel */ + if (!ring) + return 0; + + incomplete = 0; + context_next = 0; + + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + packet = &ring->packet_data; + while (packet_count < budget) { + DBGPR(" cur = %d\n", ring->cur); + +read_again: + rdata = XGBE_GET_DESC_DATA(ring, ring->cur); + + if (xgbe_rx_dirty_desc(ring) > (XGBE_RX_DESC_CNT >> 3)) + xgbe_rx_refresh(channel); + + if (hw_if->dev_read(channel)) + break; + + m = rdata->mb; + + received++; + ring->cur++; + + incomplete = XGMAC_GET_BITS(packet->attributes, + RX_PACKET_ATTRIBUTES, + INCOMPLETE); + context_next = XGMAC_GET_BITS(packet->attributes, + RX_PACKET_ATTRIBUTES, + CONTEXT_NEXT); + context = XGMAC_GET_BITS(packet->attributes, + RX_PACKET_ATTRIBUTES, + CONTEXT); + + /* Earlier error, just drain the remaining data */ + if (incomplete || context_next) { + goto read_again; + } + + if (packet->errors) { + rdata->mbuf_free = 1; + goto next_packet; + } + rdata->mb = NULL; + + m->m_pkthdr.len = rdata->rx.hdr_len + rdata->rx.len; + if (rdata->rx.hdr_len != 0) { + m->m_len = rdata->rx.hdr_len; + m->m_next->m_len = rdata->rx.len; + } else { + m->m_len = rdata->rx.len; + m_freem(m->m_next); + m->m_next = NULL; + } + if_setrcvif(m, ifp); + if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); + + ifp->if_input(ifp, m); + +next_packet: + packet_count++; + } + + DBGPR("<--xgbe_rx_poll: packet_count = %d\n", packet_count); + + return packet_count; +} + +static int xgbe_one_poll(struct xgbe_channel *channel, int budget) +{ + int processed = 0; + + DBGPR("-->xgbe_one_poll: budget=%d\n", budget); + + /* Cleanup Tx ring first */ + xgbe_tx_poll(channel); + + /* Process Rx ring next */ + processed = xgbe_rx_poll(channel, budget); + + DBGPR("<--xgbe_one_poll: received = %d\n", processed); + + return processed; +} + +static int xgbe_all_poll(struct xgbe_prv_data *pdata, int budget) +{ + struct xgbe_channel *channel; + int ring_budget; + int processed, last_processed; + unsigned int i; + + DBGPR("-->xgbe_all_poll: budget=%d\n", budget); + + processed = 0; + ring_budget = budget / pdata->rx_ring_count; + do { + last_processed = processed; + + channel = pdata->channel; + for (i = 0; i < pdata->channel_count; i++, channel++) { + /* Cleanup Tx ring first */ + xgbe_tx_poll(channel); + + /* Process Rx ring next */ + if (ring_budget > (budget - processed)) + ring_budget = budget - processed; + processed += xgbe_rx_poll(channel, ring_budget); + } + } while ((processed < budget) && (processed != last_processed)); + + DBGPR("<--xgbe_all_poll: received = %d\n", processed); + + return processed; +} diff --git a/sys/dev/axgbe/xgbe-mdio.c b/sys/dev/axgbe/xgbe-mdio.c new file mode 100644 index 000000000000..6967d54da521 --- /dev/null +++ b/sys/dev/axgbe/xgbe-mdio.c @@ -0,0 +1,1180 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014-2016 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/kernel.h> + +#include "xgbe.h" +#include "xgbe-common.h" + +static void xgbe_an_state_machine(struct xgbe_prv_data *pdata); + +static void xgbe_an_enable_kr_training(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); + + reg |= XGBE_KR_TRAINING_ENABLE; + XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); +} + +static void xgbe_an_disable_kr_training(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); + + reg &= ~XGBE_KR_TRAINING_ENABLE; + XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); +} + +static void xgbe_pcs_power_cycle(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + + reg |= MDIO_CTRL1_LPOWER; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); + + DELAY(75); + + reg &= ~MDIO_CTRL1_LPOWER; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); +} + +static void xgbe_serdes_start_ratechange(struct xgbe_prv_data *pdata) +{ + /* Assert Rx and Tx ratechange */ + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 1); +} + +static void xgbe_serdes_complete_ratechange(struct xgbe_prv_data *pdata) +{ + unsigned int wait; + u16 status; + + /* Release Rx and Tx ratechange */ + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0); + + /* Wait for Rx and Tx ready */ + wait = XGBE_RATECHANGE_COUNT; + while (wait--) { + DELAY(50); + + status = XSIR0_IOREAD(pdata, SIR0_STATUS); + if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && + XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) + goto rx_reset; + } + +rx_reset: + /* Perform Rx reset for the DFE changes */ + XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1); +} + +static void xgbe_xgmii_mode(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + /* Enable KR training */ + xgbe_an_enable_kr_training(pdata); + + /* Set MAC to 10G speed */ + pdata->hw_if.set_xgmii_speed(pdata); + + /* Set PCS to KR/10G speed */ + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); + reg &= ~MDIO_PCS_CTRL2_TYPE; + reg |= MDIO_PCS_CTRL2_10GBR; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + reg &= ~MDIO_CTRL1_SPEEDSEL; + reg |= MDIO_CTRL1_SPEED10G; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); + + xgbe_pcs_power_cycle(pdata); + + /* Set SerDes to 10G speed */ + xgbe_serdes_start_ratechange(pdata); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_10000_RATE); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_10000_WORD); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_10000_PLL); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, + pdata->serdes_cdr_rate[XGBE_SPEED_10000]); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, + pdata->serdes_tx_amp[XGBE_SPEED_10000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, + pdata->serdes_blwc[XGBE_SPEED_10000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, + pdata->serdes_pq_skew[XGBE_SPEED_10000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, + pdata->serdes_dfe_tap_cfg[XGBE_SPEED_10000]); + XRXTX_IOWRITE(pdata, RXTX_REG22, + pdata->serdes_dfe_tap_ena[XGBE_SPEED_10000]); + + xgbe_serdes_complete_ratechange(pdata); +} + +static void xgbe_gmii_2500_mode(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + /* Disable KR training */ + xgbe_an_disable_kr_training(pdata); + + /* Set MAC to 2.5G speed */ + pdata->hw_if.set_gmii_2500_speed(pdata); + + /* Set PCS to KX/1G speed */ + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); + reg &= ~MDIO_PCS_CTRL2_TYPE; + reg |= MDIO_PCS_CTRL2_10GBX; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + reg &= ~MDIO_CTRL1_SPEEDSEL; + reg |= MDIO_CTRL1_SPEED1G; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); + + xgbe_pcs_power_cycle(pdata); + + /* Set SerDes to 2.5G speed */ + xgbe_serdes_start_ratechange(pdata); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_2500_RATE); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_2500_WORD); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_2500_PLL); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, + pdata->serdes_cdr_rate[XGBE_SPEED_2500]); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, + pdata->serdes_tx_amp[XGBE_SPEED_2500]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, + pdata->serdes_blwc[XGBE_SPEED_2500]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, + pdata->serdes_pq_skew[XGBE_SPEED_2500]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, + pdata->serdes_dfe_tap_cfg[XGBE_SPEED_2500]); + XRXTX_IOWRITE(pdata, RXTX_REG22, + pdata->serdes_dfe_tap_ena[XGBE_SPEED_2500]); + + xgbe_serdes_complete_ratechange(pdata); +} + +static void xgbe_gmii_mode(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + /* Disable KR training */ + xgbe_an_disable_kr_training(pdata); + + /* Set MAC to 1G speed */ + pdata->hw_if.set_gmii_speed(pdata); + + /* Set PCS to KX/1G speed */ + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); + reg &= ~MDIO_PCS_CTRL2_TYPE; + reg |= MDIO_PCS_CTRL2_10GBX; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + reg &= ~MDIO_CTRL1_SPEEDSEL; + reg |= MDIO_CTRL1_SPEED1G; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); + + xgbe_pcs_power_cycle(pdata); + + /* Set SerDes to 1G speed */ + xgbe_serdes_start_ratechange(pdata); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL); + + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, + pdata->serdes_cdr_rate[XGBE_SPEED_1000]); + XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, + pdata->serdes_tx_amp[XGBE_SPEED_1000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, + pdata->serdes_blwc[XGBE_SPEED_1000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, + pdata->serdes_pq_skew[XGBE_SPEED_1000]); + XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, + pdata->serdes_dfe_tap_cfg[XGBE_SPEED_1000]); + XRXTX_IOWRITE(pdata, RXTX_REG22, + pdata->serdes_dfe_tap_ena[XGBE_SPEED_1000]); + + xgbe_serdes_complete_ratechange(pdata); +} + +static void xgbe_cur_mode(struct xgbe_prv_data *pdata, + enum xgbe_mode *mode) +{ + unsigned int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); + if ((reg & MDIO_PCS_CTRL2_TYPE) == MDIO_PCS_CTRL2_10GBR) + *mode = XGBE_MODE_KR; + else + *mode = XGBE_MODE_KX; +} + +static bool xgbe_in_kr_mode(struct xgbe_prv_data *pdata) +{ + enum xgbe_mode mode; + + xgbe_cur_mode(pdata, &mode); + + return (mode == XGBE_MODE_KR); +} + +static void xgbe_switch_mode(struct xgbe_prv_data *pdata) +{ + /* If we are in KR switch to KX, and vice-versa */ + if (xgbe_in_kr_mode(pdata)) { + if (pdata->speed_set == XGBE_SPEEDSET_1000_10000) + xgbe_gmii_mode(pdata); + else + xgbe_gmii_2500_mode(pdata); + } else { + xgbe_xgmii_mode(pdata); + } +} + +static void xgbe_set_mode(struct xgbe_prv_data *pdata, + enum xgbe_mode mode) +{ + enum xgbe_mode cur_mode; + + xgbe_cur_mode(pdata, &cur_mode); + if (mode != cur_mode) + xgbe_switch_mode(pdata); +} + +static bool xgbe_use_xgmii_mode(struct xgbe_prv_data *pdata) +{ + if (pdata->phy.autoneg == AUTONEG_ENABLE) { + if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) + return true; + } else { + if (pdata->phy.speed == SPEED_10000) + return true; + } + + return false; +} + +static bool xgbe_use_gmii_2500_mode(struct xgbe_prv_data *pdata) +{ + if (pdata->phy.autoneg == AUTONEG_ENABLE) { + if (pdata->phy.advertising & ADVERTISED_2500baseX_Full) + return true; + } else { + if (pdata->phy.speed == SPEED_2500) + return true; + } + + return false; +} + +static bool xgbe_use_gmii_mode(struct xgbe_prv_data *pdata) +{ + if (pdata->phy.autoneg == AUTONEG_ENABLE) { + if (pdata->phy.advertising & ADVERTISED_1000baseKX_Full) + return true; + } else { + if (pdata->phy.speed == SPEED_1000) + return true; + } + + return false; +} + +static void xgbe_set_an(struct xgbe_prv_data *pdata, bool enable, bool restart) +{ + unsigned int reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1); + reg &= ~MDIO_AN_CTRL1_ENABLE; + + if (enable) + reg |= MDIO_AN_CTRL1_ENABLE; + + if (restart) + reg |= MDIO_AN_CTRL1_RESTART; + + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg); +} + +static void xgbe_restart_an(struct xgbe_prv_data *pdata) +{ + xgbe_set_an(pdata, true, true); +} + +static void xgbe_disable_an(struct xgbe_prv_data *pdata) +{ + xgbe_set_an(pdata, false, false); +} + +static enum xgbe_an xgbe_an_tx_training(struct xgbe_prv_data *pdata, + enum xgbe_rx *state) +{ + unsigned int ad_reg, lp_reg, reg; + + *state = XGBE_RX_COMPLETE; + + /* If we're not in KR mode then we're done */ + if (!xgbe_in_kr_mode(pdata)) + return XGBE_AN_PAGE_RECEIVED; + + /* Enable/Disable FEC */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); + + reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL); + reg &= ~(MDIO_PMA_10GBR_FECABLE_ABLE | MDIO_PMA_10GBR_FECABLE_ERRABLE); + if ((ad_reg & 0xc000) && (lp_reg & 0xc000)) + reg |= pdata->fec_ability; + + XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FECCTRL, reg); + + /* Start KR training */ + reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL); + if (reg & XGBE_KR_TRAINING_ENABLE) { + XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 1); + + reg |= XGBE_KR_TRAINING_START; + XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, + reg); + + XSIR0_IOWRITE_BITS(pdata, SIR0_KR_RT_1, RESET, 0); + } + + return XGBE_AN_PAGE_RECEIVED; +} + +static enum xgbe_an xgbe_an_tx_xnp(struct xgbe_prv_data *pdata, + enum xgbe_rx *state) +{ + u16 msg; + + *state = XGBE_RX_XNP; + + msg = XGBE_XNP_MCF_NULL_MESSAGE; + msg |= XGBE_XNP_MP_FORMATTED; + + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 2, 0); + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP + 1, 0); + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_XNP, msg); + + return XGBE_AN_PAGE_RECEIVED; +} + +static enum xgbe_an xgbe_an_rx_bpa(struct xgbe_prv_data *pdata, + enum xgbe_rx *state) +{ + unsigned int link_support; + unsigned int reg, ad_reg, lp_reg; + + /* Read Base Ability register 2 first */ + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); + + /* Check for a supported mode, otherwise restart in a different one */ + link_support = xgbe_in_kr_mode(pdata) ? 0x80 : 0x20; + if (!(reg & link_support)) + return XGBE_AN_INCOMPAT_LINK; + + /* Check Extended Next Page support */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); + + return ((ad_reg & XGBE_XNP_NP_EXCHANGE) || + (lp_reg & XGBE_XNP_NP_EXCHANGE)) + ? xgbe_an_tx_xnp(pdata, state) + : xgbe_an_tx_training(pdata, state); +} + +static enum xgbe_an xgbe_an_rx_xnp(struct xgbe_prv_data *pdata, + enum xgbe_rx *state) +{ + unsigned int ad_reg, lp_reg; + + /* Check Extended Next Page support */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_XNP); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPX); + + return ((ad_reg & XGBE_XNP_NP_EXCHANGE) || + (lp_reg & XGBE_XNP_NP_EXCHANGE)) + ? xgbe_an_tx_xnp(pdata, state) + : xgbe_an_tx_training(pdata, state); +} + +static enum xgbe_an xgbe_an_page_received(struct xgbe_prv_data *pdata) +{ + enum xgbe_rx *state; + unsigned long an_timeout; + enum xgbe_an ret; + + if (!pdata->an_start) { + pdata->an_start = ticks; + } else { + an_timeout = pdata->an_start + + ((uint64_t)XGBE_AN_MS_TIMEOUT * (uint64_t)hz) / 1000ull; + if ((int)(ticks - an_timeout) > 0) { + /* Auto-negotiation timed out, reset state */ + pdata->kr_state = XGBE_RX_BPA; + pdata->kx_state = XGBE_RX_BPA; + + pdata->an_start = ticks; + } + } + + state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state + : &pdata->kx_state; + + switch (*state) { + case XGBE_RX_BPA: + ret = xgbe_an_rx_bpa(pdata, state); + break; + + case XGBE_RX_XNP: + ret = xgbe_an_rx_xnp(pdata, state); + break; + + default: + ret = XGBE_AN_ERROR; + } + + return ret; +} + +static enum xgbe_an xgbe_an_incompat_link(struct xgbe_prv_data *pdata) +{ + /* Be sure we aren't looping trying to negotiate */ + if (xgbe_in_kr_mode(pdata)) { + pdata->kr_state = XGBE_RX_ERROR; + + if (!(pdata->phy.advertising & ADVERTISED_1000baseKX_Full) && + !(pdata->phy.advertising & ADVERTISED_2500baseX_Full)) + return XGBE_AN_NO_LINK; + + if (pdata->kx_state != XGBE_RX_BPA) + return XGBE_AN_NO_LINK; + } else { + pdata->kx_state = XGBE_RX_ERROR; + + if (!(pdata->phy.advertising & ADVERTISED_10000baseKR_Full)) + return XGBE_AN_NO_LINK; + + if (pdata->kr_state != XGBE_RX_BPA) + return XGBE_AN_NO_LINK; + } + + xgbe_disable_an(pdata); + + xgbe_switch_mode(pdata); + + xgbe_restart_an(pdata); + + return XGBE_AN_INCOMPAT_LINK; +} + +static void xgbe_an_isr(void *data) +{ + struct xgbe_prv_data *pdata = (struct xgbe_prv_data *)data; + + /* Disable AN interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); + + /* Save the interrupt(s) that fired */ + pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT); + + if (pdata->an_int) { + /* Clear the interrupt(s) that fired and process them */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int); + + xgbe_an_state_machine(pdata); + } else { + /* Enable AN interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, + XGBE_AN_INT_MASK); + } +} + +static void xgbe_an_state_machine(struct xgbe_prv_data *pdata) +{ + enum xgbe_an cur_state = pdata->an_state; + + sx_xlock(&pdata->an_mutex); + + if (!pdata->an_int) + goto out; + +next_int: + if (pdata->an_int & XGBE_AN_PG_RCV) { + pdata->an_state = XGBE_AN_PAGE_RECEIVED; + pdata->an_int &= ~XGBE_AN_PG_RCV; + } else if (pdata->an_int & XGBE_AN_INC_LINK) { + pdata->an_state = XGBE_AN_INCOMPAT_LINK; + pdata->an_int &= ~XGBE_AN_INC_LINK; + } else if (pdata->an_int & XGBE_AN_INT_CMPLT) { + pdata->an_state = XGBE_AN_COMPLETE; + pdata->an_int &= ~XGBE_AN_INT_CMPLT; + } else { + pdata->an_state = XGBE_AN_ERROR; + } + + pdata->an_result = pdata->an_state; + +again: + cur_state = pdata->an_state; + + switch (pdata->an_state) { + case XGBE_AN_READY: + pdata->an_supported = 0; + break; + + case XGBE_AN_PAGE_RECEIVED: + pdata->an_state = xgbe_an_page_received(pdata); + pdata->an_supported++; + break; + + case XGBE_AN_INCOMPAT_LINK: + pdata->an_supported = 0; + pdata->parallel_detect = 0; + pdata->an_state = xgbe_an_incompat_link(pdata); + break; + + case XGBE_AN_COMPLETE: + pdata->parallel_detect = pdata->an_supported ? 0 : 1; + break; + + case XGBE_AN_NO_LINK: + break; + + default: + pdata->an_state = XGBE_AN_ERROR; + } + + if (pdata->an_state == XGBE_AN_NO_LINK) { + pdata->an_int = 0; + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); + } else if (pdata->an_state == XGBE_AN_ERROR) { + pdata->an_int = 0; + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); + } + + if (pdata->an_state >= XGBE_AN_COMPLETE) { + pdata->an_result = pdata->an_state; + pdata->an_state = XGBE_AN_READY; + pdata->kr_state = XGBE_RX_BPA; + pdata->kx_state = XGBE_RX_BPA; + pdata->an_start = 0; + } + + if (cur_state != pdata->an_state) + goto again; + + if (pdata->an_int) + goto next_int; + +out: + /* Enable AN interrupts on the way out */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, XGBE_AN_INT_MASK); + + sx_xunlock(&pdata->an_mutex); +} + +static void xgbe_an_init(struct xgbe_prv_data *pdata) +{ + unsigned int reg; + + /* Set up Advertisement register 3 first */ + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); + reg &= ~0xc000; + + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2, reg); + + /* Set up Advertisement register 2 next */ + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); + if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) + reg |= 0x80; + else + reg &= ~0x80; + + if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || + (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) + reg |= 0x20; + else + reg &= ~0x20; + + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1, reg); + + /* Set up Advertisement register 1 last */ + reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); + if (pdata->phy.advertising & ADVERTISED_Pause) + reg |= 0x400; + else + reg &= ~0x400; + + if (pdata->phy.advertising & ADVERTISED_Asym_Pause) + reg |= 0x800; + else + reg &= ~0x800; + + /* We don't intend to perform XNP */ + reg &= ~XGBE_XNP_NP_EXCHANGE; + + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); +} + +static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata) +{ + int new_state = 0; + + if (pdata->phy.link) { + /* Flow control support */ + pdata->pause_autoneg = pdata->phy.pause_autoneg; + + if (pdata->tx_pause != pdata->phy.tx_pause) { + new_state = 1; + pdata->hw_if.config_tx_flow_control(pdata); + pdata->tx_pause = pdata->phy.tx_pause; + } + + if (pdata->rx_pause != pdata->phy.rx_pause) { + new_state = 1; + pdata->hw_if.config_rx_flow_control(pdata); + pdata->rx_pause = pdata->phy.rx_pause; + } + + /* Speed support */ + if (pdata->phy_speed != pdata->phy.speed) { + new_state = 1; + pdata->phy_speed = pdata->phy.speed; + } + + if (pdata->phy_link != pdata->phy.link) { + new_state = 1; + pdata->phy_link = pdata->phy.link; + } + } else if (pdata->phy_link) { + new_state = 1; + pdata->phy_link = 0; + pdata->phy_speed = SPEED_UNKNOWN; + } +} + +static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) +{ + + /* Disable auto-negotiation */ + xgbe_disable_an(pdata); + + /* Validate/Set specified speed */ + switch (pdata->phy.speed) { + case SPEED_10000: + xgbe_set_mode(pdata, XGBE_MODE_KR); + break; + + case SPEED_2500: + case SPEED_1000: + xgbe_set_mode(pdata, XGBE_MODE_KX); + break; + + default: + return -EINVAL; + } + + /* Validate duplex mode */ + if (pdata->phy.duplex != DUPLEX_FULL) + return -EINVAL; + + return 0; +} + +static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) +{ + set_bit(XGBE_LINK_INIT, &pdata->dev_state); + pdata->link_check = ticks; + + if (pdata->phy.autoneg != AUTONEG_ENABLE) + return xgbe_phy_config_fixed(pdata); + + /* Disable auto-negotiation interrupt */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); + + /* Clear any auto-negotitation interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); + + /* Start auto-negotiation in a supported mode */ + if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) { + xgbe_set_mode(pdata, XGBE_MODE_KR); + } else if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || + (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) { + xgbe_set_mode(pdata, XGBE_MODE_KX); + } else { + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); + return -EINVAL; + } + + /* Disable and stop any in progress auto-negotiation */ + xgbe_disable_an(pdata); + + /* Clear any auto-negotitation interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); + + pdata->an_result = XGBE_AN_READY; + pdata->an_state = XGBE_AN_READY; + pdata->kr_state = XGBE_RX_BPA; + pdata->kx_state = XGBE_RX_BPA; + + /* Re-enable auto-negotiation interrupt */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); + + /* Set up advertisement registers based on current settings */ + xgbe_an_init(pdata); + + /* Enable and start auto-negotiation */ + xgbe_restart_an(pdata); + + return 0; +} + +static int xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) +{ + int ret; + + sx_xlock(&pdata->an_mutex); + + ret = __xgbe_phy_config_aneg(pdata); + if (ret) + set_bit(XGBE_LINK_ERR, &pdata->dev_state); + else + clear_bit(XGBE_LINK_ERR, &pdata->dev_state); + + sx_unlock(&pdata->an_mutex); + + return ret; +} + +static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata) +{ + return (pdata->an_result == XGBE_AN_COMPLETE); +} + +static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) +{ + unsigned long link_timeout; + + link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * hz); + if ((int)(ticks - link_timeout) >= 0) { + xgbe_phy_config_aneg(pdata); + } +} + +static void xgbe_phy_status_force(struct xgbe_prv_data *pdata) +{ + if (xgbe_in_kr_mode(pdata)) { + pdata->phy.speed = SPEED_10000; + } else { + switch (pdata->speed_set) { + case XGBE_SPEEDSET_1000_10000: + pdata->phy.speed = SPEED_1000; + break; + + case XGBE_SPEEDSET_2500_10000: + pdata->phy.speed = SPEED_2500; + break; + } + } + pdata->phy.duplex = DUPLEX_FULL; +} + +static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) +{ + unsigned int ad_reg, lp_reg; + + pdata->phy.lp_advertising = 0; + + if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect) + return xgbe_phy_status_force(pdata); + + pdata->phy.lp_advertising |= ADVERTISED_Autoneg; + pdata->phy.lp_advertising |= ADVERTISED_Backplane; + + /* Compare Advertisement and Link Partner register 1 */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA); + if (lp_reg & 0x400) + pdata->phy.lp_advertising |= ADVERTISED_Pause; + if (lp_reg & 0x800) + pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; + + if (pdata->phy.pause_autoneg) { + /* Set flow control based on auto-negotiation result */ + pdata->phy.tx_pause = 0; + pdata->phy.rx_pause = 0; + + if (ad_reg & lp_reg & 0x400) { + pdata->phy.tx_pause = 1; + pdata->phy.rx_pause = 1; + } else if (ad_reg & lp_reg & 0x800) { + if (ad_reg & 0x400) + pdata->phy.rx_pause = 1; + else if (lp_reg & 0x400) + pdata->phy.tx_pause = 1; + } + } + + /* Compare Advertisement and Link Partner register 2 */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1); + if (lp_reg & 0x80) + pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full; + if (lp_reg & 0x20) { + switch (pdata->speed_set) { + case XGBE_SPEEDSET_1000_10000: + pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full; + break; + case XGBE_SPEEDSET_2500_10000: + pdata->phy.lp_advertising |= ADVERTISED_2500baseX_Full; + break; + } + } + + ad_reg &= lp_reg; + if (ad_reg & 0x80) { + pdata->phy.speed = SPEED_10000; + xgbe_set_mode(pdata, XGBE_MODE_KR); + } else if (ad_reg & 0x20) { + switch (pdata->speed_set) { + case XGBE_SPEEDSET_1000_10000: + pdata->phy.speed = SPEED_1000; + break; + + case XGBE_SPEEDSET_2500_10000: + pdata->phy.speed = SPEED_2500; + break; + } + + xgbe_set_mode(pdata, XGBE_MODE_KX); + } else { + pdata->phy.speed = SPEED_UNKNOWN; + } + + /* Compare Advertisement and Link Partner register 3 */ + ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2); + lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2); +} + +static void xgbe_phy_status(struct xgbe_prv_data *pdata) +{ + unsigned int reg, link_aneg; + + if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) { + pdata->phy.link = 0; + goto adjust_link; + } + + link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE); + + /* Get the link status. Link status is latched low, so read + * once to clear and then read again to get current state + */ + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + pdata->phy.link = (reg & MDIO_STAT1_LSTATUS) ? 1 : 0; + + if (pdata->phy.link) { + if (link_aneg && !xgbe_phy_aneg_done(pdata)) { + xgbe_check_link_timeout(pdata); + return; + } + + xgbe_phy_status_aneg(pdata); + + if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) + clear_bit(XGBE_LINK_INIT, &pdata->dev_state); + } else { + if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { + xgbe_check_link_timeout(pdata); + + if (link_aneg) + return; + } + + xgbe_phy_status_aneg(pdata); + } + +adjust_link: + xgbe_phy_adjust_link(pdata); +} + +static void xgbe_phy_stop(struct xgbe_prv_data *pdata) +{ + + /* Disable auto-negotiation */ + xgbe_disable_an(pdata); + + /* Disable auto-negotiation interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0); + + bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); + + pdata->phy.link = 0; + + xgbe_phy_adjust_link(pdata); +} + +static int xgbe_phy_start(struct xgbe_prv_data *pdata) +{ + int ret; + + ret = bus_setup_intr(pdata->dev, pdata->an_irq_res, + INTR_MPSAFE | INTR_TYPE_NET, NULL, xgbe_an_isr, pdata, + &pdata->an_irq_tag); + if (ret) { + return -ret; + } + + /* Set initial mode - call the mode setting routines + * directly to insure we are properly configured + */ + if (xgbe_use_xgmii_mode(pdata)) { + xgbe_xgmii_mode(pdata); + } else if (xgbe_use_gmii_mode(pdata)) { + xgbe_gmii_mode(pdata); + } else if (xgbe_use_gmii_2500_mode(pdata)) { + xgbe_gmii_2500_mode(pdata); + } else { + ret = -EINVAL; + goto err_irq; + } + + /* Set up advertisement registers based on current settings */ + xgbe_an_init(pdata); + + /* Enable auto-negotiation interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INTMASK, 0x07); + + return xgbe_phy_config_aneg(pdata); + +err_irq: + bus_teardown_intr(pdata->dev, pdata->an_irq_res, pdata->an_irq_tag); + + return ret; +} + +static int xgbe_phy_reset(struct xgbe_prv_data *pdata) +{ + unsigned int count, reg; + + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + reg |= MDIO_CTRL1_RESET; + XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); + + count = 50; + do { + DELAY(20); + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); + } while ((reg & MDIO_CTRL1_RESET) && --count); + + if (reg & MDIO_CTRL1_RESET) + return -ETIMEDOUT; + + /* Disable auto-negotiation for now */ + xgbe_disable_an(pdata); + + /* Clear auto-negotiation interrupts */ + XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); + + return 0; +} + +static void xgbe_phy_init(struct xgbe_prv_data *pdata) +{ + sx_init(&pdata->an_mutex, "axgbe AN lock"); + pdata->mdio_mmd = MDIO_MMD_PCS; + + /* Initialize supported features */ + pdata->phy.supported = SUPPORTED_Autoneg; + pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; + pdata->phy.supported |= SUPPORTED_Backplane; + pdata->phy.supported |= SUPPORTED_10000baseKR_Full; + switch (pdata->speed_set) { + case XGBE_SPEEDSET_1000_10000: + pdata->phy.supported |= SUPPORTED_1000baseKX_Full; + break; + case XGBE_SPEEDSET_2500_10000: + pdata->phy.supported |= SUPPORTED_2500baseX_Full; + break; + } + + pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, + MDIO_PMA_10GBR_FECABLE); + pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE | + MDIO_PMA_10GBR_FECABLE_ERRABLE); + if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) + pdata->phy.supported |= SUPPORTED_10000baseR_FEC; + + pdata->phy.advertising = pdata->phy.supported; + + pdata->phy.address = 0; + + pdata->phy.autoneg = AUTONEG_ENABLE; + pdata->phy.speed = SPEED_UNKNOWN; + pdata->phy.duplex = DUPLEX_UNKNOWN; + + pdata->phy.link = 0; + + pdata->phy.pause_autoneg = pdata->pause_autoneg; + pdata->phy.tx_pause = pdata->tx_pause; + pdata->phy.rx_pause = pdata->rx_pause; + + /* Fix up Flow Control advertising */ + pdata->phy.advertising &= ~ADVERTISED_Pause; + pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; + + if (pdata->rx_pause) { + pdata->phy.advertising |= ADVERTISED_Pause; + pdata->phy.advertising |= ADVERTISED_Asym_Pause; + } + + if (pdata->tx_pause) + pdata->phy.advertising ^= ADVERTISED_Asym_Pause; +} + +void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *phy_if) +{ + phy_if->phy_init = xgbe_phy_init; + + phy_if->phy_reset = xgbe_phy_reset; + phy_if->phy_start = xgbe_phy_start; + phy_if->phy_stop = xgbe_phy_stop; + + phy_if->phy_status = xgbe_phy_status; + phy_if->phy_config_aneg = xgbe_phy_config_aneg; +} diff --git a/sys/dev/axgbe/xgbe.h b/sys/dev/axgbe/xgbe.h new file mode 100644 index 000000000000..ee55ef8f0a16 --- /dev/null +++ b/sys/dev/axgbe/xgbe.h @@ -0,0 +1,889 @@ +/* + * AMD 10Gb Ethernet driver + * + * This file is available to you under your choice of the following two + * licenses: + * + * License 1: GPLv2 + * + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc. + * + * This file is free software; you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or (at + * your option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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. + * + * + * License 2: Modified BSD + * + * Copyright (c) 2014-2016 Advanced Micro Devices, 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * The Synopsys DWC ETHER XGMAC Software Driver and documentation + * (hereinafter "Software") is an unsupported proprietary work of Synopsys, + * Inc. unless otherwise expressly agreed to in writing between Synopsys + * and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for Licensed + * Product with Synopsys or any supplement thereto. Permission is hereby + * granted, free of charge, to any person obtaining a copy of this software + * annotated with this license and the Software, to deal in the Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS + * 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 __XGBE_H__ +#define __XGBE_H__ + +#include "xgbe_osdep.h" + +/* From linux/dcbnl.h */ +#define IEEE_8021QAZ_MAX_TCS 8 + +#define XGBE_DRV_NAME "amd-xgbe" +#define XGBE_DRV_VERSION "1.0.2" +#define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver" + +/* Descriptor related defines */ +#define XGBE_TX_DESC_CNT 512 +#define XGBE_TX_DESC_MIN_FREE (XGBE_TX_DESC_CNT >> 3) +#define XGBE_TX_DESC_MAX_PROC (XGBE_TX_DESC_CNT >> 1) +#define XGBE_RX_DESC_CNT 512 + +#define XGBE_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1)) + +/* Descriptors required for maximum contiguous TSO/GSO packet */ +#define XGBE_TX_MAX_SPLIT ((GSO_MAX_SIZE / XGBE_TX_MAX_BUF_SIZE) + 1) + +/* Maximum possible descriptors needed for an SKB: + * - Maximum number of SKB frags + * - Maximum descriptors for contiguous TSO/GSO packet + * - Possible context descriptor + * - Possible TSO header descriptor + */ +#define XGBE_TX_MAX_DESCS (MAX_SKB_FRAGS + XGBE_TX_MAX_SPLIT + 2) + +#define XGBE_RX_MIN_BUF_SIZE 1522 +#define XGBE_RX_BUF_ALIGN 64 +#define XGBE_SKB_ALLOC_SIZE 256 +#define XGBE_SPH_HDSMS_SIZE 2 /* Keep in sync with SKB_ALLOC_SIZE */ + +#define XGBE_MAX_DMA_CHANNELS 16 +#define XGBE_MAX_QUEUES 16 +#define XGBE_DMA_STOP_TIMEOUT 5 + +/* DMA cache settings - Outer sharable, write-back, write-allocate */ +#define XGBE_DMA_OS_AXDOMAIN 0x2 +#define XGBE_DMA_OS_ARCACHE 0xb +#define XGBE_DMA_OS_AWCACHE 0xf + +/* DMA cache settings - System, no caches used */ +#define XGBE_DMA_SYS_AXDOMAIN 0x3 +#define XGBE_DMA_SYS_ARCACHE 0x0 +#define XGBE_DMA_SYS_AWCACHE 0x0 + +#define XGBE_DMA_INTERRUPT_MASK 0x31c7 + +#define XGMAC_MIN_PACKET 60 +#define XGMAC_STD_PACKET_MTU 1500 +#define XGMAC_MAX_STD_PACKET 1518 +#define XGMAC_JUMBO_PACKET_MTU 9000 +#define XGMAC_MAX_JUMBO_PACKET 9018 + +/* Common property names */ +#define XGBE_MAC_ADDR_PROPERTY "mac-address" +#define XGBE_PHY_MODE_PROPERTY "phy-mode" +#define XGBE_DMA_IRQS_PROPERTY "amd,per-channel-interrupt" +#define XGBE_SPEEDSET_PROPERTY "amd,speed-set" +#define XGBE_BLWC_PROPERTY "amd,serdes-blwc" +#define XGBE_CDR_RATE_PROPERTY "amd,serdes-cdr-rate" +#define XGBE_PQ_SKEW_PROPERTY "amd,serdes-pq-skew" +#define XGBE_TX_AMP_PROPERTY "amd,serdes-tx-amp" +#define XGBE_DFE_CFG_PROPERTY "amd,serdes-dfe-tap-config" +#define XGBE_DFE_ENA_PROPERTY "amd,serdes-dfe-tap-enable" + +/* Device-tree clock names */ +#define XGBE_DMA_CLOCK "dma_clk" +#define XGBE_PTP_CLOCK "ptp_clk" + +/* ACPI property names */ +#define XGBE_ACPI_DMA_FREQ "amd,dma-freq" +#define XGBE_ACPI_PTP_FREQ "amd,ptp-freq" + +/* Timestamp support - values based on 50MHz PTP clock + * 50MHz => 20 nsec + */ +#define XGBE_TSTAMP_SSINC 20 +#define XGBE_TSTAMP_SNSINC 0 + +/* Driver PMT macros */ +#define XGMAC_DRIVER_CONTEXT 1 +#define XGMAC_IOCTL_CONTEXT 2 + +#define XGBE_FIFO_MAX 81920 + +#define XGBE_TC_MIN_QUANTUM 10 + +/* Helper macro for descriptor handling + * Always use XGBE_GET_DESC_DATA to access the descriptor data + * since the index is free-running and needs to be and-ed + * with the descriptor count value of the ring to index to + * the proper descriptor data. + */ +#define XGBE_GET_DESC_DATA(_ring, _idx) \ + ((_ring)->rdata + \ + ((_idx) & ((_ring)->rdesc_count - 1))) + +/* Default coalescing parameters */ +#define XGMAC_INIT_DMA_TX_USECS 1000 +#define XGMAC_INIT_DMA_TX_FRAMES 25 + +#define XGMAC_MAX_DMA_RIWT 0xff +#define XGMAC_INIT_DMA_RX_USECS 30 +#define XGMAC_INIT_DMA_RX_FRAMES 25 + +/* Flow control queue count */ +#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8 + +/* Maximum MAC address hash table size (256 bits = 8 bytes) */ +#define XGBE_MAC_HASH_TABLE_SIZE 8 + +/* Receive Side Scaling */ +#define XGBE_RSS_HASH_KEY_SIZE 40 +#define XGBE_RSS_MAX_TABLE_SIZE 256 +#define XGBE_RSS_LOOKUP_TABLE_TYPE 0 +#define XGBE_RSS_HASH_KEY_TYPE 1 + +/* Auto-negotiation */ +#define XGBE_AN_MS_TIMEOUT 500 +#define XGBE_LINK_TIMEOUT 10 + +#define XGBE_AN_INT_CMPLT 0x01 +#define XGBE_AN_INC_LINK 0x02 +#define XGBE_AN_PG_RCV 0x04 +#define XGBE_AN_INT_MASK 0x07 + +/* Rate-change complete wait/retry count */ +#define XGBE_RATECHANGE_COUNT 500 + +/* Default SerDes settings */ +#define XGBE_SPEED_10000_BLWC 0 +#define XGBE_SPEED_10000_CDR 0x7 +#define XGBE_SPEED_10000_PLL 0x1 +#define XGBE_SPEED_10000_PQ 0x12 +#define XGBE_SPEED_10000_RATE 0x0 +#define XGBE_SPEED_10000_TXAMP 0xa +#define XGBE_SPEED_10000_WORD 0x7 +#define XGBE_SPEED_10000_DFE_TAP_CONFIG 0x1 +#define XGBE_SPEED_10000_DFE_TAP_ENABLE 0x7f + +#define XGBE_SPEED_2500_BLWC 1 +#define XGBE_SPEED_2500_CDR 0x2 +#define XGBE_SPEED_2500_PLL 0x0 +#define XGBE_SPEED_2500_PQ 0xa +#define XGBE_SPEED_2500_RATE 0x1 +#define XGBE_SPEED_2500_TXAMP 0xf +#define XGBE_SPEED_2500_WORD 0x1 +#define XGBE_SPEED_2500_DFE_TAP_CONFIG 0x3 +#define XGBE_SPEED_2500_DFE_TAP_ENABLE 0x0 + +#define XGBE_SPEED_1000_BLWC 1 +#define XGBE_SPEED_1000_CDR 0x2 +#define XGBE_SPEED_1000_PLL 0x0 +#define XGBE_SPEED_1000_PQ 0xa +#define XGBE_SPEED_1000_RATE 0x3 +#define XGBE_SPEED_1000_TXAMP 0xf +#define XGBE_SPEED_1000_WORD 0x1 +#define XGBE_SPEED_1000_DFE_TAP_CONFIG 0x3 +#define XGBE_SPEED_1000_DFE_TAP_ENABLE 0x0 + +struct xgbe_prv_data; + +struct xgbe_packet_data { + struct mbuf *m; + + unsigned int attributes; + + unsigned int errors; + + unsigned int rdesc_count; + unsigned int length; + + u64 rx_tstamp; + + unsigned int tx_packets; + unsigned int tx_bytes; +}; + +/* Common Rx and Tx descriptor mapping */ +struct xgbe_ring_desc { + __le32 desc0; + __le32 desc1; + __le32 desc2; + __le32 desc3; +}; + +/* Tx-related ring data */ +struct xgbe_tx_ring_data { + unsigned int packets; /* BQL packet count */ + unsigned int bytes; /* BQL byte count */ +}; + +/* Rx-related ring data */ +struct xgbe_rx_ring_data { + unsigned short hdr_len; /* Length of received header */ + unsigned short len; /* Length of received packet */ +}; + +/* Structure used to hold information related to the descriptor + * and the packet associated with the descriptor (always use + * use the XGBE_GET_DESC_DATA macro to access this data from the ring) + */ +struct xgbe_ring_data { + struct xgbe_ring_desc *rdesc; /* Virtual address of descriptor */ + bus_addr_t rdata_paddr; + + bus_dma_tag_t mbuf_dmat; + bus_dmamap_t mbuf_map; + bus_addr_t mbuf_hdr_paddr; + bus_addr_t mbuf_data_paddr; + bus_size_t mbuf_len; + + int mbuf_free; + struct mbuf *mb; + + struct xgbe_tx_ring_data tx; /* Tx-related data */ + struct xgbe_rx_ring_data rx; /* Rx-related data */ +}; + +struct xgbe_ring { + /* Ring lock - used just for TX rings at the moment */ + spinlock_t lock; + + /* Per packet related information */ + struct xgbe_packet_data packet_data; + + /* Virtual/DMA addresses and count of allocated descriptor memory */ + struct xgbe_ring_desc *rdesc; + bus_dmamap_t rdesc_map; + bus_dma_tag_t rdesc_dmat; + bus_addr_t rdesc_paddr; + unsigned int rdesc_count; + + bus_dma_tag_t mbuf_dmat; + bus_dmamap_t mbuf_map; + + /* Array of descriptor data corresponding the descriptor memory + * (always use the XGBE_GET_DESC_DATA macro to access this data) + */ + struct xgbe_ring_data *rdata; + + /* Ring index values + * cur - Tx: index of descriptor to be used for current transfer + * Rx: index of descriptor to check for packet availability + * dirty - Tx: index of descriptor to check for transfer complete + * Rx: index of descriptor to check for buffer reallocation + */ + unsigned int cur; + unsigned int dirty; + + /* Coalesce frame count used for interrupt bit setting */ + unsigned int coalesce_count; + + union { + struct { + unsigned int queue_stopped; + unsigned int xmit_more; + unsigned short cur_mss; + unsigned short cur_vlan_ctag; + } tx; + }; +} __aligned(CACHE_LINE_SIZE); + +/* Structure used to describe the descriptor rings associated with + * a DMA channel. + */ +struct xgbe_channel { + char name[16]; + + /* Address of private data area for device */ + struct xgbe_prv_data *pdata; + + /* Queue index and base address of queue's DMA registers */ + unsigned int queue_index; + bus_space_tag_t dma_tag; + bus_space_handle_t dma_handle; + + /* Per channel interrupt irq number */ + struct resource *dma_irq_res; + void *dma_irq_tag; + + unsigned int saved_ier; + + struct xgbe_ring *tx_ring; + struct xgbe_ring *rx_ring; +} __aligned(CACHE_LINE_SIZE); + +enum xgbe_state { + XGBE_DOWN, + XGBE_LINK_INIT, + XGBE_LINK_ERR, +}; + +enum xgbe_int { + XGMAC_INT_DMA_CH_SR_TI, + XGMAC_INT_DMA_CH_SR_TPS, + XGMAC_INT_DMA_CH_SR_TBU, + XGMAC_INT_DMA_CH_SR_RI, + XGMAC_INT_DMA_CH_SR_RBU, + XGMAC_INT_DMA_CH_SR_RPS, + XGMAC_INT_DMA_CH_SR_TI_RI, + XGMAC_INT_DMA_CH_SR_FBE, + XGMAC_INT_DMA_ALL, +}; + +enum xgbe_int_state { + XGMAC_INT_STATE_SAVE, + XGMAC_INT_STATE_RESTORE, +}; + +enum xgbe_speed { + XGBE_SPEED_1000 = 0, + XGBE_SPEED_2500, + XGBE_SPEED_10000, + XGBE_SPEEDS, +}; + +enum xgbe_an { + XGBE_AN_READY = 0, + XGBE_AN_PAGE_RECEIVED, + XGBE_AN_INCOMPAT_LINK, + XGBE_AN_COMPLETE, + XGBE_AN_NO_LINK, + XGBE_AN_ERROR, +}; + +enum xgbe_rx { + XGBE_RX_BPA = 0, + XGBE_RX_XNP, + XGBE_RX_COMPLETE, + XGBE_RX_ERROR, +}; + +enum xgbe_mode { + XGBE_MODE_KR = 0, + XGBE_MODE_KX, +}; + +enum xgbe_speedset { + XGBE_SPEEDSET_1000_10000 = 0, + XGBE_SPEEDSET_2500_10000, +}; + +struct xgbe_phy { + u32 supported; + u32 advertising; + u32 lp_advertising; + + int address; + + int autoneg; + int speed; + int duplex; + + int link; + + int pause_autoneg; + int tx_pause; + int rx_pause; +}; + +struct xgbe_mmc_stats { + /* Tx Stats */ + u64 txoctetcount_gb; + u64 txframecount_gb; + u64 txbroadcastframes_g; + u64 txmulticastframes_g; + u64 tx64octets_gb; + u64 tx65to127octets_gb; + u64 tx128to255octets_gb; + u64 tx256to511octets_gb; + u64 tx512to1023octets_gb; + u64 tx1024tomaxoctets_gb; + u64 txunicastframes_gb; + u64 txmulticastframes_gb; + u64 txbroadcastframes_gb; + u64 txunderflowerror; + u64 txoctetcount_g; + u64 txframecount_g; + u64 txpauseframes; + u64 txvlanframes_g; + + /* Rx Stats */ + u64 rxframecount_gb; + u64 rxoctetcount_gb; + u64 rxoctetcount_g; + u64 rxbroadcastframes_g; + u64 rxmulticastframes_g; + u64 rxcrcerror; + u64 rxrunterror; + u64 rxjabbererror; + u64 rxundersize_g; + u64 rxoversize_g; + u64 rx64octets_gb; + u64 rx65to127octets_gb; + u64 rx128to255octets_gb; + u64 rx256to511octets_gb; + u64 rx512to1023octets_gb; + u64 rx1024tomaxoctets_gb; + u64 rxunicastframes_g; + u64 rxlengtherror; + u64 rxoutofrangetype; + u64 rxpauseframes; + u64 rxfifooverflow; + u64 rxvlanframes_gb; + u64 rxwatchdogerror; +}; + +struct xgbe_ext_stats { + u64 tx_tso_packets; + u64 rx_split_header_packets; + u64 rx_buffer_unavailable; +}; + +struct xgbe_hw_if { + int (*tx_complete)(struct xgbe_ring_desc *); + + int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr); + int (*config_rx_mode)(struct xgbe_prv_data *); + + int (*enable_rx_csum)(struct xgbe_prv_data *); + int (*disable_rx_csum)(struct xgbe_prv_data *); + + int (*enable_rx_vlan_stripping)(struct xgbe_prv_data *); + int (*disable_rx_vlan_stripping)(struct xgbe_prv_data *); + int (*enable_rx_vlan_filtering)(struct xgbe_prv_data *); + int (*disable_rx_vlan_filtering)(struct xgbe_prv_data *); + int (*update_vlan_hash_table)(struct xgbe_prv_data *); + + int (*read_mmd_regs)(struct xgbe_prv_data *, int, int); + void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int); + int (*set_gmii_speed)(struct xgbe_prv_data *); + int (*set_gmii_2500_speed)(struct xgbe_prv_data *); + int (*set_xgmii_speed)(struct xgbe_prv_data *); + + void (*enable_tx)(struct xgbe_prv_data *); + void (*disable_tx)(struct xgbe_prv_data *); + void (*enable_rx)(struct xgbe_prv_data *); + void (*disable_rx)(struct xgbe_prv_data *); + + void (*powerup_tx)(struct xgbe_prv_data *); + void (*powerdown_tx)(struct xgbe_prv_data *); + void (*powerup_rx)(struct xgbe_prv_data *); + void (*powerdown_rx)(struct xgbe_prv_data *); + + int (*init)(struct xgbe_prv_data *); + int (*exit)(struct xgbe_prv_data *); + + int (*enable_int)(struct xgbe_channel *, enum xgbe_int); + int (*disable_int)(struct xgbe_channel *, enum xgbe_int); + void (*dev_xmit)(struct xgbe_channel *); + int (*dev_read)(struct xgbe_channel *); + void (*tx_desc_init)(struct xgbe_channel *); + void (*rx_desc_init)(struct xgbe_channel *); + void (*tx_desc_reset)(struct xgbe_ring_data *); + void (*rx_desc_reset)(struct xgbe_prv_data *, struct xgbe_ring_data *, + unsigned int); + int (*is_last_desc)(struct xgbe_ring_desc *); + int (*is_context_desc)(struct xgbe_ring_desc *); + void (*tx_start_xmit)(struct xgbe_channel *, struct xgbe_ring *); + + /* For FLOW ctrl */ + int (*config_tx_flow_control)(struct xgbe_prv_data *); + int (*config_rx_flow_control)(struct xgbe_prv_data *); + + /* For RX coalescing */ + int (*config_rx_coalesce)(struct xgbe_prv_data *); + int (*config_tx_coalesce)(struct xgbe_prv_data *); + unsigned int (*usec_to_riwt)(struct xgbe_prv_data *, unsigned int); + unsigned int (*riwt_to_usec)(struct xgbe_prv_data *, unsigned int); + + /* For RX and TX threshold config */ + int (*config_rx_threshold)(struct xgbe_prv_data *, unsigned int); + int (*config_tx_threshold)(struct xgbe_prv_data *, unsigned int); + + /* For RX and TX Store and Forward Mode config */ + int (*config_rsf_mode)(struct xgbe_prv_data *, unsigned int); + int (*config_tsf_mode)(struct xgbe_prv_data *, unsigned int); + + /* For TX DMA Operate on Second Frame config */ + int (*config_osp_mode)(struct xgbe_prv_data *); + + /* For RX and TX PBL config */ + int (*config_rx_pbl_val)(struct xgbe_prv_data *); + int (*get_rx_pbl_val)(struct xgbe_prv_data *); + int (*config_tx_pbl_val)(struct xgbe_prv_data *); + int (*get_tx_pbl_val)(struct xgbe_prv_data *); + int (*config_pblx8)(struct xgbe_prv_data *); + + /* For MMC statistics */ + void (*rx_mmc_int)(struct xgbe_prv_data *); + void (*tx_mmc_int)(struct xgbe_prv_data *); + void (*read_mmc_stats)(struct xgbe_prv_data *); + + /* For Receive Side Scaling */ + int (*disable_rss)(struct xgbe_prv_data *); +}; + +struct xgbe_phy_if { + /* For initial PHY setup */ + void (*phy_init)(struct xgbe_prv_data *); + + /* For PHY support when setting device up/down */ + int (*phy_reset)(struct xgbe_prv_data *); + int (*phy_start)(struct xgbe_prv_data *); + void (*phy_stop)(struct xgbe_prv_data *); + + /* For PHY support while device is up */ + void (*phy_status)(struct xgbe_prv_data *); + int (*phy_config_aneg)(struct xgbe_prv_data *); +}; + +struct xgbe_desc_if { + int (*alloc_ring_resources)(struct xgbe_prv_data *); + void (*free_ring_resources)(struct xgbe_prv_data *); + int (*map_tx_skb)(struct xgbe_channel *, struct mbuf *); + int (*map_rx_buffer)(struct xgbe_prv_data *, struct xgbe_ring *, + struct xgbe_ring_data *); + void (*unmap_rdata)(struct xgbe_prv_data *, struct xgbe_ring_data *); + void (*wrapper_tx_desc_init)(struct xgbe_prv_data *); + void (*wrapper_rx_desc_init)(struct xgbe_prv_data *); +}; + +/* This structure contains flags that indicate what hardware features + * or configurations are present in the device. + */ +struct xgbe_hw_features { + /* HW Version */ + unsigned int version; + + /* HW Feature Register0 */ + unsigned int gmii; /* 1000 Mbps support */ + unsigned int vlhash; /* VLAN Hash Filter */ + unsigned int sma; /* SMA(MDIO) Interface */ + unsigned int rwk; /* PMT remote wake-up packet */ + unsigned int mgk; /* PMT magic packet */ + unsigned int mmc; /* RMON module */ + unsigned int aoe; /* ARP Offload */ + unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */ + unsigned int eee; /* Energy Efficient Ethernet */ + unsigned int tx_coe; /* Tx Checksum Offload */ + unsigned int rx_coe; /* Rx Checksum Offload */ + unsigned int addn_mac; /* Additional MAC Addresses */ + unsigned int ts_src; /* Timestamp Source */ + unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */ + + /* HW Feature Register1 */ + unsigned int rx_fifo_size; /* MTL Receive FIFO Size */ + unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */ + unsigned int adv_ts_hi; /* Advance Timestamping High Word */ + unsigned int dma_width; /* DMA width */ + unsigned int dcb; /* DCB Feature */ + unsigned int sph; /* Split Header Feature */ + unsigned int tso; /* TCP Segmentation Offload */ + unsigned int dma_debug; /* DMA Debug Registers */ + unsigned int rss; /* Receive Side Scaling */ + unsigned int tc_cnt; /* Number of Traffic Classes */ + unsigned int hash_table_size; /* Hash Table Size */ + unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */ + + /* HW Feature Register2 */ + unsigned int rx_q_cnt; /* Number of MTL Receive Queues */ + unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */ + unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */ + unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */ + unsigned int pps_out_num; /* Number of PPS outputs */ + unsigned int aux_snap_num; /* Number of Aux snapshot inputs */ +}; + +struct xgbe_prv_data { + struct ifnet *netdev; + struct platform_device *pdev; + struct acpi_device *adev; + device_t dev; + + /* ACPI or DT flag */ + unsigned int use_acpi; + + /* XGMAC/XPCS related mmio registers */ + struct resource *xgmac_res; /* XGMAC CSRs */ + struct resource *xpcs_res; /* XPCS MMD registers */ + struct resource *rxtx_res; /* SerDes Rx/Tx CSRs */ + struct resource *sir0_res; /* SerDes integration registers (1/2) */ + struct resource *sir1_res; /* SerDes integration registers (2/2) */ + + /* DMA tag */ + bus_dma_tag_t dmat; + + /* XPCS indirect addressing lock */ + spinlock_t xpcs_lock; + + /* Flags representing xgbe_state */ + unsigned long dev_state; + + struct resource *dev_irq_res; + struct resource *chan_irq_res[4]; + void *dev_irq_tag; + unsigned int per_channel_irq; + + struct xgbe_hw_if hw_if; + struct xgbe_phy_if phy_if; + struct xgbe_desc_if desc_if; + + /* AXI DMA settings */ + unsigned int coherent; + unsigned int axdomain; + unsigned int arcache; + unsigned int awcache; + + /* Service routine support */ + struct taskqueue *dev_workqueue; + struct task service_work; + struct callout service_timer; + + /* Rings for Tx/Rx on a DMA channel */ + struct xgbe_channel *channel; + unsigned int channel_count; + unsigned int tx_ring_count; + unsigned int tx_desc_count; + unsigned int rx_ring_count; + unsigned int rx_desc_count; + + unsigned int tx_q_count; + unsigned int rx_q_count; + + /* Tx/Rx common settings */ + unsigned int pblx8; + + /* Tx settings */ + unsigned int tx_sf_mode; + unsigned int tx_threshold; + unsigned int tx_pbl; + unsigned int tx_osp_mode; + + /* Rx settings */ + unsigned int rx_sf_mode; + unsigned int rx_threshold; + unsigned int rx_pbl; + + /* Tx coalescing settings */ + unsigned int tx_usecs; + unsigned int tx_frames; + + /* Rx coalescing settings */ + unsigned int rx_riwt; + unsigned int rx_usecs; + unsigned int rx_frames; + + /* Current Rx buffer size */ + unsigned int rx_buf_size; + + /* Flow control settings */ + unsigned int pause_autoneg; + unsigned int tx_pause; + unsigned int rx_pause; + + /* Receive Side Scaling settings */ + u8 rss_key[XGBE_RSS_HASH_KEY_SIZE]; + u32 rss_table[XGBE_RSS_MAX_TABLE_SIZE]; + u32 rss_options; + + /* Netdev related settings */ + unsigned char mac_addr[ETH_ALEN]; + struct xgbe_mmc_stats mmc_stats; + struct xgbe_ext_stats ext_stats; + + /* Device clocks */ + struct clk *sysclk; + unsigned long sysclk_rate; + struct clk *ptpclk; + unsigned long ptpclk_rate; + + /* DCB support */ + unsigned int q2tc_map[XGBE_MAX_QUEUES]; + unsigned int prio2q_map[IEEE_8021QAZ_MAX_TCS]; + u8 num_tcs; + + /* Hardware features of the device */ + struct xgbe_hw_features hw_feat; + + /* Device restart work structure */ + struct task restart_work; + + /* Keeps track of power mode */ + unsigned int power_down; + + /* Network interface message level setting */ + u32 msg_enable; + + /* Current PHY settings */ + int phy_link; + int phy_speed; + + /* MDIO/PHY related settings */ + struct xgbe_phy phy; + int mdio_mmd; + unsigned long link_check; + + char an_name[IFNAMSIZ + 32]; + + struct resource *an_irq_res; + void *an_irq_tag; + + unsigned int speed_set; + + /* SerDes UEFI configurable settings. + * Switching between modes/speeds requires new values for some + * SerDes settings. The values can be supplied as device + * properties in array format. The first array entry is for + * 1GbE, second for 2.5GbE and third for 10GbE + */ + u32 serdes_blwc[XGBE_SPEEDS]; + u32 serdes_cdr_rate[XGBE_SPEEDS]; + u32 serdes_pq_skew[XGBE_SPEEDS]; + u32 serdes_tx_amp[XGBE_SPEEDS]; + u32 serdes_dfe_tap_cfg[XGBE_SPEEDS]; + u32 serdes_dfe_tap_ena[XGBE_SPEEDS]; + + /* Auto-negotiation state machine support */ + unsigned int an_int; + struct sx an_mutex; + enum xgbe_an an_result; + enum xgbe_an an_state; + enum xgbe_rx kr_state; + enum xgbe_rx kx_state; + unsigned int an_supported; + unsigned int parallel_detect; + unsigned int fec_ability; + unsigned long an_start; + + unsigned int lpm_ctrl; /* CTRL1 for resume */ +}; + +/* Function prototypes*/ + +int xgbe_open(struct ifnet *); +int xgbe_close(struct ifnet *); +int xgbe_xmit(struct ifnet *, struct mbuf *); +int xgbe_change_mtu(struct ifnet *, int); +void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *); +void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *); +void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *); +void xgbe_get_all_hw_features(struct xgbe_prv_data *); +void xgbe_init_rx_coalesce(struct xgbe_prv_data *); +void xgbe_init_tx_coalesce(struct xgbe_prv_data *); + +/* NOTE: Uncomment for function trace log messages in KERNEL LOG */ +#if 0 +#define YDEBUG +#define YDEBUG_MDIO +#endif + +/* For debug prints */ +#ifdef YDEBUG +#define DBGPR(x...) printf(x) +#else +#define DBGPR(x...) do { } while (0) +#endif + +#ifdef YDEBUG_MDIO +#define DBGPR_MDIO(x...) printf(x) +#else +#define DBGPR_MDIO(x...) do { } while (0) +#endif + +#endif diff --git a/sys/dev/axgbe/xgbe_osdep.h b/sys/dev/axgbe/xgbe_osdep.h new file mode 100644 index 000000000000..e6d793ecc43a --- /dev/null +++ b/sys/dev/axgbe/xgbe_osdep.h @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2016,2017 SoftIron Inc. + * All rights reserved. + * + * This software was developed by Andrew Turner under + * the sponsorship of SoftIron Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _XGBE_OSDEP_H_ +#define _XGBE_OSDEP_H_ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/endian.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/mutex.h> +#include <sys/socket.h> +#include <sys/sx.h> +#include <sys/taskqueue.h> + +#include <machine/bus.h> + +#include <net/ethernet.h> +#include <net/if.h> +#include <net/if_var.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t __le32; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef struct { + struct mtx lock; +} spinlock_t; + +static inline void +spin_lock_init(spinlock_t *spinlock) +{ + + mtx_init(&spinlock->lock, "axgbe_spin", NULL, MTX_DEF); +} + +#define spin_lock_irqsave(spinlock, flags) \ +do { \ + (flags) = intr_disable(); \ + mtx_lock(&(spinlock)->lock); \ +} while (0) + +#define spin_unlock_irqrestore(spinlock, flags) \ +do { \ + mtx_unlock(&(spinlock)->lock); \ + intr_restore(flags); \ +} while (0) + +#define BIT(pos) (1ul << pos) + +static inline void +clear_bit(int pos, unsigned long *p) +{ + + atomic_clear_long(p, 1ul << pos); +} + +static inline int +test_bit(int pos, unsigned long *p) +{ + unsigned long val; + + val = *p; + return ((val & 1ul << pos) != 0); +} + +static inline void +set_bit(int pos, unsigned long *p) +{ + + atomic_set_long(p, 1ul << pos); +} + +#define lower_32_bits(x) ((x) & 0xffffffffu) +#define upper_32_bits(x) (((x) >> 32) & 0xffffffffu) +#define cpu_to_le32(x) le32toh(x) +#define le32_to_cpu(x) htole32(x) + +MALLOC_DECLARE(M_AXGBE); + +#define ADVERTISED_Pause 0x01 +#define ADVERTISED_Asym_Pause 0x02 +#define ADVERTISED_Autoneg 0x04 +#define ADVERTISED_Backplane 0x08 +#define ADVERTISED_10000baseKR_Full 0x10 +#define ADVERTISED_2500baseX_Full 0x20 +#define ADVERTISED_1000baseKX_Full 0x40 + +#define AUTONEG_DISABLE 0 +#define AUTONEG_ENABLE 1 + +#define DUPLEX_UNKNOWN 1 +#define DUPLEX_FULL 2 + +#define SPEED_UNKNOWN 1 +#define SPEED_10000 2 +#define SPEED_2500 3 +#define SPEED_1000 4 + +#define SUPPORTED_Autoneg 0x01 +#define SUPPORTED_Pause 0x02 +#define SUPPORTED_Asym_Pause 0x04 +#define SUPPORTED_Backplane 0x08 +#define SUPPORTED_10000baseKR_Full 0x10 +#define SUPPORTED_1000baseKX_Full 0x20 +#define SUPPORTED_2500baseX_Full 0x40 +#define SUPPORTED_10000baseR_FEC 0x80 + +#define BMCR_SPEED100 0x2000 + +#define MDIO_MMD_PMAPMD 1 +#define MDIO_MMD_PCS 3 +#define MDIO_MMD_AN 7 +#define MDIO_PMA_10GBR_FECABLE 170 +#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001 +#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002 +#define MII_ADDR_C45 (1<<30) + +#define MDIO_CTRL1 0x00 /* MII_BMCR */ +#define MDIO_CTRL1_RESET 0x8000 /* BMCR_RESET */ +#define MDIO_CTRL1_SPEEDSELEXT 0x2040 /* BMCR_SPEED1000|BMCR_SPEED100*/ +#define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x3c) +#define MDIO_AN_CTRL1_ENABLE 0x1000 /* BMCR_AUTOEN */ +#define MDIO_CTRL1_LPOWER 0x0800 /* BMCR_PDOWN */ +#define MDIO_AN_CTRL1_RESTART 0x0200 /* BMCR_STARTNEG */ + +#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00) + +#define MDIO_STAT1 1 /* MII_BMSR */ +#define MDIO_STAT1_LSTATUS 0x0004 /* BMSR_LINK */ + +#define MDIO_CTRL2 0x07 +#define MDIO_PCS_CTRL2_10GBR 0x0000 +#define MDIO_PCS_CTRL2_10GBX 0x0001 +#define MDIO_PCS_CTRL2_TYPE 0x0003 + +#define MDIO_AN_ADVERTISE 16 + +#define MDIO_AN_LPA 19 + +#define ETH_ALEN ETHER_ADDR_LEN +#define ETH_HLEN ETHER_HDR_LEN +#define ETH_FCS_LEN 4 +#define VLAN_HLEN ETHER_VLAN_ENCAP_LEN + +#define ARRAY_SIZE(x) nitems(x) + +#define BITS_PER_LONG (sizeof(long) * CHAR_BIT) +#define BITS_TO_LONGS(n) howmany((n), BITS_PER_LONG) + +#define NSEC_PER_SEC 1000000000ul + +#define min_t(t, a, b) MIN((t)(a), (t)(b)) +#define max_t(t, a, b) MAX((t)(a), (t)(b)) + +#endif /* _XGBE_OSDEP_H_ */ diff --git a/sys/dev/buslogic/bt.c b/sys/dev/buslogic/bt.c index d3f45c893b13..c17c4f439b4c 100644 --- a/sys/dev/buslogic/bt.c +++ b/sys/dev/buslogic/bt.c @@ -3,7 +3,6 @@ * Product specific probe and attach routines can be found in: * sys/dev/buslogic/bt_isa.c BT-54X, BT-445 cards * sys/dev/buslogic/bt_mca.c BT-64X, SDC3211B, SDC3211F - * sys/dev/buslogic/bt_eisa.c BT-74X, BT-75x cards, SDC3222F * sys/dev/buslogic/bt_pci.c BT-946, BT-948, BT-956, BT-958 cards * * Copyright (c) 1998, 1999 Justin T. Gibbs. @@ -169,7 +168,7 @@ static void bttimeout(void *arg); * XXX * Do our own re-probe protection until a configuration * manager can do it for us. This ensures that we don't - * reprobe a card already found by the EISA or PCI probes. + * reprobe a card already found by the PCI probes. */ struct bt_isa_port bt_isa_ports[] = { @@ -313,7 +312,6 @@ bt_port_probe(device_t dev, struct bt_probe_info *info) return (1); } } else { - /* VL/EISA/PCI DMA */ info->drq = -1; } switch (config_data.irq) { @@ -482,7 +480,6 @@ bt_fetch_adapter_info(device_t dev) * BT-542B/742A (revision H) * 2.xx BusLogic "A" Series Host Adapters: * BT-542B/742A (revision G and below) - * 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter */ length_param = sizeof(esetup_info); error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &length_param, /*parmlen*/1, @@ -499,19 +496,6 @@ bt_fetch_adapter_info(device_t dev) if (esetup_info.bus_type == 'A' && bt->firmware_ver[0] == '2') { snprintf(bt->model, sizeof(bt->model), "542B"); - } else if (esetup_info.bus_type == 'E' - && bt->firmware_ver[0] == '2') { - - /* - * The 742A seems to object if its mailboxes are - * allocated above the 16MB mark. - */ - bt->mailbox_addrlimit = BUS_SPACE_MAXADDR_24BIT; - snprintf(bt->model, sizeof(bt->model), "742A"); - } else if (esetup_info.bus_type == 'E' - && bt->firmware_ver[0] == '0') { - /* AMI FastDisk EISA Series 441 0.x */ - snprintf(bt->model, sizeof(bt->model), "747A"); } else { ha_model_data_t model_data; int i; diff --git a/sys/dev/buslogic/bt_eisa.c b/sys/dev/buslogic/bt_eisa.c deleted file mode 100644 index e68d2f77be28..000000000000 --- a/sys/dev/buslogic/bt_eisa.c +++ /dev/null @@ -1,357 +0,0 @@ -/*- - * Product specific probe and attach routines for: - * Buslogic BT74x SCSI controllers - * - * Copyright (c) 1995, 1998, 1999 Justin T. Gibbs - * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/buslogic/btreg.h> - -#define EISA_DEVICE_ID_BUSLOGIC_74X_B 0x0ab34201 -#define EISA_DEVICE_ID_BUSLOGIC_74X_C 0x0ab34202 -#define EISA_DEVICE_ID_SDC3222B 0x0ab34281 -#define EISA_DEVICE_ID_SDC3222F 0x0ab34781 -#define EISA_DEVICE_ID_SDC3222WS 0x0ab34981 -#define EISA_DEVICE_ID_SDC3222WB 0x0ab34982 -#define EISA_DEVICE_ID_AMI_4801 0x05a94801 - -#define BT_IOSIZE 0x04 /* Move to central header */ -#define BT_EISA_IOSIZE 0x100 -#define BT_EISA_SLOT_OFFSET 0xc00 - -#define EISA_IOCONF 0x08C -#define PORTADDR 0x07 -#define PORT_330 0x00 -#define PORT_334 0x01 -#define PORT_230 0x02 -#define PORT_234 0x03 -#define PORT_130 0x04 -#define PORT_134 0x05 -#define IRQ_CHANNEL 0xe0 -#define INT_11 0x40 -#define INT_10 0x20 -#define INT_15 0xa0 -#define INT_12 0x60 -#define INT_14 0x80 -#define INT_9 0x00 - -#define EISA_IRQ_TYPE 0x08D -#define LEVEL 0x40 - -/* Definitions for the AMI Series 48 controller */ -#define AMI_EISA_IOSIZE 0x500 /* Two separate ranges?? */ -#define AMI_EISA_SLOT_OFFSET 0x800 -#define AMI_EISA_IOCONF 0x000 -#define AMI_DMA_CHANNEL 0x03 -#define AMI_IRQ_CHANNEL 0x1c -#define AMI_INT_15 0x14 -#define AMI_INT_14 0x10 -#define AMI_INT_12 0x0c -#define AMI_INT_11 0x00 -#define AMI_INT_10 0x08 -#define AMI_INT_9 0x04 -#define AMI_BIOS_ADDR 0xe0 - -#define AMI_EISA_IOCONF1 0x001 -#define AMI_PORTADDR 0x0e -#define AMI_PORT_334 0x08 -#define AMI_PORT_330 0x00 -#define AMI_PORT_234 0x0c -#define AMI_PORT_230 0x04 -#define AMI_PORT_134 0x0a -#define AMI_PORT_130 0x02 -#define AMI_IRQ_LEVEL 0x01 - - -#define AMI_MISC2_OPTIONS 0x49E -#define AMI_ENABLE_ISA_DMA 0x08 - -static const char *bt_match(eisa_id_t type); - -static int -bt_eisa_alloc_resources(device_t dev) -{ - struct bt_softc *bt = device_get_softc(dev); - int rid; - struct resource *port; - struct resource *irq; - int shared; - - /* - * XXX assumes that the iospace ranges are sorted in increasing - * order. - */ - rid = 0; - port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (!port) - return (ENOMEM); - - bt_init_softc(dev, port, 0, 0); - - if (eisa_get_irq(dev) != -1) { - shared = bt->level_trigger_ints ? RF_SHAREABLE : 0; - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - shared | RF_ACTIVE); - if (!irq) { - if (port) - bus_release_resource(dev, SYS_RES_IOPORT, - 0, port); - return (ENOMEM); - } - } else - irq = NULL; - bt->irq = irq; - - return (0); -} - -static void -bt_eisa_release_resources(device_t dev) -{ - struct bt_softc *bt = device_get_softc(dev); - - if (bt->port) - bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->port); - if (bt->irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, bt->irq); - bt_free_softc(dev); -} - -static const char* -bt_match(eisa_id_t type) -{ - switch(type) { - case EISA_DEVICE_ID_BUSLOGIC_74X_B: - return ("Buslogic 74xB SCSI host adapter"); - case EISA_DEVICE_ID_BUSLOGIC_74X_C: - return ("Buslogic 74xC SCSI host adapter"); - case EISA_DEVICE_ID_SDC3222B: - return ("Storage Dimensions SDC3222B SCSI host adapter"); - case EISA_DEVICE_ID_SDC3222F: - return ("Storage Dimensions SDC3222F SCSI host adapter"); - case EISA_DEVICE_ID_SDC3222WS: - return ("Storage Dimensions SDC3222WS SCSI host adapter"); - case EISA_DEVICE_ID_SDC3222WB: - return ("Storage Dimensions SDC3222WB SCSI host adapter"); - case EISA_DEVICE_ID_AMI_4801: - return ("AMI Series 48 SCSI host adapter"); - default: - break; - } - return (NULL); -} - -static int -bt_eisa_probe(device_t dev) -{ - const char *desc; - u_long iobase; - struct bt_probe_info info; - u_long port; - u_long iosize; - u_int ioconf; - int result; - int shared; - - desc = bt_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE); - if (eisa_get_id(dev) == EISA_DEVICE_ID_AMI_4801) { - u_int ioconf1; - - iobase += AMI_EISA_SLOT_OFFSET; - iosize = AMI_EISA_IOSIZE; - ioconf1 = inb(iobase + AMI_EISA_IOCONF1); - /* Determine "ISA" I/O port */ - switch (ioconf1 & AMI_PORTADDR) { - case AMI_PORT_330: - port = 0x330; - break; - case AMI_PORT_334: - port = 0x334; - break; - case AMI_PORT_230: - port = 0x230; - break; - case AMI_PORT_234: - port = 0x234; - break; - case AMI_PORT_134: - port = 0x134; - break; - case AMI_PORT_130: - port = 0x130; - break; - default: - /* Disabled */ - printf("bt: AMI EISA Adapter at " - "slot %d has a disabled I/O " - "port. Cannot attach.\n", - eisa_get_slot(dev)); - return (ENXIO); - } - shared = (inb(iobase + AMI_EISA_IOCONF1) & AMI_IRQ_LEVEL) ? - EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; - } else { - iobase += BT_EISA_SLOT_OFFSET; - iosize = BT_EISA_IOSIZE; - - ioconf = inb(iobase + EISA_IOCONF); - /* Determine "ISA" I/O port */ - switch (ioconf & PORTADDR) { - case PORT_330: - port = 0x330; - break; - case PORT_334: - port = 0x334; - break; - case PORT_230: - port = 0x230; - break; - case PORT_234: - port = 0x234; - break; - case PORT_130: - port = 0x130; - break; - case PORT_134: - port = 0x134; - break; - default: - /* Disabled */ - printf("bt: Buslogic EISA Adapter at " - "slot %d has a disabled I/O " - "port. Cannot attach.\n", - eisa_get_slot(dev)); - return (ENXIO); - } - shared = (inb(iobase + EISA_IRQ_TYPE) & LEVEL) ? - EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; - } - bt_mark_probed_iop(port); - - /* Tell parent where our resources are going to be */ - eisa_add_iospace(dev, iobase, iosize, RESVADDR_NONE); - eisa_add_iospace(dev, port, BT_IOSIZE, RESVADDR_NONE); - - /* And allocate them */ - bt_eisa_alloc_resources(dev); - - if (bt_port_probe(dev, &info) != 0) { - printf("bt_eisa_probe: Probe failed for " - "card at slot 0x%x\n", eisa_get_slot(dev)); - result = ENXIO; - } else { - eisa_add_intr(dev, info.irq, shared); - result = BUS_PROBE_DEFAULT; - } - bt_eisa_release_resources(dev); - - return (result); -} - -static int -bt_eisa_attach(device_t dev) -{ - struct bt_softc *bt = device_get_softc(dev); - - /* Allocate resources */ - bt_eisa_alloc_resources(dev); - - /* Allocate a dmatag for our SCB DMA maps */ - /* XXX Should be a child of the PCI bus dma tag */ - if (bus_dma_tag_create( /* parent */ NULL, - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg, */ NULL, - &bt->parent_dmat) != 0) { - bt_eisa_release_resources(dev); - return (ENOMEM); - } - - /* - * Now that we know we own the resources we need, do the full - * card initialization. - */ - if (bt_probe(dev) || bt_fetch_adapter_info(dev) || bt_init(dev)) { - bt_eisa_release_resources(dev); - return (ENXIO); - } - - /* Attach sub-devices - always succeeds (sets up intr) */ - bt_attach(dev); - - return 0; -} - -static device_method_t bt_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, bt_eisa_probe), - DEVMETHOD(device_attach, bt_eisa_attach), - - { 0, 0 } -}; - -static driver_t bt_eisa_driver = { - "bt", - bt_eisa_methods, - sizeof(struct bt_softc), -}; - -static devclass_t bt_devclass; - -DRIVER_MODULE(bt, eisa, bt_eisa_driver, bt_devclass, 0, 0); -MODULE_DEPEND(bt, eisa, 1, 1, 1); diff --git a/sys/dev/buslogic/bt_isa.c b/sys/dev/buslogic/bt_isa.c index ce121c32ae29..ce6f273ed85f 100644 --- a/sys/dev/buslogic/bt_isa.c +++ b/sys/dev/buslogic/bt_isa.c @@ -150,7 +150,7 @@ bt_isa_probe(device_t dev) /* * Ensure this port has not already been claimed already - * by a PCI, EISA or ISA adapter. + * by a PCI, ISA adapter. */ if (bt_check_probed_iop(ioport) != 0) continue; diff --git a/sys/dev/buslogic/bt_mca.c b/sys/dev/buslogic/bt_mca.c deleted file mode 100644 index 97800fda1e10..000000000000 --- a/sys/dev/buslogic/bt_mca.c +++ /dev/null @@ -1,341 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Written using the bt_isa/bt_pci code as a reference. - * - * Thanks to Andy Farkas <andyf@speednet.com.au> for - * testing and feedback. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mutex.h> - -#include <machine/cpufunc.h> -#include <machine/md_var.h> - -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/mca/mca_busreg.h> -#include <dev/mca/mca_busvar.h> - -#include <isa/isavar.h> - -#include <dev/buslogic/btreg.h> - -#include <cam/scsi/scsi_all.h> - -static struct mca_ident bt_mca_devs[] = { - { 0x0708, "BusLogic 32 Bit Bus Master MCA-to-SCSI Host Adapter" }, - { 0x0708, "BusTek BT-640A Micro Channel to SCSI Host Adapter" }, - { 0x0708, "Storage Dimensions SDC3211B 32-bit SCSI Host Adapter" }, - { 0x0709, "Storage Dimensions SDC3211F 32-bit FAST SCSI Host Adapter" }, - { 0, NULL }, -}; - -#define BT_MCA_IOPORT_POS1 MCA_ADP_POS(MCA_POS0) -#define BT_MCA_IOPORT_POS2 MCA_ADP_POS(MCA_POS1) -#define BT_MCA_IOPORT_MASK1 0x10 -#define BT_MCA_IOPORT_MASK2 0x03 -#define BT_MCA_IOPORT_SIZE 0x03 -#define BT_MCA_IOPORT(pos) (0x30 + \ - (((u_int32_t)pos &\ - BT_MCA_IOPORT_MASK2) << 8) + \ - (((u_int32_t)pos &\ - BT_MCA_IOPORT_MASK1) >> 2)) - -#define BT_MCA_IRQ_POS MCA_ADP_POS(MCA_POS0) -#define BT_MCA_IRQ_MASK 0x0e -#define BT_MCA_IRQ(pos) (((pos & BT_MCA_IRQ_MASK) >> 1) + 8) - -#define BT_MCA_DRQ_POS MCA_ADP_POS(MCA_POS3) -#define BT_MCA_DRQ_MASK 0x0f -#define BT_MCA_DRQ(pos) (pos & BT_MCA_DRQ_MASK) - -#define BT_MCA_SCSIID_POS MCA_ADP_POS(MCA_POS2) -#define BT_MCA_SCSIID_MASK 0xe0 -#define BT_MCA_SCSIID(pos) ((pos & BT_MCA_SCSIID_MASK) >> 5) - -static bus_dma_filter_t btvlbouncefilter; -static bus_dmamap_callback_t btmapsensebuffers; - -static void -bt_mca_release_resources (device_t dev) -{ - struct bt_softc * bt = device_get_softc(dev); - - if (bt->port) - bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->port); - if (bt->irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, bt->irq); - if (bt->drq) - bus_release_resource(dev, SYS_RES_DRQ, 0, bt->drq); - - bt_free_softc(dev); -} - -#define BT_MCA_PROBE 0 -#define BT_MCA_ATTACH 1 - -static int -bt_mca_alloc_resources(device_t dev, int mode) -{ - struct resource * io = NULL; - struct resource * irq = NULL; - struct resource * drq = NULL; - int rid; - - rid = 0; - io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (io == NULL) { - printf("bt_mca_alloc_resources() failed to allocate IOPORT\n"); - return (ENOMEM); - } - - if (mode == BT_MCA_ATTACH) { - - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (irq == NULL) { - printf("bt_mca_alloc_resources() failed to allocate IRQ\n"); - goto bad; - } - - rid = 0; - drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, RF_ACTIVE); - if (drq == NULL) { - printf("bt_mca_alloc_resources() failed to allocate DRQ\n"); - goto bad; - } - } - - bt_init_softc(dev, io, irq, drq); - - return (0); -bad: - bt_mca_release_resources(dev); - return (ENOMEM); -} - -static int -bt_mca_probe (device_t dev) -{ - const char * desc; - mca_id_t id = mca_get_id(dev); - struct bt_probe_info info; - u_int32_t iobase = 0; - u_int32_t iosize = 0; - u_int8_t drq = 0; - u_int8_t irq = 0; - u_int8_t pos; - int result; - - desc = mca_match_id(id, bt_mca_devs); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - pos = (mca_pos_read(dev, BT_MCA_IOPORT_POS1) & BT_MCA_IOPORT_MASK1) | - (mca_pos_read(dev, BT_MCA_IOPORT_POS2) & BT_MCA_IOPORT_MASK2); - iobase = BT_MCA_IOPORT(pos); - iosize = BT_MCA_IOPORT_SIZE; - - pos = mca_pos_read(dev, BT_MCA_DRQ_POS); - drq = BT_MCA_DRQ(pos); - - pos = mca_pos_read(dev, BT_MCA_IRQ_POS); - irq = BT_MCA_IRQ(pos); - - bt_mark_probed_iop(iobase); - - mca_add_iospace(dev, iobase, iosize); - - /* And allocate them */ - bt_mca_alloc_resources(dev, BT_MCA_PROBE); - - if (bt_port_probe(dev, &info) != 0) { - printf("bt_mca_probe: Probe failed for " - "card at slot %d\n", mca_get_slot(dev) + 1); - result = ENXIO; - } else { - mca_add_drq(dev, drq); - mca_add_irq(dev, irq); - result = BUS_PROBE_DEFAULT; - } - bt_mca_release_resources(dev); - - return (result); -} - -static int -bt_mca_attach (device_t dev) -{ - struct bt_softc * bt = device_get_softc(dev); - int error = 0; - - /* Allocate resources */ - if ((error = bt_mca_alloc_resources(dev, BT_MCA_ATTACH))) { - device_printf(dev, "Unable to allocate resources in bt_mca_attach()\n"); - return (error); - } - - isa_dmacascade(rman_get_start(bt->drq)); - - /* Allocate a dmatag for our CCB DMA maps */ - if (bus_dma_tag_create( /* parent */ NULL, - /* alignemnt */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_24BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ btvlbouncefilter, - /* filterarg */ bt, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &bt->parent_dmat) != 0) { - bt_mca_release_resources(dev); - return (ENOMEM); - } - - if (bt_init(dev)) { - bt_mca_release_resources(dev); - return (ENOMEM); - } - - /* DMA tag for our sense buffers */ - if (bus_dma_tag_create( /* parent */ bt->parent_dmat, - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ bt->max_ccbs * - sizeof(struct scsi_sense_data), - /* nsegments */ 1, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &bt->sense_dmat) != 0) { - bt_mca_release_resources(dev); - return (ENOMEM); - } - - bt->init_level++; - - /* Allocation of sense buffers */ - if (bus_dmamem_alloc(bt->sense_dmat, - (void **)&bt->sense_buffers, - BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) { - bt_mca_release_resources(dev); - return (ENOMEM); - } - - bt->init_level++; - - /* And permanently map them */ - bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap, - bt->sense_buffers, - bt->max_ccbs * sizeof(*bt->sense_buffers), - btmapsensebuffers, bt, /*flags*/0); - - bt->init_level++; - - if ((error = bt_attach(dev))) { - bt_mca_release_resources(dev); - return (error); - } - - return (0); -} - -/* - * This code should be shared with the ISA - * stubs as its exactly the same. - */ - -#define BIOS_MAP_SIZE (16 * 1024) - -static int -btvlbouncefilter(void *arg, bus_addr_t addr) -{ - struct bt_softc *bt; - - bt = (struct bt_softc *)arg; - - addr &= BUS_SPACE_MAXADDR_24BIT; - - if (addr == 0 - || (addr >= bt->bios_addr - && addr < (bt->bios_addr + BIOS_MAP_SIZE))) - return (1); - return (0); -} - -static void -btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct bt_softc* bt; - - bt = (struct bt_softc*)arg; - bt->sense_buffers_physbase = segs->ds_addr; -} - -static device_method_t bt_mca_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, bt_mca_probe), - DEVMETHOD(device_attach, bt_mca_attach), - - { 0, 0 } -}; - -static driver_t bt_mca_driver = { - "bt", - bt_mca_methods, - sizeof(struct bt_softc), -}; - -static devclass_t bt_devclass; - -DRIVER_MODULE(bt, mca, bt_mca_driver, bt_devclass, 0, 0); -MODULE_DEPEND(bt, mca, 1, 1, 1); diff --git a/sys/dev/buslogic/btreg.h b/sys/dev/buslogic/btreg.h index a22c5aab6b0b..b7ca500c0f4c 100644 --- a/sys/dev/buslogic/btreg.h +++ b/sys/dev/buslogic/btreg.h @@ -4,7 +4,6 @@ * attach routines can be found in: * sys/dev/buslogic/bt_isa.c BT-54X, BT-445 cards * sys/dev/buslogic/bt_mca.c BT-64X, SDC3211B, SDC3211F - * sys/dev/buslogic/bt_eisa.c BT-74X, BT-75x cards, SDC3222F * sys/dev/buslogic/bt_pci.c BT-946, BT-948, BT-956, BT-958 cards * * Copyright (c) 1998, 1999 Justin T. Gibbs. @@ -238,15 +237,6 @@ typedef struct { sync : 1; } targ_syncinfo_t; -typedef enum { - HAB_ISA = 'A', - HAB_MCA = 'B', - HAB_EISA = 'C', - HAB_NUBUS = 'D', - HAB_VESA = 'E', - HAB_PCI = 'F' -} ha_type_t; - typedef struct { u_int8_t initiate_sync : 1, parity_enable : 1, diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index 9f86e8f2ab36..746ffdc68311 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -168,6 +168,12 @@ static struct bxe_device_type bxe_devs[] = { }, { BRCM_VENDORID, + CHIP_NUM_57840_2_20, + PCI_ANY_ID, PCI_ANY_ID, + "QLogic NetXtreme II BCM57840 2x20GbE" + }, + { + BRCM_VENDORID, CHIP_NUM_57840_MF, PCI_ANY_ID, PCI_ANY_ID, "QLogic NetXtreme II BCM57840 MF 10GbE" diff --git a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c index 9bcc1b0daea4..255f94eda3bd 100644 --- a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c +++ b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c @@ -1461,6 +1461,9 @@ static void process_data(struct iwch_ep *ep) { struct sockaddr_in *local, *remote; +#ifdef KTR + char local_str[INET_ADDRSTRLEN], remote_str[INET_ADDRSTRLEN]; +#endif CTR4(KTR_IW_CXGB, "%s ep %p so %p state %s", __FUNCTION__, ep, ep->com.so, states[ep->com.state]); @@ -1479,8 +1482,8 @@ process_data(struct iwch_ep *ep) in_getsockaddr(ep->com.so, (struct sockaddr **)&local); in_getpeeraddr(ep->com.so, (struct sockaddr **)&remote); CTR3(KTR_IW_CXGB, "%s local %s remote %s", __FUNCTION__, - inet_ntoa(local->sin_addr), - inet_ntoa(remote->sin_addr)); + inet_ntoa_r(local->sin_addr, local_str), + inet_ntoa_r(remote->sin_addr, remote_str)); ep->com.local_addr = *local; ep->com.remote_addr = *remote; free(local, M_SONAME); @@ -1519,6 +1522,9 @@ process_newconn(struct iw_cm_id *parent_cm_id, struct socket *child_so) struct sockaddr_in *local; struct sockaddr_in *remote; struct iwch_ep *parent_ep = parent_cm_id->provider_data; +#ifdef KTR + char buf[INET_ADDRSTRLEN]; +#endif CTR3(KTR_IW_CXGB, "%s parent ep %p so %p", __FUNCTION__, parent_ep, parent_ep->com.so); if (!child_so) { @@ -1539,7 +1545,7 @@ process_newconn(struct iw_cm_id *parent_cm_id, struct socket *child_so) in_getpeeraddr(child_so, (struct sockaddr **)&remote); CTR3(KTR_IW_CXGB, "%s remote addr %s port %d", __FUNCTION__, - inet_ntoa(remote->sin_addr), ntohs(remote->sin_port)); + inet_ntoa_r(remote->sin_addr, buf), ntohs(remote->sin_port)); child_ep->com.tdev = parent_ep->com.tdev; child_ep->com.local_addr.sin_family = parent_ep->com.local_addr.sin_family; child_ep->com.local_addr.sin_port = parent_ep->com.local_addr.sin_port; diff --git a/sys/dev/dpt/dpt.h b/sys/dev/dpt/dpt.h index 6c0e341db475..e337f09a120e 100644 --- a/sys/dev/dpt/dpt.h +++ b/sys/dev/dpt/dpt.h @@ -147,17 +147,13 @@ typedef void *physaddr; #define min(a,b) ((a<b)?(a):(b)) #define MAXISA 4 -#define MAXEISA 16 #define MAXPCI 16 #define MAXIRQ 16 #define MAXTARGET 16 #define IS_ISA 'I' -#define IS_EISA 'E' #define IS_PCI 'P' -#define BROKEN_INQUIRY 1 - #define BUSMASTER 0xff #define PIO 0xfe @@ -198,13 +194,6 @@ typedef void *physaddr; #define PCI_REG_ConfigParam1 0x50 #define PCI_REG_ConfigParam2 0x54 -#define EATA_CMD_PIO_SETUPTEST 0xc6 -#define EATA_CMD_PIO_READ_CONFIG 0xf0 -#define EATA_CMD_PIO_SET_CONFIG 0xf1 -#define EATA_CMD_PIO_SEND_CP 0xf2 -#define EATA_CMD_PIO_RECEIVE_SP 0xf3 -#define EATA_CMD_PIO_TRUNC 0xf4 - #define EATA_CMD_RESET 0xf9 #define EATA_COLD_BOOT 0x06 /* Last resort only! */ @@ -548,12 +537,9 @@ typedef struct driveParam_S driveParam_T; #define SI_NO_SmartROM 0x8000 #define SI_ISA_BUS 0x00 -#define SI_MCA_BUS 0x01 -#define SI_EISA_BUS 0x02 #define SI_PCI_BUS 0x04 #define HBA_BUS_ISA 0x00 -#define HBA_BUS_EISA 0x01 #define HBA_BUS_PCI 0x02 typedef struct dpt_sysinfo { @@ -791,12 +777,9 @@ typedef struct eata_ccb { #define ADF_2001 0x0001 /* PM2001 */ #define ADF_2012A 0x0002 /* PM2012A */ #define ADF_PLUS_ISA 0x0004 /* PM2011,PM2021 */ -#define ADF_PLUS_EISA 0x0008 /* PM2012B,PM2022 */ #define ADF_SC3_ISA 0x0010 /* PM2021 */ -#define ADF_SC3_EISA 0x0020 /* PM2022,PM2122, etc */ #define ADF_SC3_PCI 0x0040 /* SmartCache III PCI */ #define ADF_SC4_ISA 0x0080 /* SmartCache IV ISA */ -#define ADF_SC4_EISA 0x0100 /* SmartCache IV EISA */ #define ADF_SC4_PCI 0x0200 /* SmartCache IV PCI */ #define ADF_ALL_MASTER 0xFFFE /* All bus mastering */ #define ADF_ALL_CACHE 0xFFFC /* All caching */ @@ -1114,8 +1097,7 @@ typedef struct dpt_softc { u_int8_t more_support :1, /* HBA supports MORE flag */ immediate_support :1, /* HBA supports IMMEDIATE */ - broken_INQUIRY :1, /* EISA HBA w/broken INQUIRY */ - spare2 :5; + spare2 :6; u_int8_t resetlevel[MAX_CHANNELS]; u_int32_t last_ccb; /* Last used ccb */ @@ -1201,8 +1183,7 @@ typedef struct dpt_user_softc { u_int8_t primary; u_int8_t more_support :1, immediate_support :1, - broken_INQUIRY :1, - spare2 :5; + spare2 :6; u_int8_t resetlevel[MAX_CHANNELS]; u_int32_t last_ccb; @@ -1277,10 +1258,6 @@ int dpt_init(struct dpt_softc *dpt); int dpt_attach(dpt_softc_t * dpt); void dpt_intr(void *arg); -#ifdef DEV_EISA -dpt_conf_t * dpt_pio_get_conf(u_int32_t); -#endif - #if 0 extern void hex_dump(u_char * data, int length, char *name, int no); diff --git a/sys/dev/dpt/dpt_eisa.c b/sys/dev/dpt/dpt_eisa.c deleted file mode 100644 index 6de34050c059..000000000000 --- a/sys/dev/dpt/dpt_eisa.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * Copyright (c) 1997, 2000 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_eisa.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/eisa/eisaconf.h> - -#include <cam/scsi/scsi_all.h> - -#include <dev/dpt/dpt.h> - -#define DPT_EISA_IOSIZE 0x9 -#define DPT_EISA_SLOT_OFFSET 0x0c00 -#define DPT_EISA_EATA_REG_OFFSET 0x0088 - -#define DPT_EISA_DPT2402 0x12142402 /* DPT PM2012A/9X */ -#define DPT_EISA_DPTA401 0x1214A401 /* DPT PM2012B/9X */ -#define DPT_EISA_DPTA402 0x1214A402 /* DPT PM2012B2/9X */ -#define DPT_EISA_DPTA410 0x1214A410 /* DPT PM2x22A/9X */ -#define DPT_EISA_DPTA411 0x1214A411 /* DPT Spectre */ -#define DPT_EISA_DPTA412 0x1214A412 /* DPT PM2021A/9X */ -#define DPT_EISA_DPTA420 0x1214A420 /* DPT Smart Cache IV (PM2042) */ -#define DPT_EISA_DPTA501 0x1214A501 /* DPT PM2012B1/9X" */ -#define DPT_EISA_DPTA502 0x1214A502 /* DPT PM2012Bx/9X */ -#define DPT_EISA_DPTA701 0x1214A701 /* DPT PM2011B1/9X */ -#define DPT_EISA_DPTBC01 0x1214BC01 /* DPT PM3011/7X ESDI */ -#define DPT_EISA_DPT8200 0x12148200 /* NEC EATA SCSI */ -#define DPT_EISA_DPT2408 0x12142408 /* ATT EATA SCSI */ - -/* Function Prototypes */ - -static const char * dpt_eisa_match (eisa_id_t); -static int dpt_eisa_probe (device_t); -static int dpt_eisa_attach (device_t); - -static int -dpt_eisa_probe (device_t dev) -{ - const char * desc; - u_int32_t io_base; - dpt_conf_t * conf; - - desc = dpt_eisa_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + - DPT_EISA_SLOT_OFFSET + - DPT_EISA_EATA_REG_OFFSET; - - conf = dpt_pio_get_conf(io_base); - if (!conf) { - printf("dpt: dpt_pio_get_conf() failed.\n"); - return (ENXIO); - } - - eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE); - eisa_add_intr(dev, conf->IRQ, - (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE)); - - return 0; -} - -static int -dpt_eisa_attach (device_t dev) -{ - dpt_softc_t * dpt; - int error = 0; - - dpt = device_get_softc(dev); - dpt->dev = dev; - dpt_alloc(dev); - - dpt->io_rid = 0; - dpt->io_type = SYS_RES_IOPORT; - dpt->irq_rid = 0; - - error = dpt_alloc_resources(dev); - if (error) { - goto bad; - } - - /* Allocate a dmatag representing the capabilities of this attachment */ - if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), - /* alignemnt */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &dpt->parent_dmat) != 0) { - error = ENXIO; - goto bad; - } - - if (dpt_init(dpt) != 0) { - error = ENXIO; - goto bad; - } - - /* Register with the XPT */ - dpt_attach(dpt); - - if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | - INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { - device_printf(dev, "Unable to register interrupt handler\n"); - error = ENXIO; - goto bad; - } - - return (error); - - bad: - dpt_release_resources(dev); - - dpt_free(dpt); - - return (error); -} - -static const char * -dpt_eisa_match(type) - eisa_id_t type; -{ - switch (type) { - case DPT_EISA_DPT2402: - case DPT_EISA_DPTA401: - case DPT_EISA_DPTA402: - case DPT_EISA_DPTA410: - case DPT_EISA_DPTA411: - case DPT_EISA_DPTA412: - case DPT_EISA_DPTA420: - case DPT_EISA_DPTA501: - case DPT_EISA_DPTA502: - case DPT_EISA_DPTA701: - case DPT_EISA_DPTBC01: - case DPT_EISA_DPT8200: - case DPT_EISA_DPT2408: - return ("DPT SCSI Host Bus Adapter"); - break; - default: - break; - } - - return (NULL); -} - -static device_method_t dpt_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, dpt_eisa_probe), - DEVMETHOD(device_attach, dpt_eisa_attach), - DEVMETHOD(device_detach, dpt_detach), - - { 0, 0 } -}; - -static driver_t dpt_eisa_driver = { - "dpt", - dpt_eisa_methods, - sizeof(dpt_softc_t), -}; - -DRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0); -MODULE_DEPEND(dpt, eisa, 1, 1, 1); -MODULE_DEPEND(dpt, cam, 1, 1, 1); diff --git a/sys/dev/dpt/dpt_scsi.c b/sys/dev/dpt/dpt_scsi.c index f960dc9ccaf3..541b58665cf2 100644 --- a/sys/dev/dpt/dpt_scsi.c +++ b/sys/dev/dpt/dpt_scsi.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); #define _DPT_C_ #include "opt_dpt.h" -#include "opt_eisa.h" #include <sys/param.h> #include <sys/systm.h> @@ -79,7 +78,7 @@ __FBSDID("$FreeBSD$"); #include <dev/dpt/dpt.h> -/* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */ +/* dpt_isa.c, and dpt_pci.c need this in a central place */ devclass_t dpt_devclass; #define microtime_now dpt_time_now() @@ -107,9 +106,6 @@ devclass_t dpt_devclass; /* ================= Private Inline Function declarations ===================*/ static __inline int dpt_just_reset(dpt_softc_t * dpt); static __inline int dpt_raid_busy(dpt_softc_t * dpt); -#ifdef DEV_EISA -static __inline int dpt_pio_wait (u_int32_t, u_int, u_int, u_int); -#endif static __inline int dpt_wait(dpt_softc_t *dpt, u_int bits, u_int state); static __inline struct dpt_ccb* dptgetccb(struct dpt_softc *dpt); @@ -185,24 +181,6 @@ dpt_raid_busy(dpt_softc_t * dpt) return (0); } -#ifdef DEV_EISA -static __inline int -dpt_pio_wait (u_int32_t base, u_int reg, u_int bits, u_int state) -{ - int i; - u_int c; - - for (i = 0; i < 20000; i++) { /* wait 20ms for not busy */ - c = inb(base + reg) & bits; - if (!(c == state)) - return (0); - else - DELAY(50); - } - return (-1); -} -#endif - static __inline int dpt_wait(dpt_softc_t *dpt, u_int bits, u_int state) { @@ -392,96 +370,6 @@ dptallocccbs(dpt_softc_t *dpt) return (i); } -#ifdef DEV_EISA -dpt_conf_t * -dpt_pio_get_conf (u_int32_t base) -{ - static dpt_conf_t * conf; - u_int16_t * p; - int i; - - /* - * Allocate a dpt_conf_t - */ - if (!conf) { - conf = (dpt_conf_t *)malloc(sizeof(dpt_conf_t), - M_DEVBUF, M_NOWAIT | M_ZERO); - } - - /* - * If we didn't get one then we probably won't ever get one. - */ - if (!conf) { - printf("dpt: unable to allocate dpt_conf_t\n"); - return (NULL); - } - - /* - * Reset the controller. - */ - outb((base + HA_WCOMMAND), EATA_CMD_RESET); - - /* - * Wait for the controller to become ready. - * For some reason there can be -no- delays after calling reset - * before we wait on ready status. - */ - if (dpt_pio_wait(base, HA_RSTATUS, HA_SBUSY, 0)) { - printf("dpt: timeout waiting for controller to become ready\n"); - return (NULL); - } - - if (dpt_pio_wait(base, HA_RAUXSTAT, HA_ABUSY, 0)) { - printf("dpt: timetout waiting for adapter ready.\n"); - return (NULL); - } - - /* - * Send the PIO_READ_CONFIG command. - */ - outb((base + HA_WCOMMAND), EATA_CMD_PIO_READ_CONFIG); - - /* - * Read the data into the struct. - */ - p = (u_int16_t *)conf; - for (i = 0; i < (sizeof(dpt_conf_t) / 2); i++) { - - if (dpt_pio_wait(base, HA_RSTATUS, HA_SDRQ, 0)) { - if (bootverbose) - printf("dpt: timeout in data read.\n"); - return (NULL); - } - - (*p) = inw(base + HA_RDATA); - p++; - } - - if (inb(base + HA_RSTATUS) & HA_SERROR) { - if (bootverbose) - printf("dpt: error reading configuration data.\n"); - return (NULL); - } - -#define BE_EATA_SIGNATURE 0x45415441 -#define LE_EATA_SIGNATURE 0x41544145 - - /* - * Test to see if we have a valid card. - */ - if ((conf->signature == BE_EATA_SIGNATURE) || - (conf->signature == LE_EATA_SIGNATURE)) { - - while (inb(base + HA_RSTATUS) & HA_SDRQ) { - inw(base + HA_RDATA); - } - - return (conf); - } - return (NULL); -} -#endif - /* * Read a configuration page into the supplied dpt_cont_t buffer. */ @@ -1352,8 +1240,6 @@ dpt_init(struct dpt_softc *dpt) else dpt->immediate_support = 0; - dpt->broken_INQUIRY = FALSE; - dpt->cplen = ntohl(conf.cplen); dpt->cppadlen = ntohs(conf.cppadlen); dpt->max_dccbs = ntohs(conf.queuesiz); diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 2da26faa3ccc..818e2e411cf3 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1625,6 +1625,11 @@ em_if_timer(if_ctx_t ctx, uint16_t qid) int i; int trigger = 0; + if (qid != 0) { + /* XXX all this stuff is per-adapter */ + return; + } + em_if_update_admin_status(ctx); em_update_stats_counters(adapter); diff --git a/sys/dev/eisa/eisa_if.m b/sys/dev/eisa/eisa_if.m deleted file mode 100644 index 72c8184cdce5..000000000000 --- a/sys/dev/eisa/eisa_if.m +++ /dev/null @@ -1,65 +0,0 @@ -#- -# Copyright (c) 2004 M. Warner Losh -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -#include <sys/bus.h> -#include <sys/types.h> - -INTERFACE eisa; - -# -# Add interrupt information for an EISA device. irq is the irq number -# and trigger is either EISA_TRIGGER_EDGE or EISA_TRIGGER_LEVEL -# -METHOD int add_intr { - device_t dev; - device_t child; - int irq; - int trigger; -}; - -# -# Adds an I/O space to the reservation lis -# -METHOD int add_iospace { - device_t dev; - device_t child; - u_long iobase; - u_long iosize; - int flags; -}; - -# -# Adds a memory range to the reservation lis -# -METHOD int add_mspace { - device_t dev; - device_t child; - u_long mbase; - u_long msize; - int flags; -}; diff --git a/sys/dev/eisa/eisaconf.c b/sys/dev/eisa/eisaconf.c deleted file mode 100644 index 28a9bc622de9..000000000000 --- a/sys/dev/eisa/eisaconf.c +++ /dev/null @@ -1,582 +0,0 @@ -/*- - * EISA bus probe and attach routines - * - * Copyright (c) 1995, 1996 Justin T. Gibbs. - * 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 immediately at the beginning of the file, without modification, - * 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. The name of the author may not 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_eisa.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/limits.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/eisa/eisaconf.h> - -typedef struct resvaddr { - u_long addr; /* start address */ - u_long size; /* size of reserved area */ - int flags; - struct resource *res; /* resource manager handle */ - LIST_ENTRY(resvaddr) links; /* List links */ -} resvaddr_t; - -LIST_HEAD(resvlist, resvaddr); - -struct irq_node { - int irq_no; - int irq_trigger; - void *idesc; - TAILQ_ENTRY(irq_node) links; -}; - -TAILQ_HEAD(irqlist, irq_node); - -struct eisa_ioconf { - int slot; - struct resvlist ioaddrs; /* list of reserved I/O ranges */ - struct resvlist maddrs; /* list of reserved memory ranges */ - struct irqlist irqs; /* list of reserved irqs */ -}; - -/* To be replaced by the "super device" generic device structure... */ -struct eisa_device { - eisa_id_t id; - struct eisa_ioconf ioconf; -}; - - -#define MAX_COL 79 -#ifndef EISA_SLOTS -#define EISA_SLOTS 10 /* PCI clashes with higher ones.. fix later */ -#endif -int num_eisa_slots = EISA_SLOTS; -TUNABLE_INT("hw.eisa_slots", &num_eisa_slots); - -static devclass_t eisa_devclass; - -static int eisa_probe_slot(int slot, eisa_id_t *eisa_id); -static struct irq_node *eisa_find_irq(struct eisa_device *e_dev, int rid); -static struct resvaddr *eisa_find_maddr(struct eisa_device *e_dev, int rid); -static struct resvaddr *eisa_find_ioaddr(struct eisa_device *e_dev, int rid); - -static int -mainboard_probe(device_t dev) -{ - char *idstring; - eisa_id_t id = eisa_get_id(dev); - - if (eisa_get_slot(dev) != 0) - return (ENXIO); - - idstring = (char *)malloc(8 + sizeof(" (System Board)") + 1, - M_DEVBUF, M_NOWAIT); - if (idstring == NULL) - panic("Eisa probe unable to malloc"); - sprintf(idstring, "%c%c%c%03x%01x (System Board)", - EISA_MFCTR_CHAR0(id), EISA_MFCTR_CHAR1(id), EISA_MFCTR_CHAR2(id), - EISA_PRODUCT_ID(id), EISA_REVISION_ID(id)); - device_set_desc(dev, idstring); - - return (0); -} - -static int -mainboard_attach(device_t dev) -{ - return (0); -} - -static device_method_t mainboard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, mainboard_probe), - DEVMETHOD(device_attach, mainboard_attach), - - { 0, 0 } -}; - -static driver_t mainboard_driver = { - "mainboard", - mainboard_methods, - 1, -}; - -static devclass_t mainboard_devclass; - -DRIVER_MODULE(mainboard, eisa, mainboard_driver, mainboard_devclass, 0, 0); - -/* -** probe for EISA devices -*/ -static int -eisa_probe(device_t dev) -{ - int devices_found, slot; - struct eisa_device *e_dev; - device_t child; - eisa_id_t eisa_id; - - device_set_desc(dev, "EISA bus"); - - devices_found = 0; - for (slot = 0; slot < num_eisa_slots; slot++) { - eisa_id = 0; - if (eisa_probe_slot(slot, &eisa_id)) { - /* - * If there's no card in the first slot (the - * mainboard), then the system doesn't have EISA. - * We abort the probe early in this case since - * continuing on causes a hang on some systems. - * Interestingly enough, the inb has been seen to - * cause the hang. - */ - if (slot == 0) - break; - continue; - } - - devices_found++; - - /* Prepare an eisa_device_node for this slot */ - e_dev = (struct eisa_device *)malloc(sizeof(*e_dev), - M_DEVBUF, M_NOWAIT|M_ZERO); - if (!e_dev) { - device_printf(dev, "cannot malloc eisa_device"); - break; /* Try to attach what we have already */ - } - - e_dev->id = eisa_id; - e_dev->ioconf.slot = slot; - - /* Initialize our lists of reserved addresses */ - LIST_INIT(&(e_dev->ioconf.ioaddrs)); - LIST_INIT(&(e_dev->ioconf.maddrs)); - TAILQ_INIT(&(e_dev->ioconf.irqs)); - - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, e_dev); - } - - /* - * EISA busses themselves are not easily detectable, the easiest way - * to tell if there is an eisa bus is if we found something - there - * should be a motherboard "card" there somewhere. - */ - return (devices_found ? 0 : ENXIO); -} - -static int -eisa_probe_slot(int slot, eisa_id_t *eisa_id) -{ - eisa_id_t probe_id; - int base, i, id_size; - - probe_id = 0; - id_size = sizeof(probe_id); - base = 0x0c80 + (slot * 0x1000); - - for (i = 0; i < id_size; i++) - probe_id |= inb(base + i) << ((id_size - i - 1) * CHAR_BIT); - - /* If we found a card, return its EISA id. */ - if ((probe_id & 0x80000000) == 0) { - *eisa_id = probe_id; - return (0); - } - - return (ENXIO); -} - -static void -eisa_probe_nomatch(device_t dev, device_t child) -{ - u_int32_t eisa_id = eisa_get_id(child); - u_int8_t slot = eisa_get_slot(child); - - device_printf(dev, "%c%c%c%03x%01x (0x%08x) at slot %d (no driver attached)\n", - EISA_MFCTR_CHAR0(eisa_id), EISA_MFCTR_CHAR1(eisa_id), - EISA_MFCTR_CHAR2(eisa_id), EISA_PRODUCT_ID(eisa_id), - EISA_REVISION_ID(eisa_id), eisa_id, slot); - return; -} - -static int -eisa_print_child(device_t dev, device_t child) -{ - struct eisa_device * e_dev = device_get_ivars(child); - int rid; - struct irq_node * irq; - struct resvaddr * resv; - int retval = 0; - - retval += bus_print_child_header(dev, child); - rid = 0; - while ((resv = eisa_find_ioaddr(e_dev, rid++))) { - if (resv->size == 1 || (resv->flags & RESVADDR_BITMASK)) - retval += printf("%s%lx", rid == 1 ? " port 0x" : ",0x", - resv->addr); - else - retval += printf("%s%lx-0x%lx", rid == 1 ? " port 0x" : - ",0x", resv->addr, resv->addr + resv->size - 1); - } - rid = 0; - while ((resv = eisa_find_maddr(e_dev, rid++))) { - if (resv->size == 1 || (resv->flags & RESVADDR_BITMASK)) - retval += printf("%s%lx", rid == 1 ? " mem 0x" : ",0x", - resv->addr); - else - retval += printf("%s%lx-0x%lx", rid == 1 ? " mem 0x" : - ",0x", resv->addr, resv->addr + resv->size - 1); - } - rid = 0; - while ((irq = eisa_find_irq(e_dev, rid++)) != NULL) - retval += printf(" irq %d (%s)", irq->irq_no, - irq->irq_trigger ? "level" : "edge"); - retval += printf(" at slot %d on %s\n", eisa_get_slot(child), - device_get_nameunit(dev)); - - return (retval); -} - -static struct irq_node * -eisa_find_irq(struct eisa_device *e_dev, int rid) -{ - int i; - struct irq_node *irq; - - for (i = 0, irq = TAILQ_FIRST(&e_dev->ioconf.irqs); - i < rid && irq != NULL; i++, irq = TAILQ_NEXT(irq, links)) - continue; - - return (irq); -} - -static struct resvaddr * -eisa_find_maddr(struct eisa_device *e_dev, int rid) -{ - int i; - struct resvaddr *resv; - - for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.maddrs); - i < rid && resv != NULL; i++, resv = LIST_NEXT(resv, links)) - continue; - - return (resv); -} - -static struct resvaddr * -eisa_find_ioaddr(struct eisa_device *e_dev, int rid) -{ - int i; - struct resvaddr *resv; - - for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.ioaddrs); - i < rid && resv != NULL; i++, resv = LIST_NEXT(resv, links)) - continue; - - return (resv); -} - -static int -eisa_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) -{ - struct eisa_device *e_dev = device_get_ivars(child); - struct irq_node *irq; - - switch (which) { - case EISA_IVAR_SLOT: - *result = e_dev->ioconf.slot; - break; - - case EISA_IVAR_ID: - *result = e_dev->id; - break; - - case EISA_IVAR_IRQ: - /* XXX only first irq */ - if ((irq = eisa_find_irq(e_dev, 0)) != NULL) - *result = irq->irq_no; - else - *result = -1; - break; - - default: - return (ENOENT); - } - - return (0); -} - -static int -eisa_write_ivar(device_t dev, device_t child, int which, uintptr_t value) -{ - return (EINVAL); -} - -static struct resource * -eisa_alloc_resource(device_t dev, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - int isdefault; - struct eisa_device *e_dev = device_get_ivars(child); - struct resource *rv, **rvp = 0; - - isdefault = (device_get_parent(child) == dev && - RMAN_IS_DEFAULT_RANGE(start, end) && count == 1); - - switch (type) { - case SYS_RES_IRQ: - if (isdefault) { - struct irq_node * irq = eisa_find_irq(e_dev, *rid); - if (irq == NULL) - return (NULL); - start = end = irq->irq_no; - count = 1; - if (irq->irq_trigger == EISA_TRIGGER_LEVEL) - flags |= RF_SHAREABLE; - else - flags &= ~RF_SHAREABLE; - } - break; - - case SYS_RES_MEMORY: - if (isdefault) { - struct resvaddr *resv; - - resv = eisa_find_maddr(e_dev, *rid); - if (resv == NULL) - return (NULL); - - start = resv->addr; - end = resv->addr + (resv->size - 1); - count = resv->size; - rvp = &resv->res; - } - break; - - case SYS_RES_IOPORT: - if (isdefault) { - struct resvaddr *resv; - - resv = eisa_find_ioaddr(e_dev, *rid); - if (resv == NULL) - return (NULL); - - start = resv->addr; - end = resv->addr + (resv->size - 1); - count = resv->size; - rvp = &resv->res; - } - break; - - default: - return 0; - } - - rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - type, rid, start, end, count, flags); - if (rvp) - *rvp = rv; - - return (rv); -} - -static int -eisa_release_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - int rv; - struct eisa_device *e_dev = device_get_ivars(child); - struct resvaddr *resv = 0; - - switch (type) { - case SYS_RES_IRQ: - if (eisa_find_irq(e_dev, rid) == NULL) - return (EINVAL); - break; - - case SYS_RES_MEMORY: - if (device_get_parent(child) == dev) - resv = eisa_find_maddr(e_dev, rid); - break; - - - case SYS_RES_IOPORT: - if (device_get_parent(child) == dev) - resv = eisa_find_ioaddr(e_dev, rid); - break; - - default: - return (ENOENT); - } - - rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r); - - if (rv == 0) { - if (resv != NULL) - resv->res = 0; - } - - return (rv); -} - -static int -eisa_add_intr_m(device_t eisa, device_t dev, int irq, int trigger) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - struct irq_node *irq_info; - - irq_info = (struct irq_node *)malloc(sizeof(*irq_info), M_DEVBUF, - M_NOWAIT); - if (irq_info == NULL) - return (1); - - irq_info->irq_no = irq; - irq_info->irq_trigger = trigger; - irq_info->idesc = NULL; - TAILQ_INSERT_TAIL(&e_dev->ioconf.irqs, irq_info, links); - return (0); -} - -static int -eisa_add_resvaddr(struct eisa_device *e_dev, struct resvlist *head, u_long base, - u_long size, int flags) -{ - resvaddr_t *reservation; - - reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t), - M_DEVBUF, M_NOWAIT); - if(!reservation) - return (ENOMEM); - - reservation->addr = base; - reservation->size = size; - reservation->flags = flags; - - if (!LIST_FIRST(head)) { - LIST_INSERT_HEAD(head, reservation, links); - } - else { - resvaddr_t *node; - LIST_FOREACH(node, head, links) { - if (node->addr > reservation->addr) { - /* - * List is sorted in increasing - * address order. - */ - LIST_INSERT_BEFORE(node, reservation, links); - break; - } - - if (node->addr == reservation->addr) { - /* - * If the entry we want to add - * matches any already in here, - * fail. - */ - free(reservation, M_DEVBUF); - return (EEXIST); - } - - if (!LIST_NEXT(node, links)) { - LIST_INSERT_AFTER(node, reservation, links); - break; - } - } - } - return (0); -} - -static int -eisa_add_mspace_m(device_t eisa, device_t dev, u_long mbase, u_long msize, - int flags) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - - return (eisa_add_resvaddr(e_dev, &(e_dev->ioconf.maddrs), mbase, msize, - flags)); -} - -static int -eisa_add_iospace_m(device_t eisa, device_t dev, u_long iobase, u_long iosize, - int flags) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - - return (eisa_add_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), iobase, - iosize, flags)); -} - -static device_method_t eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, eisa_probe), - DEVMETHOD(device_attach, bus_generic_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, eisa_print_child), - DEVMETHOD(bus_probe_nomatch, eisa_probe_nomatch), - DEVMETHOD(bus_read_ivar, eisa_read_ivar), - DEVMETHOD(bus_write_ivar, eisa_write_ivar), - DEVMETHOD(bus_alloc_resource, eisa_alloc_resource), - DEVMETHOD(bus_release_resource, eisa_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - /* EISA interface */ - DEVMETHOD(eisa_add_intr, eisa_add_intr_m), - DEVMETHOD(eisa_add_iospace, eisa_add_iospace_m), - DEVMETHOD(eisa_add_mspace, eisa_add_mspace_m), - - DEVMETHOD_END -}; - -static driver_t eisa_driver = { - "eisa", - eisa_methods, - 1, /* no softc */ -}; - -DRIVER_MODULE(eisa, eisab, eisa_driver, eisa_devclass, 0, 0); -DRIVER_MODULE(eisa, legacy, eisa_driver, eisa_devclass, 0, 0); diff --git a/sys/dev/eisa/eisaconf.h b/sys/dev/eisa/eisaconf.h deleted file mode 100644 index 522cd5db59e1..000000000000 --- a/sys/dev/eisa/eisaconf.h +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * EISA bus device definitions - * - * Copyright (c) 1995, 1996 Justin T. Gibbs. - * 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 immediately at the beginning of the file, without modification, - * 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. The name of the author may not 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. - * - * $FreeBSD$ - */ - -#ifndef _DEV_EISA_EISACONF_H_ -#define _DEV_EISA_EISACONF_H_ 1 - -#include "eisa_if.h" -#define EISA_SLOT_SIZE 0x1000 - -#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */ -#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */ -#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */ -#define EISA_MFCTR_ID(ID) (short)((ID>>16) & 0xFF) /* Bits 16-31 */ -#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */ -#define EISA_REVISION_ID(ID) (u_char)(ID & 0x0F) /* Bits 0-3 */ - -extern int num_eisa_slots; - -typedef u_int32_t eisa_id_t; - -enum eisa_device_ivars { - EISA_IVAR_SLOT, - EISA_IVAR_ID, - EISA_IVAR_IRQ -}; - -#define EISA_TRIGGER_EDGE 0x0 -#define EISA_TRIGGER_LEVEL 0x1 - -/* - * Simplified accessors for isa devices - */ -#define EISA_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(eisa, var, EISA, ivar, type) - -EISA_ACCESSOR(slot, SLOT, int) -EISA_ACCESSOR(id, ID, eisa_id_t) -EISA_ACCESSOR(irq, IRQ, eisa_id_t) - -#undef EISA_ACCESSOR - -#define RESVADDR_NONE 0x00 -#define RESVADDR_BITMASK 0x01 /* size is a mask of reserved - * bits at addr - */ -#define RESVADDR_RELOCATABLE 0x02 - -static __inline int -eisa_add_intr(device_t dev, int irq, int trigger) -{ - return (EISA_ADD_INTR(device_get_parent(dev), dev, irq, trigger)); -} - -static __inline int -eisa_add_iospace(device_t dev, u_long iobase, u_long iosize, int flags) -{ - return (EISA_ADD_IOSPACE(device_get_parent(dev), dev, iobase, iosize, - flags)); -} - -static __inline int -eisa_add_mspace(device_t dev, u_long mbase, u_long msize, int flags) -{ - return (EISA_ADD_MSPACE(device_get_parent(dev), dev, mbase, msize, - flags)); -} - -#endif /* _DEV_EISA_EISACONF_H_ */ diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c index 9f6848a1de58..fcd8796f6d09 100644 --- a/sys/dev/ep/if_ep.c +++ b/sys/dev/ep/if_ep.c @@ -530,31 +530,17 @@ startagain: CSR_WRITE_2(sc, EP_COMMAND, SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE); - /* XXX 4.x and earlier would splhigh here */ - CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, len); /* Second dword meaningless */ CSR_WRITE_2(sc, EP_W1_TX_PIO_WR_1, 0x0); - if (EP_FTST(sc, F_ACCESS_32_BITS)) { - for (m = m0; m != NULL; m = m->m_next) { - if (m->m_len > 3) - CSR_WRITE_MULTI_4(sc, EP_W1_TX_PIO_WR_1, - mtod(m, uint32_t *), m->m_len / 4); - if (m->m_len & 3) - CSR_WRITE_MULTI_1(sc, EP_W1_TX_PIO_WR_1, - mtod(m, uint8_t *)+(m->m_len & (~3)), - m->m_len & 3); - } - } else { - for (m = m0; m != NULL; m = m->m_next) { - if (m->m_len > 1) - CSR_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1, - mtod(m, uint16_t *), m->m_len / 2); - if (m->m_len & 1) - CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1, - *(mtod(m, uint8_t *)+m->m_len - 1)); - } + for (m = m0; m != NULL; m = m->m_next) { + if (m->m_len > 1) + CSR_WRITE_MULTI_2(sc, EP_W1_TX_PIO_WR_1, + mtod(m, uint16_t *), m->m_len / 2); + if (m->m_len & 1) + CSR_WRITE_1(sc, EP_W1_TX_PIO_WR_1, + *(mtod(m, uint8_t *)+m->m_len - 1)); } while (pad--) @@ -788,25 +774,13 @@ read_again: mcur->m_next = m; lenthisone = min(rx_fifo, M_TRAILINGSPACE(m)); } - if (EP_FTST(sc, F_ACCESS_32_BITS)) { - /* default for EISA configured cards */ - CSR_READ_MULTI_4(sc, EP_W1_RX_PIO_RD_1, - (uint32_t *)(mtod(m, caddr_t)+m->m_len), - lenthisone / 4); - m->m_len += (lenthisone & ~3); - if (lenthisone & 3) - CSR_READ_MULTI_1(sc, EP_W1_RX_PIO_RD_1, - mtod(m, caddr_t)+m->m_len, lenthisone & 3); - m->m_len += (lenthisone & 3); - } else { - CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1, - (uint16_t *)(mtod(m, caddr_t)+m->m_len), - lenthisone / 2); - m->m_len += lenthisone; - if (lenthisone & 1) - *(mtod(m, caddr_t)+m->m_len - 1) = - CSR_READ_1(sc, EP_W1_RX_PIO_RD_1); - } + CSR_READ_MULTI_2(sc, EP_W1_RX_PIO_RD_1, + (uint16_t *)(mtod(m, caddr_t)+m->m_len), + lenthisone / 2); + m->m_len += lenthisone; + if (lenthisone & 1) + *(mtod(m, caddr_t)+m->m_len - 1) = + CSR_READ_1(sc, EP_W1_RX_PIO_RD_1); rx_fifo -= lenthisone; } diff --git a/sys/dev/ep/if_ep_eisa.c b/sys/dev/ep/if_ep_eisa.c deleted file mode 100644 index bc77ec8870f5..000000000000 --- a/sys/dev/ep/if_ep_eisa.c +++ /dev/null @@ -1,252 +0,0 @@ -/*- - * Product specific probe and attach routines for: - * 3COM 3C579 and 3C509(in eisa config mode) ethernet controllers - * - * Copyright (c) 1996 Justin T. Gibbs - * 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 immediately at the beginning of the file, without modification, - * 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. Absolutely no warranty of function or purpose is made by the author - * Justin T. Gibbs. - * 4. Modifications may be freely made to this file if the above conditions - * are met. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/if.h> -#include <net/if_arp.h> -#include <net/if_media.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/ep/if_epreg.h> -#include <dev/ep/if_epvar.h> - -#define EISA_DEVICE_ID_3COM_3C509_TP 0x506d5090 -#define EISA_DEVICE_ID_3COM_3C509_BNC 0x506d5091 -#define EISA_DEVICE_ID_3COM_3C579_TP 0x506d5092 -#define EISA_DEVICE_ID_3COM_3C579_BNC 0x506d5093 -#define EISA_DEVICE_ID_3COM_3C509_COMBO 0x506d5094 -#define EISA_DEVICE_ID_3COM_3C509_TPO 0x506d5095 - -#define EP_EISA_SLOT_OFFSET 0x0c80 -#define EP_EISA_IOSIZE 0x000a - -#define EISA_IOCONF 0x0008 -#define IRQ_CHANNEL 0xf000 -#define INT_3 0x3000 -#define INT_5 0x5000 -#define INT_7 0x7000 -#define INT_9 0x9000 -#define INT_10 0xa000 -#define INT_11 0xb000 -#define INT_12 0xc000 -#define INT_15 0xf000 -#define EISA_BPROM_MEDIA_CONF 0x0006 -#define TRANS_TYPE 0xc000 -#define TRANS_TP 0x0000 -#define TRANS_AUI 0x4000 -#define TRANS_BNC 0xc000 - -static const char *ep_match(eisa_id_t type); - -static const char * -ep_match(eisa_id_t type) -{ - switch (type) { - case EISA_DEVICE_ID_3COM_3C509_TP: - return ("3Com 3C509-TP"); - case EISA_DEVICE_ID_3COM_3C509_BNC: - return ("3Com 3C509-BNC"); - case EISA_DEVICE_ID_3COM_3C579_TP: - return ("3Com 3C579-TP"); - case EISA_DEVICE_ID_3COM_3C579_BNC: - return ("3Com 3C579-BNC"); - case EISA_DEVICE_ID_3COM_3C509_COMBO: - return ("3Com 3C509-Combo"); - case EISA_DEVICE_ID_3COM_3C509_TPO: - return ("3Com 3C509-TPO"); - default: - return (NULL); - } -} - -static int -ep_eisa_probe(device_t dev) -{ - const char *desc; - u_long iobase; - u_short conf; - u_long port; - int irq; - int int_trig; - - desc = ep_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - port = (eisa_get_slot(dev) * EISA_SLOT_SIZE); - iobase = port + EP_EISA_SLOT_OFFSET; - - /* We must be in EISA configuration mode */ - if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f) - return (ENXIO); - - eisa_add_iospace(dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE); - eisa_add_iospace(dev, port, EP_IOSIZE, RESVADDR_NONE); - - conf = inw(iobase + EISA_IOCONF); - /* Determine our IRQ */ - switch (conf & IRQ_CHANNEL) { - case INT_3: - irq = 3; - break; - case INT_5: - irq = 5; - break; - case INT_7: - irq = 7; - break; - case INT_9: - irq = 9; - break; - case INT_10: - irq = 10; - break; - case INT_11: - irq = 11; - break; - case INT_12: - irq = 12; - break; - case INT_15: - irq = 15; - break; - default: - /* Disabled */ - printf("ep: 3COM Network Adapter at " - "slot %d has its IRQ disabled. " - "Probe failed.\n", - eisa_get_slot(dev)); - return (ENXIO); - } - - switch (eisa_get_id(dev)) { - case EISA_DEVICE_ID_3COM_3C579_BNC: - case EISA_DEVICE_ID_3COM_3C579_TP: - int_trig = EISA_TRIGGER_LEVEL; - break; - default: - int_trig = EISA_TRIGGER_EDGE; - break; - } - - eisa_add_intr(dev, irq, int_trig); - - return (0); -} - -static int -ep_eisa_attach(device_t dev) -{ - struct ep_softc *sc = device_get_softc(dev); - struct resource *eisa_io = NULL; - uint32_t eisa_iobase; - int irq; - int error = 0; - int rid; - - rid = 1; - eisa_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (!eisa_io) { - device_printf(dev, "No I/O space?!\n"); - error = ENXIO; - goto bad; - } - eisa_iobase = rman_get_start(eisa_io); - - /* Reset and Enable the card */ - outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER); - DELAY(1000); /* we must wait at least 1 ms */ - outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER); - /* Now the registers are availible through the lower ioport */ - - if ((error = ep_alloc(dev))) { - device_printf(dev, "ep_alloc() failed! (%d)\n", error); - goto bad; - } - switch (eisa_get_id(dev)) { - case EISA_DEVICE_ID_3COM_3C579_BNC: - case EISA_DEVICE_ID_3COM_3C579_TP: - sc->stat = F_ACCESS_32_BITS; - break; - } - - ep_get_media(sc); - - irq = rman_get_start(sc->irq); - if (irq == 9) - irq = 2; - - GO_WINDOW(sc, 0); - SET_IRQ(sc, irq); - - if ((error = ep_attach(sc))) { - device_printf(dev, "ep_attach() failed! (%d)\n", error); - goto bad; - } - if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, ep_intr, sc, &sc->ep_intrhand))) { - device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); - goto bad; - } - return (0); - -bad: - if (eisa_io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io); - - ep_free(dev); - return (error); -} - -static device_method_t ep_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ep_eisa_probe), - DEVMETHOD(device_attach, ep_eisa_attach), - DEVMETHOD(device_detach, ep_detach), - - DEVMETHOD_END -}; - -static driver_t ep_eisa_driver = { - "ep", - ep_eisa_methods, - sizeof(struct ep_softc), -}; - -extern devclass_t ep_devclass; - -DRIVER_MODULE(ep, eisa, ep_eisa_driver, ep_devclass, 0, 0); diff --git a/sys/dev/ep/if_ep_isa.c b/sys/dev/ep/if_ep_isa.c index 7bcb3d410057..11523f184029 100644 --- a/sys/dev/ep/if_ep_isa.c +++ b/sys/dev/ep/if_ep_isa.c @@ -194,8 +194,7 @@ ep_isa_identify(driver_t * driver, device_t parent) (void)get_eeprom_data(ELINK_ID_PORT, j); /* - * Construct an 'isa_id' in 'EISA' - * format. + * Construct an 'isa_id' in 'EISA' format. */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_MFG_ID); isa_id = (htons(data) << 16); @@ -220,7 +219,7 @@ ep_isa_identify(driver_t * driver, device_t parent) if ((data & ADDR_CFG_MASK) == ADDR_CFG_EISA) { device_printf(parent, - "<%s> at port 0x%03x in EISA mode!\n", + "<%s> at port 0x%03x in EISA mode, ignoring!\n", desc, ioport); /* * Set the adaptor tag so that the next card can be diff --git a/sys/dev/ep/if_ep_mca.c b/sys/dev/ep/if_ep_mca.c deleted file mode 100644 index 3a044bfca3c1..000000000000 --- a/sys/dev/ep/if_ep_mca.c +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/lock.h> -#include <sys/module.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/if.h> -#include <net/if_media.h> - -#include <dev/mca/mca_busreg.h> -#include <dev/mca/mca_busvar.h> - -#include <dev/ep/if_epreg.h> -#include <dev/ep/if_epvar.h> - -#define EP_MCA_627C 0x627C -#define EP_MCA_627D 0x627D -#define EP_MCA_62DB 0x62db -#define EP_MCA_62F6 0x62f6 -#define EP_MCA_62F7 0x62f7 - -static struct mca_ident ep_mca_devs[] = { - {EP_MCA_627C, "3Com 3C529 Network Adapter"}, - {EP_MCA_627D, "3Com 3C529-TP Network Adapter"}, - - /* - * These are from the linux 3c509 driver. - * I have not seen the ADFs for them and have - * not tested or even seen the hardware. - * Someone with the ADFs should replace the names with - * whatever is in the AdapterName field of the ADF. - * (and fix the media setup for the cards as well.) - */ - {EP_MCA_62DB, "3Com 3c529 EtherLink III (test mode)"}, - {EP_MCA_62F6, "3Com 3c529 EtherLink III (TP or coax)"}, - {EP_MCA_62F7, "3Com 3c529 EtherLink III (TP)"}, - - {0, NULL}, -}; - -#define EP_MCA_IOPORT_POS MCA_ADP_POS(MCA_POS2) -#define EP_MCA_IOPORT_MASK 0xfc -#define EP_MCA_IOPORT_SIZE EP_IOSIZE -#define EP_MCA_IOPORT(pos) ((((uint32_t)pos & EP_MCA_IOPORT_MASK) \ - | 0x02) << 8) - -#define EP_MCA_IRQ_POS MCA_ADP_POS(MCA_POS3) -#define EP_MCA_IRQ_MASK 0x0f -#define EP_MCA_IRQ(pos) (pos & EP_MCA_IRQ_MASK) - -#define EP_MCA_MEDIA_POS MCA_ADP_POS(MCA_POS2) -#define EP_MCA_MEDIA_MASK 0x03 -#define EP_MCA_MEDIA(pos) (pos & EP_MCA_MEDIA_MASK) - -static int -ep_mca_probe(device_t dev) -{ - const char *desc; - uint32_t iobase = 0; - uint8_t irq = 0; - uint8_t pos; - - desc = mca_match_id(mca_get_id(dev), ep_mca_devs); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - pos = mca_pos_read(dev, EP_MCA_IOPORT_POS); - iobase = EP_MCA_IOPORT(pos); - - pos = mca_pos_read(dev, EP_MCA_IRQ_POS); - irq = EP_MCA_IRQ(pos); - - mca_add_iospace(dev, iobase, EP_MCA_IOPORT_SIZE); - mca_add_irq(dev, irq); - - return (0); -} - -static int -ep_mca_attach(device_t dev) -{ - struct ep_softc *sc = device_get_softc(dev); - int error = 0; - - if ((error = ep_alloc(dev))) - goto bad; - sc->stat = F_ACCESS_32_BITS; - - ep_get_media(sc); - - GO_WINDOW(sc, 0); - SET_IRQ(sc, rman_get_start(sc->irq)); - - if ((error = ep_attach(sc))) - goto bad; - if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ep_intr, - sc, &sc->ep_intrhand))) { - device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); - goto bad; - } - return (0); -bad: - ep_free(dev); - return (error); -} - -static device_method_t ep_mca_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ep_mca_probe), - DEVMETHOD(device_attach, ep_mca_attach), - DEVMETHOD(device_detach, ep_detach), - - DEVMETHOD_END -}; - -static driver_t ep_mca_driver = { - "ep", - ep_mca_methods, - sizeof(struct ep_softc), -}; - -static devclass_t ep_devclass; - -DRIVER_MODULE(ep, mca, ep_mca_driver, ep_devclass, 0, 0); diff --git a/sys/dev/ep/if_epreg.h b/sys/dev/ep/if_epreg.h index 9453891488df..15f937579f0d 100644 --- a/sys/dev/ep/if_epreg.h +++ b/sys/dev/ep/if_epreg.h @@ -113,7 +113,7 @@ /************************************************************************** * * * These are the registers for the 3Com 3c509 and their bit patterns when * - * applicable. They have been taken out the "EtherLink III Parallel * + * applicable. They have been taken out the "EtherLink III Parallel * * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual * * from 3com. * * * diff --git a/sys/dev/ep/if_epvar.h b/sys/dev/ep/if_epvar.h index c7b9cb39d5b0..a7ad8ea45364 100644 --- a/sys/dev/ep/if_epvar.h +++ b/sys/dev/ep/if_epvar.h @@ -59,7 +59,6 @@ struct ep_softc { #define F_RX_FIRST 0x001 #define F_ENADDR_SKIP 0x002 #define F_PROMISC 0x008 -#define F_ACCESS_32_BITS 0x100 #define F_HAS_TX_PLL 0x200 int gone; /* adapter is not present (for PCCARD) */ diff --git a/sys/dev/ida/ida_eisa.c b/sys/dev/ida/ida_eisa.c deleted file mode 100644 index aa5086353454..000000000000 --- a/sys/dev/ida/ida_eisa.c +++ /dev/null @@ -1,345 +0,0 @@ -/*- - * Copyright (c) 2000 Jonathan Lemon - * Copyright (c) 1999 by Matthew N. Dodd <winter@jurai.net> - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <sys/bio.h> -#include <sys/conf.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <geom/geom_disk.h> - -#include <dev/ida/idavar.h> -#include <dev/ida/idareg.h> - -#include <dev/eisa/eisaconf.h> - -#define IDA_EISA_IOPORT_START 0x0c88 -#define IDA_EISA_IOPORT_LEN 0x0017 - -#define IDA_EISA_IRQ_REG 0x0cc0 -#define IDA_EISA_IRQ_MASK 0xf0 -#define IDA_EISA_IRQ_15 0x80 -#define IDA_EISA_IRQ_14 0x40 -#define IDA_EISA_IRQ_11 0x10 -#define IDA_EISA_IRQ_10 0x20 - -static int -ida_v1_fifo_full(struct ida_softc *ida) -{ - u_int8_t status; - - status = ida_inb(ida, R_EISA_SYSTEM_DOORBELL); - return ((status & EISA_CHANNEL_CLEAR) == 0); -} - -static void -ida_v1_submit(struct ida_softc *ida, struct ida_qcb *qcb) -{ - u_int16_t size; - - /* - * On these cards, this location is actually for control flags. - * Set them to zero and pass in structure size via an I/O port. - */ - size = qcb->hwqcb->hdr.size << 2; - qcb->hwqcb->hdr.size = 0; - - ida_outb(ida, R_EISA_SYSTEM_DOORBELL, EISA_CHANNEL_CLEAR); - ida_outl(ida, R_EISA_LIST_ADDR, qcb->hwqcb_busaddr); - ida_outw(ida, R_EISA_LIST_LEN, size); - ida_outb(ida, R_EISA_LOCAL_DOORBELL, EISA_CHANNEL_BUSY); -} - -static bus_addr_t -ida_v1_done(struct ida_softc *ida) -{ - struct ida_hardware_qcb *hwqcb; - bus_addr_t completed; - u_int8_t status; - - if ((ida_inb(ida, R_EISA_SYSTEM_DOORBELL) & EISA_CHANNEL_BUSY) == 0) - return (0); - - ida_outb(ida, R_EISA_SYSTEM_DOORBELL, EISA_CHANNEL_BUSY); - completed = ida_inl(ida, R_EISA_COMPLETE_ADDR); - status = ida_inb(ida, R_EISA_LIST_STATUS); - ida_outb(ida, R_EISA_LOCAL_DOORBELL, EISA_CHANNEL_CLEAR); - - if (completed != 0) { - hwqcb = (struct ida_hardware_qcb *) - ((bus_addr_t)ida->hwqcbs + - ((completed & ~3) - ida->hwqcb_busaddr)); - hwqcb->req.error = status; - } - - return (completed); -} - -static int -ida_v1_int_pending(struct ida_softc *ida) -{ - return (ida_inb(ida, R_EISA_SYSTEM_DOORBELL) & EISA_CHANNEL_BUSY); -} - -static void -ida_v1_int_enable(struct ida_softc *ida, int enable) -{ - if (enable) { - ida_outb(ida, R_EISA_SYSTEM_DOORBELL, ~EISA_CHANNEL_CLEAR); - ida_outb(ida, R_EISA_LOCAL_DOORBELL, EISA_CHANNEL_BUSY); - ida_outb(ida, R_EISA_INT_MASK, INT_ENABLE); - ida_outb(ida, R_EISA_SYSTEM_MASK, INT_ENABLE); - ida->flags |= IDA_INTERRUPTS; - } else { - ida_outb(ida, R_EISA_SYSTEM_MASK, INT_DISABLE); - ida->flags &= ~IDA_INTERRUPTS; - } -} - -static int -ida_v2_fifo_full(struct ida_softc *ida) -{ - return (ida_inl(ida, R_CMD_FIFO) == 0); -} - -static void -ida_v2_submit(struct ida_softc *ida, struct ida_qcb *qcb) -{ - ida_outl(ida, R_CMD_FIFO, qcb->hwqcb_busaddr); -} - -static bus_addr_t -ida_v2_done(struct ida_softc *ida) -{ - return (ida_inl(ida, R_DONE_FIFO)); -} - -static int -ida_v2_int_pending(struct ida_softc *ida) -{ - return (ida_inl(ida, R_INT_PENDING)); -} - -static void -ida_v2_int_enable(struct ida_softc *ida, int enable) -{ - if (enable) - ida->flags |= IDA_INTERRUPTS; - else - ida->flags &= ~IDA_INTERRUPTS; - ida_outl(ida, R_INT_MASK, enable ? INT_ENABLE : INT_DISABLE); -} - -static struct ida_access ida_v1_access = { - ida_v1_fifo_full, - ida_v1_submit, - ida_v1_done, - ida_v1_int_pending, - ida_v1_int_enable, -}; - -static struct ida_access ida_v2_access = { - ida_v2_fifo_full, - ida_v2_submit, - ida_v2_done, - ida_v2_int_pending, - ida_v2_int_enable, -}; - -static struct ida_board board_id[] = { - { 0x0e114001, "Compaq IDA controller", - &ida_v1_access, 0 }, - { 0x0e114002, "Compaq IDA-2 controller", - &ida_v1_access, 0 }, - { 0x0e114010, "Compaq IAES controller", - &ida_v1_access, 0 }, - { 0x0e114020, "Compaq SMART array controller", - &ida_v1_access, 0 }, - { 0x0e114030, "Compaq SMART-2/E array controller", - &ida_v2_access, 0 }, - - { 0, "", 0, 0 } -}; - -static struct ida_board *ida_eisa_match(eisa_id_t); -static int ida_eisa_probe(device_t); -static int ida_eisa_attach(device_t); - -static device_method_t ida_eisa_methods[] = { - DEVMETHOD(device_probe, ida_eisa_probe), - DEVMETHOD(device_attach, ida_eisa_attach), - DEVMETHOD(device_detach, ida_detach), - - { 0, 0 } -}; - -static driver_t ida_eisa_driver = { - "ida", - ida_eisa_methods, - sizeof(struct ida_softc) -}; - -static devclass_t ida_devclass; - -static struct ida_board * -ida_eisa_match(eisa_id_t id) -{ - int i; - - for (i = 0; board_id[i].board; i++) - if (board_id[i].board == id) - return (&board_id[i]); - return (NULL); -} - -static int -ida_eisa_probe(device_t dev) -{ - struct ida_board *board; - u_int32_t io_base; - u_int irq = 0; - - board = ida_eisa_match(eisa_get_id(dev)); - if (board == NULL) - return (ENXIO); - device_set_desc(dev, board->desc); - - io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE); - - switch (IDA_EISA_IRQ_MASK & (inb(IDA_EISA_IRQ_REG + io_base))) { - case IDA_EISA_IRQ_15: - irq = 15; - break; - case IDA_EISA_IRQ_14: - irq = 14; - break; - case IDA_EISA_IRQ_11: - irq = 11; - break; - case IDA_EISA_IRQ_10: - irq = 10; - break; - default: - device_printf(dev, "slot %d, illegal irq setting.\n", - eisa_get_slot(dev)); - return (ENXIO); - } - - eisa_add_iospace(dev, (io_base + IDA_EISA_IOPORT_START), - IDA_EISA_IOPORT_LEN, RESVADDR_NONE); - - eisa_add_intr(dev, irq, EISA_TRIGGER_LEVEL); /* XXX ??? */ - - return (0); -} - -static int -ida_eisa_attach(device_t dev) -{ - struct ida_softc *ida; - struct ida_board *board; - int error; - int rid; - - ida = device_get_softc(dev); - ida->dev = dev; - - board = ida_eisa_match(eisa_get_id(dev)); - ida->cmd = *board->accessor; - ida->flags = board->flags; - mtx_init(&ida->lock, "ida", NULL, MTX_DEF); - callout_init_mtx(&ida->ch, &ida->lock, 0); - - ida->regs_res_type = SYS_RES_IOPORT; - ida->regs_res_id = 0; - ida->regs = bus_alloc_resource_any(dev, ida->regs_res_type, - &ida->regs_res_id, RF_ACTIVE); - if (ida->regs == NULL) { - device_printf(dev, "can't allocate register resources\n"); - return (ENOMEM); - } - - error = bus_dma_tag_create( - /* parent */ bus_get_dma_tag(dev), - /* alignment */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ BUS_SPACE_UNRESTRICTED, - /* maxsegsize */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ BUS_DMA_ALLOCNOW, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &ida->parent_dmat); - - if (error != 0) { - device_printf(dev, "can't allocate DMA tag\n"); - ida_free(ida); - return (ENOMEM); - } - - rid = 0; - ida->irq_res_type = SYS_RES_IRQ; - ida->irq = bus_alloc_resource_any(dev, ida->irq_res_type, &rid, - RF_ACTIVE | RF_SHAREABLE); - if (ida->irq == NULL) { - ida_free(ida); - return (ENOMEM); - } - - error = bus_setup_intr(dev, ida->irq, INTR_TYPE_BIO | INTR_ENTROPY | INTR_MPSAFE, - NULL, ida_intr, ida, &ida->ih); - if (error) { - device_printf(dev, "can't setup interrupt\n"); - ida_free(ida); - return (ENOMEM); - } - - error = ida_setup(ida); - if (error) { - ida_free(ida); - return (error); - } - - return (0); -} - -DRIVER_MODULE(ida, eisa, ida_eisa_driver, ida_devclass, 0, 0); diff --git a/sys/dev/ida/idareg.h b/sys/dev/ida/idareg.h index 7fb48d45063b..3b74f0bfcacd 100644 --- a/sys/dev/ida/idareg.h +++ b/sys/dev/ida/idareg.h @@ -31,23 +31,6 @@ */ /* - * defines for older EISA controllers (IDA, IDA-2, IAES, SMART) - */ -#define R_EISA_INT_MASK 0x01 -#define R_EISA_LOCAL_MASK 0x04 -#define R_EISA_LOCAL_DOORBELL 0x05 -#define R_EISA_SYSTEM_MASK 0x06 -#define R_EISA_SYSTEM_DOORBELL 0x07 -#define R_EISA_LIST_ADDR 0x08 -#define R_EISA_LIST_LEN 0x0c -#define R_EISA_TAG 0x0f -#define R_EISA_COMPLETE_ADDR 0x10 -#define R_EISA_LIST_STATUS 0x16 - -#define EISA_CHANNEL_BUSY 0x01 -#define EISA_CHANNEL_CLEAR 0x02 - -/* * board register offsets for SMART-2 controllers */ #define R_CMD_FIFO 0x04 diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c index 230a41456796..f3b6d7c1e7b4 100644 --- a/sys/dev/iscsi/icl_soft.c +++ b/sys/dev/iscsi/icl_soft.c @@ -169,6 +169,40 @@ icl_conn_receive(struct icl_conn *ic, size_t len) return (m); } +static int +icl_conn_receive_buf(struct icl_conn *ic, void *buf, size_t len) +{ + struct iovec iov[1]; + struct uio uio; + struct socket *so; + int error, flags; + + so = ic->ic_socket; + + memset(&uio, 0, sizeof(uio)); + iov[0].iov_base = buf; + iov[0].iov_len = len; + uio.uio_iov = iov; + uio.uio_iovcnt = 1; + uio.uio_offset = 0; + uio.uio_resid = len; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + + flags = MSG_DONTWAIT; + error = soreceive(so, NULL, &uio, NULL, NULL, &flags); + if (error != 0) { + ICL_DEBUG("soreceive error %d", error); + return (-1); + } + if (uio.uio_resid != 0) { + ICL_DEBUG("short read"); + return (-1); + } + + return (0); +} + static struct icl_pdu * icl_pdu_new_empty(struct icl_conn *ic, int flags) { @@ -226,10 +260,10 @@ icl_soft_conn_new_pdu(struct icl_conn *ic, int flags) if (ip == NULL) return (NULL); - ip->ip_bhs_mbuf = m_getm2(NULL, sizeof(struct iscsi_bhs), - flags, MT_DATA, M_PKTHDR); + CTASSERT(sizeof(struct iscsi_bhs) <= MHLEN); + ip->ip_bhs_mbuf = m_gethdr(flags, MT_DATA); if (ip->ip_bhs_mbuf == NULL) { - ICL_WARN("failed to allocate %zd bytes", sizeof(*ip)); + ICL_WARN("failed to allocate BHS mbuf"); icl_pdu_free(ip); return (NULL); } @@ -308,28 +342,13 @@ icl_pdu_size(const struct icl_pdu *response) static int icl_pdu_receive_bhs(struct icl_pdu *request, size_t *availablep) { - struct mbuf *m; - m = icl_conn_receive(request->ip_conn, sizeof(struct iscsi_bhs)); - if (m == NULL) { + if (icl_conn_receive_buf(request->ip_conn, + request->ip_bhs, sizeof(struct iscsi_bhs))) { ICL_DEBUG("failed to receive BHS"); return (-1); } - request->ip_bhs_mbuf = m_pullup(m, sizeof(struct iscsi_bhs)); - if (request->ip_bhs_mbuf == NULL) { - ICL_WARN("m_pullup failed"); - return (-1); - } - request->ip_bhs = mtod(request->ip_bhs_mbuf, struct iscsi_bhs *); - - /* - * XXX: For architectures with strict alignment requirements - * we may need to allocate ip_bhs and copy the data into it. - * For some reason, though, not doing this doesn't seem - * to cause problems; tested on sparc64. - */ - *availablep -= sizeof(struct iscsi_bhs); return (0); } @@ -371,28 +390,23 @@ icl_mbuf_to_crc32c(const struct mbuf *m0) static int icl_pdu_check_header_digest(struct icl_pdu *request, size_t *availablep) { - struct mbuf *m; uint32_t received_digest, valid_digest; if (request->ip_conn->ic_header_crc32c == false) return (0); - m = icl_conn_receive(request->ip_conn, ISCSI_HEADER_DIGEST_SIZE); - if (m == NULL) { + CTASSERT(sizeof(received_digest) == ISCSI_HEADER_DIGEST_SIZE); + if (icl_conn_receive_buf(request->ip_conn, + &received_digest, ISCSI_HEADER_DIGEST_SIZE)) { ICL_DEBUG("failed to receive header digest"); return (-1); } - - CTASSERT(sizeof(received_digest) == ISCSI_HEADER_DIGEST_SIZE); - m_copydata(m, 0, ISCSI_HEADER_DIGEST_SIZE, (void *)&received_digest); - m_freem(m); - *availablep -= ISCSI_HEADER_DIGEST_SIZE; - /* - * XXX: Handle AHS. - */ + /* Temporary attach AHS to BHS to calculate header digest. */ + request->ip_bhs_mbuf->m_next = request->ip_ahs_mbuf; valid_digest = icl_mbuf_to_crc32c(request->ip_bhs_mbuf); + request->ip_bhs_mbuf->m_next = NULL; if (received_digest != valid_digest) { ICL_WARN("header digest check failed; got 0x%x, " "should be 0x%x", received_digest, valid_digest); @@ -526,7 +540,6 @@ icl_pdu_receive_data_segment(struct icl_pdu *request, static int icl_pdu_check_data_digest(struct icl_pdu *request, size_t *availablep) { - struct mbuf *m; uint32_t received_digest, valid_digest; if (request->ip_conn->ic_data_crc32c == false) @@ -535,16 +548,12 @@ icl_pdu_check_data_digest(struct icl_pdu *request, size_t *availablep) if (request->ip_data_len == 0) return (0); - m = icl_conn_receive(request->ip_conn, ISCSI_DATA_DIGEST_SIZE); - if (m == NULL) { + CTASSERT(sizeof(received_digest) == ISCSI_DATA_DIGEST_SIZE); + if (icl_conn_receive_buf(request->ip_conn, + &received_digest, ISCSI_DATA_DIGEST_SIZE)) { ICL_DEBUG("failed to receive data digest"); return (-1); } - - CTASSERT(sizeof(received_digest) == ISCSI_DATA_DIGEST_SIZE); - m_copydata(m, 0, ISCSI_DATA_DIGEST_SIZE, (void *)&received_digest); - m_freem(m); - *availablep -= ISCSI_DATA_DIGEST_SIZE; /* @@ -580,7 +589,7 @@ icl_conn_receive_pdu(struct icl_conn *ic, size_t *availablep) if (ic->ic_receive_state == ICL_CONN_STATE_BHS) { KASSERT(ic->ic_receive_pdu == NULL, ("ic->ic_receive_pdu != NULL")); - request = icl_pdu_new_empty(ic, M_NOWAIT); + request = icl_soft_conn_new_pdu(ic, M_NOWAIT); if (request == NULL) { ICL_DEBUG("failed to allocate PDU; " "dropping connection"); @@ -883,7 +892,7 @@ icl_conn_send_pdus(struct icl_conn *ic, struct icl_pdu_stailq *queue) { struct icl_pdu *request, *request2; struct socket *so; - size_t available, size, size2; + long available, size, size2; int coalesced, error; ICL_CONN_LOCK_ASSERT_NOT(ic); @@ -922,7 +931,7 @@ icl_conn_send_pdus(struct icl_conn *ic, struct icl_pdu_stailq *queue) if (available < size) { #if 1 ICL_DEBUG("no space to send; " - "have %zd, need %zd", + "have %ld, need %ld", available, size); #endif so->so_snd.sb_lowat = size; @@ -969,7 +978,7 @@ icl_conn_send_pdus(struct icl_conn *ic, struct icl_pdu_stailq *queue) } #if 0 if (coalesced > 1) { - ICL_DEBUG("coalesced %d PDUs into %zd bytes", + ICL_DEBUG("coalesced %d PDUs into %ld bytes", coalesced, size); } #endif @@ -1087,7 +1096,7 @@ icl_pdu_append_data(struct icl_pdu *request, const void *addr, size_t len, KASSERT(len > 0, ("len == 0")); - newmb = m_getm2(NULL, len, flags, MT_DATA, M_PKTHDR); + newmb = m_getm2(NULL, len, flags, MT_DATA, 0); if (newmb == NULL) { ICL_WARN("failed to allocate mbuf for %zd bytes", len); return (ENOMEM); diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index 45b6d300f101..fc2553d48b9d 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -231,14 +231,16 @@ iscsi_session_send_postponed(struct iscsi_session *is) ISCSI_SESSION_LOCK_ASSERT(is); - while (!STAILQ_EMPTY(&is->is_postponed)) { - request = STAILQ_FIRST(&is->is_postponed); + if (STAILQ_EMPTY(&is->is_postponed)) + return; + while ((request = STAILQ_FIRST(&is->is_postponed)) != NULL) { postpone = iscsi_pdu_prepare(request); if (postpone) - break; + return; STAILQ_REMOVE_HEAD(&is->is_postponed, ip_next); icl_pdu_queue(request); } + xpt_release_simq(is->is_sim, 1); } static void @@ -252,6 +254,8 @@ iscsi_pdu_queue_locked(struct icl_pdu *request) iscsi_session_send_postponed(is); postpone = iscsi_pdu_prepare(request); if (postpone) { + if (STAILQ_EMPTY(&is->is_postponed)) + xpt_freeze_simq(is->is_sim, 1); STAILQ_INSERT_TAIL(&is->is_postponed, request, ip_next); return; } @@ -339,8 +343,9 @@ iscsi_session_cleanup(struct iscsi_session *is, bool destroy_sim) /* * Remove postponed PDUs. */ - while (!STAILQ_EMPTY(&is->is_postponed)) { - pdu = STAILQ_FIRST(&is->is_postponed); + if (!STAILQ_EMPTY(&is->is_postponed)) + xpt_release_simq(is->is_sim, 1); + while ((pdu = STAILQ_FIRST(&is->is_postponed)) != NULL) { STAILQ_REMOVE_HEAD(&is->is_postponed, ip_next); icl_pdu_free(pdu); } @@ -475,15 +480,14 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is) static void iscsi_maintenance_thread(void *arg) { - struct iscsi_session *is; - - is = arg; + struct iscsi_session *is = arg; + ISCSI_SESSION_LOCK(is); for (;;) { - ISCSI_SESSION_LOCK(is); if (is->is_reconnecting == false && is->is_terminating == false && - STAILQ_EMPTY(&is->is_postponed)) + (STAILQ_EMPTY(&is->is_postponed) || + ISCSI_SNGT(is->is_cmdsn, is->is_maxcmdsn))) cv_wait(&is->is_maintenance_cv, &is->is_lock); /* Terminate supersedes reconnect. */ @@ -497,12 +501,13 @@ iscsi_maintenance_thread(void *arg) if (is->is_reconnecting) { ISCSI_SESSION_UNLOCK(is); iscsi_maintenance_thread_reconnect(is); + ISCSI_SESSION_LOCK(is); continue; } iscsi_session_send_postponed(is); - ISCSI_SESSION_UNLOCK(is); } + ISCSI_SESSION_UNLOCK(is); } static void diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 88dfc485f8ba..f1116f61e0f4 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -130,6 +130,15 @@ static const struct iwi_ident iwi_ident_table[] = { { 0, 0, NULL } }; +static const uint8_t def_chan_2ghz[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; +static const uint8_t def_chan_5ghz_band1[] = + { 36, 40, 44, 48, 52, 56, 60, 64 }; +static const uint8_t def_chan_5ghz_band2[] = + { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }; +static const uint8_t def_chan_5ghz_band3[] = + { 149, 153, 157, 161, 165 }; + static struct ieee80211vap *iwi_vap_create(struct ieee80211com *, const char [IFNAMSIZ], int, enum ieee80211_opmode, int, const uint8_t [IEEE80211_ADDR_LEN], @@ -204,6 +213,9 @@ static void iwi_radio_off(void *, int); static void iwi_sysctlattach(struct iwi_softc *); static void iwi_led_event(struct iwi_softc *, int); static void iwi_ledattach(struct iwi_softc *); +static void iwi_collect_bands(struct ieee80211com *, uint8_t [], size_t); +static void iwi_getradiocaps(struct ieee80211com *, int, int *, + struct ieee80211_channel []); static int iwi_probe(device_t); static int iwi_attach(device_t); @@ -271,7 +283,6 @@ iwi_attach(device_t dev) struct iwi_softc *sc = device_get_softc(dev); struct ieee80211com *ic = &sc->sc_ic; uint16_t val; - uint8_t bands[IEEE80211_MODE_BYTES]; int i, error; sc->sc_dev = dev; @@ -374,12 +385,8 @@ iwi_attach(device_t dev) ic->ic_macaddr[4] = val & 0xff; ic->ic_macaddr[5] = val >> 8; - memset(bands, 0, sizeof(bands)); - setbit(bands, IEEE80211_MODE_11B); - setbit(bands, IEEE80211_MODE_11G); - if (pci_get_device(dev) >= 0x4223) - setbit(bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, bands); + iwi_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); ieee80211_ifattach(ic); /* override default methods */ @@ -399,6 +406,7 @@ iwi_attach(device_t dev) ic->ic_ioctl = iwi_ioctl; ic->ic_transmit = iwi_transmit; ic->ic_parent = iwi_parent; + ic->ic_getradiocaps = iwi_getradiocaps; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -3569,3 +3577,40 @@ iwi_scan_end(struct ieee80211com *ic) iwi_cmd(sc, IWI_CMD_ABORT_SCAN, NULL, 0); IWI_UNLOCK(sc); } + +static void +iwi_collect_bands(struct ieee80211com *ic, uint8_t bands[], size_t bands_sz) +{ + struct iwi_softc *sc = ic->ic_softc; + device_t dev = sc->sc_dev; + + memset(bands, 0, bands_sz); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + if (pci_get_device(dev) >= 0x4223) + setbit(bands, IEEE80211_MODE_11A); +} + +static void +iwi_getradiocaps(struct ieee80211com *ic, + int maxchans, int *nchans, struct ieee80211_channel chans[]) +{ + uint8_t bands[IEEE80211_MODE_BYTES]; + + iwi_collect_bands(ic, bands, sizeof(bands)); + *nchans = 0; + if (isset(bands, IEEE80211_MODE_11B) || isset(bands, IEEE80211_MODE_11G)) + ieee80211_add_channel_list_2ghz(chans, maxchans, nchans, + def_chan_2ghz, nitems(def_chan_2ghz), bands, 0); + if (isset(bands, IEEE80211_MODE_11A)) { + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + def_chan_5ghz_band1, nitems(def_chan_5ghz_band1), + bands, 0); + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + def_chan_5ghz_band2, nitems(def_chan_5ghz_band2), + bands, 0); + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + def_chan_5ghz_band3, nitems(def_chan_5ghz_band3), + bands, 0); + } +} diff --git a/sys/dev/mca/mca_bus.c b/sys/dev/mca/mca_bus.c deleted file mode 100644 index 2de61da3d455..000000000000 --- a/sys/dev/mca/mca_bus.c +++ /dev/null @@ -1,533 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * References: - * The CMU Mach3 microkernel - * NetBSD MCA patches by Scott Telford - * Linux MCA code. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/limits.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <dev/mca/mca_busreg.h> -#include <dev/mca/mca_busvar.h> - -#include <sys/interrupt.h> - -#define MAX_COL 79 - -static void mca_reg_print (device_t, char *, char *, int *); - -struct mca_device { - struct resource_list rl; /* Resources */ - - mca_id_t id; - u_int8_t slot; - u_int8_t enabled; - u_int8_t pos[8]; /* Programable Option Select Regs. */ -}; - -/* Not supposed to use this function! */ -void -mca_pos_set (device_t dev, u_int8_t reg, u_int8_t data) -{ - struct mca_device * m_dev = device_get_ivars(dev); - u_int8_t slot = mca_get_slot(dev); - - if ((slot > MCA_MAX_ADAPTERS) || (reg > MCA_POS7)) - return; - - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - - /* Select adapter setup regs */ - outb(MCA_ADAP_SETUP_REG, ((slot & 0x0f) | MCA_ADAP_SET)); - - /* Write the register */ - outb(MCA_POS_REG(reg), data); - - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - - /* Update the IVAR copy */ - m_dev->pos[reg] = data; - - return; -} - -u_int8_t -mca_pos_get (device_t dev, u_int8_t reg) -{ - u_int8_t slot = mca_get_slot(dev); - u_int8_t data = 0; - - if ((slot > MCA_MAX_ADAPTERS) || (reg > MCA_POS7)) - return (0); - - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - - switch (slot) { - case MCA_MB_SCSI_SLOT: - - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - - /* Select motherboard video setup regs */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_SCSI); - - /* read the register */ - data = inb(MCA_POS_REG(reg)); - - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - - break; - case MCA_MB_VIDEO_SLOT: - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - - /* Select motherboard scsi setup regs */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_VIDEO); - - /* read the register */ - data = inb(MCA_POS_REG(reg)); - - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - break; - default: - - /* Select adapter setup regs */ - outb(MCA_ADAP_SETUP_REG, - ((slot & 0x0f) | MCA_ADAP_SET)); - - /* read the register */ - data = inb(MCA_POS_REG(reg)); - - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - break; - } - - return (data); -} - -const char * -mca_match_id (u_int16_t id, struct mca_ident *mca_devs) -{ - struct mca_ident * m = mca_devs; - while(m->name != NULL) { - if (id == m->id) - return (m->name); - m++; - } - return (NULL); -} - -u_int8_t -mca_pos_read (device_t dev, u_int8_t reg) -{ - struct mca_device * m_dev = device_get_ivars(dev); - - if (reg > MCA_POS7) - return (0); - - return (m_dev->pos[reg]); -} - -void -mca_add_irq (dev, irq) - device_t dev; - int irq; -{ - struct mca_device * m_dev = device_get_ivars(dev); - int rid = 0; - - while (resource_list_find(&(m_dev->rl), SYS_RES_IRQ, rid)) rid++; - resource_list_add(&(m_dev->rl), SYS_RES_IRQ, rid, irq, irq, 1); - - return; -} - -void -mca_add_drq (dev, drq) - device_t dev; - int drq; -{ - struct mca_device * m_dev = device_get_ivars(dev); - int rid = 0; - - while (resource_list_find(&(m_dev->rl), SYS_RES_DRQ, rid)) rid++; - resource_list_add(&(m_dev->rl), SYS_RES_DRQ, rid, drq, drq, 1); - - return; -} - -void -mca_add_mspace (dev, mbase, msize) - device_t dev; - u_long mbase; - u_long msize; -{ - struct mca_device * m_dev = device_get_ivars(dev); - int rid = 0; - - while (resource_list_find(&(m_dev->rl), SYS_RES_MEMORY, rid)) rid++; - resource_list_add(&(m_dev->rl), SYS_RES_MEMORY, rid, - mbase, (mbase + msize), msize); - - return; -} - -void -mca_add_iospace (dev, iobase, iosize) - device_t dev; - u_long iobase; - u_long iosize; -{ - struct mca_device * m_dev = device_get_ivars(dev); - int rid = 0; - - while (resource_list_find(&(m_dev->rl), SYS_RES_IOPORT, rid)) rid++; - resource_list_add(&(m_dev->rl), SYS_RES_IOPORT, rid, - iobase, (iobase + iosize), iosize); - - return; -} - -static int -mca_probe (device_t dev) -{ - device_t child; - struct mca_device * m_dev = NULL; - int devices_found = 0; - u_int8_t slot; - u_int8_t reg; - - device_set_desc(dev, "MCA bus"); - - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - - if (bootverbose) { - printf("POS REG 00 01 02 03 04 05 06 07\n"); - printf("-----------------------------------\n"); - } - - for (slot = 0; slot < MCA_MAX_SLOTS; slot++) { - - if (!m_dev) { - m_dev = (struct mca_device *)malloc(sizeof(*m_dev), - M_DEVBUF, M_NOWAIT); - if (!m_dev) { - device_printf(dev, "cannot malloc mca_device"); - break; - } - } - bzero(m_dev, sizeof(*m_dev)); - - /* Select adapter setup regs */ - outb(MCA_ADAP_SETUP_REG, ((slot & 0x0f) | MCA_ADAP_SET)); - - /* Read the POS registers */ - for (reg = MCA_POS0; reg <= MCA_POS7; reg++) { - m_dev->pos[reg] = inb(MCA_POS_REG(reg)); - } - - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - - if (bootverbose) { - printf("mca slot %d:", slot + 1); - for (reg = MCA_POS0; reg <= MCA_POS7; reg++) { - printf(" %02x", m_dev->pos[reg]); - } - printf("\n"); - } - - m_dev->id = (u_int16_t)m_dev->pos[MCA_POS0] | - ((u_int16_t)m_dev->pos[MCA_POS1] << 8); - - if (m_dev->id == 0xffff) { - continue; - } - - devices_found++; - - m_dev->enabled = (m_dev->pos[MCA_POS2] & MCA_POS2_ENABLE); - m_dev->slot = slot; - - resource_list_init(&(m_dev->rl)); - - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, m_dev); - - m_dev = NULL; - } - - if (m_dev) { - free(m_dev, M_DEVBUF); - } - - return (devices_found ? 0 : ENXIO); -} - -static void -mca_reg_print (dev, string, separator, column) - device_t dev; - char * string; - char * separator; - int * column; -{ - int length = strlen(string); - - length += (separator ? 2 : 1); - - if (((*column) + length) >= MAX_COL) { - printf("\n"); - (*column) = 0; - } else if ((*column) != 0) { - if (separator) { - printf("%c", *separator); - (*column)++; - } - printf(" "); - (*column)++; - } - - if ((*column) == 0) { - (*column) += device_printf(dev, "%s", string); - } else { - (*column) += printf("%s", string); - } - - return; -} - -static int -mca_print_child (device_t dev, device_t child) -{ - char buf[MAX_COL+1]; - struct mca_device * m_dev = device_get_ivars(child); - int rid; - struct resource_list_entry * rle; - char separator = ','; - int column = 0; - int retval = 0; - - if (device_get_desc(child)) { - snprintf(buf, sizeof(buf), "<%s>", device_get_desc(child)); - mca_reg_print(child, buf, NULL, &column); - } - - rid = 0; - while ((rle = resource_list_find(&(m_dev->rl), SYS_RES_IOPORT, rid++))) { - if (rle->count == 1) { - snprintf(buf, sizeof(buf), "%s%jx", - ((rid == 1) ? "io 0x" : "0x"), - rle->start); - } else { - snprintf(buf, sizeof(buf), "%s%jx-0x%jx", - ((rid == 1) ? "io 0x" : "0x"), - rle->start, - (rle->start + rle->count)); - } - mca_reg_print(child, buf, - ((rid == 2) ? &separator : NULL), &column); - } - - rid = 0; - while ((rle = resource_list_find(&(m_dev->rl), SYS_RES_MEMORY, rid++))) { - if (rle->count == 1) { - snprintf(buf, sizeof(buf), "%s%jx", - ((rid == 1) ? "mem 0x" : "0x"), - rle->start); - } else { - snprintf(buf, sizeof(buf), "%s%jx-0x%jx", - ((rid == 1) ? "mem 0x" : "0x"), - rle->start, - (rle->start + rle->count)); - } - mca_reg_print(child, buf, - ((rid == 2) ? &separator : NULL), &column); - } - - rid = 0; - while ((rle = resource_list_find(&(m_dev->rl), SYS_RES_IRQ, rid++))) { - snprintf(buf, sizeof(buf), "irq %jd", rle->start); - mca_reg_print(child, buf, - ((rid == 1) ? &separator : NULL), &column); - } - - rid = 0; - while ((rle = resource_list_find(&(m_dev->rl), SYS_RES_DRQ, rid++))) { - snprintf(buf, sizeof(buf), "drq %jx", rle->start); - mca_reg_print(child, buf, - ((rid == 1) ? &separator : NULL), &column); - } - - snprintf(buf, sizeof(buf), "on %s id %04x slot %d\n", - device_get_nameunit(dev), - mca_get_id(child), mca_get_slot(child)+1); - mca_reg_print(child, buf, NULL, &column); - - return (retval); -} - -static void -mca_probe_nomatch (device_t dev, device_t child) -{ - mca_id_t mca_id = mca_get_id(child); - u_int8_t slot = mca_get_slot(child); - u_int8_t enabled = mca_get_enabled(child); - - device_printf(dev, "unknown card (id 0x%04x, %s) at slot %d\n", - mca_id, - (enabled ? "enabled" : "disabled"), - slot + 1); - - return; -} - -static int -mca_read_ivar (device_t dev, device_t child, int which, uintptr_t * result) -{ - struct mca_device * m_dev = device_get_ivars(child); - - switch (which) { - case MCA_IVAR_SLOT: - *result = m_dev->slot; - break; - case MCA_IVAR_ID: - *result = m_dev->id; - break; - case MCA_IVAR_ENABLED: - *result = m_dev->enabled; - break; - default: - return (ENOENT); - break; - } - - return (0); -} - -static struct resource * -mca_alloc_resource (device_t dev, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct mca_device * m_dev = device_get_ivars(child); - struct resource_list_entry * rle; - int isdefault; - int passthrough; - - isdefault = RMAN_IS_DEFAULT_RANGE(start, end); - passthrough = (device_get_parent(child) != dev); - - if (!passthrough && !isdefault) { - rle = resource_list_find(&(m_dev->rl), type, *rid); - if (!rle) { - resource_list_add(&(m_dev->rl), type, *rid, - start, end, count); - } - } - - if (type == SYS_RES_IRQ) { - flags |= RF_SHAREABLE; - } - - return (resource_list_alloc(&(m_dev->rl), dev, child, type, rid, - start, end, count, flags)); -} - -static struct resource_list * -mca_get_resource_list (device_t dev, device_t child) -{ - struct mca_device * m_dev = device_get_ivars(child); - struct resource_list * rl = &m_dev->rl; - - if (!rl) - return (NULL); - - return (rl); -} - -static device_method_t mca_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, mca_probe), - DEVMETHOD(device_attach, bus_generic_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, mca_print_child), - DEVMETHOD(bus_probe_nomatch, mca_probe_nomatch), - DEVMETHOD(bus_read_ivar, mca_read_ivar), - DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - DEVMETHOD(bus_get_resource_list,mca_get_resource_list), - DEVMETHOD(bus_alloc_resource, mca_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), - DEVMETHOD(bus_activate_resource,bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - - DEVMETHOD_END -}; - -static driver_t mca_driver = { - "mca", - mca_methods, - 1, /* no softc */ -}; - -static devclass_t mca_devclass; - -DRIVER_MODULE(mca, legacy, mca_driver, mca_devclass, 0, 0); diff --git a/sys/dev/mca/mca_busreg.h b/sys/dev/mca/mca_busreg.h deleted file mode 100644 index e818b68b8023..000000000000 --- a/sys/dev/mca/mca_busreg.h +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Standardized MCA configuration information - */ - -#define MCA_MAX_SLOTS 8 /* max number of slots per bus */ -#define MCA_MB_SCSI_SLOT 8 -#define MCA_MB_VIDEO_SLOT 9 -#define MCA_MAX_ADAPTERS 9 - -/* - * When an ADF file talks about a POS register - * its not talking about the same index we are - * so provide this to convert ADF pos register - * offsets to our register offsets. (Since - * to us, POS0 and POS1 are just 2 more registers - */ - -#define MCA_ADP_POS(pos) (pos + 2) - -#define MCA_POS0 0 /* low byte of board ID */ -#define MCA_POS1 1 /* high byte of board ID */ -#define MCA_POS2 2 -# define MCA_POS2_ENABLE 0x01 /* POS2, hi => adapter enabled */ -#define MCA_POS3 3 -#define MCA_POS4 4 -#define MCA_POS5 5 -# define MCA_POS5_CHCK_STAT 0x40 /* lo => CHCK status available */ -# define MCA_POS5_CHCK 0x80 /* lo => adapter CHCK signal */ -#define MCA_POS6 6 /* low byte of CHCK status */ -#define MCA_POS7 7 /* high byte of CHCK status */ - -/* - * MCA register addresses for IBM PS/2 - */ - -#define MCA_SYS_CTL_A_REG 0x92 /* PS/2 System Control Port A */ -#define MCA_SYS_CTL_B_REG 0x60 /* PS/2 System Control Port B */ -#define MCA_ARB_REG 0x90 /* MCA Arbitration port */ -#define MCA_CSF_REG 0x91 /* MCA Card Select Feedback */ - -/* - * 0x96, 0x97 POS Registers - * 0x100 - 0x107 POS Registers - */ - -#define MCA_MB_SETUP_REG 0x94 /* Motherboard setup register */ -# define MCA_MB_SETUP_DIS 0xff /* Disable motherboard setup */ -# define MCA_MB_SETUP_VIDEO 0xdf -# define MCA_MB_SETUP_SCSI 0xf7 /* Pri. SCSI setup reg */ -# define MCA_MB_SETUP_SCSI_ALT 0xfd /* Alt. SCSI setup reg */ - -#define MCA_ADAP_SETUP_REG 0x96 /* Adapter setup register */ -# define MCA_ADAP_SETUP_DIS 0x0 /* Disable adapter setup */ -# define MCA_ADAP_SET 0x08 /* Adapter setup mode */ -# define MCA_ADAP_CHR 0x80 /* Adapter channel reset */ -#define MCA_POS_REG(n) (0x100+(n)) /* POS registers 0-7 */ diff --git a/sys/dev/mca/mca_busvar.h b/sys/dev/mca/mca_busvar.h deleted file mode 100644 index db11d67699f6..000000000000 --- a/sys/dev/mca/mca_busvar.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -typedef u_int16_t mca_id_t; - -struct mca_ident { - mca_id_t id; - char *name; -}; - -const char * mca_match_id (u_int16_t, struct mca_ident *); - -/* - * Simplified accessors for isa devices - */ - -enum mca_device_ivars { - MCA_IVAR_SLOT, - MCA_IVAR_ID, - MCA_IVAR_ENABLED, -}; - -#define MCA_ACCESSOR(A, B, T) \ - \ -static __inline T mca_get_ ## A(device_t dev) \ -{ \ - uintptr_t v; \ - BUS_READ_IVAR(device_get_parent(dev), dev, MCA_IVAR_ ## B, &v); \ - return (T) v; \ -} - -MCA_ACCESSOR(slot, SLOT, int) -MCA_ACCESSOR(id, ID, mca_id_t) -MCA_ACCESSOR(enabled, ENABLED, int) - -/* don't use these! */ -void mca_pos_set (device_t, u_int8_t, u_int8_t); -u_int8_t mca_pos_get (device_t, u_int8_t); - -u_int8_t mca_pos_read (device_t, u_int8_t); - -void mca_add_irq (device_t, int); -void mca_add_drq (device_t, int); -void mca_add_iospace (device_t, u_long, u_long); -void mca_add_mspace (device_t, u_long, u_long); diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index de0a69603e9b..c9c73bfafda4 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -1689,7 +1689,8 @@ xmdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread mdio->md_options = sc->flags; mdio->md_mediasize = sc->mediasize; mdio->md_sectorsize = sc->sectorsize; - if (sc->type == MD_VNODE) + if (sc->type == MD_VNODE || + (sc->type == MD_PRELOAD && mdio->md_file != NULL)) error = copyout(sc->file, mdio->md_file, strlen(sc->file) + 1); return (error); @@ -1733,6 +1734,8 @@ md_preloaded(u_char *image, size_t length, const char *name) sc->pl_ptr = image; sc->pl_len = length; sc->start = mdstart_preload; + if (name != NULL) + strlcpy(sc->file, name, sizeof(sc->file)); #if defined(MD_ROOT) && !defined(ROOTDEVNAME) if (sc->unit == 0) rootdevnames[0] = MD_ROOT_FSTYPE ":/dev/md0"; @@ -1835,7 +1838,8 @@ g_md_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sbuf_printf(sb, " fs %ju", (uintmax_t) mp->fwsectors); sbuf_printf(sb, " l %ju", (uintmax_t) mp->mediasize); sbuf_printf(sb, " t %s", type); - if (mp->type == MD_VNODE && mp->vnode != NULL) + if ((mp->type == MD_VNODE && mp->vnode != NULL) || + (mp->type == MD_PRELOAD && mp->file[0] != '\0')) sbuf_printf(sb, " file %s", mp->file); } else { sbuf_printf(sb, "%s<unit>%d</unit>\n", indent, @@ -1855,7 +1859,8 @@ g_md_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, "read-only"); sbuf_printf(sb, "%s<type>%s</type>\n", indent, type); - if (mp->type == MD_VNODE && mp->vnode != NULL) { + if ((mp->type == MD_VNODE && mp->vnode != NULL) || + (mp->type == MD_PRELOAD && mp->file[0] != '\0')) { sbuf_printf(sb, "%s<file>", indent); g_conf_printf_escaped(sb, "%s", mp->file); sbuf_printf(sb, "</file>\n"); diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c index 970053c1ec71..e3b09582a367 100644 --- a/sys/dev/mlx/mlx.c +++ b/sys/dev/mlx/mlx.c @@ -450,7 +450,7 @@ mlx_attach(struct mlx_softc *sc) } sc->mlx_enq2->me_firmware_id = ('0' << 24) | (0 << 16) | (meo->me_fwminor << 8) | meo->me_fwmajor; - /* XXX require 2.42 or better (PCI) or 2.14 or better (EISA) */ + /* XXX require 2.42 or better (PCI) */ if (meo->me_fwminor < 42) { device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); device_printf(sc->mlx_dev, " *** WARNING *** Use revision 2.42 or later\n"); diff --git a/sys/dev/mlx4/mlx4_ib/mlx4_ib_mad.c b/sys/dev/mlx4/mlx4_ib/mlx4_ib_mad.c index c910165cf7f1..dd02acc7e403 100644 --- a/sys/dev/mlx4/mlx4_ib/mlx4_ib_mad.c +++ b/sys/dev/mlx4/mlx4_ib/mlx4_ib_mad.c @@ -614,7 +614,7 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port, is_eth = 1; if (is_eth) { - if (!wc->wc_flags & IB_WC_GRH) { + if (!(wc->wc_flags & IB_WC_GRH)) { mlx4_ib_warn(ibdev, "RoCE grh not present.\n"); return -EINVAL; } diff --git a/sys/dev/netmap/netmap_generic.c b/sys/dev/netmap/netmap_generic.c index cb1cff1f0e71..45dc99184987 100644 --- a/sys/dev/netmap/netmap_generic.c +++ b/sys/dev/netmap/netmap_generic.c @@ -109,10 +109,13 @@ __FBSDID("$FreeBSD$"); * chain into uma_zfree(zone_pack, mf) * (or reinstall the buffer ?) */ -#define SET_MBUF_DESTRUCTOR(m, fn) do { \ - (m)->m_ext.ext_free = (void *)fn; \ - (m)->m_ext.ext_type = EXT_EXTREF; \ -} while (0) +static inline void +set_mbuf_destructor(struct mbuf *m, void *fn) +{ + + m->m_ext.ext_free = fn; + m->m_ext.ext_type = EXT_EXTREF; +} static int void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) @@ -167,9 +170,12 @@ nm_os_get_mbuf(struct ifnet *ifp, int len) static void void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { } -#define SET_MBUF_DESTRUCTOR(m, fn) do { \ - (m)->m_ext.ext_free = fn ? (void *)fn : (void *)void_mbuf_dtor; \ -} while (0) +static inline void +set_mbuf_destructor(struct mbuf *m, void *fn) +{ + + m->m_ext.ext_free = (fn != NULL) ? fn : (void *)void_mbuf_dtor; +} static inline struct mbuf * nm_os_get_mbuf(struct ifnet *ifp, int len) @@ -381,7 +387,7 @@ generic_netmap_unregister(struct netmap_adapter *na) * TX event is consumed. */ mtx_lock_spin(&kring->tx_event_lock); if (kring->tx_event) { - SET_MBUF_DESTRUCTOR(kring->tx_event, NULL); + set_mbuf_destructor(kring->tx_event, NULL); } kring->tx_event = NULL; mtx_unlock_spin(&kring->tx_event_lock); @@ -762,7 +768,7 @@ generic_set_tx_event(struct netmap_kring *kring, u_int hwcur) return; } - SET_MBUF_DESTRUCTOR(m, generic_mbuf_destructor); + set_mbuf_destructor(m, generic_mbuf_destructor); kring->tx_event = m; mtx_unlock_spin(&kring->tx_event_lock); diff --git a/sys/dev/pci/eisa_pci.c b/sys/dev/pci/eisa_pci.c deleted file mode 100644 index 98fa2707c305..000000000000 --- a/sys/dev/pci/eisa_pci.c +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier - * Copyright (c) 2000 Michael Smith <msmith@freebsd.org> - * Copyright (c) 2000 BSDi - * 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. The name of the author may not 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * PCI:EISA bridge support - */ - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <dev/pci/pcivar.h> -#include <dev/pci/pcireg.h> - -static int eisab_probe(device_t dev); -static int eisab_attach(device_t dev); - -static device_method_t eisab_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, eisab_probe), - DEVMETHOD(device_attach, eisab_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - DEVMETHOD_END -}; - -static driver_t eisab_driver = { - "eisab", - eisab_methods, - 0, -}; - -static devclass_t eisab_devclass; - -DRIVER_MODULE(eisab, pci, eisab_driver, eisab_devclass, 0, 0); - -static int -eisab_probe(device_t dev) -{ - int matched = 0; - - /* - * Generic match by class/subclass. - */ - if ((pci_get_class(dev) == PCIC_BRIDGE) && - (pci_get_subclass(dev) == PCIS_BRIDGE_EISA)) - matched = 1; - - /* - * Some bridges don't correctly report their class. - */ - switch (pci_get_devid(dev)) { - case 0x04828086: /* may show up as PCI-HOST or 0:0 */ - matched = 1; - break; - default: - break; - } - - if (matched) { - device_set_desc(dev, "PCI-EISA bridge"); - return(-10000); - } - return(ENXIO); -} - -static int -eisab_attach(device_t dev) -{ - /* - * Attach an EISA bus. Note that we can only have one EISA bus. - */ - if (!devclass_get_device(devclass_find("eisa"), 0)) - device_add_child(dev, "eisa", -1); - - /* - * Attach an ISA bus as well, since the EISA bus may have ISA - * cards installed, and we may have no EISA support in the system. - */ - if (!devclass_get_device(devclass_find("isa"), 0)) - device_add_child(dev, "isa", -1); - - bus_generic_attach(dev); - - return(0); -} diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 291bb2ea8090..b8765cb38c08 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -1040,3 +1040,19 @@ #define PCIR_SRIOV_BARS 0x24 #define PCIR_SRIOV_BAR(x) (PCIR_SRIOV_BARS + (x) * 4) +/* + * PCI Express Firmware Interface definitions + */ +#define PCI_OSC_STATUS 0 +#define PCI_OSC_SUPPORT 1 +#define PCIM_OSC_SUPPORT_EXT_PCI_CONF 0x01 /* Extended PCI Config Space */ +#define PCIM_OSC_SUPPORT_ASPM 0x02 /* Active State Power Management */ +#define PCIM_OSC_SUPPORT_CPMC 0x04 /* Clock Power Management Cap */ +#define PCIM_OSC_SUPPORT_SEG_GROUP 0x08 /* PCI Segment Groups supported */ +#define PCIM_OSC_SUPPORT_MSI 0x10 /* MSI signalling supported */ +#define PCI_OSC_CTL 2 +#define PCIM_OSC_CTL_PCIE_HP 0x01 /* PCIe Native Hot Plug */ +#define PCIM_OSC_CTL_SHPC_HP 0x02 /* SHPC Native Hot Plug */ +#define PCIM_OSC_CTL_PCIE_PME 0x04 /* PCIe Native Power Mgt Events */ +#define PCIM_OSC_CTL_PCIE_AER 0x08 /* PCIe Advanced Error Reporting */ +#define PCIM_OSC_CTL_PCIE_CAP_STRUCT 0x10 /* Various Capability Structures */ diff --git a/sys/dev/pdq/if_fea.c b/sys/dev/pdq/if_fea.c deleted file mode 100644 index 73c6caeebdad..000000000000 --- a/sys/dev/pdq/if_fea.c +++ /dev/null @@ -1,286 +0,0 @@ -/*- - * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com> - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * 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$ - */ - -/* - * DEC PDQ FDDI Controller - * - * This module support the DEFEA EISA FDDI Controller. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/module.h> -#include <sys/mutex.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/if.h> -#include <net/if_var.h> -#include <net/if_media.h> -#include <net/fddi.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/pdq/pdq_freebsd.h> -#include <dev/pdq/pdqreg.h> - -static void pdq_eisa_subprobe (pdq_bus_t, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *); -static void pdq_eisa_devinit (pdq_softc_t *); -static const char * pdq_eisa_match (eisa_id_t); - -static int pdq_eisa_probe (device_t); -static int pdq_eisa_attach (device_t); -static int pdq_eisa_detach (device_t); -static int pdq_eisa_shutdown (device_t); -static void pdq_eisa_ifintr (void *); - -#define DEFEA_IRQS 0x0000FBA9U - -#define DEFEA_INTRENABLE 0x8 /* level interrupt */ -#define DEFEA_DECODE_IRQ(n) ((DEFEA_IRQS >> ((n) << 2)) & 0x0f) - -#define EISA_DEVICE_ID_DEC_DEC3001 0x10a33001 -#define EISA_DEVICE_ID_DEC_DEC3002 0x10a33002 -#define EISA_DEVICE_ID_DEC_DEC3003 0x10a33003 -#define EISA_DEVICE_ID_DEC_DEC3004 0x10a33004 - -static void -pdq_eisa_subprobe(bc, iobase, maddr, msize, irq) - pdq_bus_t bc; - u_int32_t iobase; - u_int32_t *maddr; - u_int32_t *msize; - u_int32_t *irq; -{ - if (irq != NULL) - *irq = DEFEA_DECODE_IRQ(PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_IO_CONFIG_STAT_0) & 3); - *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8) - | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16); - *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8; - - return; -} - -static void -pdq_eisa_devinit (sc) - pdq_softc_t *sc; -{ - pdq_uint8_t data; - - /* - * Do the standard initialization for the DEFEA registers. - */ - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_FUNCTION_CTRL, 0x23); - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_1_1, (sc->io_bsh >> 8) & 0xF0); - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_0_1, (sc->io_bsh >> 8) & 0xF0); - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_SLOT_CTRL, 0x01); - data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF); -#if defined(PDQ_IOMAPPED) - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data & ~1); -#else - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data | 1); -#endif - data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0); - PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE); - - return; -} - -static const char * -pdq_eisa_match (type) - eisa_id_t type; -{ - switch (type) { - case EISA_DEVICE_ID_DEC_DEC3001: - case EISA_DEVICE_ID_DEC_DEC3002: - case EISA_DEVICE_ID_DEC_DEC3003: - case EISA_DEVICE_ID_DEC_DEC3004: - return ("DEC FDDIcontroller/EISA Adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -pdq_eisa_probe (dev) - device_t dev; -{ - const char *desc; - u_int32_t iobase; - u_int32_t irq; - u_int32_t maddr; - u_int32_t msize; - - u_int32_t eisa_id = eisa_get_id(dev); - - desc = pdq_eisa_match(eisa_id); - if (!desc) { - return (ENXIO); - } - - device_set_desc(dev, desc); - - iobase = eisa_get_slot(dev) * EISA_SLOT_SIZE; - pdq_eisa_subprobe((pdq_bus_t)SYS_RES_IOPORT, iobase, &maddr, &msize, &irq); - - eisa_add_iospace(dev, iobase, 0x200, RESVADDR_NONE); - eisa_add_mspace(dev, maddr, msize, RESVADDR_NONE); - eisa_add_intr(dev, irq, EISA_TRIGGER_LEVEL); - - return (0); -} - -static void -pdq_eisa_ifintr(arg) - void * arg; -{ - pdq_softc_t * sc; - - sc = arg; - - PDQ_LOCK(sc); - (void) pdq_interrupt(sc->sc_pdq); - PDQ_LOCK(sc); - - return; -} - -static int -pdq_eisa_attach (dev) - device_t dev; -{ - pdq_softc_t * sc; - int error; - - sc = device_get_softc(dev); - - sc->dev = dev; - - sc->io_rid = 0; - sc->io_type = SYS_RES_IOPORT; - sc->io = bus_alloc_resource_any(dev, sc->io_type, &sc->io_rid, - RF_ACTIVE); - if (!sc->io) { - device_printf(dev, "Unable to allocate I/O space resource.\n"); - error = ENXIO; - goto bad; - } - sc->io_bsh = rman_get_bushandle(sc->io); - sc->io_bst = rman_get_bustag(sc->io); - - sc->mem_rid = 0; - sc->mem_type = SYS_RES_MEMORY; - sc->mem = bus_alloc_resource_any(dev, sc->mem_type, &sc->mem_rid, - RF_ACTIVE); - if (!sc->mem) { - device_printf(dev, "Unable to allocate memory resource.\n"); - error = ENXIO; - goto bad; - } - sc->mem_bsh = rman_get_bushandle(sc->mem); - sc->mem_bst = rman_get_bustag(sc->mem); - - sc->irq_rid = 0; - sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, - RF_SHAREABLE | RF_ACTIVE); - if (!sc->irq) { - device_printf(dev, "Unable to allocate interrupt resource.\n"); - error = ENXIO; - goto bad; - } - - pdq_eisa_devinit(sc); - error = pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, - PDQ_DEFEA); - if (error) - goto bad; - - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, pdq_eisa_ifintr, sc, &sc->irq_ih); - if (error) { - device_printf(dev, "Failed to setup interrupt handler.\n"); - pdq_ifdetach(sc); - return (error); - } - - return (0); -bad: - pdq_free(dev); - return (error); -} - -static int -pdq_eisa_detach (dev) - device_t dev; -{ - pdq_softc_t * sc; - - sc = device_get_softc(dev); - pdq_ifdetach(sc); - - return (0); -} - -static int -pdq_eisa_shutdown(dev) - device_t dev; -{ - pdq_softc_t * sc; - - sc = device_get_softc(dev); - PDQ_LOCK(sc); - pdq_hwreset(sc->sc_pdq); - PDQ_UNLOCK(sc); - - return (0); -} - -static device_method_t pdq_eisa_methods[] = { - DEVMETHOD(device_probe, pdq_eisa_probe), - DEVMETHOD(device_attach, pdq_eisa_attach), - DEVMETHOD(device_attach, pdq_eisa_detach), - DEVMETHOD(device_shutdown, pdq_eisa_shutdown), - - { 0, 0 } -}; - -static driver_t pdq_eisa_driver = { - "fea", - pdq_eisa_methods, - sizeof(pdq_softc_t), -}; - -DRIVER_MODULE(fea, eisa, pdq_eisa_driver, pdq_devclass, 0, 0); -/* MODULE_DEPEND(fea, eisa, 1, 1, 1); */ -MODULE_DEPEND(fea, fddi, 1, 1, 1); diff --git a/sys/dev/pdq/pdq.c b/sys/dev/pdq/pdq.c index 00add2cbc2ff..9bb86ce6c3dd 100644 --- a/sys/dev/pdq/pdq.c +++ b/sys/dev/pdq/pdq.c @@ -163,10 +163,6 @@ static const char * const * const pdq_pmd_types[] = { static const char * const pdq_descriptions[] = { "DEFPA PCI", - "DEFEA EISA", - "DEFTA TC", - "DEFAA Futurebus", - "DEFQA Q-bus", }; static void @@ -1088,8 +1084,7 @@ pdq_hwreset( state = PDQ_PSTS_ADAPTER_STATE(PDQ_CSR_READ(csrs, csr_port_status)); if (state == PDQS_DMA_UNAVAILABLE) return; - PDQ_CSR_WRITE(csrs, csr_port_data_a, - (state == PDQS_HALTED && pdq->pdq_type != PDQ_DEFTA) ? 0 : PDQ_PRESET_SKIP_SELFTEST); + PDQ_CSR_WRITE(csrs, csr_port_data_a, PDQ_PRESET_SKIP_SELFTEST); PDQ_CSR_WRITE(csrs, csr_port_reset, 1); PDQ_OS_USEC_DELAY(100); PDQ_CSR_WRITE(csrs, csr_port_reset, 0); @@ -1164,13 +1159,11 @@ pdq_stop( pdq_read_fwrev(&pdq->pdq_csrs, &pdq->pdq_fwrev); pdq->pdq_chip_rev = pdq_read_chiprev(&pdq->pdq_csrs); - if (pdq->pdq_type == PDQ_DEFPA) { - /* - * Disable interrupts and DMA. - */ - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, 0); - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x10); - } + /* + * Disable interrupts and DMA. + */ + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, 0); + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x10); /* * Flush all the databuf queues. @@ -1229,27 +1222,21 @@ pdq_stop( * Allow the DEFPA to do DMA. Then program the physical * addresses of the consumer and descriptor blocks. */ - if (pdq->pdq_type == PDQ_DEFPA) { #ifdef PDQTEST - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, - PDQ_PFI_MODE_DMA_ENABLE); + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, + PDQ_PFI_MODE_DMA_ENABLE); #else - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, - PDQ_PFI_MODE_DMA_ENABLE - /*|PDQ_PFI_MODE_PFI_PCI_INTR*/|PDQ_PFI_MODE_PDQ_PCI_INTR); + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_mode_control, + PDQ_PFI_MODE_DMA_ENABLE + /*|PDQ_PFI_MODE_PFI_PCI_INTR*/|PDQ_PFI_MODE_PDQ_PCI_INTR); #endif - } /* * Make sure the unsolicited queue has events ... */ pdq_process_unsolicited_events(pdq); - if ((pdq->pdq_type == PDQ_DEFEA && pdq->pdq_chip_rev == PDQ_CHIP_REV_E) - || pdq->pdq_type == PDQ_DEFTA) - PDQ_CSR_WRITE(csrs, csr_port_data_b, PDQ_DMA_BURST_16LW); - else - PDQ_CSR_WRITE(csrs, csr_port_data_b, PDQ_DMA_BURST_8LW); + PDQ_CSR_WRITE(csrs, csr_port_data_b, PDQ_DMA_BURST_8LW); PDQ_CSR_WRITE(csrs, csr_port_data_a, PDQ_SUB_CMD_DMA_BURST_SIZE_SET); pdq_do_port_control(csrs, PDQ_PCTL_SUB_CMD); @@ -1408,8 +1395,7 @@ pdq_interrupt( pdq_uint32_t data; int progress = 0; - if (pdq->pdq_type == PDQ_DEFPA) - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x18); + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x18); while ((data = PDQ_CSR_READ(csrs, csr_port_status)) & PDQ_PSTS_INTR_PENDING) { progress = 1; @@ -1454,7 +1440,7 @@ pdq_interrupt( pdq_halt_code_t halt_code = PDQ_PSTS_HALT_ID(PDQ_CSR_READ(csrs, csr_port_status)); printf(": halt code = %d (%s)\n", halt_code, pdq_halt_codes[halt_code]); - if (halt_code == PDQH_DMA_ERROR && pdq->pdq_type == PDQ_DEFPA) { + if (halt_code == PDQH_DMA_ERROR) { PDQ_PRINTF(("\tPFI status = 0x%x, Host 0 Fatal Interrupt = 0x%x\n", PDQ_CSR_READ(&pdq->pdq_pci_csrs, csr_pfi_status), data & PDQ_HOST_INT_FATAL_ERROR)); @@ -1503,8 +1489,7 @@ pdq_interrupt( PDQ_CSR_WRITE(csrs, csr_host_int_type_0, PDQ_HOST_INT_XMT_DATA_FLUSH); } } - if (pdq->pdq_type == PDQ_DEFPA) - PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x18); + PDQ_CSR_WRITE(&pdq->pdq_pci_csrs, csr_pfi_status, 0x18); } return progress; } @@ -1639,9 +1624,8 @@ pdq_initialize( * Initialize the CSR references. * the DEFAA (FutureBus+) skips a longword between registers */ - pdq_init_csrs(&pdq->pdq_csrs, bus, csr_base, pdq->pdq_type == PDQ_DEFAA ? 2 : 1); - if (pdq->pdq_type == PDQ_DEFPA) - pdq_init_pci_csrs(&pdq->pdq_pci_csrs, bus, csr_base, 1); + pdq_init_csrs(&pdq->pdq_csrs, bus, csr_base, 1); + pdq_init_pci_csrs(&pdq->pdq_pci_csrs, bus, csr_base, 1); PDQ_PRINTF(("PDQ CSRs: BASE = " PDQ_OS_CSR_FMT "\n", pdq->pdq_csrs.csr_base)); PDQ_PRINTF((" Port Reset = " PDQ_OS_CSR_FMT " [0x%08x]\n", @@ -1774,7 +1758,7 @@ pdq_initialize( if (state == PDQS_HALTED) { pdq_halt_code_t halt_code = PDQ_PSTS_HALT_ID(PDQ_CSR_READ(&pdq->pdq_csrs, csr_port_status)); printf("Halt code = %d (%s)\n", halt_code, pdq_halt_codes[halt_code]); - if (halt_code == PDQH_DMA_ERROR && pdq->pdq_type == PDQ_DEFPA) + if (halt_code == PDQH_DMA_ERROR) PDQ_PRINTF(("PFI status = 0x%x, Host 0 Fatal Interrupt = 0x%x\n", PDQ_CSR_READ(&pdq->pdq_pci_csrs, csr_pfi_status), PDQ_CSR_READ(&pdq->pdq_csrs, csr_host_int_type_0) & PDQ_HOST_INT_FATAL_ERROR)); diff --git a/sys/dev/pdq/pdq_freebsd.h b/sys/dev/pdq/pdq_freebsd.h index a556b36afffb..a378e05d4e5a 100644 --- a/sys/dev/pdq/pdq_freebsd.h +++ b/sys/dev/pdq/pdq_freebsd.h @@ -86,10 +86,6 @@ extern devclass_t pdq_devclass; enum _pdq_type_t { PDQ_DEFPA, /* PCI-bus */ - PDQ_DEFEA, /* EISA-bus */ - PDQ_DEFTA, /* TurboChannel */ - PDQ_DEFAA, /* FutureBus+ */ - PDQ_DEFQA /* Q-bus */ }; #define sc_ifmedia ifmedia diff --git a/sys/dev/pdq/pdq_ifsubr.c b/sys/dev/pdq/pdq_ifsubr.c index f8df3a7b2b76..ed724df50309 100644 --- a/sys/dev/pdq/pdq_ifsubr.c +++ b/sys/dev/pdq/pdq_ifsubr.c @@ -459,6 +459,8 @@ pdq_ifattach(pdq_softc_t *sc, const pdq_uint8_t *llc, pdq_type_t type) { struct ifnet *ifp; + KASSERT(type == PDQ_DEFPA, ("We only support PCI attachment.")); + ifp = PDQ_IFNET(sc) = if_alloc(IFT_FDDI); if (ifp == NULL) { device_printf(sc->dev, "can not if_alloc()\n"); diff --git a/sys/dev/pdq/pdqreg.h b/sys/dev/pdq/pdqreg.h index a4dea690b154..1d2a15882fef 100644 --- a/sys/dev/pdq/pdqreg.h +++ b/sys/dev/pdq/pdqreg.h @@ -127,52 +127,6 @@ struct _pdq_pci_csrs_t { #define PDQ_PFI_STATUS_PDQ_INTR 0x10 /* PDQ Int received */ #define PDQ_PFI_STATUS_DMA_ABORT 0x08 /* PDQ DMA Abort asserted */ -#define PDQ_EISA_BURST_HOLDOFF 0x0040 -#define PDQ_EISA_SLOT_ID 0x0C80 -#define PDQ_EISA_SLOT_CTRL 0x0C84 -#define PDQ_EISA_MEM_ADD_CMP_0 0x0C85 -#define PDQ_EISA_MEM_ADD_CMP_1 0x0C86 -#define PDQ_EISA_MEM_ADD_CMP_2 0x0C87 -#define PDQ_EISA_MEM_ADD_HI_CMP_0 0x0C88 -#define PDQ_EISA_MEM_ADD_HI_CMP_1 0x0C89 -#define PDQ_EISA_MEM_ADD_HI_CMP_2 0x0C8A -#define PDQ_EISA_MEM_ADD_MASK_0 0x0C8B -#define PDQ_EISA_MEM_ADD_MASK_1 0x0C8C -#define PDQ_EISA_MEM_ADD_MASK_2 0x0C8D -#define PDQ_EISA_MEM_ADD_LO_CMP_0 0x0C8E -#define PDQ_EISA_MEM_ADD_LO_CMP_1 0x0C8F -#define PDQ_EISA_MEM_ADD_LO_CMP_2 0x0C90 -#define PDQ_EISA_IO_CMP_0_0 0x0C91 -#define PDQ_EISA_IO_CMP_0_1 0x0C92 -#define PDQ_EISA_IO_CMP_1_0 0x0C93 -#define PDQ_EISA_IO_CMP_1_1 0x0C94 -#define PDQ_EISA_IO_CMP_2_0 0x0C95 -#define PDQ_EISA_IO_CMP_2_1 0x0C96 -#define PDQ_EISA_IO_CMP_3_0 0x0C97 -#define PDQ_EISA_IO_CMP_3_1 0x0C98 -#define PDQ_EISA_IO_ADD_MASK_0_0 0x0C99 -#define PDQ_EISA_IO_ADD_MASK_0_1 0x0C9A -#define PDQ_EISA_IO_ADD_MASK_1_0 0x0C9B -#define PDQ_EISA_IO_ADD_MASK_1_1 0x0C9C -#define PDQ_EISA_IO_ADD_MASK_2_0 0x0C9D -#define PDQ_EISA_IO_ADD_MASK_2_1 0x0C9E -#define PDQ_EISA_IO_ADD_MASK_3_0 0x0C9F -#define PDQ_EISA_IO_ADD_MASK_3_1 0x0CA0 -#define PDQ_EISA_MOD_CONFIG_1 0x0CA1 -#define PDQ_EISA_MOD_CONFIG_2 0x0CA2 -#define PDQ_EISA_MOD_CONFIG_3 0x0CA3 -#define PDQ_EISA_MOD_CONFIG_4 0x0CA4 -#define PDQ_EISA_MOD_CONFIG_5 0x0CA5 -#define PDQ_EISA_MOD_CONFIG_6 0x0CA6 -#define PDQ_EISA_MOD_CONFIG_7 0x0CA7 -#define PDQ_EISA_DIP_SWITCH 0x0CA8 -#define PDQ_EISA_IO_CONFIG_STAT_0 0x0CA9 -#define PDQ_EISA_IO_CONFIG_STAT_1 0x0CAA -#define PDQ_EISA_DMA_CONFIG 0x0CAB -#define PDQ_EISA_INPUT_PORT 0x0CAC -#define PDQ_EISA_OUTPUT_PORT 0x0CAD -#define PDQ_EISA_FUNCTION_CTRL 0x0CAE - #define PDQ_TC_CSR_OFFSET 0x00100000 #define PDQ_TC_CSR_SPACE 0x0040 #define PDQ_FBUS_CSR_OFFSET 0x00200000 diff --git a/sys/dev/pdq/pdqvar.h b/sys/dev/pdq/pdqvar.h index db532732f27a..a84c00bc6624 100644 --- a/sys/dev/pdq/pdqvar.h +++ b/sys/dev/pdq/pdqvar.h @@ -53,10 +53,6 @@ typedef enum _pdq_state_t pdq_state_t; enum _pdq_type_t { PDQ_DEFPA, /* PCI-bus */ - PDQ_DEFEA, /* EISA-bus */ - PDQ_DEFTA, /* TurboChannel */ - PDQ_DEFAA, /* FutureBus+ */ - PDQ_DEFQA /* Q-bus */ }; #if defined(PDQTEST) diff --git a/sys/dev/sdhci/sdhci_acpi.c b/sys/dev/sdhci/sdhci_acpi.c index a0560ecd8467..4f5b2f046683 100644 --- a/sys/dev/sdhci/sdhci_acpi.c +++ b/sys/dev/sdhci/sdhci_acpi.c @@ -60,9 +60,11 @@ static const struct sdhci_acpi_device { const char *desc; u_int quirks; } sdhci_acpi_devices[] = { - { "80860F14", 1, "Intel Bay Trail eMMC 4.5 Controller", + { "80860F14", 1, "Intel Bay Trail SD Host Controller", SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | SDHCI_QUIRK_INTEL_POWER_UP_RESET }, + { "80860F14", 3, "Intel Bay Trail SD Host Controller", + SDHCI_QUIRK_INTEL_POWER_UP_RESET }, { "80860F16", 0, "Intel Bay Trail SD Host Controller", 0 }, { NULL, 0, NULL, 0} diff --git a/sys/dev/usb/controller/ehci_imx.c b/sys/dev/usb/controller/ehci_imx.c index df4d202c38ef..4ebccdfdc30a 100644 --- a/sys/dev/usb/controller/ehci_imx.c +++ b/sys/dev/usb/controller/ehci_imx.c @@ -298,8 +298,9 @@ imx_ehci_attach(device_t dev) * Set flags that affect ehci_init() behavior, and hook our post-reset * code into the standard controller code. */ - esc->sc_flags |= EHCI_SCFLG_NORESTERM; + esc->sc_flags |= EHCI_SCFLG_NORESTERM | EHCI_SCFLG_TT; esc->sc_vendor_post_reset = imx_ehci_post_reset; + esc->sc_vendor_get_port_speed = ehci_get_port_speed_portsc; err = ehci_init(esc); if (err != 0) { diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 37189753012e..9c725d1d293e 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -3473,6 +3473,7 @@ vtnet_update_vlan_filter(struct vtnet_softc *sc, int add, uint16_t tag) sc->vtnet_vlan_filter[idx] &= ~(1 << bit); if (ifp->if_capenable & IFCAP_VLAN_HWFILTER && + ifp->if_drv_flags & IFF_DRV_RUNNING && vtnet_exec_vlan_filter(sc, add, tag) != 0) { device_printf(sc->vtnet_dev, "cannot %s VLAN %d %s the host filter table\n", diff --git a/sys/dev/vt/vt_buf.c b/sys/dev/vt/vt_buf.c index 92da3d26330d..5a7bee55f256 100644 --- a/sys/dev/vt/vt_buf.c +++ b/sys/dev/vt/vt_buf.c @@ -55,10 +55,10 @@ static MALLOC_DEFINE(M_VTBUF, "vtbuf", "vt buffer"); } while (0) #ifndef SC_NO_CUTPASTE +static int vtbuf_htw(const struct vt_buf *vb, int row); static int vtbuf_wth(const struct vt_buf *vb, int row); static int vtbuf_in_this_range(int begin, int test, int end, int sz); #endif -static int vtbuf_htw(const struct vt_buf *vb, int row); /* * line4 @@ -161,6 +161,21 @@ vthistory_getpos(const struct vt_buf *vb, unsigned int *offset) } #ifndef SC_NO_CUTPASTE /* Only mouse support use it now. */ +/* Translate history row to current view row number. */ +static int +vtbuf_htw(const struct vt_buf *vb, int row) +{ + + /* + * total 1000 rows. + * History offset roffset winrow + * 205 200 ((205 - 200 + 1000) % 1000) = 5 + * 90 990 ((90 - 990 + 1000) % 1000) = 100 + */ + return ((row - vb->vb_roffset + vb->vb_history_size) % + vb->vb_history_size); +} + /* Translate current view row number to history row. */ static int vtbuf_wth(const struct vt_buf *vb, int row) @@ -192,21 +207,6 @@ vtbuf_in_this_range(int begin, int test, int end, int sz) } #endif -/* Translate history row to current view row number. */ -static int -vtbuf_htw(const struct vt_buf *vb, int row) -{ - - /* - * total 1000 rows. - * History offset roffset winrow - * 205 200 ((205 - 200 + 1000) % 1000) = 5 - * 90 990 ((90 - 990 + 1000) % 1000) = 100 - */ - return ((row - vb->vb_roffset + vb->vb_history_size) % - vb->vb_history_size); -} - int vtbuf_iscursor(const struct vt_buf *vb, int row, int col) { diff --git a/sys/dev/vx/if_vx_eisa.c b/sys/dev/vx/if_vx_eisa.c deleted file mode 100644 index 2556580c1e5c..000000000000 --- a/sys/dev/vx/if_vx_eisa.c +++ /dev/null @@ -1,193 +0,0 @@ -/*- - * Copyright (C) 1996 Naoki Hamada <nao@tom-yam.or.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. - * 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/kernel.h> -#include <sys/mutex.h> -#include <sys/socket.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/ethernet.h> -#include <net/if.h> -#include <net/if_var.h> - -#include <dev/eisa/eisaconf.h> - -#include <dev/vx/if_vxreg.h> -#include <dev/vx/if_vxvar.h> - -#define EISA_DEVICE_ID_3COM_3C592 0x506d5920 -#define EISA_DEVICE_ID_3COM_3C597_TX 0x506d5970 -#define EISA_DEVICE_ID_3COM_3C597_T4 0x506d5971 -#define EISA_DEVICE_ID_3COM_3C597_MII 0x506d5972 - - -#define VX_EISA_SLOT_OFFSET 0x0c80 -#define VX_EISA_IOSIZE 0x000a -#define VX_RESOURCE_CONFIG 0x0008 - - -static const char *vx_match(eisa_id_t type); - -static const char * -vx_match(eisa_id_t type) -{ - switch (type) { - case EISA_DEVICE_ID_3COM_3C592: - return "3Com 3C592"; - case EISA_DEVICE_ID_3COM_3C597_TX: - return "3Com 3C597-TX"; - case EISA_DEVICE_ID_3COM_3C597_T4: - return "3Com 3C597-T4"; - case EISA_DEVICE_ID_3COM_3C597_MII: - return "3Com 3C597-MII"; - default: - break; - } - return (NULL); -} - -static int -vx_eisa_probe(device_t dev) -{ - const char *desc; - u_long iobase; - u_long port; - - desc = vx_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - port = eisa_get_slot(dev) * EISA_SLOT_SIZE; - iobase = port + VX_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, VX_EISA_IOSIZE, RESVADDR_NONE); - eisa_add_iospace(dev, port, VX_IOSIZE, RESVADDR_NONE); - - /* Set irq */ - eisa_add_intr(dev, inw(iobase + VX_RESOURCE_CONFIG) >> 12, - EISA_TRIGGER_EDGE); - - return (0); -} - -static int -vx_eisa_attach(device_t dev) -{ - struct vx_softc *sc; - struct resource *io = 0; - struct resource *eisa_io = 0; - struct resource *irq = 0; - int rid; - - /* - * The addresses are sorted in increasing order - * so we know the port to pass to the core ep - * driver comes first. - */ - rid = 0; - io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - rid = 1; - eisa_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); - if (!eisa_io) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - sc = device_get_softc(dev); - - sc->vx_res = io; - sc->vx_bst = rman_get_bustag(io); - sc->vx_bsh = rman_get_bushandle(io); - - rid = 0; - irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (!irq) { - device_printf(dev, "No irq?!\n"); - goto bad; - } - sc->vx_irq = irq; - - /* Now the registers are available through the lower ioport */ - - if (vx_attach(dev) == 0) - goto bad; - - if (bus_setup_intr(dev, irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, - vx_intr, sc, &sc->vx_intrhand)) - goto bad_mtx; - - return (0); - -bad_mtx: - mtx_destroy(&sc->vx_mtx); - ether_ifdetach(sc->vx_ifp); - if_free(sc->vx_ifp); -bad: - if (io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - if (eisa_io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io); - if (irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - return (ENXIO); -} - -static device_method_t vx_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, vx_eisa_probe), - DEVMETHOD(device_attach, vx_eisa_attach), - - DEVMETHOD_END -}; - -static driver_t vx_eisa_driver = { - "vx", - vx_eisa_methods, - sizeof(struct vx_softc) -}; - -static devclass_t vx_devclass; - -DRIVER_MODULE(vx, eisa, vx_eisa_driver, vx_devclass, 0, 0); diff --git a/sys/dev/vx/if_vxreg.h b/sys/dev/vx/if_vxreg.h index 08ac4088abac..2960f49f1f50 100644 --- a/sys/dev/vx/if_vxreg.h +++ b/sys/dev/vx/if_vxreg.h @@ -77,8 +77,6 @@ #define EEPROM_MFG_PRODUCT 0x6 /* Product code */ #define EEPROM_MFG_ID 0x7 /* 0x6d50 */ #define EEPROM_ADDR_CFG 0x8 /* Base addr */ -#define ADDR_CFG_EISA 0x1f -#define ADDR_CFG_MASK 0x1f #define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */ #define EEPROM_OEM_ADDR0 0xa #define EEPROM_OEM_ADDR1 0xb @@ -87,8 +85,6 @@ #define EEPROM_COMPAT 0xe #define EEPROM_SOFTINFO2 0xf #define EEPROM_CAP 0x10 -#define CAP_ISA 0x2083 -#define CAP_PCMCIA 0x2082 #define EEPROM_INT_CONFIG_0 0x12 #define EEPROM_INT_CONFIG_1 0x13 /* RAM Partition TX FIFO/RX FIFO */ @@ -112,7 +108,7 @@ /************************************************************************** * These are the registers for the 3Com 3c509 and their bit patterns when * - * applicable. They have been taken out the "EtherLink III Parallel * + * applicable. They have been taken out the "EtherLink III Parallel * * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual * * from 3com. * **************************************************************************/ diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 65726392d08b..e600ff1cea47 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -208,7 +208,7 @@ devfs_newdirent(char *name, int namelen) struct dirent d; d.d_namlen = namelen; - i = sizeof (*de) + GENERIC_DIRSIZ(&d); + i = sizeof(*de) + GENERIC_DIRSIZ(&d); de = malloc(i, M_DEVFS3, M_WAITOK | M_ZERO); de->de_dirent = (struct dirent *)(de + 1); de->de_dirent->d_namlen = namelen; @@ -246,7 +246,8 @@ devfs_parent_dirent(struct devfs_dirent *de) } struct devfs_dirent * -devfs_vmkdir(struct devfs_mount *dmp, char *name, int namelen, struct devfs_dirent *dotdot, u_int inode) +devfs_vmkdir(struct devfs_mount *dmp, char *name, int namelen, + struct devfs_dirent *dotdot, u_int inode) { struct devfs_dirent *dd; struct devfs_dirent *de; diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 03e13d0f7648..e4f25411e2f5 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -693,7 +693,7 @@ devfs_fsync(struct vop_fsync_args *ap) error = vop_stdfsync(ap); if (bo->bo_dirty.bv_cnt != 0 || error != 0) - panic("devfs_fsync: vop_stdfsync failed."); + printf("devfs_fsync: vop_stdfsync failed."); } return (0); diff --git a/sys/fs/ext2fs/ext2_alloc.c b/sys/fs/ext2fs/ext2_alloc.c index 6510a0a8ab83..46f160846981 100644 --- a/sys/fs/ext2fs/ext2_alloc.c +++ b/sys/fs/ext2fs/ext2_alloc.c @@ -167,7 +167,7 @@ ext2_reallocblks(struct vop_reallocblks_args *ap) uint32_t *bap, *sbap, *ebap; struct ext2mount *ump; struct cluster_save *buflist; - struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; + struct indir start_ap[EXT2_NIADDR + 1], end_ap[EXT2_NIADDR + 1], *idp; e2fs_lbn_t start_lbn, end_lbn; int soff; e2fs_daddr_t newblk, blkno; @@ -203,7 +203,7 @@ ext2_reallocblks(struct vop_reallocblks_args *ap) * this for other indirect block boundaries, but it is only * important for the first one. */ - if (start_lbn < NDADDR && end_lbn >= NDADDR) + if (start_lbn < EXT2_NDADDR && end_lbn >= EXT2_NDADDR) return (ENOSPC); /* * If the latest allocation is in a new cylinder group, assume that @@ -403,9 +403,9 @@ ext2_valloc(struct vnode *pvp, int mode, struct ucred *cred, struct vnode **vpp) ip->i_mode = 0; ip->i_flags = 0; /* now we want to make sure that the block pointers are zeroed out */ - for (i = 0; i < NDADDR; i++) + for (i = 0; i < EXT2_NDADDR; i++) ip->i_db[i] = 0; - for (i = 0; i < NIADDR; i++) + for (i = 0; i < EXT2_NIADDR; i++) ip->i_ib[i] = 0; /* diff --git a/sys/fs/ext2fs/ext2_balloc.c b/sys/fs/ext2fs/ext2_balloc.c index fcfccc2f6d53..d45791e22cde 100644 --- a/sys/fs/ext2fs/ext2_balloc.c +++ b/sys/fs/ext2fs/ext2_balloc.c @@ -64,7 +64,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, struct ext2mount *ump; struct buf *bp, *nbp; struct vnode *vp = ITOV(ip); - struct indir indirs[NIADDR + 2]; + struct indir indirs[EXT2_NIADDR + 2]; e4fs_daddr_t nb, newb; e2fs_daddr_t *bap, pref; int osize, nsize, num, i, error; @@ -85,9 +85,9 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred, ip->i_next_alloc_goal++; } /* - * The first NDADDR blocks are direct blocks + * The first EXT2_NDADDR blocks are direct blocks */ - if (lbn < NDADDR) { + if (lbn < EXT2_NDADDR) { nb = ip->i_db[lbn]; /* * no new block is to be allocated, and no need to expand diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c index 480f423fb3bb..ea28bb05b5ff 100644 --- a/sys/fs/ext2fs/ext2_bmap.c +++ b/sys/fs/ext2fs/ext2_bmap.c @@ -163,7 +163,7 @@ ext2_bmaparray(struct vnode *vp, daddr_t bn, daddr_t *bnp, int *runp, int *runb) struct buf *bp; struct ext2mount *ump; struct mount *mp; - struct indir a[NIADDR + 1], *ap; + struct indir a[EXT2_NIADDR + 1], *ap; daddr_t daddr; e2fs_lbn_t metalbn; int error, num, maxrun = 0, bsize; @@ -198,7 +198,7 @@ ext2_bmaparray(struct vnode *vp, daddr_t bn, daddr_t *bnp, int *runp, int *runb) } else if (runp) { daddr_t bnb = bn; - for (++bn; bn < NDADDR && *runp < maxrun && + for (++bn; bn < EXT2_NDADDR && *runp < maxrun && is_sequential(ump, ip->i_db[bn - 1], ip->i_db[bn]); ++bn, ++*runp); bn = bnb; @@ -325,17 +325,18 @@ ext2_getlbns(struct vnode *vp, daddr_t bn, struct indir *ap, int *nump) if ((long)bn < 0) bn = -(long)bn; - /* The first NDADDR blocks are direct blocks. */ - if (bn < NDADDR) + /* The first EXT2_NDADDR blocks are direct blocks. */ + if (bn < EXT2_NDADDR) return (0); /* * Determine the number of levels of indirection. After this loop * is done, blockcnt indicates the number of data blocks possible - * at the previous level of indirection, and NIADDR - i is the number - * of levels of indirection needed to locate the requested block. + * at the previous level of indirection, and EXT2_NIADDR - i is the + * number of levels of indirection needed to locate the requested block. */ - for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { + for (blockcnt = 1, i = EXT2_NIADDR, bn -= EXT2_NDADDR; ; + i--, bn -= blockcnt) { if (i == 0) return (EFBIG); /* @@ -351,9 +352,9 @@ ext2_getlbns(struct vnode *vp, daddr_t bn, struct indir *ap, int *nump) /* Calculate the address of the first meta-block. */ if (realbn >= 0) - metalbn = -(realbn - bn + NIADDR - i); + metalbn = -(realbn - bn + EXT2_NIADDR - i); else - metalbn = -(-realbn - bn + NIADDR - i); + metalbn = -(-realbn - bn + EXT2_NIADDR - i); /* * At each iteration, off is the offset into the bap array which is @@ -362,9 +363,9 @@ ext2_getlbns(struct vnode *vp, daddr_t bn, struct indir *ap, int *nump) * into the argument array. */ ap->in_lbn = metalbn; - ap->in_off = off = NIADDR - i; + ap->in_off = off = EXT2_NIADDR - i; ap++; - for (++numlevels; i <= NIADDR; i++) { + for (++numlevels; i <= EXT2_NIADDR; i++) { /* If searching for a meta-data block, quit when found. */ if (metalbn == realbn) break; diff --git a/sys/fs/ext2fs/ext2_inode.c b/sys/fs/ext2fs/ext2_inode.c index 914dab97cd3b..44e9295c6263 100644 --- a/sys/fs/ext2fs/ext2_inode.c +++ b/sys/fs/ext2fs/ext2_inode.c @@ -113,8 +113,9 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, struct vnode *ovp = vp; int32_t lastblock; struct inode *oip; - int32_t bn, lbn, lastiblock[NIADDR], indir_lbn[NIADDR]; - uint32_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR]; + int32_t bn, lbn, lastiblock[EXT2_NIADDR], indir_lbn[EXT2_NIADDR]; + uint32_t oldblks[EXT2_NDADDR + EXT2_NIADDR]; + uint32_t newblks[EXT2_NDADDR + EXT2_NIADDR]; struct m_ext2fs *fs; struct buf *bp; int offset, size, level; @@ -218,7 +219,7 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, * the file is truncated to 0. */ lastblock = lblkno(fs, length + fs->e2fs_bsize - 1) - 1; - lastiblock[SINGLE] = lastblock - NDADDR; + lastiblock[SINGLE] = lastblock - EXT2_NDADDR; lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); nblocks = btodb(fs->e2fs_bsize); @@ -229,13 +230,13 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, * normalized to -1 for calls to ext2_indirtrunc below. */ for (level = TRIPLE; level >= SINGLE; level--) { - oldblks[NDADDR + level] = oip->i_ib[level]; + oldblks[EXT2_NDADDR + level] = oip->i_ib[level]; if (lastiblock[level] < 0) { oip->i_ib[level] = 0; lastiblock[level] = -1; } } - for (i = 0; i < NDADDR; i++) { + for (i = 0; i < EXT2_NDADDR; i++) { oldblks[i] = oip->i_db[i]; if (i > lastblock) oip->i_db[i] = 0; @@ -249,13 +250,13 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, * Note that we save the new block configuration so we can check it * when we are done. */ - for (i = 0; i < NDADDR; i++) { + for (i = 0; i < EXT2_NDADDR; i++) { newblks[i] = oip->i_db[i]; oip->i_db[i] = oldblks[i]; } - for (i = 0; i < NIADDR; i++) { - newblks[NDADDR + i] = oip->i_ib[i]; - oip->i_ib[i] = oldblks[NDADDR + i]; + for (i = 0; i < EXT2_NIADDR; i++) { + newblks[EXT2_NDADDR + i] = oip->i_ib[i]; + oip->i_ib[i] = oldblks[EXT2_NDADDR + i]; } oip->i_size = osize; error = vtruncbuf(ovp, cred, length, (int)fs->e2fs_bsize); @@ -266,7 +267,7 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, /* * Indirect blocks first. */ - indir_lbn[SINGLE] = -NDADDR; + indir_lbn[SINGLE] = -EXT2_NDADDR; indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; for (level = TRIPLE; level >= SINGLE; level--) { @@ -290,7 +291,7 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, /* * All whole direct blocks or frags. */ - for (i = NDADDR - 1; i > lastblock; i--) { + for (i = EXT2_NDADDR - 1; i > lastblock; i--) { long bsize; bn = oip->i_db[i]; @@ -335,9 +336,9 @@ ext2_truncate(struct vnode *vp, off_t length, int flags, struct ucred *cred, done: #ifdef INVARIANTS for (level = SINGLE; level <= TRIPLE; level++) - if (newblks[NDADDR + level] != oip->i_ib[level]) + if (newblks[EXT2_NDADDR + level] != oip->i_ib[level]) panic("itrunc1"); - for (i = 0; i < NDADDR; i++) + for (i = 0; i < EXT2_NDADDR; i++) if (newblks[i] != oip->i_db[i]) panic("itrunc2"); BO_LOCK(bo); diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 4ae6b37fc21d..988f0f85a912 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -123,9 +123,9 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) ip->i_uid = ei->e2di_uid; ip->i_gid = ei->e2di_gid; /* XXX use memcpy */ - for (i = 0; i < NDADDR; i++) + for (i = 0; i < EXT2_NDADDR; i++) ip->i_db[i] = ei->e2di_blocks[i]; - for (i = 0; i < NIADDR; i++) + for (i = 0; i < EXT2_NIADDR; i++) ip->i_ib[i] = ei->e2di_blocks[EXT2_NDIR_BLOCKS + i]; } @@ -169,8 +169,8 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) ei->e2di_uid = ip->i_uid; ei->e2di_gid = ip->i_gid; /* XXX use memcpy */ - for (i = 0; i < NDADDR; i++) + for (i = 0; i < EXT2_NDADDR; i++) ei->e2di_blocks[i] = ip->i_db[i]; - for (i = 0; i < NIADDR; i++) + for (i = 0; i < EXT2_NIADDR; i++) ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i]; } diff --git a/sys/fs/ext2fs/inode.h b/sys/fs/ext2fs/inode.h index 2bc019cd443b..4f64c35f2a18 100644 --- a/sys/fs/ext2fs/inode.h +++ b/sys/fs/ext2fs/inode.h @@ -50,8 +50,8 @@ */ #define doff_t int32_t -#define NDADDR 12 /* Direct addresses in inode. */ -#define NIADDR 3 /* Indirect addresses in inode. */ +#define EXT2_NDADDR 12 /* Direct addresses in inode. */ +#define EXT2_NIADDR 3 /* Indirect addresses in inode. */ /* * The size of physical and logical block numbers in EXT2FS. @@ -106,8 +106,8 @@ struct inode { int32_t i_birthnsec; /* Inode creation time. */ uint32_t i_gen; /* Generation number. */ uint32_t i_flags; /* Status flags (chflags). */ - uint32_t i_db[NDADDR]; /* Direct disk blocks. */ - uint32_t i_ib[NIADDR]; /* Indirect disk blocks. */ + uint32_t i_db[EXT2_NDADDR]; /* Direct disk blocks. */ + uint32_t i_ib[EXT2_NIADDR]; /* Indirect disk blocks. */ struct ext4_extent_cache i_ext_cache; /* cache for ext4 extent */ }; diff --git a/sys/fs/nandfs/bmap.c b/sys/fs/nandfs/bmap.c index 35f943565d12..d92546bd37e7 100644 --- a/sys/fs/nandfs/bmap.c +++ b/sys/fs/nandfs/bmap.c @@ -67,7 +67,7 @@ int bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) { struct nandfs_inode *ip; - struct nandfs_indir a[NIADDR + 1], *ap; + struct nandfs_indir a[NANDFS_NIADDR + 1], *ap; nandfs_daddr_t daddr; struct buf *bp; int error; @@ -129,7 +129,7 @@ bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) int bmap_dirty_meta(struct nandfs_node *node, nandfs_lbn_t lblk, int force) { - struct nandfs_indir a[NIADDR+1], *ap; + struct nandfs_indir a[NANDFS_NIADDR+1], *ap; #ifdef DEBUG nandfs_daddr_t daddr; #endif @@ -179,7 +179,7 @@ bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t vblk) { struct nandfs_inode *ip; - struct nandfs_indir a[NIADDR+1], *ap; + struct nandfs_indir a[NANDFS_NIADDR+1], *ap; struct buf *bp; nandfs_daddr_t daddr; int error; @@ -267,7 +267,7 @@ bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, return (error); } -CTASSERT(NIADDR <= 3); +CTASSERT(NANDFS_NIADDR <= 3); #define SINGLE 0 /* index of single indirect block */ #define DOUBLE 1 /* index of double indirect block */ #define TRIPLE 2 /* index of triple indirect block */ @@ -399,8 +399,8 @@ bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk, nandfs_lbn_t todo) { struct nandfs_inode *ip; - struct nandfs_indir a[NIADDR + 1], f[NIADDR], *ap; - nandfs_daddr_t indir_lbn[NIADDR]; + struct nandfs_indir a[NANDFS_NIADDR + 1], f[NANDFS_NIADDR], *ap; + nandfs_daddr_t indir_lbn[NANDFS_NIADDR]; nandfs_daddr_t *copy; int error, level; nandfs_lbn_t left, tosub; @@ -421,12 +421,12 @@ bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk, if (error) return (error); - indir_lbn[SINGLE] = -NDADDR; + indir_lbn[SINGLE] = -NANDFS_NDADDR; indir_lbn[DOUBLE] = indir_lbn[SINGLE] - MNINDIR(fsdev) - 1; indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - MNINDIR(fsdev) * MNINDIR(fsdev) - 1; - for (i = 0; i < NIADDR; i++) { + for (i = 0; i < NANDFS_NIADDR; i++) { f[i].in_off = MNINDIR(fsdev) - 1; f[i].in_lbn = 0xdeadbeef; } @@ -482,7 +482,7 @@ direct: if (num < 0) i = lastblk; else - i = NDADDR - 1; + i = NANDFS_NDADDR - 1; for (; i >= 0 && left > 0; i--) { if (ip->i_db[i] != 0) { @@ -508,13 +508,13 @@ direct: nandfs_lbn_t get_maxfilesize(struct nandfs_device *fsdev) { - struct nandfs_indir f[NIADDR]; + struct nandfs_indir f[NANDFS_NIADDR]; nandfs_lbn_t max; int i; - max = NDADDR; + max = NANDFS_NDADDR; - for (i = 0; i < NIADDR; i++) { + for (i = 0; i < NANDFS_NIADDR; i++) { f[i].in_off = MNINDIR(fsdev) - 1; max += blocks_inside(fsdev, i, f); } @@ -557,17 +557,17 @@ bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, if (bn < 0) bn = -bn; - /* The first NDADDR blocks are direct blocks. */ - if (bn < NDADDR) + /* The first NANDFS_NDADDR blocks are direct blocks. */ + if (bn < NANDFS_NDADDR) return (0); /* * Determine the number of levels of indirection. After this loop * is done, blockcnt indicates the number of data blocks possible - * at the previous level of indirection, and NIADDR - i is the number - * of levels of indirection needed to locate the requested block. + * at the previous level of indirection, and NANDFS_NIADDR - i is the + * number of levels of indirection needed to locate the requested block. */ - for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { + for (blockcnt = 1, i = NANDFS_NIADDR, bn -= NANDFS_NDADDR;; i--, bn -= blockcnt) { DPRINTF(BMAP, ("%s: blockcnt=%jd i=%d bn=%jd\n", __func__, blockcnt, i, bn)); if (i == 0) @@ -579,9 +579,9 @@ bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, /* Calculate the address of the first meta-block. */ if (realbn >= 0) - metalbn = -(realbn - bn + NIADDR - i); + metalbn = -(realbn - bn + NANDFS_NIADDR - i); else - metalbn = -(-realbn - bn + NIADDR - i); + metalbn = -(-realbn - bn + NANDFS_NIADDR - i); /* * At each iteration, off is the offset into the bap array which is @@ -590,13 +590,13 @@ bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, * into the argument array. */ ap->in_lbn = metalbn; - ap->in_off = off = NIADDR - i; + ap->in_off = off = NANDFS_NIADDR - i; DPRINTF(BMAP, ("%s: initial: ap->in_lbn=%jx ap->in_off=%d\n", __func__, metalbn, off)); ap++; - for (++numlevels; i <= NIADDR; i++) { + for (++numlevels; i <= NANDFS_NIADDR; i++) { /* If searching for a meta-data block, quit when found. */ if (metalbn == realbn) break; diff --git a/sys/fs/nandfs/nandfs_fs.h b/sys/fs/nandfs/nandfs_fs.h index a0d060d30903..3e23d7729993 100644 --- a/sys/fs/nandfs/nandfs_fs.h +++ b/sys/fs/nandfs/nandfs_fs.h @@ -56,8 +56,8 @@ #define NANDFS_SYS_NODE(ino) \ (((ino) >= NANDFS_DAT_INO) && ((ino) <= NANDFS_GC_INO)) -#define NDADDR 12 /* Direct addresses in inode. */ -#define NIADDR 3 /* Indirect addresses in inode. */ +#define NANDFS_NDADDR 12 /* Direct addresses in inode. */ +#define NANDFS_NIADDR 3 /* Indirect addresses in inode. */ typedef int64_t nandfs_daddr_t; typedef int64_t nandfs_lbn_t; @@ -75,8 +75,8 @@ struct nandfs_inode { uint16_t i_links_count; /* 50: number of references to the inode*/ uint32_t i_flags; /* 52: NANDFS_*_FL flags */ nandfs_daddr_t i_special; /* 56: special */ - nandfs_daddr_t i_db[NDADDR]; /* 64: Direct disk blocks. */ - nandfs_daddr_t i_ib[NIADDR]; /* 160: Indirect disk blocks. */ + nandfs_daddr_t i_db[NANDFS_NDADDR]; /* 64: Direct disk blocks. */ + nandfs_daddr_t i_ib[NANDFS_NIADDR]; /* 160: Indirect disk blocks. */ uint64_t i_xattr; /* 184: reserved for extended attributes*/ uint32_t i_generation; /* 192: file generation for NFS */ uint32_t i_pad[15]; /* 196: make it 64 bits aligned */ diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 07c8b8686e1e..a7cedaf911eb 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -749,8 +749,7 @@ static int nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, struct sockaddr_in **sinp, char *dirpath, size_t dirpathsize, int *dirlenp) { - char nam[MNAMELEN + 1]; - char *delimp, *hostp, *spec; + char *nam, *delimp, *hostp, *spec; int error, have_bracket = 0, offset, rv, speclen; struct sockaddr_in *sin; size_t len; @@ -758,6 +757,7 @@ nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, error = vfs_getopt(opts, "from", (void **)&spec, &speclen); if (error != 0) return (error); + nam = malloc(MNAMELEN + 1, M_TEMP, M_WAITOK); /* * This part comes from sbin/mount_nfs/mount_nfs.c:getnfsargs(). @@ -776,6 +776,7 @@ nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, hostp = delimp + 1; } else { printf("%s: no <host>:<dirpath> nfs-name\n", __func__); + free(nam, M_TEMP); return (EINVAL); } *delimp = '\0'; @@ -791,6 +792,7 @@ nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, spec[speclen - 1] = '\0'; if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) { printf("%s: %s:%s: name too long", __func__, hostp, spec); + free(nam, M_TEMP); return (EINVAL); } /* Make both '@' and ':' notations equal */ @@ -816,6 +818,7 @@ nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, if (rv != 1) { printf("%s: cannot parse '%s', inet_pton() returned %d\n", __func__, hostp, rv); + free(nam, M_TEMP); free(sin, M_SONAME); return (EINVAL); } @@ -832,6 +835,7 @@ nfs_mount_parse_from(struct vfsoptlist *opts, char **hostnamep, strlcpy(dirpath, spec, dirpathsize); *dirlenp = strlen(dirpath); + free(nam, M_TEMP); return (0); } @@ -874,7 +878,7 @@ nfs_mount(struct mount *mp) struct sockaddr *nam = NULL; struct vnode *vp; struct thread *td; - char hst[MNAMELEN]; + char *hst; u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; char *cp, *opt, *name, *secname; int nametimeo = NFS_DEFAULT_NAMETIMEO; @@ -886,6 +890,7 @@ nfs_mount(struct mount *mp) has_nfs_args_opt = 0; has_nfs_from_opt = 0; + hst = malloc(MNAMELEN, M_TEMP, M_WAITOK); if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; goto out; @@ -1265,8 +1270,13 @@ nfs_mount(struct mount *mp) error = EINVAL; goto out; } - bcopy(args.hostname, hst, MNAMELEN); - hst[MNAMELEN - 1] = '\0'; + if (len >= MNAMELEN) { + vfs_mount_error(mp, "Hostname too long"); + error = EINVAL; + goto out; + } + bcopy(args.hostname, hst, len); + hst[len] = '\0'; } if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0) @@ -1324,6 +1334,7 @@ out: mp->mnt_kern_flag |= MNTK_NULL_NOCACHE; MNT_IUNLOCK(mp); } + free(hst, M_TEMP); return (error); } @@ -1541,7 +1552,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, * traversals of the mount point (i.e. "..") will not work if * the nfsnode gets flushed out of the cache. Ufs does not have * this problem, because one can identify root inodes by their - * number == ROOTINO (2). + * number == UFS_ROOTINO (2). */ if (nmp->nm_fhsize > 0) { /* diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index e5ad4ab83cf9..3c6d0b3ffba7 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -174,7 +174,11 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) if (port >= IPPORT_RESERVED && nd.nd_procnum != NFSPROC_NULL) { #ifdef INET6 - char b6[INET6_ADDRSTRLEN]; + char buf[INET6_ADDRSTRLEN]; +#else + char buf[INET_ADDRSTRLEN]; +#endif +#ifdef INET6 #if defined(KLD_MODULE) /* Do not use ip6_sprintf: the nfs module should work without INET6. */ #define ip6_sprintf(buf, a) \ @@ -189,12 +193,12 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) printf("NFS request from unprivileged port (%s:%d)\n", #ifdef INET6 sin->sin_family == AF_INET6 ? - ip6_sprintf(b6, &satosin6(sin)->sin6_addr) : + ip6_sprintf(buf, &satosin6(sin)->sin6_addr) : #if defined(KLD_MODULE) #undef ip6_sprintf #endif #endif - inet_ntoa(sin->sin_addr), port); + inet_ntoa_r(sin->sin_addr, buf), port); svcerr_weakauth(rqst); svc_freereq(rqst); m_freem(nd.nd_mrep); @@ -551,18 +555,16 @@ nfsrvd_init(int terminating) nfsd_master_proc = NULL; NFSD_UNLOCK(); nfsrv_freeallbackchannel_xprts(); - svcpool_destroy(nfsrvd_pool); - nfsrvd_pool = NULL; + svcpool_close(nfsrvd_pool); + NFSD_LOCK(); + } else { + NFSD_UNLOCK(); + nfsrvd_pool = svcpool_create("nfsd", + SYSCTL_STATIC_CHILDREN(_vfs_nfsd)); + nfsrvd_pool->sp_rcache = NULL; + nfsrvd_pool->sp_assign = fhanew_assign; + nfsrvd_pool->sp_done = fha_nd_complete; NFSD_LOCK(); } - - NFSD_UNLOCK(); - - nfsrvd_pool = svcpool_create("nfsd", SYSCTL_STATIC_CHILDREN(_vfs_nfsd)); - nfsrvd_pool->sp_rcache = NULL; - nfsrvd_pool->sp_assign = fhanew_assign; - nfsrvd_pool->sp_done = fha_nd_complete; - - NFSD_LOCK(); } diff --git a/sys/i386/bios/mca_machdep.c b/sys/i386/bios/mca_machdep.c deleted file mode 100644 index e511f3ff786c..000000000000 --- a/sys/i386/bios/mca_machdep.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> -#include <machine/md_var.h> -#include <machine/vm86.h> -#include <machine/pc/bios.h> -#include <machine/cpufunc.h> - -#include <dev/mca/mca_busreg.h> -#include <i386/bios/mca_machdep.h> - -/* Global MCA bus flag */ -int MCA_system = 0; - -/* System Configuration Block */ -struct sys_config { - u_int16_t count; - u_int8_t model; - u_int8_t submodel; - u_int8_t bios_rev; - u_int8_t feature; -#define FEATURE_MCAISA 0x01 /* Machine contains both MCA and ISA bus*/ -#define FEATURE_MCABUS 0x02 /* MicroChannel Architecture */ -#define FEATURE_EBDA 0x04 /* Extended BIOS data area allocated */ -#define FEATURE_WAITEV 0x08 /* Wait for external event is supported */ -#define FEATURE_KBDINT 0x10 /* Keyboard intercept called by Int 09h */ -#define FEATURE_RTC 0x20 /* Real-time clock present */ -#define FEATURE_IC2 0x40 /* Second interrupt chip present */ -#define FEATURE_DMA3 0x80 /* DMA channel 3 used by hard disk BIOS */ - u_int8_t pad[3]; -} __packed; - -/* Function Prototypes */ -static void bios_mcabus_present (void *); -SYSINIT(mca_present, SI_SUB_CPU, SI_ORDER_ANY, bios_mcabus_present, NULL); - -/* Functions */ -static void -bios_mcabus_present(void * dummy) -{ - struct vm86frame vmf; - struct sys_config * scp; - vm_offset_t paddr; - - bzero(&vmf, sizeof(struct vm86frame)); - - vmf.vmf_ah = 0xc0; - if (vm86_intcall(0x15, &vmf)) { - if (bootverbose) { - printf("BIOS SDT: INT call failed.\n"); - } - return; - } - - if ((vmf.vmf_ah != 0) && (vmf.vmf_flags & 0x01)) { - if (bootverbose) { - printf("BIOS SDT: Not supported. Not PS/2?\n"); - printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n", - vmf.vmf_ah, vmf.vmf_flags); - } - return; - } - - paddr = vmf.vmf_es; - paddr = (paddr << 4) + vmf.vmf_bx; - scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr); - - if (bootverbose) { - printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n", - scp->model, scp->submodel, scp->bios_rev); - printf("BIOS SDT: features 0x%b\n", scp->feature, - "\20" - "\01MCA+ISA" - "\02MCA" - "\03EBDA" - "\04WAITEV" - "\05KBDINT" - "\06RTC" - "\07IC2" - "\08DMA3" - "\n"); - } - - MCA_system = ((scp->feature & FEATURE_MCABUS) ? 1 : 0); - - if (MCA_system) - printf("MicroChannel Architecture System detected.\n"); - - return; -} - -int -mca_bus_nmi (void) -{ - int slot; - int retval = 0; - int pos5 = 0; - - /* Disable motherboard setup */ - outb(MCA_MB_SETUP_REG, MCA_MB_SETUP_DIS); - - /* For each slot */ - for (slot = 0; slot < MCA_MAX_SLOTS; slot++) { - - /* Select the slot */ - outb(MCA_ADAP_SETUP_REG, slot | MCA_ADAP_SET); - pos5 = inb(MCA_POS_REG(MCA_POS5)); - - /* If Adapter Check is low */ - if ((pos5 & MCA_POS5_CHCK) == 0) { - retval++; - - /* If Adapter Check Status is available */ - if ((pos5 & MCA_POS5_CHCK_STAT) == 0) { - printf("MCA NMI: slot %d, POS6=0x%02x, POS7=0x%02x\n", - slot+1, - inb( MCA_POS_REG(MCA_POS6) ), - inb( MCA_POS_REG(MCA_POS7) )); - } else { - printf("MCA NMI: slot %d\n", slot+1); - } - } - /* Disable adapter setup */ - outb(MCA_ADAP_SETUP_REG, MCA_ADAP_SETUP_DIS); - } - - return (retval); -} diff --git a/sys/i386/bios/mca_machdep.h b/sys/i386/bios/mca_machdep.h deleted file mode 100644 index c639b5b74044..000000000000 --- a/sys/i386/bios/mca_machdep.h +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -extern int MCA_system; - -extern int mca_bus_nmi (void); diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index ff2495d1e4c7..a81350e079b7 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -337,31 +337,6 @@ options MAXMEM=(128*1024) #options BROKEN_KEYBOARD_RESET # -# EISA bus -# -# The EISA bus device is `eisa'. It provides auto-detection and -# configuration support for all devices on the EISA bus. - -device eisa - -# By default, only 10 EISA slots are probed, since the slot numbers -# above clash with the configuration address space of the PCI subsystem, -# and the EISA probe is not very smart about this. This is sufficient -# for most machines, but in particular the HP NetServer LC series comes -# with an onboard AIC7770 dual-channel SCSI controller on EISA slot #11, -# thus you need to bump this figure to 12 for them. -options EISA_SLOTS=12 - -# -# MCA bus: -# -# The MCA bus device is `mca'. It provides auto-detection and -# configuration support for all devices on the MCA bus. -# No hints are required for MCA. - -device mca - -# # AGP GART support device agp diff --git a/sys/i386/i386/i686_mem.c b/sys/i386/i386/i686_mem.c index a7b8166324a8..03e5b179239c 100644 --- a/sys/i386/i386/i686_mem.c +++ b/sys/i386/i386/i686_mem.c @@ -588,6 +588,10 @@ i686_mrinit(struct mem_range_softc *sc) u_int regs[4]; int i, nmdesc = 0, pabits; + if (sc->mr_desc != NULL) + /* Already initialized. */ + return; + mtrrcap = rdmsr(MSR_MTRRcap); mtrrdef = rdmsr(MSR_MTRRdefType); @@ -716,5 +720,6 @@ i686_mem_drvinit(void *unused) return; } mem_range_softc.mr_op = &i686_mrops; + i686_mrinit(&mem_range_softc); } -SYSINIT(i686memdev, SI_SUB_DRIVERS, SI_ORDER_FIRST, i686_mem_drvinit, NULL); +SYSINIT(i686memdev, SI_SUB_CPU, SI_ORDER_ANY, i686_mem_drvinit, NULL); diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c index 5b10914fe036..98f7ae0b40c4 100644 --- a/sys/kern/kern_condvar.c +++ b/sys/kern/kern_condvar.c @@ -122,7 +122,7 @@ _cv_wait(struct cv *cvp, struct lock_object *lock) "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return; sleepq_lock(cvp); @@ -176,7 +176,7 @@ _cv_wait_unlock(struct cv *cvp, struct lock_object *lock) ("cv_wait_unlock cannot be used with Giant")); class = LOCK_CLASS(lock); - if (SCHEDULER_STOPPED()) { + if (SCHEDULER_STOPPED_TD(td)) { class->lc_unlock(lock); return; } @@ -227,7 +227,7 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock) "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return (0); sleepq_lock(cvp); @@ -287,7 +287,7 @@ _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return (0); sleepq_lock(cvp); @@ -349,7 +349,7 @@ _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return (0); sleepq_lock(cvp); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index b83e5809912b..7b5b0786deca 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1320,6 +1320,7 @@ err_exit: struct exec_args_kva { vm_offset_t addr; + u_int gen; SLIST_ENTRY(exec_args_kva) next; }; @@ -1327,6 +1328,7 @@ static DPCPU_DEFINE(struct exec_args_kva *, exec_args_kva); static SLIST_HEAD(, exec_args_kva) exec_args_kva_freelist; static struct mtx exec_args_kva_mtx; +static u_int exec_args_gen; static void exec_prealloc_args_kva(void *arg __unused) @@ -1339,6 +1341,7 @@ exec_prealloc_args_kva(void *arg __unused) for (i = 0; i < exec_map_entries; i++) { argkva = malloc(sizeof(*argkva), M_PARGS, M_WAITOK); argkva->addr = kmap_alloc_wait(exec_map, exec_map_entry_size); + argkva->gen = exec_args_gen; SLIST_INSERT_HEAD(&exec_args_kva_freelist, argkva, next); } } @@ -1364,15 +1367,16 @@ exec_alloc_args_kva(void **cookie) } static void -exec_free_args_kva(void *cookie) +exec_release_args_kva(struct exec_args_kva *argkva, u_int gen) { - struct exec_args_kva *argkva; vm_offset_t base; - argkva = cookie; base = argkva->addr; - - vm_map_madvise(exec_map, base, base + exec_map_entry_size, MADV_FREE); + if (argkva->gen != gen) { + vm_map_madvise(exec_map, base, base + exec_map_entry_size, + MADV_FREE); + argkva->gen = gen; + } if (!atomic_cmpset_ptr((uintptr_t *)DPCPU_PTR(exec_args_kva), (uintptr_t)NULL, (uintptr_t)argkva)) { mtx_lock(&exec_args_kva_mtx); @@ -1382,6 +1386,46 @@ exec_free_args_kva(void *cookie) } } +static void +exec_free_args_kva(void *cookie) +{ + + exec_release_args_kva(cookie, exec_args_gen); +} + +static void +exec_args_kva_lowmem(void *arg __unused) +{ + SLIST_HEAD(, exec_args_kva) head; + struct exec_args_kva *argkva; + u_int gen; + int i; + + gen = atomic_fetchadd_int(&exec_args_gen, 1) + 1; + + /* + * Force an madvise of each KVA range. Any currently allocated ranges + * will have MADV_FREE applied once they are freed. + */ + SLIST_INIT(&head); + mtx_lock(&exec_args_kva_mtx); + SLIST_SWAP(&head, &exec_args_kva_freelist, exec_args_kva); + mtx_unlock(&exec_args_kva_mtx); + while ((argkva = SLIST_FIRST(&head)) != NULL) { + SLIST_REMOVE_HEAD(&head, next); + exec_release_args_kva(argkva, gen); + } + + CPU_FOREACH(i) { + argkva = (void *)atomic_readandclear_ptr( + (uintptr_t *)DPCPU_ID_PTR(i, exec_args_kva)); + if (argkva != NULL) + exec_release_args_kva(argkva, gen); + } +} +EVENTHANDLER_DEFINE(vm_lowmem, exec_args_kva_lowmem, NULL, + EVENTHANDLER_PRI_ANY); + /* * Allocate temporary demand-paged, zero-filled memory for the file name, * argument, and environment strings. diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index a1734e1da0d7..1197a7519eda 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3999,6 +3999,9 @@ db_show_prison(struct prison *pr) int ii; #endif unsigned jsf; +#ifdef INET + char ip4buf[INET_ADDRSTRLEN]; +#endif #ifdef INET6 char ip6buf[INET6_ADDRSTRLEN]; #endif @@ -4050,7 +4053,7 @@ db_show_prison(struct prison *pr) for (ii = 0; ii < pr->pr_ip4s; ii++) db_printf(" %s %s\n", ii == 0 ? "ip4.addr =" : " ", - inet_ntoa(pr->pr_ip4[ii])); + inet_ntoa_r(pr->pr_ip4[ii], ip4buf)); #endif #ifdef INET6 db_printf(" ip6s = %d\n", pr->pr_ip6s); diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 1b10623519f9..13a8ca9cff27 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -168,6 +168,72 @@ SYSCTL_UINT(_debug_lockmgr, OID_AUTO, retries, CTLFLAG_RW, &alk_retries, 0, ""); SYSCTL_UINT(_debug_lockmgr, OID_AUTO, loops, CTLFLAG_RW, &alk_loops, 0, ""); #endif +static bool __always_inline lockmgr_slock_try(struct lock *lk, uintptr_t *xp, + int flags); +static bool __always_inline lockmgr_sunlock_try(struct lock *lk, uintptr_t x); + +static void +lockmgr_note_shared_acquire(struct lock *lk, int contested, + uint64_t waittime, const char *file, int line, int flags) +{ + + lock_profile_obtain_lock_success(&lk->lock_object, contested, waittime, + file, line); + LOCK_LOG_LOCK("SLOCK", &lk->lock_object, 0, 0, file, line); + WITNESS_LOCK(&lk->lock_object, LK_TRYWIT(flags), file, line); + TD_LOCKS_INC(curthread); + TD_SLOCKS_INC(curthread); + STACK_SAVE(lk); +} + +static void +lockmgr_note_shared_release(struct lock *lk, const char *file, int line) +{ + + lock_profile_release_lock(&lk->lock_object); + WITNESS_UNLOCK(&lk->lock_object, 0, file, line); + LOCK_LOG_LOCK("SUNLOCK", &lk->lock_object, 0, 0, file, line); + TD_LOCKS_DEC(curthread); + TD_SLOCKS_DEC(curthread); +} + +static void +lockmgr_note_exclusive_acquire(struct lock *lk, int contested, + uint64_t waittime, const char *file, int line, int flags) +{ + + lock_profile_obtain_lock_success(&lk->lock_object, contested, waittime, + file, line); + LOCK_LOG_LOCK("XLOCK", &lk->lock_object, 0, lk->lk_recurse, file, line); + WITNESS_LOCK(&lk->lock_object, LOP_EXCLUSIVE | LK_TRYWIT(flags), file, + line); + TD_LOCKS_INC(curthread); + STACK_SAVE(lk); +} + +static void +lockmgr_note_exclusive_release(struct lock *lk, const char *file, int line) +{ + + lock_profile_release_lock(&lk->lock_object); + LOCK_LOG_LOCK("XUNLOCK", &lk->lock_object, 0, lk->lk_recurse, file, + line); + WITNESS_UNLOCK(&lk->lock_object, LOP_EXCLUSIVE, file, line); + TD_LOCKS_DEC(curthread); +} + +static void +lockmgr_note_exclusive_upgrade(struct lock *lk, const char *file, int line, + int flags) +{ + + LOCK_LOG_LOCK("XUPGRADE", &lk->lock_object, 0, 0, file, + line); + WITNESS_UPGRADE(&lk->lock_object, LOP_EXCLUSIVE | + LK_TRYWIT(flags), file, line); + TD_SLOCKS_DEC(curthread); +} + static __inline struct thread * lockmgr_xholder(const struct lock *lk) { @@ -234,35 +300,11 @@ wakeupshlk(struct lock *lk, const char *file, int line) u_int realexslp; int queue, wakeup_swapper; - WITNESS_UNLOCK(&lk->lock_object, 0, file, line); - LOCK_LOG_LOCK("SUNLOCK", &lk->lock_object, 0, 0, file, line); - wakeup_swapper = 0; for (;;) { x = lk->lk_lock; - - /* - * If there is more than one shared lock held, just drop one - * and return. - */ - if (LK_SHARERS(x) > 1) { - if (atomic_cmpset_rel_ptr(&lk->lk_lock, x, - x - LK_ONE_SHARER)) - break; - continue; - } - - /* - * If there are not waiters on the exclusive queue, drop the - * lock quickly. - */ - if ((x & LK_ALL_WAITERS) == 0) { - MPASS((x & ~LK_EXCLUSIVE_SPINNERS) == - LK_SHARERS_LOCK(1)); - if (atomic_cmpset_rel_ptr(&lk->lk_lock, x, LK_UNLOCKED)) - break; - continue; - } + if (lockmgr_sunlock_try(lk, x)) + break; /* * We should have a sharer with waiters, so enter the hard @@ -332,9 +374,7 @@ wakeupshlk(struct lock *lk, const char *file, int line) break; } - lock_profile_release_lock(&lk->lock_object); - TD_LOCKS_DEC(curthread); - TD_SLOCKS_DEC(curthread); + lockmgr_note_shared_release(lk, file, line); return (wakeup_swapper); } @@ -448,6 +488,165 @@ lockdestroy(struct lock *lk) lock_destroy(&lk->lock_object); } +static bool __always_inline +lockmgr_slock_try(struct lock *lk, uintptr_t *xp, int flags) +{ + + /* + * If no other thread has an exclusive lock, or + * no exclusive waiter is present, bump the count of + * sharers. Since we have to preserve the state of + * waiters, if we fail to acquire the shared lock + * loop back and retry. + */ + *xp = lk->lk_lock; + while (LK_CAN_SHARE(*xp, flags)) { + if (atomic_fcmpset_acq_ptr(&lk->lk_lock, xp, + *xp + LK_ONE_SHARER)) { + return (true); + } + } + return (false); +} + +static bool __always_inline +lockmgr_sunlock_try(struct lock *lk, uintptr_t x) +{ + + for (;;) { + /* + * If there is more than one shared lock held, just drop one + * and return. + */ + if (LK_SHARERS(x) > 1) { + if (atomic_fcmpset_rel_ptr(&lk->lk_lock, &x, + x - LK_ONE_SHARER)) + return (true); + continue; + } + + /* + * If there are not waiters on the exclusive queue, drop the + * lock quickly. + */ + if ((x & LK_ALL_WAITERS) == 0) { + MPASS((x & ~LK_EXCLUSIVE_SPINNERS) == + LK_SHARERS_LOCK(1)); + if (atomic_fcmpset_rel_ptr(&lk->lk_lock, &x, + LK_UNLOCKED)) + return (true); + continue; + } + break; + } + return (false); +} + +int +lockmgr_lock_fast_path(struct lock *lk, u_int flags, struct lock_object *ilk, + const char *file, int line) +{ + struct lock_class *class; + uintptr_t x, v, tid; + u_int op; + bool locked; + + op = flags & LK_TYPE_MASK; + locked = false; + switch (op) { + case LK_SHARED: + if (LK_CAN_WITNESS(flags)) + WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER, + file, line, flags & LK_INTERLOCK ? ilk : NULL); + if (__predict_false(lk->lock_object.lo_flags & LK_NOSHARE)) + break; + if (lockmgr_slock_try(lk, &x, flags)) { + lockmgr_note_shared_acquire(lk, 0, 0, + file, line, flags); + locked = true; + } + break; + case LK_EXCLUSIVE: + if (LK_CAN_WITNESS(flags)) + WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER | + LOP_EXCLUSIVE, file, line, flags & LK_INTERLOCK ? + ilk : NULL); + tid = (uintptr_t)curthread; + if (lk->lk_lock == LK_UNLOCKED && + atomic_cmpset_acq_ptr(&lk->lk_lock, LK_UNLOCKED, tid)) { + lockmgr_note_exclusive_acquire(lk, 0, 0, file, line, + flags); + locked = true; + } + break; + case LK_UPGRADE: + case LK_TRYUPGRADE: + _lockmgr_assert(lk, KA_SLOCKED, file, line); + tid = (uintptr_t)curthread; + v = lk->lk_lock; + x = v & LK_ALL_WAITERS; + v &= LK_EXCLUSIVE_SPINNERS; + if (atomic_cmpset_ptr(&lk->lk_lock, LK_SHARERS_LOCK(1) | x | v, + tid | x)) { + lockmgr_note_exclusive_upgrade(lk, file, line, flags); + locked = true; + } + break; + default: + break; + } + if (__predict_true(locked)) { + if (__predict_false(flags & LK_INTERLOCK)) { + class = LOCK_CLASS(ilk); + class->lc_unlock(ilk); + } + return (0); + } else { + return (__lockmgr_args(lk, flags, ilk, LK_WMESG_DEFAULT, + LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, file, line)); + } +} + +int +lockmgr_unlock_fast_path(struct lock *lk, u_int flags, struct lock_object *ilk) +{ + struct lock_class *class; + uintptr_t x, tid; + bool unlocked; + const char *file; + int line; + + file = __FILE__; + line = __LINE__; + + _lockmgr_assert(lk, KA_LOCKED, file, line); + unlocked = false; + x = lk->lk_lock; + if (__predict_true(x & LK_SHARE) != 0) { + if (lockmgr_sunlock_try(lk, x)) { + lockmgr_note_shared_release(lk, file, line); + unlocked = true; + } + } else { + tid = (uintptr_t)curthread; + if (!lockmgr_recursed(lk) && + atomic_cmpset_rel_ptr(&lk->lk_lock, tid, LK_UNLOCKED)) { + lockmgr_note_exclusive_release(lk, file, line); + unlocked = true; + } + } + if (__predict_true(unlocked)) { + if (__predict_false(flags & LK_INTERLOCK)) { + class = LOCK_CLASS(ilk); + class->lc_unlock(ilk); + } + return (0); + } else { + return (__lockmgr_args(lk, flags | LK_RELEASE, ilk, LK_WMESG_DEFAULT, + LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)); + } +} + int __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, const char *wmesg, int pri, int timo, const char *file, int line) @@ -518,21 +717,8 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER, file, line, flags & LK_INTERLOCK ? ilk : NULL); for (;;) { - x = lk->lk_lock; - - /* - * If no other thread has an exclusive lock, or - * no exclusive waiter is present, bump the count of - * sharers. Since we have to preserve the state of - * waiters, if we fail to acquire the shared lock - * loop back and retry. - */ - if (LK_CAN_SHARE(x, flags)) { - if (atomic_cmpset_acq_ptr(&lk->lk_lock, x, - x + LK_ONE_SHARER)) - break; - continue; - } + if (lockmgr_slock_try(lk, &x, flags)) + break; #ifdef HWPMC_HOOKS PMC_SOFT_CALL( , , lock, failed); #endif @@ -697,15 +883,13 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, __func__, lk); } if (error == 0) { - lock_profile_obtain_lock_success(&lk->lock_object, - contested, waittime, file, line); - LOCK_LOG_LOCK("SLOCK", &lk->lock_object, 0, 0, file, - line); - WITNESS_LOCK(&lk->lock_object, LK_TRYWIT(flags), file, - line); - TD_LOCKS_INC(curthread); - TD_SLOCKS_INC(curthread); - STACK_SAVE(lk); +#ifdef LOCK_PROFILING + lockmgr_note_shared_acquire(lk, contested, waittime, + file, line, flags); +#else + lockmgr_note_shared_acquire(lk, 0, 0, file, line, + flags); +#endif } break; case LK_UPGRADE: @@ -968,14 +1152,13 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, __func__, lk); } if (error == 0) { - lock_profile_obtain_lock_success(&lk->lock_object, - contested, waittime, file, line); - LOCK_LOG_LOCK("XLOCK", &lk->lock_object, 0, - lk->lk_recurse, file, line); - WITNESS_LOCK(&lk->lock_object, LOP_EXCLUSIVE | - LK_TRYWIT(flags), file, line); - TD_LOCKS_INC(curthread); - STACK_SAVE(lk); +#ifdef LOCK_PROFILING + lockmgr_note_exclusive_acquire(lk, contested, waittime, + file, line, flags); +#else + lockmgr_note_exclusive_acquire(lk, 0, 0, file, line, + flags); +#endif } break; case LK_DOWNGRADE: diff --git a/sys/kern/kern_lockstat.c b/sys/kern/kern_lockstat.c index 10da98bbb0d6..679a01c01f5c 100644 --- a/sys/kern/kern_lockstat.c +++ b/sys/kern/kern_lockstat.c @@ -62,7 +62,7 @@ SDT_PROBE_DEFINE1(lockstat, , , sx__downgrade, "struct sx *"); SDT_PROBE_DEFINE2(lockstat, , , thread__spin, "struct mtx *", "uint64_t"); -int __read_mostly lockstat_enabled; +volatile int __read_mostly lockstat_enabled; uint64_t lockstat_nsecs(struct lock_object *lo) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 581d99b711be..8e3ea6d84ed0 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -231,9 +231,6 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line) struct mtx *m; uintptr_t tid, v; - if (SCHEDULER_STOPPED()) - return; - m = mtxlock2mtx(c); KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), @@ -266,9 +263,6 @@ __mtx_unlock_flags(volatile uintptr_t *c, int opts, const char *file, int line) { struct mtx *m; - if (SCHEDULER_STOPPED()) - return; - m = mtxlock2mtx(c); KASSERT(m->mtx_lock != MTX_DESTROYED, @@ -281,7 +275,11 @@ __mtx_unlock_flags(volatile uintptr_t *c, int opts, const char *file, int line) line); mtx_assert(m, MA_OWNED); +#ifdef LOCK_PROFILING __mtx_unlock_sleep(c, opts, file, line); +#else + __mtx_unlock(m, curthread, opts, file, line); +#endif TD_LOCKS_DEC(curthread); } @@ -425,9 +423,14 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line) * We call this if the lock is either contested (i.e. we need to go to * sleep waiting for it), or if we need to recurse on it. */ +#if LOCK_DEBUG > 0 void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, const char *file, int line) +#else +void +__mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts) +#endif { struct mtx *m; struct turnstile *ts; @@ -448,6 +451,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, u_int sleep_cnt = 0; int64_t sleep_time = 0; int64_t all_time = 0; + int doing_lockstat; #endif if (SCHEDULER_STOPPED()) @@ -486,7 +490,13 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, "_mtx_lock_sleep: %s contested (lock=%p) at %s:%d", m->lock_object.lo_name, (void *)m->mtx_lock, file, line); #ifdef KDTRACE_HOOKS - all_time -= lockstat_nsecs(&m->lock_object); +#ifdef LOCK_PROFILING + doing_lockstat = 1; +#else + doing_lockstat = lockstat_enabled; +#endif + if (__predict_false(doing_lockstat)) + all_time -= lockstat_nsecs(&m->lock_object); #endif for (;;) { @@ -593,9 +603,6 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, #endif v = MTX_READ_VALUE(m); } -#ifdef KDTRACE_HOOKS - all_time += lockstat_nsecs(&m->lock_object); -#endif #ifdef KTR if (cont_logged) { CTR4(KTR_CONTENTION, @@ -603,6 +610,11 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, m->lock_object.lo_name, (void *)tid, file, line); } #endif +#ifdef KDTRACE_HOOKS + if (__predict_true(!doing_lockstat)) + return; + all_time += lockstat_nsecs(&m->lock_object); +#endif LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire, m, contested, waittime, file, line); #ifdef KDTRACE_HOOKS @@ -610,7 +622,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, LOCKSTAT_RECORD1(adaptive__block, m, sleep_time); /* - * Only record the loops spinning and not sleeping. + * Only record the loops spinning and not sleeping. */ if (lda.spin_cnt > sleep_cnt) LOCKSTAT_RECORD1(adaptive__spin, m, all_time - sleep_time); @@ -856,8 +868,13 @@ thread_lock_set(struct thread *td, struct mtx *new) * We are only called here if the lock is recursed, contested (i.e. we * need to wake up a blocked thread) or lockstat probe is active. */ +#if LOCK_DEBUG > 0 void __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file, int line) +#else +void +__mtx_unlock_sleep(volatile uintptr_t *c, int opts) +#endif { struct mtx *m; struct turnstile *ts; diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 03677663d806..5dbeae995635 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -1010,10 +1010,13 @@ racct_proc_exit(struct proc *p) racct_set_locked(p, RACCT_CPU, runtime, 0); racct_add_cred_locked(p->p_ucred, RACCT_PCTCPU, pct); + KASSERT(p->p_racct->r_resources[RACCT_RSS] == 0, + ("process reaped with %ju allocated for RSS\n", + p->p_racct->r_resources[RACCT_RSS])); for (i = 0; i <= RACCT_MAX; i++) { if (p->p_racct->r_resources[i] == 0) continue; - if (!RACCT_IS_RECLAIMABLE(i)) + if (!RACCT_IS_RECLAIMABLE(i)) continue; racct_set_locked(p, i, 0, 0); } diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 9464588b9eda..bf74b6710499 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -267,9 +267,6 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line) struct rwlock *rw; uintptr_t tid, v; - if (SCHEDULER_STOPPED()) - return; - rw = rwlock2rw(c); KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), @@ -335,9 +332,6 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line) { struct rwlock *rw; - if (SCHEDULER_STOPPED()) - return; - rw = rwlock2rw(c); KASSERT(rw->rw_lock != RW_DESTROYED, @@ -347,7 +341,11 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line) LOCK_LOG_LOCK("WUNLOCK", &rw->lock_object, 0, rw->rw_recurse, file, line); +#ifdef LOCK_PROFILING _rw_wunlock_hard(rw, (uintptr_t)curthread, file, line); +#else + __rw_wunlock(rw, curthread, file, line); +#endif TD_LOCKS_DEC(curthread); } diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 96ca4dffef28..b072e8babce0 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -295,8 +295,6 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line) uintptr_t tid, x; int error = 0; - if (SCHEDULER_STOPPED()) - return (0); KASSERT(kdb_active != 0 || !TD_IS_IDLETHREAD(curthread), ("sx_xlock() by idle thread %p on sx %s @ %s:%d", curthread, sx->lock_object.lo_name, file, line)); @@ -360,15 +358,17 @@ void _sx_xunlock(struct sx *sx, const char *file, int line) { - if (SCHEDULER_STOPPED()) - return; KASSERT(sx->sx_lock != SX_LOCK_DESTROYED, ("sx_xunlock() of destroyed sx @ %s:%d", file, line)); _sx_assert(sx, SA_XLOCKED, file, line); WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line); LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file, line); +#if LOCK_DEBUG > 0 _sx_xunlock_hard(sx, (uintptr_t)curthread, file, line); +#else + __sx_xunlock(sx, curthread, file, line); +#endif TD_LOCKS_DEC(curthread); } diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 847c6d70ad94..87f1a3605d80 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -162,7 +162,7 @@ _sleep(void *ident, struct lock_object *lock, int priority, else class = NULL; - if (SCHEDULER_STOPPED()) { + if (SCHEDULER_STOPPED_TD(td)) { if (lock != NULL && priority & PDROP) class->lc_unlock(lock); return (0); @@ -250,7 +250,7 @@ msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg, KASSERT(ident != NULL, ("msleep_spin_sbt: NULL ident")); KASSERT(TD_IS_RUNNING(td), ("msleep_spin_sbt: curthread not running")); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return (0); sleepq_lock(ident); @@ -411,7 +411,7 @@ mi_switch(int flags, struct thread *newtd) */ if (kdb_active) kdb_switch(); - if (SCHEDULER_STOPPED()) + if (SCHEDULER_STOPPED_TD(td)) return; if (flags & SW_VOL) { td->td_ru.ru_nvcsw++; diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index 157283078288..8a7f4e7ef9ad 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -430,6 +430,7 @@ sleepq_catch_signals(void *wchan, int pri) struct sigacts *ps; int sig, ret; + ret = 0; td = curthread; p = curproc; sc = SC_LOOKUP(wchan); @@ -443,53 +444,65 @@ sleepq_catch_signals(void *wchan, int pri) } /* - * See if there are any pending signals for this thread. If not - * we can switch immediately. Otherwise do the signal processing - * directly. + * See if there are any pending signals or suspension requests for this + * thread. If not, we can switch immediately. */ thread_lock(td); - if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) == 0) { - sleepq_switch(wchan, pri); - return (0); - } - thread_unlock(td); - mtx_unlock_spin(&sc->sc_lock); - CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", - (void *)td, (long)p->p_pid, td->td_name); - PROC_LOCK(p); - ps = p->p_sigacts; - mtx_lock(&ps->ps_mtx); - sig = cursig(td); - if (sig == -1) { - mtx_unlock(&ps->ps_mtx); - KASSERT((td->td_flags & TDF_SBDRY) != 0, ("lost TDF_SBDRY")); - KASSERT(TD_SBDRY_INTR(td), - ("lost TDF_SERESTART of TDF_SEINTR")); - KASSERT((td->td_flags & (TDF_SEINTR | TDF_SERESTART)) != - (TDF_SEINTR | TDF_SERESTART), - ("both TDF_SEINTR and TDF_SERESTART")); - ret = TD_SBDRY_ERRNO(td); - } else if (sig == 0) { - mtx_unlock(&ps->ps_mtx); - ret = thread_suspend_check(1); - MPASS(ret == 0 || ret == EINTR || ret == ERESTART); - } else { - if (SIGISMEMBER(ps->ps_sigintr, sig)) - ret = EINTR; - else - ret = ERESTART; - mtx_unlock(&ps->ps_mtx); + if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) != 0) { + thread_unlock(td); + mtx_unlock_spin(&sc->sc_lock); + CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)", + (void *)td, (long)p->p_pid, td->td_name); + PROC_LOCK(p); + /* + * Check for suspension first. Checking for signals and then + * suspending could result in a missed signal, since a signal + * can be delivered while this thread is suspended. + */ + if ((td->td_flags & TDF_NEEDSUSPCHK) != 0) { + ret = thread_suspend_check(1); + MPASS(ret == 0 || ret == EINTR || ret == ERESTART); + if (ret != 0) { + PROC_UNLOCK(p); + mtx_lock_spin(&sc->sc_lock); + thread_lock(td); + goto out; + } + } + if ((td->td_flags & TDF_NEEDSIGCHK) != 0) { + ps = p->p_sigacts; + mtx_lock(&ps->ps_mtx); + sig = cursig(td); + if (sig == -1) { + mtx_unlock(&ps->ps_mtx); + KASSERT((td->td_flags & TDF_SBDRY) != 0, + ("lost TDF_SBDRY")); + KASSERT(TD_SBDRY_INTR(td), + ("lost TDF_SERESTART of TDF_SEINTR")); + KASSERT((td->td_flags & + (TDF_SEINTR | TDF_SERESTART)) != + (TDF_SEINTR | TDF_SERESTART), + ("both TDF_SEINTR and TDF_SERESTART")); + ret = TD_SBDRY_ERRNO(td); + } else if (sig != 0) { + ret = SIGISMEMBER(ps->ps_sigintr, sig) ? + EINTR : ERESTART; + mtx_unlock(&ps->ps_mtx); + } else { + mtx_unlock(&ps->ps_mtx); + } + } + /* + * Lock the per-process spinlock prior to dropping the PROC_LOCK + * to avoid a signal delivery race. PROC_LOCK, PROC_SLOCK, and + * thread_lock() are currently held in tdsendsignal(). + */ + PROC_SLOCK(p); + mtx_lock_spin(&sc->sc_lock); + PROC_UNLOCK(p); + thread_lock(td); + PROC_SUNLOCK(p); } - /* - * Lock the per-process spinlock prior to dropping the PROC_LOCK - * to avoid a signal delivery race. PROC_LOCK, PROC_SLOCK, and - * thread_lock() are currently held in tdsendsignal(). - */ - PROC_SLOCK(p); - mtx_lock_spin(&sc->sc_lock); - PROC_UNLOCK(p); - thread_lock(td); - PROC_SUNLOCK(p); if (ret == 0) { sleepq_switch(wchan, pri); return (0); diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index 7e4f1b81949b..01df8fffdb99 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -468,10 +468,11 @@ copyout_map(struct thread *td, vm_offset_t *addr, size_t sz) /* round size up to page boundary */ size = (vm_size_t)round_page(sz); - - error = vm_mmap(&vms->vm_map, addr, size, VM_PROT_READ | VM_PROT_WRITE, - VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, OBJT_DEFAULT, NULL, 0); - + if (size == 0) + return (EINVAL); + error = vm_mmap_object(&vms->vm_map, addr, size, VM_PROT_READ | + VM_PROT_WRITE, VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, NULL, 0, + FALSE, td); return (error); } diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index e5b02fd3db56..cd1bf0b7142c 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -891,20 +891,20 @@ shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize, return (EACCES); maxprot &= cap_maxprot; + /* See comment in vn_mmap(). */ + if ( +#ifdef _LP64 + objsize > OFF_MAX || +#endif + foff < 0 || foff > OFF_MAX - objsize) + return (EINVAL); + #ifdef MAC error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, flags); if (error != 0) return (error); #endif - /* - * XXXRW: This validation is probably insufficient, and subject to - * sign errors. It should be fixed. - */ - if (foff >= shmfd->shm_size || - foff + objsize > round_page(shmfd->shm_size)) - return (EINVAL); - mtx_lock(&shm_timestamp_lock); vfs_timestamp(&shmfd->shm_atime); mtx_unlock(&shm_timestamp_lock); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index dce0e1aecc7e..1e01ccdac35c 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/resourcevar.h> #include <sys/signalvar.h> +#include <sys/syscallsubr.h> #include <sys/protosw.h> #include <sys/rwlock.h> #include <sys/sema.h> @@ -858,12 +859,9 @@ aio_process_mlock(struct kaiocb *job) ("%s: opcode %d", __func__, job->uaiocb.aio_lio_opcode)); aio_switch_vmspace(job); - error = vm_mlock(job->userproc, job->cred, - __DEVOLATILE(void *, cb->aio_buf), cb->aio_nbytes); - if (error) - aio_complete(job, -1, error); - else - aio_complete(job, 0, 0); + error = kern_mlock(job->userproc, job->cred, + __DEVOLATILE(uintptr_t, cb->aio_buf), cb->aio_nbytes); + aio_complete(job, error != 0 ? -1 : 0, error); } static void diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index fe34e5658c41..5c0d1b8d4775 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -520,10 +520,11 @@ vop_stdlock(ap) } */ *ap; { struct vnode *vp = ap->a_vp; + struct mtx *ilk; - return (_lockmgr_args(vp->v_vnlock, ap->a_flags, VI_MTX(vp), - LK_WMESG_DEFAULT, LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, ap->a_file, - ap->a_line)); + ilk = VI_MTX(vp); + return (lockmgr_lock_fast_path(vp->v_vnlock, ap->a_flags, + (ilk != NULL) ? &ilk->lock_object : NULL, ap->a_file, ap->a_line)); } /* See above. */ @@ -535,8 +536,11 @@ vop_stdunlock(ap) } */ *ap; { struct vnode *vp = ap->a_vp; + struct mtx *ilk; - return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE, VI_MTX(vp))); + ilk = VI_MTX(vp); + return (lockmgr_unlock_fast_path(vp->v_vnlock, ap->a_flags, + (ilk != NULL) ? &ilk->lock_object : NULL)); } /* See above. */ diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 1f2cceaf7a62..e8f142049c50 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -2455,6 +2455,24 @@ vn_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size, } maxprot &= cap_maxprot; + /* + * For regular files and shared memory, POSIX requires that + * the value of foff be a legitimate offset within the data + * object. In particular, negative offsets are invalid. + * Blocking negative offsets and overflows here avoids + * possible wraparound or user-level access into reserved + * ranges of the data object later. In contrast, POSIX does + * not dictate how offsets are used by device drivers, so in + * the case of a device mapping a negative offset is passed + * on. + */ + if ( +#ifdef _LP64 + size > OFF_MAX || +#endif + foff < 0 || foff > OFF_MAX - size) + return (EINVAL); + writecounted = FALSE; error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, vp, &foff, &object, &writecounted); diff --git a/sys/libkern/inet_ntoa.c b/sys/libkern/inet_ntoa.c index 767b2d9df175..0c3444c3d0b3 100644 --- a/sys/libkern/inet_ntoa.c +++ b/sys/libkern/inet_ntoa.c @@ -36,20 +36,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> char * -inet_ntoa(struct in_addr ina) -{ - static char buf[4*sizeof "123"]; - unsigned char *ucp = (unsigned char *)&ina; - - sprintf(buf, "%d.%d.%d.%d", - ucp[0] & 0xff, - ucp[1] & 0xff, - ucp[2] & 0xff, - ucp[3] & 0xff); - return buf; -} - -char * inet_ntoa_r(struct in_addr ina, char *buf) { unsigned char *ucp = (unsigned char *)&ina; diff --git a/sys/dev/bhnd/bcma/bcma_nexus.c b/sys/mips/broadcom/bcma_nexus.c index 15d8e63c8087..aba057abdeab 100644 --- a/sys/dev/bhnd/bcma/bcma_nexus.c +++ b/sys/mips/broadcom/bcma_nexus.c @@ -43,49 +43,41 @@ __FBSDID("$FreeBSD$"); #include <machine/resource.h> #include <dev/bhnd/bhnd_ids.h> -#include <dev/bhnd/bhnd_nexusvar.h> -#include <dev/bhnd/cores/chipc/chipcreg.h> -#include "bcmavar.h" -#include "bcma_eromreg.h" +#include <dev/bhnd/bcma/bcmavar.h> + +#include "bcm_machdep.h" + +#include "bhnd_nexusvar.h" /* - * Supports bcma(4) attachment to a nexus bus. + * Supports bcma(4) attachment to a MIPS nexus bus. */ static int bcma_nexus_attach(device_t); static int bcma_nexus_probe(device_t); -struct bcma_nexus_softc { - struct bcma_softc parent_sc; - struct bhnd_chipid bcma_cid; -}; - static int bcma_nexus_probe(device_t dev) { - struct bcma_nexus_softc *sc; - int error; - - sc = device_get_softc(dev); - - /* Read the ChipCommon info using the hints the kernel - * was compiled with. */ - if ((error = bhnd_nexus_read_chipid(dev, &sc->bcma_cid))) - return (error); + int error; - if (sc->bcma_cid.chip_type != BHND_CHIPTYPE_BCMA) + switch (bcm_get_platform()->cid.chip_type) { + case BHND_CHIPTYPE_BCMA: + case BHND_CHIPTYPE_BCMA_ALT: + case BHND_CHIPTYPE_UBUS: + break; + default: return (ENXIO); + } - if ((error = bcma_probe(dev)) > 0) { - device_printf(dev, "error %d in probe\n", error); + if ((error = bcma_probe(dev)) > 0) return (error); - } /* Set device description */ - bhnd_set_default_bus_desc(dev, &sc->bcma_cid); + bhnd_set_default_bus_desc(dev, &bcm_get_platform()->cid); - return (0); + return (BUS_PROBE_SPECIFIC); } static int @@ -108,25 +100,15 @@ failed: return (error); } -static const struct bhnd_chipid * -bcma_nexus_get_chipid(device_t dev, device_t child) { - struct bcma_nexus_softc *sc = device_get_softc(dev); - return (&sc->bcma_cid); -} - static device_method_t bcma_nexus_methods[] = { - /* Device interface */ DEVMETHOD(device_probe, bcma_nexus_probe), DEVMETHOD(device_attach, bcma_nexus_attach), - /* bhnd interface */ - DEVMETHOD(bhnd_bus_get_chipid, bcma_nexus_get_chipid), - DEVMETHOD_END }; DEFINE_CLASS_2(bhnd, bcma_nexus_driver, bcma_nexus_methods, - sizeof(struct bcma_nexus_softc), bhnd_nexus_driver, bcma_driver); + sizeof(struct bcma_softc), bhnd_nexus_driver, bcma_driver); EARLY_DRIVER_MODULE(bcma_nexus, nexus, bcma_nexus_driver, bhnd_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/dev/bhnd/bhnd_nexus.c b/sys/mips/broadcom/bhnd_nexus.c index dc926a22105b..f2a4d117b62e 100644 --- a/sys/dev/bhnd/bhnd_nexus.c +++ b/sys/mips/broadcom/bhnd_nexus.c @@ -32,10 +32,9 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); - /* * bhnd(4) driver mix-in providing shared common methods for - * bhnd bus devices attached via a root nexus. + * bhnd bus devices attached via a MIPS root nexus. */ #include <sys/param.h> @@ -48,50 +47,16 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> +#include <dev/bhnd/bhndvar.h> #include <dev/bhnd/bhnd_ids.h> -#include <dev/bhnd/cores/chipc/chipcreg.h> -#include "bhnd_nexusvar.h" +#include "bcm_machdep.h" -static const struct resource_spec bhnd_nexus_res_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* chipc registers */ - { -1, 0, 0 } -}; +#include "bhnd_nexusvar.h" /** - * Map ChipCommon's register block and read the chip identifier data. - * - * @param dev A bhnd_nexus device. - * @param chipid On success, will be populated with the chip identifier. - * @retval 0 success - * @retval non-zero An error occurred reading the chip identifier.. + * Default bhnd_nexus implementation of BHND_BUS_ACTIVATE_RESOURCE(). */ -int -bhnd_nexus_read_chipid(device_t dev, struct bhnd_chipid *chipid) -{ - struct resource_spec rspec[nitems(bhnd_nexus_res_spec)]; - int error; - - memcpy(rspec, bhnd_nexus_res_spec, sizeof(rspec)); - error = bhnd_read_chipid(dev, rspec, 0, chipid); - if (error) - device_printf(dev, "error %d reading chip ID\n", error); - - return (error); -} - -static bool -bhnd_nexus_is_hw_disabled(device_t dev, device_t child) -{ - return (false); -} - -static bhnd_attach_type -bhnd_nexus_get_attach_type(device_t dev, device_t child) -{ - return (BHND_ATTACH_NATIVE); -} - static int bhnd_nexus_activate_resource(device_t dev, device_t child, int type, int rid, struct bhnd_resource *r) @@ -106,6 +71,9 @@ bhnd_nexus_activate_resource(device_t dev, device_t child, int type, int rid, return (0); } +/** + * Default bhnd_nexus implementation of BHND_BUS_DEACTIVATE_RESOURCE(). + */ static int bhnd_nexus_deactivate_resource(device_t dev, device_t child, int type, int rid, struct bhnd_resource *r) @@ -122,6 +90,52 @@ bhnd_nexus_deactivate_resource(device_t dev, device_t child, return (0); } +/** + * Default bhnd_nexus implementation of BHND_BUS_IS_HW_DISABLED(). + */ +static bool +bhnd_nexus_is_hw_disabled(device_t dev, device_t child) +{ + struct bcm_platform *bp; + struct bhnd_chipid *cid; + + bp = bcm_get_platform(); + cid = &bp->cid; + + /* The BCM4706 low-cost package leaves secondary GMAC cores + * floating */ + if (cid->chip_id == BHND_CHIPID_BCM4706 && + cid->chip_pkg == BHND_PKGID_BCM4706L && + bhnd_get_device(child) == BHND_COREID_4706_GMAC && + bhnd_get_core_unit(child) != 0) + { + return (true); + } + + return (false); +} + +/** + * Default bhnd_nexus implementation of BHND_BUS_AGET_ATTACH_TYPE(). + */ +static bhnd_attach_type +bhnd_nexus_get_attach_type(device_t dev, device_t child) +{ + return (BHND_ATTACH_NATIVE); +} + +/** + * Default bhnd_nexus implementation of BHND_BUS_GET_CHIPID(). + */ +static const struct bhnd_chipid * +bhnd_nexus_get_chipid(device_t dev, device_t child) +{ + return (&bcm_get_platform()->cid); +} + +/** + * Default bhnd_nexus implementation of BHND_BUS_GET_INTR_COUNT(). + */ static int bhnd_nexus_get_intr_count(device_t dev, device_t child) { @@ -129,14 +143,30 @@ bhnd_nexus_get_intr_count(device_t dev, device_t child) return (0); } +/** + * Default bhnd_nexus implementation of BHND_BUS_ASSIGN_INTR(). + */ +static int +bhnd_nexus_assign_intr(device_t dev, device_t child, int rid) +{ + uint32_t ivec; + int error; + + if ((error = bhnd_get_core_ivec(child, rid, &ivec))) + return (error); + + return (bus_set_resource(child, SYS_RES_IRQ, rid, ivec, 1)); +} + static device_method_t bhnd_nexus_methods[] = { /* bhnd interface */ DEVMETHOD(bhnd_bus_activate_resource, bhnd_nexus_activate_resource), DEVMETHOD(bhnd_bus_deactivate_resource, bhnd_nexus_deactivate_resource), DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_nexus_is_hw_disabled), DEVMETHOD(bhnd_bus_get_attach_type, bhnd_nexus_get_attach_type), - + DEVMETHOD(bhnd_bus_get_chipid, bhnd_nexus_get_chipid), DEVMETHOD(bhnd_bus_get_intr_count, bhnd_nexus_get_intr_count), + DEVMETHOD(bhnd_bus_assign_intr, bhnd_nexus_assign_intr), DEVMETHOD_END }; diff --git a/sys/dev/bhnd/bhnd_nexusvar.h b/sys/mips/broadcom/bhnd_nexusvar.h index e52595b1bad7..410070f7cf34 100644 --- a/sys/dev/bhnd/bhnd_nexusvar.h +++ b/sys/mips/broadcom/bhnd_nexusvar.h @@ -29,18 +29,12 @@ * $FreeBSD$ */ -#ifndef _BHND_BHND_NEXUSVAR_H_ -#define _BHND_BHND_NEXUSVAR_H_ +#ifndef _MIPS_BROADCOM_BHND_NEXUSVAR_H_ +#define _MIPS_BROADCOM_BHND_NEXUSVAR_H_ #include <sys/param.h> -#include <sys/kernel.h> -#include <sys/bus.h> -#include <sys/module.h> - -#include "bhndvar.h" +#include <sys/kobj.h> DECLARE_CLASS(bhnd_nexus_driver); -int bhnd_nexus_read_chipid(device_t dev, struct bhnd_chipid *chipid); - -#endif /* _BHND_BHND_NEXUSVAR_H_ */ +#endif /* _MIPS_BROADCOM_BHND_NEXUSVAR_H_ */ diff --git a/sys/mips/broadcom/files.broadcom b/sys/mips/broadcom/files.broadcom index f293c1e327e9..4dadde293e86 100644 --- a/sys/mips/broadcom/files.broadcom +++ b/sys/mips/broadcom/files.broadcom @@ -10,6 +10,12 @@ mips/broadcom/bcm_mips74k.c optional bcma_nexus bcma mips/broadcom/bcm_nvram_cfe.c optional bhnd siba_nexus cfe | \ bhnd bcma_nexus cfe mips/broadcom/bcm_pmu.c standard + +mips/broadcom/bhnd_nexus.c optional bhnd siba_nexus | \ + bhnd bcma_nexus +mips/broadcom/bcma_nexus.c optional bcma_nexus bcma bhnd +mips/broadcom/siba_nexus.c optional siba_nexus siba bhnd + mips/mips/tick.c standard mips/broadcom/uart_cpu_chipc.c optional uart diff --git a/sys/dev/bhnd/siba/siba_nexus.c b/sys/mips/broadcom/siba_nexus.c index cfd6c5dbe30f..479a1c013608 100644 --- a/sys/dev/bhnd/siba/siba_nexus.c +++ b/sys/mips/broadcom/siba_nexus.c @@ -38,10 +38,12 @@ __FBSDID("$FreeBSD$"); #include <machine/resource.h> #include <dev/bhnd/bhnd_ids.h> -#include <dev/bhnd/bhnd_nexusvar.h> -#include <dev/bhnd/cores/chipc/chipcreg.h> -#include "sibavar.h" +#include <dev/bhnd/siba/sibavar.h> + +#include "bcm_machdep.h" + +#include "bhnd_nexusvar.h" /* * Supports siba(4) attachment to a MIPS nexus bus. @@ -49,36 +51,21 @@ __FBSDID("$FreeBSD$"); * Derived from Bruce M. Simpson' original siba(4) driver. */ -struct siba_nexus_softc { - struct siba_softc parent_sc; - struct bhnd_chipid siba_cid; -}; - static int siba_nexus_probe(device_t dev) { - struct siba_nexus_softc *sc; - int error; - - sc = device_get_softc(dev); - - /* Read the ChipCommon info using the hints the kernel - * was compiled with. */ - if ((error = bhnd_nexus_read_chipid(dev, &sc->siba_cid))) - return (error); + int error; - if (sc->siba_cid.chip_type != BHND_CHIPTYPE_SIBA) + if (bcm_get_platform()->cid.chip_type != BHND_CHIPTYPE_SIBA) return (ENXIO); - if ((error = siba_probe(dev)) > 0) { - device_printf(dev, "error %d in probe\n", error); + if ((error = siba_probe(dev)) > 0) return (error); - } /* Set device description */ - bhnd_set_default_bus_desc(dev, &sc->siba_cid); + bhnd_set_default_bus_desc(dev, &bcm_get_platform()->cid); - return (0); + return (BUS_PROBE_SPECIFIC); } static int @@ -101,25 +88,16 @@ failed: return (error); } -static const struct bhnd_chipid * -siba_nexus_get_chipid(device_t dev, device_t child) { - struct siba_nexus_softc *sc = device_get_softc(dev); - return (&sc->siba_cid); -} - static device_method_t siba_nexus_methods[] = { /* Device interface */ DEVMETHOD(device_probe, siba_nexus_probe), DEVMETHOD(device_attach, siba_nexus_attach), - /* bhnd interface */ - DEVMETHOD(bhnd_bus_get_chipid, siba_nexus_get_chipid), - DEVMETHOD_END }; DEFINE_CLASS_2(bhnd, siba_nexus_driver, siba_nexus_methods, - sizeof(struct siba_nexus_softc), bhnd_nexus_driver, siba_driver); + sizeof(struct siba_softc), bhnd_nexus_driver, siba_driver); EARLY_DRIVER_MODULE(siba_nexus, nexus, siba_nexus_driver, bhnd_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 20f23387648f..976690e97992 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -27,7 +27,6 @@ SUBDIR= \ age \ ${_agp} \ aha \ - ${_ahb} \ ahci \ ${_aic} \ aic7xxx \ @@ -736,9 +735,6 @@ _sbni= sbni _streams= streams _stg= stg _svr4= svr4 -.if ${MK_EISA} != "no" -_ahb= ahb -.endif _cm= cm .if ${MK_SOURCELESS_UCODE} != "no" _ctau= ctau diff --git a/sys/modules/ahb/Makefile b/sys/modules/ahb/Makefile deleted file mode 100644 index f3d7498d6c2d..000000000000 --- a/sys/modules/ahb/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../dev/ahb - -KMOD= ahb -SRCS= ahb.c opt_cam.h device_if.h bus_if.h eisa_if.h - -.include <bsd.kmod.mk> diff --git a/sys/modules/aic7xxx/ahc/Makefile b/sys/modules/aic7xxx/ahc/Makefile index 432d3c0a9ad4..7b47625baf86 100644 --- a/sys/modules/aic7xxx/ahc/Makefile +++ b/sys/modules/aic7xxx/ahc/Makefile @@ -6,9 +6,6 @@ SYSDIR?=${.CURDIR}/../../.. .PATH: ${SYSDIR}/dev/aic7xxx KMOD= ahc -.if ${MK_EISA} != "no" -SUBDIR+= ahc_eisa -.endif SUBDIR+= ahc_isa ahc_pci GENSRCS= aic7xxx_seq.h aic7xxx_reg.h diff --git a/sys/modules/aic7xxx/ahc/ahc_eisa/Makefile b/sys/modules/aic7xxx/ahc/ahc_eisa/Makefile deleted file mode 100644 index 4c8253f4b0bd..000000000000 --- a/sys/modules/aic7xxx/ahc/ahc_eisa/Makefile +++ /dev/null @@ -1,13 +0,0 @@ - -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../../../dev/aic7xxx -KMOD= ahc_eisa - -SRCS= ahc_eisa.c -SRCS+= device_if.h bus_if.h eisa_if.h pci_if.h -SRCS+= opt_scsi.h opt_cam.h opt_aic7xxx.h - -CFLAGS+= -I${.CURDIR}/../../../../dev/aic7xxx -I.. - -.include <bsd.kmod.mk> diff --git a/sys/modules/dpt/Makefile b/sys/modules/dpt/Makefile index ee588adb829f..7b4f9cc5bc3a 100644 --- a/sys/modules/dpt/Makefile +++ b/sys/modules/dpt/Makefile @@ -7,10 +7,8 @@ SYSDIR?=${.CURDIR}/../.. KMOD= dpt SRCS= dpt_scsi.c dpt.h \ dpt_pci.c pci_if.h \ - opt_dpt.h opt_eisa.h \ + opt_dpt.h \ opt_cam.h opt_scsi.h \ device_if.h bus_if.h -SRCS.DEV_EISA= dpt_eisa.c eisa_if.h - .include <bsd.kmod.mk> diff --git a/sys/modules/ep/Makefile b/sys/modules/ep/Makefile index df117abe8b9d..6759781e41c0 100644 --- a/sys/modules/ep/Makefile +++ b/sys/modules/ep/Makefile @@ -9,7 +9,6 @@ KMOD= if_ep SRCS= if_ep.c SRCS+= if_ep_pccard.c pccarddevs.h card_if.h SRCS+= if_ep_isa.c isa_if.h -SRCS.DEV_EISA= if_ep_eisa.c eisa_if.h SRCS+= bus_if.h device_if.h .include <bsd.kmod.mk> diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile index 629a1da2d190..1162b5597776 100644 --- a/sys/modules/linux64/Makefile +++ b/sys/modules/linux64/Makefile @@ -7,7 +7,7 @@ VDSO= linux_vdso KMOD= linux64 SRCS= linux_fork.c linux_dummy.c linux_file.c linux_event.c \ linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \ - linux_machdep.c linux_misc.c linux_signal.c \ + linux_machdep.c linux_misc.c linux_ptrace.c linux_signal.c \ linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \ linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \ opt_inet6.h opt_compat.h opt_posix.h opt_usb.h \ diff --git a/sys/modules/vx/Makefile b/sys/modules/vx/Makefile index 2086dc8bf694..21e033a7b371 100644 --- a/sys/modules/vx/Makefile +++ b/sys/modules/vx/Makefile @@ -7,7 +7,6 @@ SYSDIR?=${.CURDIR}/../.. KMOD= if_vx SRCS= if_vx.c if_vx_pci.c -SRCS.DEV_EISA= if_vx_eisa.c eisa_if.h SRCS+= device_if.h bus_if.h pci_if.h .include <bsd.kmod.mk> diff --git a/sys/net/bpf.h b/sys/net/bpf.h index 058f3c048c33..679f896d9538 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -231,1056 +231,8 @@ struct bpf_zbuf_header { u_int _bzh_pad[5]; }; -/* - * Data-link level type codes. - */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* IEEE 802 Networks */ -#define DLT_ARCNET 7 /* ARCNET */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_RAW 12 /* raw IP */ - -/* - * These are values from BSD/OS's "bpf.h". - * These are not the same as the values from the traditional libpcap - * "bpf.h"; however, these values shouldn't be generated by any - * OS other than BSD/OS, so the correct values to use here are the - * BSD/OS values. - * - * Platforms that have already assigned these values to other - * DLT_ codes, however, should give these codes the values - * from that platform, so that programs that use these codes will - * continue to compile - even though they won't correctly read - * files of these types. - */ -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * Reserved for the Symantec Enterprise Firewall. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer header type LINKTYPE_ values corresponding to DLT_ types - * that differ between platforms; don't use those values for new DLT_ - * new types. - */ - -/* - * Values starting with 104 are used for newly-assigned link-layer - * header type values; for those link-layer header types, the DLT_ - * value returned by pcap_datalink() and passed to pcap_open_dead(), - * and the LINKTYPE_ value that appears in capture files, are the - * same. - * - * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is - * the highest such value. - */ -#define DLT_MATCHING_MIN 104 - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * Values between 106 and 107 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * OpenBSD defines it as 12, but that collides with DLT_RAW, so we - * define it as 108 here. If OpenBSD picks up this file, it should - * define DLT_LOOP as 12 in its version, as per the comment above - - * and should not use 108 as a DLT_ value. - */ -#define DLT_LOOP 108 - -/* - * Values between 109 and 112 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#define DLT_ENC 109 - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * Reserved for use in capture-file headers as a link-layer type - * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, - * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it - * in capture-file headers. - */ -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * Reserved for 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for use by OpenBSD's pfsync device. - */ -#define DLT_PFSYNC 121 - -/* - * Reserved for Siemens HiPath HDLC. XXX - */ -#define DLT_HHDLC 121 - -/* - * Reserved for RFC 2625 IP-over-Fibre Channel. - */ -#define DLT_IP_OVER_FC 122 - -/* - * Reserved for Full Frontal ATM on Solaris. - */ -#define DLT_SUNATM 123 - -/* - * Reserved as per request from Kent Dahlgren <kent@praesum.com> - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * BSD header for 802.11 plus a number of bits of link-layer information - * including radio information. - */ -#ifndef DLT_IEEE802_11_RADIO -#define DLT_IEEE802_11_RADIO 127 -#endif - -/* - * Reserved for TZSP encapsulation. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * Reserved for Linux ARCNET. - */ -#define DLT_ARCNET_LINUX 129 - -/* - * Juniper-private data link types. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * <dieter@apple.com>. The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * Various SS7 encapsulations, as per a request from Jeff Morriss - * <jeff.morriss[AT]ulticom.com> and subsequent discussions. - */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ - -/* - * Reserved for DOCSIS. - */ -#define DLT_DOCSIS 143 - -/* - * Reserved for Linux IrDA. - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but it might be used by some non-AVS drivers now or in the - * future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * Reserved for BACnet MS/TP. - */ -#define DLT_BACNET_MS_TP 165 - -/* - * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>. - * - * This is used in some OSes to allow a kernel socket filter to distinguish - * between incoming and outgoing packets, on a socket intended to - * supply pppd with outgoing packets so it can do dial-on-demand and - * hangup-on-lack-of-demand; incoming packets are filtered out so they - * don't cause pppd to hold the connection up (you don't want random - * input packets such as port scans, packets from old lost connections, - * etc. to force the connection to stay up). - * - * The first byte of the PPP header (0xff03) is modified to accommodate - * the direction - 0x00 = IN, 0x01 = OUT. - */ -#define DLT_PPP_PPPD 166 - -/* - * Names for backwards compatibility with older versions of some PPP - * software; new software should use DLT_PPP_PPPD. - */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, cookies, etc.. - */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 - -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ - -/* - * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line - * monitoring equipment. - */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. The DLT_ is used - * for internal communication to Physical Interface Cards (PIC) - */ -#define DLT_JUNIPER_PIC_PEER 174 - -/* - * Link types requested by Gregor Maier <gregor@endace.com> of Endace - * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of - * the link-layer header. - */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ - -/* - * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD - * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header - * includes additional information before the LAPD header, so it's - * not necessarily a generic LAPD header. - */ -#define DLT_LINUX_LAPD 177 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ are used for prepending meta-information - * like interface index, interface name - * before standard Ethernet, PPP, Frelay & C-HDLC Frames - */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 - -/* - * Multi Link Frame Relay (FRF.16) - */ -#define DLT_MFR 182 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for internal communication with a - * voice Adapter Card (PIC) - */ -#define DLT_JUNIPER_VP 183 - -/* - * Arinc 429 frames. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Every frame contains a 32bit A429 label. - * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf - */ -#define DLT_A429 184 - -/* - * Arinc 653 Interpartition Communication messages. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Please refer to the A653-1 standard for more information. - */ -#define DLT_A653_ICM 185 - -/* - * USB packets, beginning with a USB setup header; requested by - * Paolo Abeni <paolo.abeni@email.it>. - */ -#define DLT_USB 186 - -/* - * Bluetooth HCI UART transport layer (part H:4); requested by - * Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4 187 - -/* - * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz - * <cruz_petagay@bah.com>. - */ -#define DLT_IEEE802_16_MAC_CPS 188 - -/* - * USB packets, beginning with a Linux USB header; requested by - * Paolo Abeni <paolo.abeni@email.it>. - */ -#define DLT_USB_LINUX 189 - -/* - * Controller Area Network (CAN) v. 2.0B packets. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - * Used to dump CAN packets coming from a CAN Vector board. - * More documentation on the CAN v2.0B frames can be found at - * http://www.can-cia.org/downloads/?269 - */ -#define DLT_CAN20B 190 - -/* - * IEEE 802.15.4, with address fields padded, as is done by Linux - * drivers; requested by Juergen Schimmer. - */ -#define DLT_IEEE802_15_4_LINUX 191 - -/* - * Per Packet Information encapsulated packets. - * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. - */ -#define DLT_PPI 192 - -/* - * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; - * requested by Charles Clancy. - */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for internal communication with a - * integrated service module (ISM). - */ -#define DLT_JUNIPER_ISM 194 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>. - */ -#define DLT_IEEE802_15_4 195 - -/* - * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). - */ -#define DLT_SITA 196 - -/* - * Various link-layer types, with a pseudo-header, for Endace DAG cards; - * encapsulates Endace ERF records. Requested by Stephen Donnelly - * <stephen@endace.com>. - */ -#define DLT_ERF 197 - -/* - * Special header prepended to Ethernet packets when capturing from a - * u10 Networks board. Requested by Phil Mulholland - * <phil@u10networks.com>. - */ -#define DLT_RAIF1 198 - -/* - * IPMB packet for IPMI, beginning with the I2C slave address, followed - * by the netFn and LUN, etc.. Requested by Chanthy Toeung - * <chanthy.toeung@ca.kontron.com>. - */ -#define DLT_IPMB 199 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - * The DLT_ is used for capturing data on a secure tunnel interface. - */ -#define DLT_JUNIPER_ST 200 - -/* - * Bluetooth HCI UART transport layer (part H:4), with pseudo-header - * that includes direction information; requested by Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 - -/* - * AX.25 packet with a 1-byte KISS header; see - * - * http://www.ax25.net/kiss.htm - * - * as per Richard Stearn <richard@rns-stearn.demon.co.uk>. - */ -#define DLT_AX25_KISS 202 - -/* - * LAPD packets from an ISDN channel, starting with the address field, - * with no pseudo-header. - * Requested by Varuna De Silva <varunax@gmail.com>. - */ -#define DLT_LAPD 203 - -/* - * Variants of various link-layer headers, with a one-byte direction - * pseudo-header prepended - zero means "received by this host", - * non-zero (any non-zero value) means "sent by this host" - as per - * Will Barker <w.barker@zen.co.uk>. - */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ - -/* - * 208 is reserved for an as-yet-unspecified proprietary link-layer - * type, as requested by Will Barker. - */ - -/* - * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman - * <avn@pigeonpoint.com>. - */ -#define DLT_IPMB_LINUX 209 - -/* - * FlexRay automotive bus - http://www.flexray.com/ - as requested - * by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_FLEXRAY 210 - -/* - * Media Oriented Systems Transport (MOST) bus for multimedia - * transport - http://www.mostcooperation.com/ - as requested - * by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_MOST 211 - -/* - * Local Interconnect Network (LIN) bus for vehicle networks - - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber - * <hannes.kaelber@x2e.de>. - */ -#define DLT_LIN 212 - -/* - * X2E-private data link type used for serial line capture, - * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_X2E_SERIAL 213 - -/* - * X2E-private data link type used for the Xoraya data logger - * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. - */ -#define DLT_X2E_XORAYA 214 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), but with the PHY-level data for non-ASK PHYs (4 octets - * of 0 as preamble, one octet of SFD, one octet of frame length+ - * reserved bit, and then the MAC-layer data, starting with the - * frame control field). - * - * Requested by Max Filippov <jcmvbkbc@gmail.com>. - */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 - -/* - * David Gibson <david@gibson.dropbear.id.au> requested this for - * captures from the Linux kernel /dev/input/eventN devices. This - * is used to communicate keystrokes and mouse movements from the - * Linux kernel to display systems, such as Xorg. - */ -#define DLT_LINUX_EVDEV 216 - -/* - * GSM Um and Abis interfaces, preceded by a "gsmtap" header. - * - * Requested by Harald Welte <laforge@gnumonks.org>. - */ -#define DLT_GSMTAP_UM 217 -#define DLT_GSMTAP_ABIS 218 - -/* - * MPLS, with an MPLS label as the link-layer header. - * Requested by Michele Marchetto <michele@openbsd.org> on behalf - * of OpenBSD. - */ -#define DLT_MPLS 219 - -/* - * USB packets, beginning with a Linux USB header, with the USB header - * padded to 64 bytes; required for memory-mapped access. - */ -#define DLT_USB_LINUX_MMAPPED 220 - -/* - * DECT packets, with a pseudo-header; requested by - * Matthias Wenzel <tcpdump@mazzoo.de>. - */ -#define DLT_DECT 221 -/* - * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov> - * Date: Mon, 11 May 2009 11:18:30 -0500 - * - * DLT_AOS. We need it for AOS Space Data Link Protocol. - * I have already written dissectors for but need an OK from - * legal before I can submit a patch. - * - */ -#define DLT_AOS 222 - -/* - * Wireless HART (Highway Addressable Remote Transducer) - * From the HART Communication Foundation - * IES/PAS 62591 - * - * Requested by Sam Roberts <vieuxtech@gmail.com>. - */ -#define DLT_WIHART 223 - -/* - * Fibre Channel FC-2 frames, beginning with a Frame_Header. - * Requested by Kahou Lei <kahou82@gmail.com>. - */ -#define DLT_FC_2 224 - -/* - * Fibre Channel FC-2 frames, beginning with an encoding of the - * SOF, and ending with an encoding of the EOF. - * - * The encodings represent the frame delimiters as 4-byte sequences - * representing the corresponding ordered sets, with K28.5 - * represented as 0xBC, and the D symbols as the corresponding - * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, - * is represented as 0xBC 0xB5 0x55 0x55. - * - * Requested by Kahou Lei <kahou82@gmail.com>. - */ -#define DLT_FC_2_WITH_FRAME_DELIMS 225 -/* - * Solaris ipnet pseudo-header; requested by Darren Reed <Darren.Reed@Sun.COM>. - * - * The pseudo-header starts with a one-byte version number; for version 2, - * the pseudo-header is: - * - * struct dl_ipnetinfo { - * u_int8_t dli_version; - * u_int8_t dli_family; - * u_int16_t dli_htype; - * u_int32_t dli_pktlen; - * u_int32_t dli_ifindex; - * u_int32_t dli_grifindex; - * u_int32_t dli_zsrc; - * u_int32_t dli_zdst; - * }; - * - * dli_version is 2 for the current version of the pseudo-header. - * - * dli_family is a Solaris address family value, so it's 2 for IPv4 - * and 26 for IPv6. - * - * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing - * packets, and 2 for packets arriving from another zone on the same - * machine. - * - * dli_pktlen is the length of the packet data following the pseudo-header - * (so the captured length minus dli_pktlen is the length of the - * pseudo-header, assuming the entire pseudo-header was captured). - * - * dli_ifindex is the interface index of the interface on which the - * packet arrived. - * - * dli_grifindex is the group interface index number (for IPMP interfaces). - * - * dli_zsrc is the zone identifier for the source of the packet. - * - * dli_zdst is the zone identifier for the destination of the packet. - * - * A zone number of 0 is the global zone; a zone number of 0xffffffff - * means that the packet arrived from another host on the network, not - * from another zone on the same machine. - * - * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates - * which of those it is. - */ -#define DLT_IPNET 226 - -/* - * CAN (Controller Area Network) frames, with a pseudo-header as supplied - * by Linux SocketCAN. See Documentation/networking/can.txt in the Linux - * source. - * - * Requested by Felix Obenhuber <felix@obenhuber.de>. - */ -#define DLT_CAN_SOCKETCAN 227 - -/* - * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies - * whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>. - */ -#define DLT_IPV4 228 -#define DLT_IPV6 229 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), and with no FCS at the end of the frame; requested by - * Jon Smirl <jonsmirl@gmail.com>. - */ -#define DLT_IEEE802_15_4_NOFCS 230 - -/* - * Raw D-Bus: - * - * http://www.freedesktop.org/wiki/Software/dbus - * - * messages: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages - * - * starting with the endianness flag, followed by the message type, etc., - * but without the authentication handshake before the message sequence: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol - * - * Requested by Martin Vidner <martin@vidner.net>. - */ -#define DLT_DBUS 231 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - */ -#define DLT_JUNIPER_VS 232 -#define DLT_JUNIPER_SRX_E2E 233 -#define DLT_JUNIPER_FIBRECHANNEL 234 - -/* - * DVB-CI (DVB Common Interface for communication between a PC Card - * module and a DVB receiver). See - * - * http://www.kaiser.cx/pcap-dvbci.html - * - * for the specification. - * - * Requested by Martin Kaiser <martin@kaiser.cx>. - */ -#define DLT_DVB_CI 235 - -/* - * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but - * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel - * <hans-christoph.schemmel@cinterion.com>. - */ -#define DLT_MUX27010 236 - -/* - * STANAG 5066 D_PDUs. Requested by M. Baris Demiray - * <barisdemiray@gmail.com>. - */ -#define DLT_STANAG_5066_D_PDU 237 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler <hannes@juniper.net>. - */ -#define DLT_JUNIPER_ATM_CEMIC 238 - -/* - * NetFilter LOG messages - * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) - * - * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl> - */ -#define DLT_NFLOG 239 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and always - * with the payload including the FCS, as supplied by their - * netANALYZER hardware and software. - * - * Requested by Holger P. Frommer <HPfrommer@hilscher.com> - */ -#define DLT_NETANALYZER 240 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and FCS and - * with the Ethernet header preceded by 7 bytes of preamble and - * 1 byte of SFD, as supplied by their netANALYZER hardware and - * software. - * - * Requested by Holger P. Frommer <HPfrommer@hilscher.com> - */ -#define DLT_NETANALYZER_TRANSPARENT 241 - -/* - * IP-over-InfiniBand, as specified by RFC 4391. - * - * Requested by Petr Sumbera <petr.sumbera@oracle.com>. - */ -#define DLT_IPOIB 242 - -/* - * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). - * - * Requested by Guy Martin <gmsoft@tuxicoman.be>. - */ -#define DLT_MPEG_2_TS 243 - -/* - * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as - * used by their ng40 protocol tester. - * - * Requested by Jens Grimmer <jens.grimmer@ng4t.com>. - */ -#define DLT_NG40 244 - -/* - * Pseudo-header giving adapter number and flags, followed by an NFC - * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, - * as specified by NFC Forum Logical Link Control Protocol Technical - * Specification LLCP 1.1. - * - * Requested by Mike Wakerly <mikey@google.com>. - */ -#define DLT_NFC_LLCP 245 - -/* - * 245 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. - * - * DLT_PFSYNC has different values on different platforms, and all of - * them collide with something used elsewhere. On platforms that - * don't already define it, define it as 245. - */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) -#define DLT_PFSYNC 246 -#endif - -/* - * Raw InfiniBand packets, starting with the Local Routing Header. - * - * Requested by Oren Kladnitsky <orenk@mellanox.com>. - */ -#define DLT_INFINIBAND 247 - -/* - * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). - * - * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>. - */ -#define DLT_SCTP 248 - -/* - * USB packets, beginning with a USBPcap header. - * - * Requested by Tomasz Mon <desowin@gmail.com> - */ -#define DLT_USBPCAP 249 - -/* - * Schweitzer Engineering Laboratories "RTAC" product serial-line - * packets. - * - * Requested by Chris Bontje <chris_bontje@selinc.com>. - */ -#define DLT_RTAC_SERIAL 250 - -/* - * Bluetooth Low Energy air interface link-layer packets. - * - * Requested by Mike Kershaw <dragorn@kismetwireless.net>. - */ -#define DLT_BLUETOOTH_LE_LL 251 - -/* - * DLT type for upper-protocol layer PDU saves from wireshark. - * - * the actual contents are determined by two TAGs stored with each - * packet: - * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the - * original packet. - * - * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector - * that can make sense of the data stored. - */ -#define DLT_WIRESHARK_UPPER_PDU 252 - -/* - * DLT type for the netlink protocol (nlmon devices). - */ -#define DLT_NETLINK 253 - -/* - * Bluetooth Linux Monitor headers for the BlueZ stack. - */ -#define DLT_BLUETOOTH_LINUX_MONITOR 254 - -/* - * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as - * captured by Ubertooth. - */ -#define DLT_BLUETOOTH_BREDR_BB 255 - -/* - * Bluetooth Low Energy link layer packets, as captured by Ubertooth. - */ -#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 - -/* - * PROFIBUS data link layer. - */ -#define DLT_PROFIBUS_DL 257 - -/* - * Apple's DLT_PKTAP headers. - * - * Sadly, the folks at Apple either had no clue that the DLT_USERn values - * are for internal use within an organization and partners only, and - * didn't know that the right way to get a link-layer header type is to - * ask tcpdump.org for one, or knew and didn't care, so they just - * used DLT_USER2, which causes problems for everything except for - * their version of tcpdump. - * - * So I'll just give them one; hopefully this will show up in a - * libpcap release in time for them to get this into 10.10 Big Sur - * or whatever Mavericks' successor is called. LINKTYPE_PKTAP - * will be 258 *even on OS X*; that is *intentional*, so that - * PKTAP files look the same on *all* OSes (different OSes can have - * different numerical values for a given DLT_, but *MUST NOT* have - * different values for what goes in a file, as files can be moved - * between OSes!). - * - * When capturing, on a system with a Darwin-based OS, on a device - * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this - * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, - * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, - * binary compatibility with Mavericks is preserved for programs using - * this version of libpcap. This does mean that if you were using - * DLT_USER2 for some capture device on OS X, you can't do so with - * this version of libpcap, just as you can't with Apple's libpcap - - * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't - * be able to distinguish between PKTAP and whatever you were using - * DLT_USER2 for. - * - * If the program saves the capture to a file using this version of - * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be - * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. - * That way, the file will *not* be a DLT_USER2 file. That means - * that the latest version of tcpdump, when built with this version - * of libpcap, and sufficiently recent versions of Wireshark will - * be able to read those files and interpret them correctly; however, - * Apple's version of tcpdump in OS X 10.9 won't be able to handle - * them. (Hopefully, Apple will pick up this version of libpcap, - * and the corresponding version of tcpdump, so that tcpdump will - * be able to handle the old LINKTYPE_USER2 captures *and* the new - * LINKTYPE_PKTAP captures.) - */ -#ifdef __APPLE__ -#define DLT_PKTAP DLT_USER2 -#else -#define DLT_PKTAP 258 -#endif - -/* - * Ethernet packets preceded by a header giving the last 6 octets - * of the preamble specified by 802.3-2012 Clause 65, section - * 65.1.3.2 "Transmit". - */ -#define DLT_EPON 259 - -/* - * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" - * in the PICMG HPM.2 specification. - */ -#define DLT_IPMI_HPM_2 260 - -#define DLT_MATCHING_MAX 260 /* highest value in the "matching" range */ - -/* - * DLT and savefile link type values are split into a class and - * a member of that class. A class value of 0 indicates a regular - * DLT_/LINKTYPE_ value. - */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) +/* Pull in data-link level type codes. */ +#include <net/dlt.h> /* * The instruction encodings. diff --git a/sys/net/dlt.h b/sys/net/dlt.h new file mode 100644 index 000000000000..dc818521d669 --- /dev/null +++ b/sys/net/dlt.h @@ -0,0 +1,1338 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * 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 University 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 REGENTS 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 REGENTS 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. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * $FreeBSD$ + */ + +#ifndef _NET_DLT_H_ +#define _NET_DLT_H_ + +/* + * Link-layer header type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run + * the risk of using a value that's already being used for some other + * purpose, and of having tools that read libpcap-format captures not + * being able to handle captures with your new DLT_ value, with no hope + * that they will ever be changed to do so (as that would destroy their + * ability to read captures using that value for that other purpose). + * + * See + * + * http://www.tcpdump.org/linktypes.html + * + * for detailed descriptions of some of these link-layer header types. + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by <net/bpf.h> for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by <net/bpf.h> for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap <net/bpf.h> + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. + * + * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG + * as 117 so that pflog captures would use a link-layer header type + * value that didn't collide with any other values. On all + * platforms other than OpenBSD, we defined DLT_PFLOG as 117, + * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. + * + * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. + * + * Don't use 17 for anything else. + */ + +/* + * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and + * Mac OS X; don't use it for anything else. (FreeBSD uses 121, + * which collides with DLT_HHDLC, even though it doesn't use 18 + * for anything and doesn't appear to have ever used it for anything.) + * + * We define it as 18 on those platforms; it is, unfortunately, used + * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC + * in general. As the packet format for it, like that for + * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, + * we don't support printing it in tcpdump except on OSes that + * have the relevant header files, so it's not that useful on + * other platforms. + */ +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#define DLT_PFSYNC 18 +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer header type LINKTYPE_ values corresponding to DLT_ types + * that differ between platforms; don't use those values for new DLT_ + * new types. + */ + +/* + * Values starting with 104 are used for newly-assigned link-layer + * header type values; for those link-layer header types, the DLT_ + * value returned by pcap_datalink() and passed to pcap_open_dead(), + * and the LINKTYPE_ value that appears in capture files, are the + * same. + * + * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is + * the highest such value. + */ +#define DLT_MATCHING_MIN 104 + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so + * we don't use 12 for it in OSes other than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_LOOP 12 +#else +#define DLT_LOOP 108 +#endif + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Sigh. + * + * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as + * requested by Tomas Kukosa. + * + * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that + * assigned 121 as DLT_PFSYNC. In current versions, its libpcap + * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a + * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC + * dump files with 246 as the link-layer header type. (Earlier + * versions might not have done mapping, in which case they would + * have written them out with a link-layer header type of 121.) + * + * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; + * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would + * write out DLT_PFSYNC dump files with use 18 as the link-layer + * header type. + * + * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in + * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, + * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they + * should write out DLT_PFSYNC dump files with 246 as the link-layer + * header type. (Earlier versions might not have done mapping, + * in which case they'd work the same way OpenBSD does, writing + * them out with a link-layer header type of 18.) + * + * We'll define DLT_PFSYNC as: + * + * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; + * + * 121 on FreeBSD; + * + * 246 everywhere else. + * + * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; + * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC + * is out of luck. + * + * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that + * savefiles written using *this* code won't use 18 or 121 for PFSYNC, + * they'll all use 246. + * + * Code that uses pcap_datalink() to determine the link-layer header + * type of a savefile won't, when built and run on FreeBSD, be able + * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture + * files, as pcap_datalink() will give 121 for both of them. Code + * that doesn't, such as the code in Wireshark, will be able to + * distinguish between them. + * + * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., + * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, + * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's + * libpcap won't treat those files as DLT_PFSYNC files. + * + * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; + * this means they can read DLT_HHDLC files, if any exist, but won't + * treat pcap files written by any older versions of FreeBSD libpcap that + * didn't map to 246 as DLT_PFSYNC files. + */ +#ifdef __FreeBSD__ +#define DLT_PFSYNC 121 +#else +#define DLT_HHDLC 121 +#endif + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren <kent@praesum.com> + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters <chris.waters@networkchemistry.com> + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler <hannes@juniper.net>. The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * <dieter@apple.com>. The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * <jeff.morriss[AT]ulticom.com> and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * BACnet MS/TP frames. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>. + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier <gregor@endace.com> of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * This used to be "USB packets, beginning with a USB setup header; + * requested by Paolo Abeni <paolo.abeni@email.it>." + * + * However, that header didn't work all that well - it left out some + * useful information - and was abandoned in favor of the DLT_USB_LINUX + * header. + * + * This is now used by FreeBSD for its BPF taps for USB; that has its + * own headers. So it is written, so it is done. + * + * For source-code compatibility, we also define DLT_USB to have this + * value. We do it numerically so that, if code that includes this + * file (directly or indirectly) also includes an OS header that also + * defines DLT_USB as 186, we don't get a redefinition warning. + * (NetBSD 7 does that.) + */ +#define DLT_USB_FREEBSD 186 +#define DLT_USB 186 + +/* + * Bluetooth HCI UART transport layer (part H:4); requested by + * Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4 187 + +/* + * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz + * <cruz_petagay@bah.com>. + */ +#define DLT_IEEE802_16_MAC_CPS 188 + +/* + * USB packets, beginning with a Linux USB header; requested by + * Paolo Abeni <paolo.abeni@email.it>. + */ +#define DLT_USB_LINUX 189 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + +/* + * IEEE 802.15.4, with address fields padded, as is done by Linux + * drivers; requested by Juergen Schimmer. + */ +#define DLT_IEEE802_15_4_LINUX 191 + +/* + * Per Packet Information encapsulated packets. + * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>. + */ +#define DLT_PPI 192 + +/* + * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; + * requested by Charles Clancy. + */ +#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + * The DLT_ is used for internal communication with a + * integrated service module (ISM). + */ +#define DLT_JUNIPER_ISM 194 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>. + * For this one, we expect the FCS to be present at the end of the frame; + * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. + */ +#define DLT_IEEE802_15_4 195 + +/* + * Various link-layer types, with a pseudo-header, for SITA + * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + */ +#define DLT_SITA 196 + +/* + * Various link-layer types, with a pseudo-header, for Endace DAG cards; + * encapsulates Endace ERF records. Requested by Stephen Donnelly + * <stephen@endace.com>. + */ +#define DLT_ERF 197 + +/* + * Special header prepended to Ethernet packets when capturing from a + * u10 Networks board. Requested by Phil Mulholland + * <phil@u10networks.com>. + */ +#define DLT_RAIF1 198 + +/* + * IPMB packet for IPMI, beginning with the I2C slave address, followed + * by the netFn and LUN, etc.. Requested by Chanthy Toeung + * <chanthy.toeung@ca.kontron.com>. + */ +#define DLT_IPMB 199 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define DLT_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn <richard@rns-stearn.demon.co.uk>. + */ +#define DLT_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva <varunax@gmail.com>. + */ +#define DLT_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker <w.barker@zen.co.uk>. + */ +#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * <avn@pigeonpoint.com>. + */ +#define DLT_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber <hannes.kaelber@x2e.de>. + */ +#define DLT_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber <hannes.kaelber@x2e.de>. + */ +#define DLT_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * <hannes.kaelber@x2e.de>. + */ +#define DLT_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. + */ +#define DLT_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>. + */ +#define DLT_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov <jcmvbkbc@gmail.com>. + */ +#define DLT_IEEE802_15_4_NONASK_PHY 215 + +/* + * David Gibson <david@gibson.dropbear.id.au> requested this for + * captures from the Linux kernel /dev/input/eventN devices. This + * is used to communicate keystrokes and mouse movements from the + * Linux kernel to display systems, such as Xorg. + */ +#define DLT_LINUX_EVDEV 216 + +/* + * GSM Um and Abis interfaces, preceded by a "gsmtap" header. + * + * Requested by Harald Welte <laforge@gnumonks.org>. + */ +#define DLT_GSMTAP_UM 217 +#define DLT_GSMTAP_ABIS 218 + +/* + * MPLS, with an MPLS label as the link-layer header. + * Requested by Michele Marchetto <michele@openbsd.org> on behalf + * of OpenBSD. + */ +#define DLT_MPLS 219 + +/* + * USB packets, beginning with a Linux USB header, with the USB header + * padded to 64 bytes; required for memory-mapped access. + */ +#define DLT_USB_LINUX_MMAPPED 220 + +/* + * DECT packets, with a pseudo-header; requested by + * Matthias Wenzel <tcpdump@mazzoo.de>. + */ +#define DLT_DECT 221 + +/* + * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov> + * Date: Mon, 11 May 2009 11:18:30 -0500 + * + * DLT_AOS. We need it for AOS Space Data Link Protocol. + * I have already written dissectors for but need an OK from + * legal before I can submit a patch. + * + */ +#define DLT_AOS 222 + +/* + * Wireless HART (Highway Addressable Remote Transducer) + * From the HART Communication Foundation + * IES/PAS 62591 + * + * Requested by Sam Roberts <vieuxtech@gmail.com>. + */ +#define DLT_WIHART 223 + +/* + * Fibre Channel FC-2 frames, beginning with a Frame_Header. + * Requested by Kahou Lei <kahou82@gmail.com>. + */ +#define DLT_FC_2 224 + +/* + * Fibre Channel FC-2 frames, beginning with an encoding of the + * SOF, and ending with an encoding of the EOF. + * + * The encodings represent the frame delimiters as 4-byte sequences + * representing the corresponding ordered sets, with K28.5 + * represented as 0xBC, and the D symbols as the corresponding + * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, + * is represented as 0xBC 0xB5 0x55 0x55. + * + * Requested by Kahou Lei <kahou82@gmail.com>. + */ +#define DLT_FC_2_WITH_FRAME_DELIMS 225 + +/* + * Solaris ipnet pseudo-header; requested by Darren Reed <Darren.Reed@Sun.COM>. + * + * The pseudo-header starts with a one-byte version number; for version 2, + * the pseudo-header is: + * + * struct dl_ipnetinfo { + * u_int8_t dli_version; + * u_int8_t dli_family; + * u_int16_t dli_htype; + * u_int32_t dli_pktlen; + * u_int32_t dli_ifindex; + * u_int32_t dli_grifindex; + * u_int32_t dli_zsrc; + * u_int32_t dli_zdst; + * }; + * + * dli_version is 2 for the current version of the pseudo-header. + * + * dli_family is a Solaris address family value, so it's 2 for IPv4 + * and 26 for IPv6. + * + * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing + * packets, and 2 for packets arriving from another zone on the same + * machine. + * + * dli_pktlen is the length of the packet data following the pseudo-header + * (so the captured length minus dli_pktlen is the length of the + * pseudo-header, assuming the entire pseudo-header was captured). + * + * dli_ifindex is the interface index of the interface on which the + * packet arrived. + * + * dli_grifindex is the group interface index number (for IPMP interfaces). + * + * dli_zsrc is the zone identifier for the source of the packet. + * + * dli_zdst is the zone identifier for the destination of the packet. + * + * A zone number of 0 is the global zone; a zone number of 0xffffffff + * means that the packet arrived from another host on the network, not + * from another zone on the same machine. + * + * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates + * which of those it is. + */ +#define DLT_IPNET 226 + +/* + * CAN (Controller Area Network) frames, with a pseudo-header as supplied + * by Linux SocketCAN, and with multi-byte numerical fields in that header + * in big-endian byte order. + * + * See Documentation/networking/can.txt in the Linux source. + * + * Requested by Felix Obenhuber <felix@obenhuber.de>. + */ +#define DLT_CAN_SOCKETCAN 227 + +/* + * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies + * whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>. + */ +#define DLT_IPV4 228 +#define DLT_IPV6 229 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), and with no FCS at the end of the frame; requested by + * Jon Smirl <jonsmirl@gmail.com>. + */ +#define DLT_IEEE802_15_4_NOFCS 230 + +/* + * Raw D-Bus: + * + * http://www.freedesktop.org/wiki/Software/dbus + * + * messages: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * + * starting with the endianness flag, followed by the message type, etc., + * but without the authentication handshake before the message sequence: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * + * Requested by Martin Vidner <martin@vidner.net>. + */ +#define DLT_DBUS 231 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + */ +#define DLT_JUNIPER_VS 232 +#define DLT_JUNIPER_SRX_E2E 233 +#define DLT_JUNIPER_FIBRECHANNEL 234 + +/* + * DVB-CI (DVB Common Interface for communication between a PC Card + * module and a DVB receiver). See + * + * http://www.kaiser.cx/pcap-dvbci.html + * + * for the specification. + * + * Requested by Martin Kaiser <martin@kaiser.cx>. + */ +#define DLT_DVB_CI 235 + +/* + * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but + * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel + * <hans-christoph.schemmel@cinterion.com>. + */ +#define DLT_MUX27010 236 + +/* + * STANAG 5066 D_PDUs. Requested by M. Baris Demiray + * <barisdemiray@gmail.com>. + */ +#define DLT_STANAG_5066_D_PDU 237 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler <hannes@juniper.net>. + */ +#define DLT_JUNIPER_ATM_CEMIC 238 + +/* + * NetFilter LOG messages + * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) + * + * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl> + */ +#define DLT_NFLOG 239 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and always + * with the payload including the FCS, as supplied by their + * netANALYZER hardware and software. + * + * Requested by Holger P. Frommer <HPfrommer@hilscher.com> + */ +#define DLT_NETANALYZER 240 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and FCS and + * with the Ethernet header preceded by 7 bytes of preamble and + * 1 byte of SFD, as supplied by their netANALYZER hardware and + * software. + * + * Requested by Holger P. Frommer <HPfrommer@hilscher.com> + */ +#define DLT_NETANALYZER_TRANSPARENT 241 + +/* + * IP-over-InfiniBand, as specified by RFC 4391. + * + * Requested by Petr Sumbera <petr.sumbera@oracle.com>. + */ +#define DLT_IPOIB 242 + +/* + * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). + * + * Requested by Guy Martin <gmsoft@tuxicoman.be>. + */ +#define DLT_MPEG_2_TS 243 + +/* + * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as + * used by their ng40 protocol tester. + * + * Requested by Jens Grimmer <jens.grimmer@ng4t.com>. + */ +#define DLT_NG40 244 + +/* + * Pseudo-header giving adapter number and flags, followed by an NFC + * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, + * as specified by NFC Forum Logical Link Control Protocol Technical + * Specification LLCP 1.1. + * + * Requested by Mike Wakerly <mikey@google.com>. + */ +#define DLT_NFC_LLCP 245 + +/* + * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. + * + * DLT_PFSYNC has different values on different platforms, and all of + * them collide with something used elsewhere. On platforms that + * don't already define it, define it as 246. + */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) +#define DLT_PFSYNC 246 +#endif + +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky <orenk@mellanox.com>. + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>. + */ +#define DLT_SCTP 248 + +/* + * USB packets, beginning with a USBPcap header. + * + * Requested by Tomasz Mon <desowin@gmail.com> + */ +#define DLT_USBPCAP 249 + +/* + * Schweitzer Engineering Laboratories "RTAC" product serial-line + * packets. + * + * Requested by Chris Bontje <chris_bontje@selinc.com>. + */ +#define DLT_RTAC_SERIAL 250 + +/* + * Bluetooth Low Energy air interface link-layer packets. + * + * Requested by Mike Kershaw <dragorn@kismetwireless.net>. + */ +#define DLT_BLUETOOTH_LE_LL 251 + +/* + * DLT type for upper-protocol layer PDU saves from wireshark. + * + * the actual contents are determined by two TAGs stored with each + * packet: + * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the + * original packet. + * + * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector + * that can make sense of the data stored. + */ +#define DLT_WIRESHARK_UPPER_PDU 252 + +/* + * DLT type for the netlink protocol (nlmon devices). + */ +#define DLT_NETLINK 253 + +/* + * Bluetooth Linux Monitor headers for the BlueZ stack. + */ +#define DLT_BLUETOOTH_LINUX_MONITOR 254 + +/* + * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as + * captured by Ubertooth. + */ +#define DLT_BLUETOOTH_BREDR_BB 255 + +/* + * Bluetooth Low Energy link layer packets, as captured by Ubertooth. + */ +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 + +/* + * PROFIBUS data link layer. + */ +#define DLT_PROFIBUS_DL 257 + +/* + * Apple's DLT_PKTAP headers. + * + * Sadly, the folks at Apple either had no clue that the DLT_USERn values + * are for internal use within an organization and partners only, and + * didn't know that the right way to get a link-layer header type is to + * ask tcpdump.org for one, or knew and didn't care, so they just + * used DLT_USER2, which causes problems for everything except for + * their version of tcpdump. + * + * So I'll just give them one; hopefully this will show up in a + * libpcap release in time for them to get this into 10.10 Big Sur + * or whatever Mavericks' successor is called. LINKTYPE_PKTAP + * will be 258 *even on OS X*; that is *intentional*, so that + * PKTAP files look the same on *all* OSes (different OSes can have + * different numerical values for a given DLT_, but *MUST NOT* have + * different values for what goes in a file, as files can be moved + * between OSes!). + * + * When capturing, on a system with a Darwin-based OS, on a device + * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this + * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, + * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, + * binary compatibility with Mavericks is preserved for programs using + * this version of libpcap. This does mean that if you were using + * DLT_USER2 for some capture device on OS X, you can't do so with + * this version of libpcap, just as you can't with Apple's libpcap - + * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't + * be able to distinguish between PKTAP and whatever you were using + * DLT_USER2 for. + * + * If the program saves the capture to a file using this version of + * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be + * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. + * That way, the file will *not* be a DLT_USER2 file. That means + * that the latest version of tcpdump, when built with this version + * of libpcap, and sufficiently recent versions of Wireshark will + * be able to read those files and interpret them correctly; however, + * Apple's version of tcpdump in OS X 10.9 won't be able to handle + * them. (Hopefully, Apple will pick up this version of libpcap, + * and the corresponding version of tcpdump, so that tcpdump will + * be able to handle the old LINKTYPE_USER2 captures *and* the new + * LINKTYPE_PKTAP captures.) + */ +#ifdef __APPLE__ +#define DLT_PKTAP DLT_USER2 +#else +#define DLT_PKTAP 258 +#endif + +/* + * Ethernet packets preceded by a header giving the last 6 octets + * of the preamble specified by 802.3-2012 Clause 65, section + * 65.1.3.2 "Transmit". + */ +#define DLT_EPON 259 + +/* + * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" + * in the PICMG HPM.2 specification. + */ +#define DLT_IPMI_HPM_2 260 + +/* + * per Joshua Wright <jwright@hasborg.com>, formats for Zwave captures. + */ +#define DLT_ZWAVE_R1_R2 261 +#define DLT_ZWAVE_R3 262 + +/* + * per Steve Karg <skarg@users.sourceforge.net>, formats for Wattstopper + * Digital Lighting Management room bus serial protocol captures. + */ +#define DLT_WATTSTOPPER_DLM 263 + +/* + * ISO 14443 contactless smart card messages. + */ +#define DLT_ISO_14443 264 + +/* + * Radio data system (RDS) groups. IEC 62106. + * Per Jonathan Brucker <jonathan.brucke@gmail.com>. + */ +#define DLT_RDS 265 + +/* + * In case the code that includes this file (directly or indirectly) + * has also included OS files that happen to define DLT_MATCHING_MAX, + * with a different value (perhaps because that OS hasn't picked up + * the latest version of our DLT definitions), we undefine the + * previous value of DLT_MATCHING_MAX. + */ +#ifdef DLT_MATCHING_MAX +#undef DLT_MATCHING_MAX +#endif +#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */ + +/* + * DLT and savefile link type values are split into a class and + * a member of that class. A class value of 0 indicates a regular + * DLT_/LINKTYPE_ value. + */ +#define DLT_CLASS(x) ((x) & 0x03ff0000) + +/* + * NetBSD-specific generic "raw" link type. The class value indicates + * that this is the generic raw type, and the lower 16 bits are the + * address family we're dealing with. Those values are NetBSD-specific; + * do not assume that they correspond to AF_ values for your operating + * system. + */ +#define DLT_CLASS_NETBSD_RAWAF 0x02240000 +#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) +#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) +#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + +#endif /* !_NET_DLT_H_ */ diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 98ccf6a951a2..25dff3a5bcd2 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -464,9 +464,12 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m, if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) { la = lltable_alloc_entry(LLTABLE(ifp), 0, dst); if (la == NULL) { + char addrbuf[INET_ADDRSTRLEN]; + log(LOG_DEBUG, "arpresolve: can't allocate llinfo for %s on %s\n", - inet_ntoa(SIN(dst)->sin_addr), if_name(ifp)); + inet_ntoa_r(SIN(dst)->sin_addr, addrbuf), + if_name(ifp)); m_freem(m); return (EINVAL); } @@ -803,6 +806,7 @@ in_arpinput(struct mbuf *m) size_t linkhdrsize; int lladdr_off; int error; + char addrbuf[INET_ADDRSTRLEN]; sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; @@ -927,7 +931,7 @@ match: goto drop; /* it's from me, ignore it. */ if (!bcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { ARP_LOG(LOG_NOTICE, "link address is broadcast for IP address " - "%s!\n", inet_ntoa(isaddr)); + "%s!\n", inet_ntoa_r(isaddr, addrbuf)); goto drop; } @@ -949,7 +953,7 @@ match: myaddr.s_addr != 0) { ARP_LOG(LOG_ERR, "%*D is using my IP address %s on %s!\n", ifp->if_addrlen, (u_char *)ar_sha(ah), ":", - inet_ntoa(isaddr), ifp->if_xname); + inet_ntoa_r(isaddr, addrbuf), ifp->if_xname); itaddr = myaddr; ARPSTAT_INC(dupips); goto reply; @@ -1086,12 +1090,14 @@ reply: if (nh4.nh_ifp != ifp) { ARP_LOG(LOG_INFO, "proxy: ignoring request" " from %s via %s\n", - inet_ntoa(isaddr), ifp->if_xname); + inet_ntoa_r(isaddr, addrbuf), + ifp->if_xname); goto drop; } #ifdef DEBUG_PROXY - printf("arp: proxying for %s\n", inet_ntoa(itaddr)); + printf("arp: proxying for %s\n", + inet_ntoa_r(itaddr, addrbuf)); #endif } } @@ -1101,7 +1107,7 @@ reply: /* RFC 3927 link-local IPv4; always reply by broadcast. */ #ifdef DEBUG_LINKLOCAL printf("arp: sending reply for link-local addr %s\n", - inet_ntoa(itaddr)); + inet_ntoa_r(itaddr, addrbuf)); #endif m->m_flags |= M_BCAST; m->m_flags &= ~M_MCAST; @@ -1162,6 +1168,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp uint8_t linkhdr[LLE_MAX_LINKHDR]; size_t linkhdrsize; int lladdr_off; + char addrbuf[INET_ADDRSTRLEN]; LLE_WLOCK_ASSERT(la); @@ -1170,7 +1177,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp if (log_arp_wrong_iface) ARP_LOG(LOG_WARNING, "%s is on %s " "but got reply from %*D on %s\n", - inet_ntoa(isaddr), + inet_ntoa_r(isaddr, addrbuf), la->lle_tbl->llt_ifp->if_xname, ifp->if_addrlen, (u_char *)ar_sha(ah), ":", ifp->if_xname); @@ -1187,13 +1194,14 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp "permanent entry for %s on %s\n", ifp->if_addrlen, (u_char *)ar_sha(ah), ":", - inet_ntoa(isaddr), ifp->if_xname); + inet_ntoa_r(isaddr, addrbuf), + ifp->if_xname); return; } if (log_arp_movements) { ARP_LOG(LOG_INFO, "%s moved from %*D " "to %*D on %s\n", - inet_ntoa(isaddr), + inet_ntoa_r(isaddr, addrbuf), ifp->if_addrlen, (u_char *)&la->ll_addr, ":", ifp->if_addrlen, (u_char *)ar_sha(ah), ":", diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 3b7d3275282a..9125389c2c97 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -314,12 +314,12 @@ igmp_scrub_context(struct mbuf *m) #ifdef KTR static __inline char * -inet_ntoa_haddr(in_addr_t haddr) +inet_ntoa_haddr(in_addr_t haddr, char *addrbuf) { struct in_addr ia; ia.s_addr = htonl(haddr); - return (inet_ntoa(ia)); + return (inet_ntoa_r(ia, addrbuf)); } #endif @@ -804,6 +804,9 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip, struct in_multi *inm; int is_general_query; uint16_t timer; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif is_general_query = 0; @@ -873,7 +876,8 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip, inm = inm_lookup(ifp, igmp->igmp_group); if (inm != NULL) { CTR3(KTR_IGMPV3, "process v2 query %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, + ifp->if_xname); igmp_v2_update_group(inm, timer); } } @@ -903,9 +907,12 @@ out_locked: static void igmp_v2_update_group(struct in_multi *inm, const int timer) { +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif CTR4(KTR_IGMPV3, "%s: %s/%s timer=%d", __func__, - inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname, timer); + inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp->if_xname, timer); IN_MULTI_LOCK_ASSERT(); @@ -956,6 +963,9 @@ igmp_input_v3_query(struct ifnet *ifp, const struct ip *ip, uint32_t maxresp, nsrc, qqi; uint16_t timer; uint8_t qrv; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif is_general_query = 0; @@ -1086,7 +1096,8 @@ igmp_input_v3_query(struct ifnet *ifp, const struct ip *ip, } } CTR3(KTR_IGMPV3, "process v3 %s query on ifp %p(%s)", - inet_ntoa(igmpv3->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmpv3->igmp_group, addrbuf), ifp, + ifp->if_xname); /* * If there is a pending General Query response * scheduled sooner than the selected delay, no @@ -1219,6 +1230,9 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif IGMPSTAT_INC(igps_rcv_reports); @@ -1247,7 +1261,7 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, } CTR3(KTR_IGMPV3, "process v1 report %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, ifp->if_xname); /* * IGMPv1 report suppression. @@ -1290,14 +1304,16 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, case IGMP_AWAKENING_MEMBER: CTR3(KTR_IGMPV3, "report suppressed for %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, + ifp->if_xname); case IGMP_SLEEPING_MEMBER: inm->inm_state = IGMP_SLEEPING_MEMBER; break; case IGMP_REPORTING_MEMBER: CTR3(KTR_IGMPV3, "report suppressed for %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, + ifp->if_xname); if (igi->igi_version == IGMP_VERSION_1) inm->inm_state = IGMP_LAZY_MEMBER; else if (igi->igi_version == IGMP_VERSION_2) @@ -1328,6 +1344,9 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif /* * Make sure we don't hear our own membership report. Fast @@ -1371,7 +1390,7 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, ifa_free(&ia->ia_ifa); CTR3(KTR_IGMPV3, "process v2 report %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, ifp->if_xname); /* * IGMPv2 report suppression. @@ -1412,7 +1431,8 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, case IGMP_AWAKENING_MEMBER: CTR3(KTR_IGMPV3, "report suppressed for %s on ifp %p(%s)", - inet_ntoa(igmp->igmp_group), ifp, ifp->if_xname); + inet_ntoa_r(igmp->igmp_group, addrbuf), ifp, + ifp->if_xname); case IGMP_LAZY_MEMBER: inm->inm_state = IGMP_LAZY_MEMBER; break; @@ -1814,6 +1834,9 @@ igmp_v3_process_group_timers(struct igmp_ifsoftc *igi, { int query_response_timer_expired; int state_change_retransmit_timer_expired; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif IN_MULTI_LOCK_ASSERT(); IGMP_LOCK_ASSERT(); @@ -1900,7 +1923,8 @@ igmp_v3_process_group_timers(struct igmp_ifsoftc *igi, inm_commit(inm); CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__, - inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname); + inet_ntoa_r(inm->inm_addr, addrbuf), + inm->inm_ifp->if_xname); /* * If we are leaving the group for good, make sure @@ -2346,9 +2370,12 @@ igmp_initial_join(struct in_multi *inm, struct igmp_ifsoftc *igi) struct ifnet *ifp; struct mbufq *mq; int error, retval, syncstates; - +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif + CTR4(KTR_IGMPV3, "%s: initial join %s on ifp %p(%s)", - __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp, + __func__, inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp, inm->inm_ifp->if_xname); error = 0; @@ -2459,7 +2486,8 @@ igmp_initial_join(struct in_multi *inm, struct igmp_ifsoftc *igi) if (syncstates) { inm_commit(inm); CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__, - inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname); + inet_ntoa_r(inm->inm_addr, addrbuf), + inm->inm_ifp->if_xname); } return (error); @@ -2473,9 +2501,12 @@ igmp_handle_state_change(struct in_multi *inm, struct igmp_ifsoftc *igi) { struct ifnet *ifp; int retval; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif CTR4(KTR_IGMPV3, "%s: state change for %s on ifp %p(%s)", - __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp, + __func__, inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp, inm->inm_ifp->if_xname); ifp = inm->inm_ifp; @@ -2496,7 +2527,8 @@ igmp_handle_state_change(struct in_multi *inm, struct igmp_ifsoftc *igi) CTR1(KTR_IGMPV3, "%s: nothing to do", __func__); inm_commit(inm); CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__, - inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname); + inet_ntoa_r(inm->inm_addr, addrbuf), + inm->inm_ifp->if_xname); return (0); } @@ -2531,11 +2563,14 @@ static void igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi) { int syncstates; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif syncstates = 1; CTR4(KTR_IGMPV3, "%s: final leave %s on ifp %p(%s)", - __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp, + __func__, inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp, inm->inm_ifp->if_xname); IN_MULTI_LOCK_ASSERT(); @@ -2578,7 +2613,7 @@ igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi) } CTR4(KTR_IGMPV3, "%s: Leaving %s/%s with %d " "pending retransmissions.", __func__, - inet_ntoa(inm->inm_addr), + inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp->if_xname, inm->inm_scrv); if (inm->inm_scrv == 0) { inm->inm_state = IGMP_NOT_MEMBER; @@ -2612,10 +2647,12 @@ igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi) if (syncstates) { inm_commit(inm); CTR3(KTR_IGMPV3, "%s: T1 -> T0 for %s/%s", __func__, - inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname); + inet_ntoa_r(inm->inm_addr, addrbuf), + inm->inm_ifp->if_xname); inm->inm_st[1].iss_fmode = MCAST_UNDEFINED; CTR3(KTR_IGMPV3, "%s: T1 now MCAST_UNDEFINED for %s/%s", - __func__, inet_ntoa(inm->inm_addr), inm->inm_ifp->if_xname); + __func__, inet_ntoa_r(inm->inm_addr, addrbuf), + inm->inm_ifp->if_xname); } } @@ -2663,6 +2700,9 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm, int type; in_addr_t naddr; uint8_t mode; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif IN_MULTI_LOCK_ASSERT(); @@ -2741,7 +2781,7 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm, if (type == IGMP_DO_NOTHING) { CTR3(KTR_IGMPV3, "%s: nothing to do for %s/%s", - __func__, inet_ntoa(inm->inm_addr), + __func__, inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp->if_xname); return (0); } @@ -2756,7 +2796,7 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm, minrec0len += sizeof(in_addr_t); CTR4(KTR_IGMPV3, "%s: queueing %s for %s/%s", __func__, - igmp_rec_type_to_str(type), inet_ntoa(inm->inm_addr), + igmp_rec_type_to_str(type), inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp->if_xname); /* @@ -2845,7 +2885,7 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm, msrcs = 0; RB_FOREACH_SAFE(ims, ip_msource_tree, &inm->inm_srcs, nims) { CTR2(KTR_IGMPV3, "%s: visit node %s", __func__, - inet_ntoa_haddr(ims->ims_haddr)); + inet_ntoa_haddr(ims->ims_haddr, addrbuf)); now = ims_get_mode(inm, ims, 1); CTR2(KTR_IGMPV3, "%s: node is %d", __func__, now); if ((now != mode) || @@ -2941,7 +2981,7 @@ igmp_v3_enqueue_group_record(struct mbufq *mq, struct in_multi *inm, msrcs = 0; RB_FOREACH_FROM(ims, ip_msource_tree, nims) { CTR2(KTR_IGMPV3, "%s: visit node %s", __func__, - inet_ntoa_haddr(ims->ims_haddr)); + inet_ntoa_haddr(ims->ims_haddr, addrbuf)); now = ims_get_mode(inm, ims, 1); if ((now != mode) || (now == mode && mode == MCAST_UNDEFINED)) { @@ -3024,6 +3064,9 @@ igmp_v3_enqueue_filter_change(struct mbufq *mq, struct in_multi *inm) int nallow, nblock; uint8_t mode, now, then; rectype_t crt, drt, nrt; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif IN_MULTI_LOCK_ASSERT(); @@ -3133,7 +3176,8 @@ igmp_v3_enqueue_filter_change(struct mbufq *mq, struct in_multi *inm) nims = RB_MIN(ip_msource_tree, &inm->inm_srcs); RB_FOREACH_FROM(ims, ip_msource_tree, nims) { CTR2(KTR_IGMPV3, "%s: visit node %s", - __func__, inet_ntoa_haddr(ims->ims_haddr)); + __func__, + inet_ntoa_haddr(ims->ims_haddr, addrbuf)); now = ims_get_mode(inm, ims, 1); then = ims_get_mode(inm, ims, 0); CTR3(KTR_IGMPV3, "%s: mode: t0 %d, t1 %d", diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 9588915f29a5..7187469bcc58 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1218,7 +1218,7 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr */ if (!(rt_flags & RTF_HOST) && info.rti_ifp != ifp) { const char *sa, *mask, *addr, *lim; - int len; + const struct sockaddr_in *l3sin; mask = (const char *)&rt_mask; /* @@ -1230,14 +1230,17 @@ in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr sa = (const char *)&rt_key; addr = (const char *)l3addr; - len = ((const struct sockaddr_in *)l3addr)->sin_len; - lim = addr + len; + l3sin = (const struct sockaddr_in *)l3addr; + lim = addr + l3sin->sin_len; for ( ; addr < lim; sa++, mask++, addr++) { if ((*sa ^ *addr) & *mask) { #ifdef DIAGNOSTIC - log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n", - inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); + char addrbuf[INET_ADDRSTRLEN]; + + log(LOG_INFO, "IPv4 address: \"%s\" " + "is not on the network\n", + inet_ntoa_r(l3sin->sin_addr, addrbuf)); #endif return (EINVAL); } diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 0800512e5331..d449b1be296d 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -433,8 +433,6 @@ __END_DECLS #define IP_BINDANY 24 /* bool: allow bind to any address */ #define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */ #define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */ -#define IP_ORIGDSTADDR 27 /* bool: receive IP dst addr/port w/dgram */ -#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR /* * Options for controlling the firewall and dummynet. @@ -648,7 +646,6 @@ int in_localaddr(struct in_addr); int in_localip(struct in_addr); int in_ifhasaddr(struct ifnet *, struct in_addr); int inet_aton(const char *, struct in_addr *); /* in libkern */ -char *inet_ntoa(struct in_addr); /* in libkern */ char *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */ char *inet_ntop(int, const void *, char *, socklen_t); /* in libkern */ int inet_pton(int af, const char *, void *); /* in libkern */ diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index 07b5bbabb691..078f2f24536a 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -495,9 +495,12 @@ in_getmulti(struct ifnet *ifp, const struct in_addr *group, ("%s: ifma not AF_INET", __func__)); KASSERT(inm != NULL, ("%s: no ifma_protospec", __func__)); if (inm->inm_ifma != ifma || inm->inm_ifp != ifp || - !in_hosteq(inm->inm_addr, *group)) + !in_hosteq(inm->inm_addr, *group)) { + char addrbuf[INET_ADDRSTRLEN]; + panic("%s: ifma %p is inconsistent with %p (%s)", - __func__, ifma, inm, inet_ntoa(*group)); + __func__, ifma, inm, inet_ntoa_r(*group, addrbuf)); + } #endif ++inm->inm_refcount; *pinm = inm; @@ -875,7 +878,8 @@ inm_get_source(struct in_multi *inm, const in_addr_t haddr, struct ip_msource find; struct ip_msource *ims, *nims; #ifdef KTR - struct in_addr ia; + struct in_addr ia; + char addrbuf[INET_ADDRSTRLEN]; #endif find.ims_haddr = haddr; @@ -894,7 +898,7 @@ inm_get_source(struct in_multi *inm, const in_addr_t haddr, #ifdef KTR ia.s_addr = htonl(haddr); CTR3(KTR_IGMPV3, "%s: allocated %s as %p", __func__, - inet_ntoa(ia), ims); + inet_ntoa_r(ia, addrbuf), ims); #endif } @@ -912,6 +916,7 @@ ims_merge(struct ip_msource *ims, const struct in_msource *lims, { int n = rollback ? -1 : 1; #ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; struct in_addr ia; ia.s_addr = htonl(ims->ims_haddr); @@ -919,21 +924,21 @@ ims_merge(struct ip_msource *ims, const struct in_msource *lims, if (lims->imsl_st[0] == MCAST_EXCLUDE) { CTR3(KTR_IGMPV3, "%s: t1 ex -= %d on %s", - __func__, n, inet_ntoa(ia)); + __func__, n, inet_ntoa_r(ia, addrbuf)); ims->ims_st[1].ex -= n; } else if (lims->imsl_st[0] == MCAST_INCLUDE) { CTR3(KTR_IGMPV3, "%s: t1 in -= %d on %s", - __func__, n, inet_ntoa(ia)); + __func__, n, inet_ntoa_r(ia, addrbuf)); ims->ims_st[1].in -= n; } if (lims->imsl_st[1] == MCAST_EXCLUDE) { CTR3(KTR_IGMPV3, "%s: t1 ex += %d on %s", - __func__, n, inet_ntoa(ia)); + __func__, n, inet_ntoa_r(ia, addrbuf)); ims->ims_st[1].ex += n; } else if (lims->imsl_st[1] == MCAST_INCLUDE) { CTR3(KTR_IGMPV3, "%s: t1 in += %d on %s", - __func__, n, inet_ntoa(ia)); + __func__, n, inet_ntoa_r(ia, addrbuf)); ims->ims_st[1].in += n; } } @@ -1166,11 +1171,14 @@ in_joingroup_locked(struct ifnet *ifp, const struct in_addr *gina, struct in_mfilter timf; struct in_multi *inm; int error; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif IN_MULTI_LOCK_ASSERT(); CTR4(KTR_IGMPV3, "%s: join %s on %p(%s))", __func__, - inet_ntoa(*gina), ifp, ifp->if_xname); + inet_ntoa_r(*gina, addrbuf), ifp, ifp->if_xname); error = 0; inm = NULL; @@ -1248,13 +1256,16 @@ in_leavegroup_locked(struct in_multi *inm, /*const*/ struct in_mfilter *imf) { struct in_mfilter timf; int error; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif error = 0; IN_MULTI_LOCK_ASSERT(); CTR5(KTR_IGMPV3, "%s: leave inm %p, %s/%s, imf %p", __func__, - inm, inet_ntoa(inm->inm_addr), + inm, inet_ntoa_r(inm->inm_addr, addrbuf), (inm_is_ifp_detached(inm) ? "null" : inm->inm_ifp->if_xname), imf); @@ -1302,9 +1313,13 @@ in_addmulti(struct in_addr *ap, struct ifnet *ifp) { struct in_multi *pinm; int error; +#ifdef INVARIANTS + char addrbuf[INET_ADDRSTRLEN]; +#endif KASSERT(IN_LOCAL_GROUP(ntohl(ap->s_addr)), - ("%s: %s not in 224.0.0.0/24", __func__, inet_ntoa(*ap))); + ("%s: %s not in 224.0.0.0/24", __func__, + inet_ntoa_r(*ap, addrbuf))); error = in_joingroup(ifp, ap, NULL, &pinm); if (error != 0) @@ -1349,6 +1364,9 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) size_t idx; uint16_t fmode; int error, doblock; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif ifp = NULL; error = 0; @@ -1384,7 +1402,7 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) doblock = 1; CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p", - __func__, inet_ntoa(mreqs.imr_interface), ifp); + __func__, inet_ntoa_r(mreqs.imr_interface, addrbuf), ifp); break; } @@ -1457,7 +1475,8 @@ inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) ims = imo_match_source(imo, idx, &ssa->sa); if ((ims != NULL && doblock) || (ims == NULL && !doblock)) { CTR3(KTR_IGMPV3, "%s: source %s %spresent", __func__, - inet_ntoa(ssa->sin.sin_addr), doblock ? "" : "not "); + inet_ntoa_r(ssa->sin.sin_addr, addrbuf), + doblock ? "" : "not "); error = EADDRNOTAVAIL; goto out_inp_locked; } @@ -1934,6 +1953,9 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) struct in_msource *lims; size_t idx; int error, is_new; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif ifp = NULL; imf = NULL; @@ -1986,7 +2008,7 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt) ifp = inp_lookup_mcast_ifp(inp, &gsa->sin, mreqs.imr_interface); CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p", - __func__, inet_ntoa(mreqs.imr_interface), ifp); + __func__, inet_ntoa_r(mreqs.imr_interface, addrbuf), ifp); break; } @@ -2233,6 +2255,9 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) struct in_multi *inm; size_t idx; int error, is_final; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif ifp = NULL; error = 0; @@ -2287,7 +2312,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) INADDR_TO_IFP(mreqs.imr_interface, ifp); CTR3(KTR_IGMPV3, "%s: imr_interface = %s, ifp = %p", - __func__, inet_ntoa(mreqs.imr_interface), ifp); + __func__, inet_ntoa_r(mreqs.imr_interface, addrbuf), ifp); break; @@ -2368,7 +2393,7 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt) ims = imo_match_source(imo, idx, &ssa->sa); if (ims == NULL) { CTR3(KTR_IGMPV3, "%s: source %s %spresent", __func__, - inet_ntoa(ssa->sin.sin_addr), "not "); + inet_ntoa_r(ssa->sin.sin_addr, addrbuf), "not "); error = EADDRNOTAVAIL; goto out_inp_locked; } @@ -2450,6 +2475,9 @@ inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) struct ifnet *ifp; struct ip_moptions *imo; int error; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif if (sopt->sopt_valsize == sizeof(struct ip_mreqn)) { /* @@ -2488,7 +2516,7 @@ inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) return (EADDRNOTAVAIL); } CTR3(KTR_IGMPV3, "%s: ifp = %p, addr = %s", __func__, ifp, - inet_ntoa(addr)); + inet_ntoa_r(addr, addrbuf)); } /* Reject interfaces which do not support multicast. */ @@ -2846,6 +2874,9 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS) int retval; u_int namelen; uint32_t fmode, ifindex; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif name = (int *)arg1; namelen = arg2; @@ -2866,7 +2897,7 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS) group.s_addr = name[1]; if (!IN_MULTICAST(ntohl(group.s_addr))) { CTR2(KTR_IGMPV3, "%s: group %s is not multicast", - __func__, inet_ntoa(group)); + __func__, inet_ntoa_r(group, addrbuf)); return (EINVAL); } @@ -2901,7 +2932,7 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS) struct in_addr ina; ina.s_addr = htonl(ims->ims_haddr); CTR2(KTR_IGMPV3, "%s: visit node %s", __func__, - inet_ntoa(ina)); + inet_ntoa_r(ina, addrbuf)); #endif /* * Only copy-out sources which are in-mode. @@ -2965,13 +2996,14 @@ void inm_print(const struct in_multi *inm) { int t; + char addrbuf[INET_ADDRSTRLEN]; if ((ktr_mask & KTR_IGMPV3) == 0) return; printf("%s: --- begin inm %p ---\n", __func__, inm); printf("addr %s ifp %p(%s) ifma %p\n", - inet_ntoa(inm->inm_addr), + inet_ntoa_r(inm->inm_addr, addrbuf), inm->inm_ifp, inm->inm_ifp->if_xname, inm->inm_ifma); diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 9d66ca38f3c8..78b5bae531da 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -329,7 +329,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) inp->inp_gencnt = ++pcbinfo->ipi_gencnt; refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */ INP_LIST_WUNLOCK(pcbinfo); -#if defined(IPSEC) || defined(MAC) +#if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC) out: if (error != 0) { crfree(inp->inp_cred); @@ -2492,10 +2492,6 @@ db_print_inpflags(int inp_flags) db_printf("%sINP_RECVDSTADDR", comma ? ", " : ""); comma = 1; } - if (inp_flags & INP_ORIGDSTADDR) { - db_printf("%sINP_ORIGDSTADDR", comma ? ", " : ""); - comma = 1; - } if (inp_flags & INP_HDRINCL) { db_printf("%sINP_HDRINCL", comma ? ", " : ""); comma = 1; diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index e57138483c15..3842695597c6 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -618,7 +618,6 @@ short inp_so_options(const struct inpcb *inp); #define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */ #define INP_RECVRSSBUCKETID 0x00000200 /* populate recv datagram with bucket id */ #define INP_RATE_LIMIT_CHANGED 0x00000400 /* rate limit needs attention */ -#define INP_ORIGDSTADDR 0x00000800 /* receive IP dst address/port */ /* * Flags passed to in_pcblookup*() functions. diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 932dc567236d..363716ff2175 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -148,7 +148,7 @@ struct protosw inetsw[] = { .pr_type = SOCK_SEQPACKET, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, + .pr_flags = PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp_input, .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, @@ -160,7 +160,7 @@ struct protosw inetsw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp_input, .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index d1a26a8184b8..37a3b293bc4f 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -380,10 +380,12 @@ icmp_input(struct mbuf **mp, int *offp, int proto) */ #ifdef ICMPPRINTFS if (icmpprintfs) { - char buf[4 * sizeof "123"]; - strcpy(buf, inet_ntoa(ip->ip_src)); + char srcbuf[INET_ADDRSTRLEN]; + char dstbuf[INET_ADDRSTRLEN]; + printf("icmp_input from %s to %s, len %d\n", - buf, inet_ntoa(ip->ip_dst), icmplen); + inet_ntoa_r(ip->ip_src, srcbuf), + inet_ntoa_r(ip->ip_dst, dstbuf), icmplen); } #endif if (icmplen < ICMP_MINLEN) { @@ -649,11 +651,12 @@ reflect: icmpdst.sin_addr = icp->icmp_gwaddr; #ifdef ICMPPRINTFS if (icmpprintfs) { - char buf[4 * sizeof "123"]; - strcpy(buf, inet_ntoa(icp->icmp_ip.ip_dst)); + char dstbuf[INET_ADDRSTRLEN]; + char gwbuf[INET_ADDRSTRLEN]; printf("redirect dst %s to %s\n", - buf, inet_ntoa(icp->icmp_gwaddr)); + inet_ntoa_r(icp->icmp_ip.ip_dst, dstbuf), + inet_ntoa_r(icp->icmp_gwaddr, gwbuf)); } #endif icmpsrc.sin_addr = icp->icmp_ip.ip_dst; @@ -901,10 +904,12 @@ icmp_send(struct mbuf *m, struct mbuf *opts) m->m_pkthdr.rcvif = (struct ifnet *)0; #ifdef ICMPPRINTFS if (icmpprintfs) { - char buf[4 * sizeof "123"]; - strcpy(buf, inet_ntoa(ip->ip_dst)); + char dstbuf[INET_ADDRSTRLEN]; + char srcbuf[INET_ADDRSTRLEN]; + printf("icmp_send dst %s src %s\n", - buf, inet_ntoa(ip->ip_src)); + inet_ntoa_r(ip->ip_dst, dstbuf), + inet_ntoa_r(ip->ip_src, srcbuf)); } #endif (void) ip_output(m, opts, NULL, 0, NULL, NULL); diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index c0730caca8f4..58f8cc70a2e9 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -845,6 +845,9 @@ add_vif(struct vifctl *vifcp) struct ifaddr *ifa; struct ifnet *ifp; int error; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif VIF_LOCK(); if (vifcp->vifc_vifi >= MAXVIFS) { @@ -929,7 +932,7 @@ add_vif(struct vifctl *vifcp) VIF_UNLOCK(); CTR4(KTR_IPMF, "%s: add vif %d laddr %s thresh %x", __func__, - (int)vifcp->vifc_vifi, inet_ntoa(vifcp->vifc_lcl_addr), + (int)vifcp->vifc_vifi, inet_ntoa_r(vifcp->vifc_lcl_addr, addrbuf), (int)vifcp->vifc_threshold); return 0; @@ -1052,6 +1055,9 @@ add_mfc(struct mfcctl2 *mfccp) struct rtdetq *rte, *nrte; u_long hash = 0; u_short nstl; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif VIF_LOCK(); MFC_LOCK(); @@ -1061,7 +1067,7 @@ add_mfc(struct mfcctl2 *mfccp) /* If an entry already exists, just update the fields */ if (rt) { CTR4(KTR_IPMF, "%s: update mfc orig %s group %lx parent %x", - __func__, inet_ntoa(mfccp->mfcc_origin), + __func__, inet_ntoa_r(mfccp->mfcc_origin, addrbuf), (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), mfccp->mfcc_parent); update_mfc_params(rt, mfccp); @@ -1081,7 +1087,7 @@ add_mfc(struct mfcctl2 *mfccp) !TAILQ_EMPTY(&rt->mfc_stall)) { CTR5(KTR_IPMF, "%s: add mfc orig %s group %lx parent %x qh %p", - __func__, inet_ntoa(mfccp->mfcc_origin), + __func__, inet_ntoa_r(mfccp->mfcc_origin, addrbuf), (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), mfccp->mfcc_parent, TAILQ_FIRST(&rt->mfc_stall)); @@ -1155,12 +1161,15 @@ del_mfc(struct mfcctl2 *mfccp) struct in_addr origin; struct in_addr mcastgrp; struct mfc *rt; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif origin = mfccp->mfcc_origin; mcastgrp = mfccp->mfcc_mcastgrp; CTR3(KTR_IPMF, "%s: delete mfc orig %s group %lx", __func__, - inet_ntoa(origin), (u_long)ntohl(mcastgrp.s_addr)); + inet_ntoa_r(origin, addrbuf), (u_long)ntohl(mcastgrp.s_addr)); MFC_LOCK(); @@ -1223,9 +1232,13 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct mfc *rt; int error; vifi_t vifi; +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif CTR3(KTR_IPMF, "ip_mforward: delete mfc orig %s group %lx ifp %p", - inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr), ifp); + inet_ntoa_r(ip->ip_src, addrbuf), (u_long)ntohl(ip->ip_dst.s_addr), + ifp); if (ip->ip_hl < (sizeof(struct ip) + TUNNEL_LEN) >> 2 || ((u_char *)(ip + 1))[1] != IPOPT_LSRR ) { @@ -1288,7 +1301,7 @@ X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, MRTSTAT_INC(mrts_mfc_misses); MRTSTAT_INC(mrts_no_route); CTR2(KTR_IPMF, "ip_mforward: no mfc for (%s,%lx)", - inet_ntoa(ip->ip_src), (u_long)ntohl(ip->ip_dst.s_addr)); + inet_ntoa_r(ip->ip_src, addrbuf), (u_long)ntohl(ip->ip_dst.s_addr)); /* * Allocate mbufs early so that we don't do extra work if we are @@ -2570,7 +2583,10 @@ pim_input(struct mbuf **mp, int *offp, int proto) int minlen; int datalen = ntohs(ip->ip_len) - iphlen; int ip_tos; - +#ifdef KTR + char addrbuf[INET_ADDRSTRLEN]; +#endif + *mp = NULL; /* Keep statistics */ @@ -2583,7 +2599,7 @@ pim_input(struct mbuf **mp, int *offp, int proto) if (datalen < PIM_MINLEN) { PIMSTAT_INC(pims_rcv_tooshort); CTR3(KTR_IPMF, "%s: short packet (%d) from %s", - __func__, datalen, inet_ntoa(ip->ip_src)); + __func__, datalen, inet_ntoa_r(ip->ip_src, addrbuf)); m_freem(m); return (IPPROTO_DONE); } @@ -2683,7 +2699,8 @@ pim_input(struct mbuf **mp, int *offp, int proto) encap_ip = (struct ip *)(reghdr + 1); CTR3(KTR_IPMF, "%s: register: encap ip src %s len %d", - __func__, inet_ntoa(encap_ip->ip_src), ntohs(encap_ip->ip_len)); + __func__, inet_ntoa_r(encap_ip->ip_src, addrbuf), + ntohs(encap_ip->ip_len)); /* verify the version number of the inner packet */ if (encap_ip->ip_v != IPVERSION) { @@ -2697,7 +2714,7 @@ pim_input(struct mbuf **mp, int *offp, int proto) if (!IN_MULTICAST(ntohl(encap_ip->ip_dst.s_addr))) { PIMSTAT_INC(pims_rcv_badregisters); CTR2(KTR_IPMF, "%s: bad encap ip dest %s", __func__, - inet_ntoa(encap_ip->ip_dst)); + inet_ntoa_r(encap_ip->ip_dst, addrbuf)); m_freem(m); return (IPPROTO_DONE); } diff --git a/sys/netinet/ip_options.c b/sys/netinet/ip_options.c index 3e44ffb7b7c9..399c88bdbb52 100644 --- a/sys/netinet/ip_options.c +++ b/sys/netinet/ip_options.c @@ -196,16 +196,19 @@ ip_dooptions(struct mbuf *m, int pass) #endif if (!V_ip_dosourceroute) { if (V_ipforwarding) { - char buf[16]; /* aaa.bbb.ccc.ddd\0 */ + char srcbuf[INET_ADDRSTRLEN]; + char dstbuf[INET_ADDRSTRLEN]; + /* * Acting as a router, so generate * ICMP */ nosourcerouting: - strcpy(buf, inet_ntoa(ip->ip_dst)); log(LOG_WARNING, - "attempted source route from %s to %s\n", - inet_ntoa(ip->ip_src), buf); + "attempted source route from %s " + "to %s\n", + inet_ntoa_r(ip->ip_src, srcbuf), + inet_ntoa_r(ip->ip_dst, dstbuf)); type = ICMP_UNREACH; code = ICMP_UNREACH_SRCFAIL; goto bad; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 53f259295e36..fc229d1f078b 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1065,7 +1065,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_MINTTL: case IP_RECVOPTS: case IP_RECVRETOPTS: - case IP_ORIGDSTADDR: case IP_RECVDSTADDR: case IP_RECVTTL: case IP_RECVIF: @@ -1127,10 +1126,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) OPTSET(INP_RECVDSTADDR); break; - case IP_ORIGDSTADDR: - OPTSET2(INP_ORIGDSTADDR, optval); - break; - case IP_RECVTTL: OPTSET(INP_RECVTTL); break; @@ -1263,7 +1258,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_MINTTL: case IP_RECVOPTS: case IP_RECVRETOPTS: - case IP_ORIGDSTADDR: case IP_RECVDSTADDR: case IP_RECVTTL: case IP_RECVIF: @@ -1309,10 +1303,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) optval = OPTBIT(INP_RECVDSTADDR); break; - case IP_ORIGDSTADDR: - optval = OPTBIT2(INP_ORIGDSTADDR); - break; - case IP_RECVTTL: optval = OPTBIT(INP_RECVTTL); break; diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h index 506193c6b557..e9e843c6e95a 100644 --- a/sys/netinet/libalias/alias_local.h +++ b/sys/netinet/libalias/alias_local.h @@ -70,6 +70,12 @@ #define GET_ALIAS_PORT -1 #define GET_ALIAS_ID GET_ALIAS_PORT +#ifdef _KERNEL +#define INET_NTOA_BUF(buf) (buf) +#else +#define INET_NTOA_BUF(buf) (buf), sizeof(buf) +#endif + struct proxy_entry; struct libalias { diff --git a/sys/netinet/libalias/alias_nbt.c b/sys/netinet/libalias/alias_nbt.c index a7598f823d80..b041699f9fb6 100644 --- a/sys/netinet/libalias/alias_nbt.c +++ b/sys/netinet/libalias/alias_nbt.c @@ -344,6 +344,9 @@ AliasHandleUdpNbt( NbtDataHeader *ndh; u_char *p = NULL; char *pmax; +#ifdef LIBALIAS_DEBUG + char addrbuf[INET_ADDRSTRLEN]; +#endif (void)la; (void)lnk; @@ -379,7 +382,8 @@ AliasHandleUdpNbt( if (p == NULL || (char *)p > pmax) p = NULL; #ifdef LIBALIAS_DEBUG - printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); + printf("%s:%d-->", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)), + ntohs(ndh->source_port)); #endif /* Doing an IP address and Port number Translation */ if (uh->uh_sum != 0) { @@ -399,7 +403,8 @@ AliasHandleUdpNbt( ndh->source_ip = *alias_address; ndh->source_port = alias_port; #ifdef LIBALIAS_DEBUG - printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port)); + printf("%s:%d\n", inet_ntoa_r(ndh->source_ip, INET_NTOA_BUF(addrbuf)), + ntohs(ndh->source_port)); fflush(stdout); #endif return ((p == NULL) ? -1 : 0); @@ -480,6 +485,10 @@ AliasHandleResourceNB( { NBTNsRNB *nb; u_short bcount; +#ifdef LIBALIAS_DEBUG + char oldbuf[INET_ADDRSTRLEN]; + char newbuf[INET_ADDRSTRLEN]; +#endif if (q == NULL || (char *)(q + 1) > pmax) return (NULL); @@ -491,8 +500,10 @@ AliasHandleResourceNB( /* Processing all in_addr array */ #ifdef LIBALIAS_DEBUG - printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount); + printf("NB rec[%s->%s, %dbytes] ", + inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)), + inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf)), + bcount); #endif while (nb != NULL && bcount != 0) { if ((char *)(nb + 1) > pmax) { @@ -500,7 +511,7 @@ AliasHandleResourceNB( break; } #ifdef LIBALIAS_DEBUG - printf("<%s>", inet_ntoa(nb->addr)); + printf("<%s>", inet_ntoa_r(nb->addr, INET_NTOA_BUF(newbuf))); #endif if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) { if (*nbtarg->uh_sum != 0) { @@ -547,6 +558,10 @@ AliasHandleResourceA( { NBTNsResourceA *a; u_short bcount; +#ifdef LIBALIAS_DEBUG + char oldbuf[INET_ADDRSTRLEN]; + char newbuf[INET_ADDRSTRLEN]; +#endif if (q == NULL || (char *)(q + 1) > pmax) return (NULL); @@ -559,14 +574,15 @@ AliasHandleResourceA( /* Processing all in_addr array */ #ifdef LIBALIAS_DEBUG - printf("Arec [%s", inet_ntoa(nbtarg->oldaddr)); - printf("->%s]", inet_ntoa(nbtarg->newaddr)); + printf("Arec [%s->%s]", + inet_ntoa_r(nbtarg->oldaddr, INET_NTOA_BUF(oldbuf)), + inet_ntoa_r(nbtarg->newaddr, INET_NTOA_BUF(newbuf))); #endif while (bcount != 0) { if (a == NULL || (char *)(a + 1) > pmax) return (NULL); #ifdef LIBALIAS_DEBUG - printf("..%s", inet_ntoa(a->addr)); + printf("..%s", inet_ntoa_r(a->addr, INET_NTOA_BUF(newbuf))); #endif if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) { if (*nbtarg->uh_sum != 0) { diff --git a/sys/netinet/libalias/alias_proxy.c b/sys/netinet/libalias/alias_proxy.c index 0d49381b392f..132e56295fce 100644 --- a/sys/netinet/libalias/alias_proxy.c +++ b/sys/netinet/libalias/alias_proxy.c @@ -294,6 +294,7 @@ ProxyEncodeTcpStream(struct alias_link *lnk, int slen; char buffer[40]; struct tcphdr *tc; + char addrbuf[INET_ADDRSTRLEN]; /* Compute pointer to tcp header */ tc = (struct tcphdr *)ip_next(pip); @@ -305,7 +306,8 @@ ProxyEncodeTcpStream(struct alias_link *lnk, /* Translate destination address and port to string form */ snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]", - inet_ntoa(GetProxyAddress(lnk)), (u_int) ntohs(GetProxyPort(lnk))); + inet_ntoa_r(GetProxyAddress(lnk), INET_NTOA_BUF(addrbuf)), + (u_int) ntohs(GetProxyPort(lnk))); /* Pad string out to a multiple of two in length */ slen = strlen(buffer); diff --git a/sys/netinet/libalias/alias_sctp.c b/sys/netinet/libalias/alias_sctp.c index 67e475402d5c..fbc8e41e0ed5 100644 --- a/sys/netinet/libalias/alias_sctp.c +++ b/sys/netinet/libalias/alias_sctp.c @@ -904,6 +904,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso int ip_size = sizeof(struct ip) + sctp_size; int include_error_cause = 1; char tmp_ip[ip_size]; + char addrbuf[INET_ADDRSTRLEN]; if (ntohs(sm->ip_hdr->ip_len) < ip_size) { /* short packet, cannot send error cause */ include_error_cause = 0; @@ -984,7 +985,8 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso ((sndrply == SN_SEND_ABORT) ? "Sending" : "Replying"), ((sndrply & SN_TX_ERROR) ? "ErrorM" : "AbortM"), (include_error_cause ? ntohs(error_cause->code) : 0), - inet_ntoa(ip->ip_dst),ntohs(sctp_hdr->dest_port), + inet_ntoa_r(ip->ip_dst, INET_NTOA_BUF(addrbuf)), + ntohs(sctp_hdr->dest_port), ntohl(sctp_hdr->v_tag), ntohl(sctp_hdr->checksum))); } @@ -2574,6 +2576,8 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) { struct sctp_GlobalAddress *G_Addr = NULL; char *sp; + char addrbuf[INET_ADDRSTRLEN]; + switch(assoc->state) { case SN_ID: sp = "ID "; @@ -2598,12 +2602,14 @@ static void logsctpassoc(struct sctp_nat_assoc *assoc, char* s) break; } SctpAliasLog("%sAssoc: %s exp=%u la=%s lv=%u lp=%u gv=%u gp=%u tbl=%d\n", - s, sp, assoc->exp, inet_ntoa(assoc->l_addr), ntohl(assoc->l_vtag), - ntohs(assoc->l_port), ntohl(assoc->g_vtag), ntohs(assoc->g_port), + s, sp, assoc->exp, inet_ntoa_r(assoc->l_addr, addrbuf), + ntohl(assoc->l_vtag), ntohs(assoc->l_port), + ntohl(assoc->g_vtag), ntohs(assoc->g_port), assoc->TableRegister); /* list global addresses */ LIST_FOREACH(G_Addr, &(assoc->Gaddr), list_Gaddr) { - SctpAliasLog("\t\tga=%s\n",inet_ntoa(G_Addr->g_addr)); + SctpAliasLog("\t\tga=%s\n", + inet_ntoa_r(G_Addr->g_addr, addrbuf)); } } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 038e6b0f817d..956b15978c89 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -5790,40 +5790,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } else if (stcb == NULL) { inp_decr = inp; } -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - /*- - * I very much doubt any of the IPSEC stuff will work but I have no - * idea, so I will leave it in place. - */ - if (inp != NULL) { - switch (dst->sa_family) { -#ifdef INET - case AF_INET: - if (IPSEC_ENABLED(ipv4)) { - if (IPSEC_CHECK_POLICY(ipv4, m, - &inp->ip_inp.inp) != 0) { - SCTP_STAT_INCR(sctps_hdrops); - goto out; - } - } - break; -#endif -#ifdef INET6 - case AF_INET6: - if (IPSEC_ENABLED(ipv6)) { - if (IPSEC_CHECK_POLICY(ipv6, m, - &inp->ip_inp.inp) != 0) { - SCTP_STAT_INCR(sctps_hdrops); - goto out; - } - } - break; -#endif - default: - break; - } - } -#endif /* IPSEC */ SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n", (void *)m, iphlen, offset, length, (void *)stcb); if (stcb) { diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 0eb5359e3e82..b439b593af30 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$"); /* * includes */ -#include "opt_ipsec.h" #include "opt_compat.h" #include "opt_inet6.h" #include "opt_inet.h" @@ -82,8 +81,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip_icmp.h> #include <netinet/icmp_var.h> -#include <netipsec/ipsec_support.h> - #ifdef INET6 #include <sys/domain.h> #include <netinet/ip6.h> @@ -94,7 +91,6 @@ __FBSDID("$FreeBSD$"); #include <netinet6/scope6_var.h> #endif /* INET6 */ - #include <netinet/ip_options.h> #include <crypto/sha1.h> diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 25a7c85d667e..db3f39c2e5c4 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -2469,15 +2469,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_INP_INFO_WUNLOCK(); return (ENOBUFS); } -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - error = ipsec_init_pcbpolicy(&inp->ip_inp.inp); - if (error != 0) { - crfree(inp->ip_inp.inp.inp_cred); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); - SCTP_INP_INFO_WUNLOCK(); - return error; - } -#endif /* IPSEC */ SCTP_INCR_EP_COUNT(); inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl); SCTP_INP_INFO_WUNLOCK(); @@ -2504,9 +2495,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP); so->so_pcb = NULL; crfree(inp->ip_inp.inp.inp_cred); -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - ipsec_delete_pcbpolicy(&inp->ip_inp.inp); -#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (EOPNOTSUPP); } @@ -2527,9 +2515,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS); so->so_pcb = NULL; crfree(inp->ip_inp.inp.inp_cred); -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - ipsec_delete_pcbpolicy(&inp->ip_inp.inp); -#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (ENOBUFS); } @@ -3641,9 +3626,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) * macro here since le_next will get freed as part of the * sctp_free_assoc() call. */ -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - ipsec_delete_pcbpolicy(ip_pcb); -#endif if (ip_pcb->inp_options) { (void)sctp_m_free(ip_pcb->inp_options); ip_pcb->inp_options = 0; diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c index d27f2b53df28..4f1de87b8918 100644 --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -623,6 +623,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) struct sbuf sb; int i, error; struct hc_metrics *hc_entry; + char ip4buf[INET_ADDRSTRLEN]; #ifdef INET6 char ip6buf[INET6_ADDRSTRLEN]; #endif @@ -645,7 +646,8 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS) sbuf_printf(&sb, "%-15s %5u %8u %6lums %6lums %8u %8u %8u %4lu " "%4lu %4i\n", - hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) : + hc_entry->ip4.s_addr ? + inet_ntoa_r(hc_entry->ip4, ip4buf) : #ifdef INET6 ip6_sprintf(ip6buf, &hc_entry->ip6), #else diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 607756134a52..7736ffcf63b6 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -3494,7 +3494,7 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt) TCPSTAT_INC(tcps_rttupdated); tp->t_rttupdated++; - if (tp->t_srtt != 0) { + if ((tp->t_srtt != 0) && (tp->t_rxtshift <= TCP_RTT_INVALIDATE)) { /* * srtt is stored as fixed point with 5 bits after the * binary point (i.e., scaled by 8). The following magic diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index f9f5c05fdce4..064e45b0a51b 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -845,20 +845,16 @@ tcp_timer_rexmt(void * xtp) (tp->t_rxtshift == 3)) tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_SACK_PERMIT); /* - * If we backed off this far, our srtt estimate is probably bogus. - * Clobber it so we'll take the next rtt measurement as our srtt; - * move the current srtt into rttvar to keep the current - * retransmit times until then. + * If we backed off this far, notify the L3 protocol that we're having + * connection problems. */ - if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { + if (tp->t_rxtshift > TCP_RTT_INVALIDATE) { #ifdef INET6 if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) in6_losing(tp->t_inpcb); else #endif in_losing(tp->t_inpcb); - tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); - tp->t_srtt = 0; } tp->snd_nxt = tp->snd_una; tp->snd_recover = tp->snd_max; diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h index bb78062ddea4..8b8d8252465e 100644 --- a/sys/netinet/tcp_timer.h +++ b/sys/netinet/tcp_timer.h @@ -119,6 +119,13 @@ #define TCPTV_DELACK ( hz/10 ) /* 100ms timeout */ +/* + * If we exceed this number of retransmits for a single segment, we'll consider + * the current srtt measurement no longer valid and will recalculate from + * scratch starting with the next ACK. + */ +#define TCP_RTT_INVALIDATE (TCP_MAXRXTSHIFT / 4) + #ifdef TCPTIMERS static const char *tcptimers[] = { "REXMT", "PERSIST", "KEEP", "2MSL", "DELACK" }; diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 3ede7dc08714..f24499dbd7f3 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -304,7 +304,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off, { struct sockaddr *append_sa; struct socket *so; - struct mbuf *tmpopts, *opts = NULL; + struct mbuf *opts = NULL; #ifdef INET6 struct sockaddr_in6 udp_in6; #endif @@ -319,7 +319,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off, if (up->u_tun_func != NULL) { in_pcbref(inp); INP_RUNLOCK(inp); - (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&udp_in[0], + (*up->u_tun_func)(n, off, inp, (struct sockaddr *)udp_in, up->u_tun_ctx); INP_RLOCK(inp); return (in_pcbrele_rlocked(inp)); @@ -355,27 +355,16 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off, #endif /* INET6 */ ip_savecontrol(inp, &opts, ip, n); } - if (inp->inp_vflag & INP_IPV4 && inp->inp_flags2 & INP_ORIGDSTADDR) { - tmpopts = sbcreatecontrol((caddr_t)&udp_in[1], - sizeof(struct sockaddr_in), IP_ORIGDSTADDR, IPPROTO_IP); - if (tmpopts) { - if (opts) { - tmpopts->m_next = opts; - opts = tmpopts; - } else - opts = tmpopts; - } - } #ifdef INET6 if (inp->inp_vflag & INP_IPV6) { bzero(&udp_in6, sizeof(udp_in6)); udp_in6.sin6_len = sizeof(udp_in6); udp_in6.sin6_family = AF_INET6; - in6_sin_2_v4mapsin6(&udp_in[0], &udp_in6); + in6_sin_2_v4mapsin6(udp_in, &udp_in6); append_sa = (struct sockaddr *)&udp_in6; } else #endif /* INET6 */ - append_sa = (struct sockaddr *)&udp_in[0]; + append_sa = (struct sockaddr *)udp_in; m_adj(n, off); so = inp->inp_socket; @@ -401,7 +390,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) uint16_t len, ip_len; struct inpcbinfo *pcbinfo; struct ip save_ip; - struct sockaddr_in udpin[2]; + struct sockaddr_in udp_in; struct mbuf *m; struct m_tag *fwd_tag; int cscov_partial, iphlen; @@ -446,16 +435,11 @@ udp_input(struct mbuf **mp, int *offp, int proto) * Construct sockaddr format source address. Stuff source address * and datagram in user buffer. */ - bzero(&udpin[0], sizeof(struct sockaddr_in)); - udpin[0].sin_len = sizeof(struct sockaddr_in); - udpin[0].sin_family = AF_INET; - udpin[0].sin_port = uh->uh_sport; - udpin[0].sin_addr = ip->ip_src; - bzero(&udpin[1], sizeof(struct sockaddr_in)); - udpin[1].sin_len = sizeof(struct sockaddr_in); - udpin[1].sin_family = AF_INET; - udpin[1].sin_port = uh->uh_dport; - udpin[1].sin_addr = ip->ip_dst; + bzero(&udp_in, sizeof(udp_in)); + udp_in.sin_len = sizeof(udp_in); + udp_in.sin_family = AF_INET; + udp_in.sin_port = uh->uh_sport; + udp_in.sin_addr = ip->ip_src; /* * Make mbuf data length reflect UDP length. If not enough data to @@ -584,7 +568,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) blocked = imo_multi_filter(imo, ifp, (struct sockaddr *)&group, - (struct sockaddr *)&udpin[0]); + (struct sockaddr *)&udp_in); if (blocked != MCAST_PASS) { if (blocked == MCAST_NOTGMEMBER) IPSTAT_INC(ips_notmember); @@ -603,7 +587,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) UDP_PROBE(receive, NULL, last, ip, last, uh); if (udp_append(last, ip, n, iphlen, - udpin)) { + &udp_in)) { goto inp_lost; } } @@ -636,7 +620,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) goto badunlocked; } UDP_PROBE(receive, NULL, last, ip, last, uh); - if (udp_append(last, ip, m, iphlen, udpin) == 0) + if (udp_append(last, ip, m, iphlen, &udp_in) == 0) INP_RUNLOCK(last); inp_lost: INP_INFO_RUNLOCK(pcbinfo); @@ -726,7 +710,7 @@ udp_input(struct mbuf **mp, int *offp, int proto) } UDP_PROBE(receive, NULL, inp, ip, inp, uh); - if (udp_append(inp, ip, m, iphlen, udpin) == 0) + if (udp_append(inp, ip, m, iphlen, &udp_in) == 0) INP_RUNLOCK(inp); return (IPPROTO_DONE); diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index ae5809f8aaa4..e913c0ab977a 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -497,9 +497,6 @@ struct route_in6 { #define IPV6_RECVFLOWID 70 /* bool; receive IP6 flowid/flowtype w/ datagram */ #define IPV6_RECVRSSBUCKETID 71 /* bool; receive IP6 RSS bucket id w/ datagram */ -#define IPV6_ORIGDSTADDR 72 /* bool: allow getting dstaddr /port info */ -#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR - /* * The following option is private; do not use it from user applications. * It is deliberately defined to the same value as IP_MSFILTER. diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index bab5259f7ffe..ff8813b14347 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1267,7 +1267,7 @@ in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, } void -init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int srcordst) +init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m) { struct ip6_hdr *ip; @@ -1275,7 +1275,7 @@ init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int srcordst) bzero(sin6, sizeof(*sin6)); sin6->sin6_len = sizeof(*sin6); sin6->sin6_family = AF_INET6; - sin6->sin6_addr = srcordst ? ip->ip6_dst : ip->ip6_src; + sin6->sin6_addr = ip->ip6_src; (void)sa6_recoverscope(sin6); /* XXX: should catch errors... */ diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h index 1ff09ea93ba6..e758dacea3b8 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -113,7 +113,7 @@ int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam); int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam); int in6_selecthlim(struct in6pcb *, struct ifnet *); int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *); -void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int); +void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m); #endif /* _KERNEL */ #endif /* !_NETINET6_IN6_PCB_H_ */ diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 34ce8aa658fb..44ea1af01c2f 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -185,7 +185,7 @@ struct protosw inet6sw[] = { .pr_type = SOCK_SEQPACKET, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, + .pr_flags = PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp6_input, .pr_ctlinput = sctp6_ctlinput, .pr_ctloutput = sctp_ctloutput, @@ -199,7 +199,7 @@ struct protosw inet6sw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp6_input, .pr_ctlinput = sctp6_ctlinput, .pr_ctloutput = sctp_ctloutput, diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index d8f8864d3e53..6644361369cc 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1545,7 +1545,6 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt) #endif case IPV6_V6ONLY: case IPV6_AUTOFLOWLABEL: - case IPV6_ORIGDSTADDR: case IPV6_BINDANY: case IPV6_BINDMULTI: #ifdef RSS @@ -1731,9 +1730,6 @@ do { \ OPTSET(IN6P_AUTOFLOWLABEL); break; - case IPV6_ORIGDSTADDR: - OPTSET2(INP_ORIGDSTADDR, optval); - break; case IPV6_BINDANY: OPTSET(INP_BINDANY); break; @@ -2022,10 +2018,6 @@ do { \ optval = OPTBIT(IN6P_AUTOFLOWLABEL); break; - case IPV6_ORIGDSTADDR: - optval = OPTBIT2(INP_ORIGDSTADDR); - break; - case IPV6_BINDANY: optval = OPTBIT(INP_BINDANY); break; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 9dd6577e6b52..3ffadef2426b 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -166,7 +166,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto) RIP6STAT_INC(rip6s_ipackets); - init_sin6(&fromsa, m, 0); /* general init */ + init_sin6(&fromsa, m); /* general init */ ifp = m->m_pkthdr.rcvif; diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index 2f5db2c2c1d8..c2a45a661333 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -551,10 +551,6 @@ sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNU */ inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); #endif - /* - * Hmm what about the IPSEC stuff that is missing here but in - * sctp_attach()? - */ SCTP_INP_WUNLOCK(inp); return (0); } diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index bcf491f10808..911d1de51945 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -137,7 +137,7 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off, struct sockaddr_in6 *fromsa) { struct socket *so; - struct mbuf *opts = NULL, *tmp_opts; + struct mbuf *opts; struct udpcb *up; INP_LOCK_ASSERT(inp); @@ -149,7 +149,7 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off, if (up->u_tun_func != NULL) { in_pcbref(inp); INP_RUNLOCK(inp); - (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&fromsa[0], + (*up->u_tun_func)(n, off, inp, (struct sockaddr *)fromsa, up->u_tun_ctx); INP_RLOCK(inp); return (in_pcbrele_rlocked(inp)); @@ -173,23 +173,11 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off, if (inp->inp_flags & INP_CONTROLOPTS || inp->inp_socket->so_options & SO_TIMESTAMP) ip6_savecontrol(inp, n, &opts); - if (inp->inp_vflag & INP_IPV6 && inp->inp_flags2 & INP_ORIGDSTADDR) { - tmp_opts = sbcreatecontrol((caddr_t)&fromsa[1], - sizeof(struct sockaddr_in6), IP_ORIGDSTADDR, IPPROTO_IPV6); - if (tmp_opts) { - if (opts) { - tmp_opts->m_next = opts; - opts = tmp_opts; - } else - opts = tmp_opts; - } - - } m_adj(n, off + sizeof(struct udphdr)); so = inp->inp_socket; SOCKBUF_LOCK(&so->so_rcv); - if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n, + if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)fromsa, n, opts) == 0) { SOCKBUF_UNLOCK(&so->so_rcv); m_freem(n); @@ -214,7 +202,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) int off = *offp; int cscov_partial; int plen, ulen; - struct sockaddr_in6 fromsa[2]; + struct sockaddr_in6 fromsa; struct m_tag *fwd_tag; uint16_t uh_sum; uint8_t nxt; @@ -289,10 +277,8 @@ udp6_input(struct mbuf **mp, int *offp, int proto) /* * Construct sockaddr format source address. */ - init_sin6(&fromsa[0], m, 0); - fromsa[0].sin6_port = uh->uh_sport; - init_sin6(&fromsa[1], m, 1); - fromsa[1].sin6_port = uh->uh_dport; + init_sin6(&fromsa, m); + fromsa.sin6_port = uh->uh_sport; pcbinfo = udp_get_inpcbinfo(nxt); if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { @@ -363,7 +349,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) blocked = im6o_mc_filter(imo, ifp, (struct sockaddr *)&mcaddr, - (struct sockaddr *)&fromsa[0]); + (struct sockaddr *)&fromsa); if (blocked != MCAST_PASS) { if (blocked == MCAST_NOTGMEMBER) IP6STAT_INC(ip6s_notmember); @@ -384,7 +370,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) INP_RLOCK(last); UDP_PROBE(receive, NULL, last, ip6, last, uh); - if (udp6_append(last, n, off, fromsa)) + if (udp6_append(last, n, off, &fromsa)) goto inp_lost; INP_RUNLOCK(last); } @@ -416,7 +402,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) INP_RLOCK(last); INP_INFO_RUNLOCK(pcbinfo); UDP_PROBE(receive, NULL, last, ip6, last, uh); - if (udp6_append(last, m, off, fromsa) == 0) + if (udp6_append(last, m, off, &fromsa) == 0) INP_RUNLOCK(last); inp_lost: return (IPPROTO_DONE); @@ -496,7 +482,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } } UDP_PROBE(receive, NULL, inp, ip6, inp, uh); - if (udp6_append(inp, m, off, fromsa) == 0) + if (udp6_append(inp, m, off, &fromsa) == 0) INP_RUNLOCK(inp); return (IPPROTO_DONE); diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c index 5bab2f1dc0d3..acfe66acf458 100644 --- a/sys/netipsec/subr_ipsec.c +++ b/sys/netipsec/subr_ipsec.c @@ -126,9 +126,12 @@ ipsec6_setsockaddrs(const struct mbuf *m, union sockaddr_union *src, #ifdef IPSEC_SUPPORT /* - * Declare IPSEC_SUPPORT as module even if IPSEC is defined. - * tcpmd5.ko module depends from IPSEC_SUPPORT. + * IPSEC_SUPPORT - loading of ipsec.ko and tcpmd5.ko is supported. + * IPSEC + IPSEC_SUPPORT - loading tcpmd5.ko is supported. + * IPSEC + TCP_SIGNATURE - all is build in the kernel, do not build + * IPSEC_SUPPORT. */ +#if !defined(IPSEC) || !defined(TCP_SIGNATURE) #define IPSEC_MODULE_INCR 2 static int ipsec_kmod_enter(volatile u_int *cntr) @@ -181,6 +184,30 @@ type name (decl) \ return (ret); \ } +static int +ipsec_support_modevent(module_t mod, int type, void *data) +{ + + switch (type) { + case MOD_LOAD: + return (0); + case MOD_UNLOAD: + return (EBUSY); + default: + return (EOPNOTSUPP); + } +} + +static moduledata_t ipsec_support_mod = { + "ipsec_support", + ipsec_support_modevent, + 0 +}; +DECLARE_MODULE(ipsec_support, ipsec_support_mod, SI_SUB_PROTO_DOMAIN, + SI_ORDER_ANY); +MODULE_VERSION(ipsec_support, 1); +#endif /* !IPSEC || !TCP_SIGNATURE */ + #ifndef TCP_SIGNATURE /* Declare TCP-MD5 support as kernel module. */ static struct tcpmd5_support tcpmd5_ipsec = { @@ -222,30 +249,7 @@ tcpmd5_support_disable(void) tcp_ipsec_support->methods = NULL; } } -#endif - -static int -ipsec_support_modevent(module_t mod, int type, void *data) -{ - - switch (type) { - case MOD_LOAD: - return (0); - case MOD_UNLOAD: - return (EBUSY); - default: - return (EOPNOTSUPP); - } -} - -static moduledata_t ipsec_support_mod = { - "ipsec_support", - ipsec_support_modevent, - 0 -}; -DECLARE_MODULE(ipsec_support, ipsec_support_mod, SI_SUB_PROTO_DOMAIN, - SI_ORDER_ANY); -MODULE_VERSION(ipsec_support, 1); +#endif /* !TCP_SIGNATURE */ #ifndef IPSEC /* diff --git a/sys/netpfil/ipfw/ip_fw_log.c b/sys/netpfil/ipfw/ip_fw_log.c index 5ef8cf1abf0a..a8e53fe50381 100644 --- a/sys/netpfil/ipfw/ip_fw_log.c +++ b/sys/netpfil/ipfw/ip_fw_log.c @@ -211,6 +211,7 @@ ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, TARG(cmd->arg1, pipe)); break; case O_FORWARD_IP: { + char buf[INET_ADDRSTRLEN]; ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; int len; struct in_addr dummyaddr; @@ -220,7 +221,7 @@ ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, dummyaddr.s_addr = sa->sa.sin_addr.s_addr; len = snprintf(SNPARGS(action2, 0), "Forward to %s", - inet_ntoa(dummyaddr)); + inet_ntoa_r(dummyaddr, buf)); if (sa->sa.sin_port) snprintf(SNPARGS(action2, len), ":%d", diff --git a/sys/netpfil/pf/pf_osfp.c b/sys/netpfil/pf/pf_osfp.c index 55a7d105879f..9c41cf55d435 100644 --- a/sys/netpfil/pf/pf_osfp.c +++ b/sys/netpfil/pf/pf_osfp.c @@ -19,6 +19,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_inet6.h" + #include <sys/param.h> #include <sys/kernel.h> #include <sys/lock.h> @@ -34,7 +36,9 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <net/pfvar.h> +#ifdef INET6 #include <netinet/ip6.h> +#endif static MALLOC_DEFINE(M_PFOSFP, "pf_osfp", "pf(4) operating system fingerprints"); #define DPFPRINTF(format, x...) \ @@ -94,7 +98,11 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st struct pf_os_fingerprint fp, *fpresult; int cnt, optlen = 0; const u_int8_t *optp; - char srcname[128]; +#ifdef INET6 + char srcname[INET6_ADDRSTRLEN]; +#else + char srcname[INET_ADDRSTRLEN]; +#endif if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN) return (NULL); @@ -110,7 +118,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st fp.fp_ttl = ip->ip_ttl; if (ip->ip_off & htons(IP_DF)) fp.fp_flags |= PF_OSFP_DF; - strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname)); + inet_ntoa_r(ip->ip_src, srcname); } #ifdef INET6 else if (ip6) { @@ -119,8 +127,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st fp.fp_ttl = ip6->ip6_hlim; fp.fp_flags |= PF_OSFP_DF; fp.fp_flags |= PF_OSFP_INET6; - strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src), - sizeof(srcname)); + ip6_sprintf(srcname, (const struct in6_addr *)&ip6->ip6_src); } #endif else diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c index ea0024bc0b11..5e5552dfe313 100644 --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -75,6 +75,7 @@ static void svc_new_thread(SVCGROUP *grp); static void xprt_unregister_locked(SVCXPRT *xprt); static void svc_change_space_used(SVCPOOL *pool, long delta); static bool_t svc_request_space_available(SVCPOOL *pool); +static void svcpool_cleanup(SVCPOOL *pool); /* *************** SVCXPRT related stuff **************** */ @@ -174,8 +175,12 @@ svcpool_create(const char *name, struct sysctl_oid_list *sysctl_base) return pool; } -void -svcpool_destroy(SVCPOOL *pool) +/* + * Code common to svcpool_destroy() and svcpool_close(), which cleans up + * the pool data structures. + */ +static void +svcpool_cleanup(SVCPOOL *pool) { SVCGROUP *grp; SVCXPRT *xprt, *nxprt; @@ -211,6 +216,15 @@ svcpool_destroy(SVCPOOL *pool) mtx_lock(&pool->sp_lock); } mtx_unlock(&pool->sp_lock); +} + +void +svcpool_destroy(SVCPOOL *pool) +{ + SVCGROUP *grp; + int g; + + svcpool_cleanup(pool); for (g = 0; g < SVC_MAXGROUPS; g++) { grp = &pool->sp_groups[g]; @@ -226,6 +240,30 @@ svcpool_destroy(SVCPOOL *pool) } /* + * Similar to svcpool_destroy(), except that it does not destroy the actual + * data structures. As such, "pool" may be used again. + */ +void +svcpool_close(SVCPOOL *pool) +{ + SVCGROUP *grp; + int g; + + svcpool_cleanup(pool); + + /* Now, initialize the pool's state for a fresh svc_run() call. */ + mtx_lock(&pool->sp_lock); + pool->sp_state = SVCPOOL_INIT; + mtx_unlock(&pool->sp_lock); + for (g = 0; g < SVC_MAXGROUPS; g++) { + grp = &pool->sp_groups[g]; + mtx_lock(&grp->sg_lock); + grp->sg_state = SVCPOOL_ACTIVE; + mtx_unlock(&grp->sg_lock); + } +} + +/* * Sysctl handler to get the present thread count on a pool */ static int diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h index 22322ba68448..dacf5d1a8992 100644 --- a/sys/rpc/svc.h +++ b/sys/rpc/svc.h @@ -729,6 +729,12 @@ extern SVCPOOL* svcpool_create(const char *name, extern void svcpool_destroy(SVCPOOL *pool); /* + * Close a service pool. Similar to svcpool_destroy(), but it does not + * free the data structures. As such, the pool can be used again. + */ +extern void svcpool_close(SVCPOOL *pool); + +/* * Transport independent svc_create routine. */ extern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *), diff --git a/sys/sys/event.h b/sys/sys/event.h index fb5b11c32935..058376a2ed7b 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -29,7 +29,8 @@ #ifndef _SYS_EVENT_H_ #define _SYS_EVENT_H_ -#include <sys/queue.h> +#include <sys/_types.h> +#include <sys/queue.h> #define EVFILT_READ (-1) #define EVFILT_WRITE (-2) @@ -57,11 +58,11 @@ } while(0) struct kevent { - uintptr_t ident; /* identifier for this event */ + __uintptr_t ident; /* identifier for this event */ short filter; /* filter for event */ - u_short flags; - u_int fflags; - intptr_t data; + unsigned short flags; + unsigned int fflags; + __intptr_t data; void *udata; /* opaque user data identifier */ }; diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h index 3019e4c422e4..6074922891d9 100644 --- a/sys/sys/lockmgr.h +++ b/sys/sys/lockmgr.h @@ -68,6 +68,10 @@ struct thread; */ int __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, const char *wmesg, int prio, int timo, const char *file, int line); +int lockmgr_lock_fast_path(struct lock *lk, u_int flags, + struct lock_object *ilk, const char *file, int line); +int lockmgr_unlock_fast_path(struct lock *lk, u_int flags, + struct lock_object *ilk); #if defined(INVARIANTS) || defined(INVARIANT_SUPPORT) void _lockmgr_assert(const struct lock *lk, int what, const char *file, int line); #endif diff --git a/sys/sys/lockstat.h b/sys/sys/lockstat.h index 6183bc7c9150..64745052974b 100644 --- a/sys/sys/lockstat.h +++ b/sys/sys/lockstat.h @@ -68,7 +68,7 @@ SDT_PROBE_DECLARE(lockstat, , , thread__spin); #define LOCKSTAT_WRITER 0 #define LOCKSTAT_READER 1 -extern int lockstat_enabled; +extern volatile int lockstat_enabled; #ifdef KDTRACE_HOOKS @@ -107,6 +107,13 @@ extern int lockstat_enabled; LOCKSTAT_RECORD1(probe, lp, a); \ } while (0) +#ifndef LOCK_PROFILING +#define LOCKSTAT_PROFILE_ENABLED(probe) __predict_false(lockstat_enabled) +#define LOCKSTAT_OOL_PROFILE_ENABLED(probe) LOCKSTAT_PROFILE_ENABLED(probe) +#else +#define LOCKSTAT_OOL_PROFILE_ENABLED(probe) 1 +#endif + struct lock_object; uint64_t lockstat_nsecs(struct lock_object *); @@ -130,16 +137,12 @@ uint64_t lockstat_nsecs(struct lock_object *); #define LOCKSTAT_PROFILE_RELEASE_RWLOCK(probe, lp, a) \ LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp) -#endif /* !KDTRACE_HOOKS */ - #ifndef LOCK_PROFILING -#define LOCKSTAT_PROFILE_ENABLED(probe) \ - SDT_PROBE_ENABLED(lockstat, , , probe) -#define LOCKSTAT_OOL_PROFILE_ENABLED(probe) \ - SDT_PROBE_ENABLED(lockstat, , , probe) -#else -#define LOCKSTAT_OOL_PROFILE_ENABLED(probe) 1 +#define LOCKSTAT_PROFILE_ENABLED(probe) 0 #endif +#define LOCKSTAT_OOL_PROFILE_ENABLED(probe) 1 + +#endif /* !KDTRACE_HOOKS */ #endif /* _KERNEL */ #endif /* _SYS_LOCKSTAT_H */ diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h index e4c69b76c939..c0ac0c8c8a9d 100644 --- a/sys/sys/mutex.h +++ b/sys/sys/mutex.h @@ -98,10 +98,17 @@ void mtx_sysinit(void *arg); int _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line); void mutex_init(void); +#if LOCK_DEBUG > 0 void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, const char *file, int line); void __mtx_unlock_sleep(volatile uintptr_t *c, int opts, const char *file, int line); +#else +void __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, + int opts); +void __mtx_unlock_sleep(volatile uintptr_t *c, int opts); +#endif + #ifdef SMP void _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t v, uintptr_t tid, int opts, const char *file, int line); @@ -140,10 +147,17 @@ void thread_lock_flags_(struct thread *, int, const char *, int); _mtx_destroy(&(m)->mtx_lock) #define mtx_trylock_flags_(m, o, f, l) \ _mtx_trylock_flags_(&(m)->mtx_lock, o, f, l) +#if LOCK_DEBUG > 0 #define _mtx_lock_sleep(m, v, t, o, f, l) \ __mtx_lock_sleep(&(m)->mtx_lock, v, t, o, f, l) #define _mtx_unlock_sleep(m, o, f, l) \ __mtx_unlock_sleep(&(m)->mtx_lock, o, f, l) +#else +#define _mtx_lock_sleep(m, v, t, o, f, l) \ + __mtx_lock_sleep(&(m)->mtx_lock, v, t, o) +#define _mtx_unlock_sleep(m, o, f, l) \ + __mtx_unlock_sleep(&(m)->mtx_lock, o) +#endif #ifdef SMP #define _mtx_lock_spin(m, v, t, o, f, l) \ _mtx_lock_spin_cookie(&(m)->mtx_lock, v, t, o, f, l) diff --git a/sys/sys/param.h b/sys/sys/param.h index 07b11e2daf5c..ada0639342f8 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200020 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200021 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/resource.h b/sys/sys/resource.h index 91b11412dd90..8e445e65d01c 100644 --- a/sys/sys/resource.h +++ b/sys/sys/resource.h @@ -119,8 +119,8 @@ struct __wrusage { #define RLIM_NLIMITS 15 /* number of resource limits */ #define RLIM_INFINITY ((rlim_t)(((__uint64_t)1 << 63) - 1)) -/* XXX Missing: RLIM_SAVED_MAX, RLIM_SAVED_CUR */ - +#define RLIM_SAVED_MAX RLIM_INFINITY +#define RLIM_SAVED_CUR RLIM_INFINITY /* * Resource limit string identifiers diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h index 6e4d0696faf5..aa4b0cc2ab76 100644 --- a/sys/sys/rwlock.h +++ b/sys/sys/rwlock.h @@ -65,7 +65,7 @@ #define RW_LOCK_WAITERS (RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS) #define RW_OWNER(x) ((x) & ~RW_LOCK_FLAGMASK) -#define RW_READERS_SHIFT 4 +#define RW_READERS_SHIFT 5 #define RW_READERS(x) (RW_OWNER((x)) >> RW_READERS_SHIFT) #define RW_READERS_LOCK(x) ((x) << RW_READERS_SHIFT | RW_LOCK_READ) #define RW_ONE_READER (1 << RW_READERS_SHIFT) diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 2d9e9252f083..ef8326e01148 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -149,15 +149,24 @@ int kern_listen(struct thread *td, int s, int backlog); int kern_lseek(struct thread *td, int fd, off_t offset, int whence); int kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); +int kern_madvise(struct thread *td, uintptr_t addr, size_t len, int behav); int kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, int mode); int kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode); int kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode, int dev); +int kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr, + size_t len); +int kern_mmap(struct thread *td, uintptr_t addr, size_t size, int prot, + int flags, int fd, off_t pos); +int kern_mprotect(struct thread *td, uintptr_t addr, size_t size, int prot); int kern_msgctl(struct thread *, int, int, struct msqid_ds *); -int kern_msgsnd(struct thread *, int, const void *, size_t, int, long); int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *); +int kern_msgsnd(struct thread *, int, const void *, size_t, int, long); +int kern_msync(struct thread *td, uintptr_t addr, size_t size, int flags); +int kern_munlock(struct thread *td, uintptr_t addr, size_t size); +int kern_munmap(struct thread *td, uintptr_t addr, size_t size); int kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt); int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 2329621b5ae4..c564547123a1 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -128,7 +128,11 @@ void kassert_panic(const char *fmt, ...) __printflike(1, 2); * Otherwise, the kernel will deadlock since the scheduler isn't * going to run the thread that holds any lock we need. */ -#define SCHEDULER_STOPPED() __predict_false(curthread->td_stopsched) +#define SCHEDULER_STOPPED_TD(td) ({ \ + MPASS((td) == curthread); \ + __predict_false((td)->td_stopsched); \ +}) +#define SCHEDULER_STOPPED() SCHEDULER_STOPPED_TD(curthread) /* * Align variables. diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index fb719cfb20ac..e4ff2dd63d34 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -303,7 +303,7 @@ retry: } if (bp->b_blkno == bp->b_lblkno) { - if (lbprev >= NDADDR) + if (lbprev >= UFS_NDADDR) panic("ffs_realloccg: lbprev out of range"); bp->b_blkno = fsbtodb(fs, bprev); } @@ -524,7 +524,7 @@ ffs_reallocblks_ufs1(ap) ufs_lbn_t start_lbn, end_lbn; ufs1_daddr_t soff, newblk, blkno; ufs2_daddr_t pref; - struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; + struct indir start_ap[UFS_NIADDR + 1], end_ap[UFS_NIADDR + 1], *idp; int i, cg, len, start_lvl, end_lvl, ssize; vp = ap->a_vp; @@ -567,7 +567,7 @@ ffs_reallocblks_ufs1(ap) * this for other indirect block boundaries, but it is only * important for the first one. */ - if (start_lbn < NDADDR && end_lbn >= NDADDR) + if (start_lbn < UFS_NDADDR && end_lbn >= UFS_NDADDR) return (ENOSPC); /* * If the latest allocation is in a new cylinder group, assume that @@ -773,7 +773,7 @@ ffs_reallocblks_ufs2(ap) struct ufsmount *ump; ufs_lbn_t start_lbn, end_lbn; ufs2_daddr_t soff, newblk, blkno, pref; - struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; + struct indir start_ap[UFS_NIADDR + 1], end_ap[UFS_NIADDR + 1], *idp; int i, cg, len, start_lvl, end_lvl, ssize; vp = ap->a_vp; @@ -816,7 +816,7 @@ ffs_reallocblks_ufs2(ap) * this for other indirect block boundaries, but it is only * important for the first one. */ - if (start_lbn < NDADDR && end_lbn >= NDADDR) + if (start_lbn < UFS_NDADDR && end_lbn >= UFS_NDADDR) return (ENOSPC); /* * If the latest allocation is in a new cylinder group, assume that @@ -1334,9 +1334,9 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap) * If we are allocating the first indirect block, try to * place it immediately following the last direct block. */ - if (indx == -1 && lbn < NDADDR + NINDIR(fs) && - ip->i_din1->di_db[NDADDR - 1] != 0) - pref = ip->i_din1->di_db[NDADDR - 1] + fs->fs_frag; + if (indx == -1 && lbn < UFS_NDADDR + NINDIR(fs) && + ip->i_din1->di_db[UFS_NDADDR - 1] != 0) + pref = ip->i_din1->di_db[UFS_NDADDR - 1] + fs->fs_frag; return (pref); } /* @@ -1344,7 +1344,7 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap) * block and the indirect has been allocated in the data block area, * try to place it immediately following the indirect block. */ - if (lbn == NDADDR) { + if (lbn == UFS_NDADDR) { pref = ip->i_din1->di_ib[0]; if (pref != 0 && pref >= cgdata(fs, inocg) && pref < cgbase(fs, inocg + 1)) @@ -1368,7 +1368,7 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap) * blocks, we try to allocate in the data area of the inode's * cylinder group. */ - if (lbn < NDADDR + NINDIR(fs)) + if (lbn < UFS_NDADDR + NINDIR(fs)) return (cgdata(fs, inocg)); /* * Find a cylinder with greater than average number of @@ -1439,9 +1439,9 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) * If we are allocating the first indirect block, try to * place it immediately following the last direct block. */ - if (indx == -1 && lbn < NDADDR + NINDIR(fs) && - ip->i_din2->di_db[NDADDR - 1] != 0) - pref = ip->i_din2->di_db[NDADDR - 1] + fs->fs_frag; + if (indx == -1 && lbn < UFS_NDADDR + NINDIR(fs) && + ip->i_din2->di_db[UFS_NDADDR - 1] != 0) + pref = ip->i_din2->di_db[UFS_NDADDR - 1] + fs->fs_frag; return (pref); } /* @@ -1449,7 +1449,7 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) * block and the indirect has been allocated in the data block area, * try to place it immediately following the indirect block. */ - if (lbn == NDADDR) { + if (lbn == UFS_NDADDR) { pref = ip->i_din2->di_ib[0]; if (pref != 0 && pref >= cgdata(fs, inocg) && pref < cgbase(fs, inocg + 1)) @@ -1473,7 +1473,7 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) * blocks, we try to allocate in the data area of the inode's * cylinder group. */ - if (lbn < NDADDR + NINDIR(fs)) + if (lbn < UFS_NDADDR + NINDIR(fs)) return (cgdata(fs, inocg)); /* * Find a cylinder with greater than average number of @@ -2916,7 +2916,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) if (blksize > blkcnt) blksize = blkcnt; ffs_blkfree(ump, fs, ump->um_devvp, blkno, - blksize * fs->fs_fsize, ROOTINO, VDIR, NULL); + blksize * fs->fs_fsize, UFS_ROOTINO, VDIR, NULL); blkno += blksize; blkcnt -= blksize; blksize = fs->fs_frag; diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index 0471fd6938f6..3f0bbd7ecfb3 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -97,12 +97,12 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, ufs1_daddr_t nb; struct buf *bp, *nbp; struct ufsmount *ump; - struct indir indirs[NIADDR + 2]; + struct indir indirs[UFS_NIADDR + 2]; int deallocated, osize, nsize, num, i, error; ufs2_daddr_t newb; ufs1_daddr_t *bap, pref; - ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; - ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1]; + ufs1_daddr_t *allocib, *blkp, *allocblk, allociblk[UFS_NIADDR + 1]; + ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1]; int unwindidx = -1; int saved_inbdflush; static struct timeval lastfail; @@ -133,7 +133,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, * this fragment has to be extended to be a full block. */ lastlbn = lblkno(fs, ip->i_size); - if (lastlbn < NDADDR && lastlbn < lbn) { + if (lastlbn < UFS_NDADDR && lastlbn < lbn) { nb = lastlbn; osize = blksize(fs, ip, nb); if (osize < fs->fs_bsize && osize > 0) { @@ -161,9 +161,9 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, } } /* - * The first NDADDR blocks are direct blocks + * The first UFS_NDADDR blocks are direct blocks */ - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { if (flags & BA_METAONLY) panic("ffs_balloc_ufs1: BA_METAONLY for direct block"); nb = dp->di_db[lbn]; @@ -265,8 +265,9 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, bp->b_blkno = fsbtodb(fs, nb); vfs_bio_clrbuf(bp); if (DOINGSOFTDEP(vp)) { - softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, - newb, 0, fs->fs_bsize, 0, bp); + softdep_setup_allocdirect(ip, + UFS_NDADDR + indirs[0].in_off, newb, 0, + fs->fs_bsize, 0, bp); bdwrite(bp); } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { if (bp->b_bufsize == fs->fs_bsize) @@ -383,7 +384,7 @@ retry: * the file. Otherwise it has been allocated in the metadata * area, so we want to find our own place out in the data area. */ - if (pref == 0 || (lbn > NDADDR && fs->fs_metaspace != 0)) + if (pref == 0 || (lbn > UFS_NDADDR && fs->fs_metaspace != 0)) pref = ffs_blkpref_ufs1(ip, lbn, indirs[i].in_off, &bap[0]); error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, @@ -571,10 +572,10 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, struct fs *fs; struct buf *bp, *nbp; struct ufsmount *ump; - struct indir indirs[NIADDR + 2]; + struct indir indirs[UFS_NIADDR + 2]; ufs2_daddr_t nb, newb, *bap, pref; - ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1]; - ufs2_daddr_t *lbns_remfree, lbns[NIADDR + 1]; + ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[UFS_NIADDR + 1]; + ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1]; int deallocated, osize, nsize, num, i, error; int unwindidx = -1; int saved_inbdflush; @@ -603,7 +604,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, * Check for allocating external data. */ if (flags & IO_EXT) { - if (lbn >= NXADDR) + if (lbn >= UFS_NXADDR) return (EFBIG); /* * If the next write will extend the data into a new block, @@ -717,7 +718,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, * this fragment has to be extended to be a full block. */ lastlbn = lblkno(fs, ip->i_size); - if (lastlbn < NDADDR && lastlbn < lbn) { + if (lastlbn < UFS_NDADDR && lastlbn < lbn) { nb = lastlbn; osize = blksize(fs, ip, nb); if (osize < fs->fs_bsize && osize > 0) { @@ -744,9 +745,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, } } /* - * The first NDADDR blocks are direct blocks + * The first UFS_NDADDR blocks are direct blocks */ - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { if (flags & BA_METAONLY) panic("ffs_balloc_ufs2: BA_METAONLY for direct block"); nb = dp->di_db[lbn]; @@ -851,8 +852,9 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, bp->b_blkno = fsbtodb(fs, nb); vfs_bio_clrbuf(bp); if (DOINGSOFTDEP(vp)) { - softdep_setup_allocdirect(ip, NDADDR + indirs[0].in_off, - newb, 0, fs->fs_bsize, 0, bp); + softdep_setup_allocdirect(ip, + UFS_NDADDR + indirs[0].in_off, newb, 0, + fs->fs_bsize, 0, bp); bdwrite(bp); } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) { if (bp->b_bufsize == fs->fs_bsize) @@ -970,7 +972,7 @@ retry: * the file. Otherwise it has been allocated in the metadata * area, so we want to find our own place out in the data area. */ - if (pref == 0 || (lbn > NDADDR && fs->fs_metaspace != 0)) + if (pref == 0 || (lbn > UFS_NDADDR && fs->fs_metaspace != 0)) pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off, &bap[0]); error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 0982ddab98ac..a581742ad1dd 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -183,8 +183,9 @@ ffs_truncate(vp, length, flags, cred) struct ucred *cred; { struct inode *ip; - ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR]; - ufs2_daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR]; + ufs2_daddr_t bn, lbn, lastblock, lastiblock[UFS_NIADDR]; + ufs2_daddr_t indir_lbn[UFS_NIADDR], oldblks[UFS_NDADDR + UFS_NIADDR]; + ufs2_daddr_t newblks[UFS_NDADDR + UFS_NIADDR]; ufs2_daddr_t count, blocksreleased = 0, datablocks, blkno; struct bufobj *bo; struct fs *fs; @@ -260,14 +261,14 @@ ffs_truncate(vp, length, flags, cred) osize = ip->i_din2->di_extsize; ip->i_din2->di_blocks -= extblocks; ip->i_din2->di_extsize = 0; - for (i = 0; i < NXADDR; i++) { + for (i = 0; i < UFS_NXADDR; i++) { oldblks[i] = ip->i_din2->di_extb[i]; ip->i_din2->di_extb[i] = 0; } ip->i_flag |= IN_CHANGE; if ((error = ffs_update(vp, waitforupdate))) return (error); - for (i = 0; i < NXADDR; i++) { + for (i = 0; i < UFS_NXADDR; i++) { if (oldblks[i] == 0) continue; ffs_blkfree(ump, fs, ITODEVVP(ip), oldblks[i], @@ -338,14 +339,14 @@ ffs_truncate(vp, length, flags, cred) lbn = lblkno(fs, length - 1); if (length == 0) { blkno = -1; - } else if (lbn < NDADDR) { + } else if (lbn < UFS_NDADDR) { blkno = DIP(ip, i_db[lbn]); } else { error = UFS_BALLOC(vp, lblktosize(fs, (off_t)lbn), fs->fs_bsize, cred, BA_METAONLY, &bp); if (error) return (error); - indiroff = (lbn - NDADDR) % NINDIR(fs); + indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); if (I_IS_UFS1(ip)) blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff]; else @@ -428,7 +429,7 @@ ffs_truncate(vp, length, flags, cred) * so that we do not get a soft updates inconsistency * when we create the fragment below. */ - if (DOINGSOFTDEP(vp) && lbn < NDADDR && + if (DOINGSOFTDEP(vp) && lbn < UFS_NDADDR && fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize && (error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0) return (error); @@ -456,7 +457,7 @@ ffs_truncate(vp, length, flags, cred) * the file is truncated to 0. */ lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1; - lastiblock[SINGLE] = lastblock - NDADDR; + lastiblock[SINGLE] = lastblock - UFS_NDADDR; lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); nblocks = btodb(fs->fs_bsize); @@ -467,13 +468,13 @@ ffs_truncate(vp, length, flags, cred) * normalized to -1 for calls to ffs_indirtrunc below. */ for (level = TRIPLE; level >= SINGLE; level--) { - oldblks[NDADDR + level] = DIP(ip, i_ib[level]); + oldblks[UFS_NDADDR + level] = DIP(ip, i_ib[level]); if (lastiblock[level] < 0) { DIP_SET(ip, i_ib[level], 0); lastiblock[level] = -1; } } - for (i = 0; i < NDADDR; i++) { + for (i = 0; i < UFS_NDADDR; i++) { oldblks[i] = DIP(ip, i_db[i]); if (i > lastblock) DIP_SET(ip, i_db[i], 0); @@ -487,13 +488,13 @@ ffs_truncate(vp, length, flags, cred) * Note that we save the new block configuration so we can check it * when we are done. */ - for (i = 0; i < NDADDR; i++) { + for (i = 0; i < UFS_NDADDR; i++) { newblks[i] = DIP(ip, i_db[i]); DIP_SET(ip, i_db[i], oldblks[i]); } - for (i = 0; i < NIADDR; i++) { - newblks[NDADDR + i] = DIP(ip, i_ib[i]); - DIP_SET(ip, i_ib[i], oldblks[NDADDR + i]); + for (i = 0; i < UFS_NIADDR; i++) { + newblks[UFS_NDADDR + i] = DIP(ip, i_ib[i]); + DIP_SET(ip, i_ib[i], oldblks[UFS_NDADDR + i]); } ip->i_size = osize; DIP_SET(ip, i_size, osize); @@ -505,7 +506,7 @@ ffs_truncate(vp, length, flags, cred) /* * Indirect blocks first. */ - indir_lbn[SINGLE] = -NDADDR; + indir_lbn[SINGLE] = -UFS_NDADDR; indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; for (level = TRIPLE; level >= SINGLE; level--) { @@ -531,7 +532,7 @@ ffs_truncate(vp, length, flags, cred) /* * All whole direct blocks or frags. */ - for (i = NDADDR - 1; i > lastblock; i--) { + for (i = UFS_NDADDR - 1; i > lastblock; i--) { long bsize; bn = DIP(ip, i_db[i]); @@ -579,9 +580,9 @@ ffs_truncate(vp, length, flags, cred) done: #ifdef INVARIANTS for (level = SINGLE; level <= TRIPLE; level++) - if (newblks[NDADDR + level] != DIP(ip, i_ib[level])) + if (newblks[UFS_NDADDR + level] != DIP(ip, i_ib[level])) panic("ffs_truncate1"); - for (i = 0; i < NDADDR; i++) + for (i = 0; i < UFS_NDADDR; i++) if (newblks[i] != DIP(ip, i_db[i])) panic("ffs_truncate2"); BO_LOCK(bo); diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index 549c44e34735..09f972c097d8 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -330,7 +330,7 @@ restart: * Allocate all indirect blocks and mark all of them as not * needing to be copied. */ - for (blkno = NDADDR; blkno < numblks; blkno += NINDIR(fs)) { + for (blkno = UFS_NDADDR; blkno < numblks; blkno += NINDIR(fs)) { error = UFS_BALLOC(vp, lblktosize(fs, (off_t)blkno), fs->fs_bsize, td->td_ucred, BA_METAONLY, &ibp); if (error) @@ -576,7 +576,7 @@ loop: */ blkno = 0; loc = howmany(xp->i_size, fs->fs_bsize) - 1; - if (loc < NDADDR) { + if (loc < UFS_NDADDR) { len = fragroundup(fs, blkoff(fs, xp->i_size)); if (len != 0 && len < fs->fs_bsize) { ffs_blkfree(ump, copy_fs, vp, @@ -816,7 +816,7 @@ out1: * update the non-integrity-critical time fields and * allocated-block count. */ - for (blockno = 0; blockno < NDADDR; blockno++) { + for (blockno = 0; blockno < UFS_NDADDR; blockno++) { if (DIP(ip, i_db[blockno]) != 0) continue; error = UFS_BALLOC(vp, lblktosize(fs, blockno), @@ -923,8 +923,8 @@ cgaccount(cg, vp, nbp, passno) if (base + len >= numblks) len = numblks - base - 1; loc = 0; - if (base < NDADDR) { - for ( ; loc < NDADDR; loc++) { + if (base < UFS_NDADDR) { + for ( ; loc < UFS_NDADDR; loc++) { if (ffs_isblock(fs, cg_blksfree(cgp), loc)) DIP_SET(ip, i_db[loc], BLK_NOCOPY); else if (passno == 2 && DIP(ip, i_db[loc])== BLK_NOCOPY) @@ -938,7 +938,7 @@ cgaccount(cg, vp, nbp, passno) if (error) { return (error); } - indiroff = (base + loc - NDADDR) % NINDIR(fs); + indiroff = (base + loc - UFS_NDADDR) % NINDIR(fs); for ( ; loc < len; loc++, indiroff++) { if (indiroff >= NINDIR(fs)) { if (passno == 2) @@ -1010,7 +1010,7 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) */ lbn = fragstoblks(fs, ino_to_fsba(fs, cancelip->i_number)); blkno = 0; - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkno = VTOI(snapvp)->i_din1->di_db[lbn]; } else { if (DOINGSOFTDEP(snapvp)) @@ -1021,7 +1021,7 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) td->td_pflags &= ~TDP_COWINPROGRESS; if (error) return (error); - indiroff = (lbn - NDADDR) % NINDIR(fs); + indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff]; bqrelse(bp); } @@ -1047,7 +1047,7 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) dip->di_size = 0; dip->di_blocks = 0; dip->di_flags &= ~SF_SNAPSHOT; - bzero(&dip->di_db[0], (NDADDR + NIADDR) * sizeof(ufs1_daddr_t)); + bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs1_daddr_t)); bdwrite(bp); /* * Now go through and expunge all the blocks in the file @@ -1055,16 +1055,16 @@ expunge_ufs1(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) */ numblks = howmany(cancelip->i_size, fs->fs_bsize); if ((error = (*acctfunc)(snapvp, &cancelip->i_din1->di_db[0], - &cancelip->i_din1->di_db[NDADDR], fs, 0, expungetype))) + &cancelip->i_din1->di_db[UFS_NDADDR], fs, 0, expungetype))) return (error); if ((error = (*acctfunc)(snapvp, &cancelip->i_din1->di_ib[0], - &cancelip->i_din1->di_ib[NIADDR], fs, -1, expungetype))) + &cancelip->i_din1->di_ib[UFS_NIADDR], fs, -1, expungetype))) return (error); blksperindir = 1; - lbn = -NDADDR; - len = numblks - NDADDR; - rlbn = NDADDR; - for (i = 0; len > 0 && i < NIADDR; i++) { + lbn = -UFS_NDADDR; + len = numblks - UFS_NDADDR; + rlbn = UFS_NDADDR; + for (i = 0; len > 0 && i < UFS_NIADDR; i++) { error = indiracct_ufs1(snapvp, ITOV(cancelip), i, cancelip->i_din1->di_ib[i], lbn, rlbn, len, blksperindir, fs, acctfunc, expungetype); @@ -1100,7 +1100,7 @@ indiracct_ufs1(snapvp, cancelvp, level, blkno, lbn, rlbn, remblks, { int error, num, i; ufs_lbn_t subblksperindir; - struct indir indirs[NIADDR + 2]; + struct indir indirs[UFS_NIADDR + 2]; ufs1_daddr_t last, *bap; struct buf *bp; @@ -1196,7 +1196,7 @@ snapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP) continue; lbn = fragstoblks(fs, blkno); - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkp = &ip->i_din1->di_db[lbn]; ip->i_flag |= IN_CHANGE | IN_UPDATE; } else { @@ -1205,7 +1205,7 @@ snapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (error) return (error); blkp = &((ufs1_daddr_t *)(ibp->b_data)) - [(lbn - NDADDR) % NINDIR(fs)]; + [(lbn - UFS_NDADDR) % NINDIR(fs)]; } /* * If we are expunging a snapshot vnode and we @@ -1214,13 +1214,13 @@ snapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype) * we took our current snapshot and can be ignored. */ if (expungetype == BLK_SNAP && *blkp == BLK_NOCOPY) { - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) brelse(ibp); } else { if (*blkp != 0) panic("snapacct_ufs1: bad block"); *blkp = expungetype; - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) bdwrite(ibp); } } @@ -1294,7 +1294,7 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) */ lbn = fragstoblks(fs, ino_to_fsba(fs, cancelip->i_number)); blkno = 0; - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkno = VTOI(snapvp)->i_din2->di_db[lbn]; } else { if (DOINGSOFTDEP(snapvp)) @@ -1305,7 +1305,7 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) td->td_pflags &= ~TDP_COWINPROGRESS; if (error) return (error); - indiroff = (lbn - NDADDR) % NINDIR(fs); + indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); blkno = ((ufs2_daddr_t *)(bp->b_data))[indiroff]; bqrelse(bp); } @@ -1331,7 +1331,7 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) dip->di_size = 0; dip->di_blocks = 0; dip->di_flags &= ~SF_SNAPSHOT; - bzero(&dip->di_db[0], (NDADDR + NIADDR) * sizeof(ufs2_daddr_t)); + bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs2_daddr_t)); bdwrite(bp); /* * Now go through and expunge all the blocks in the file @@ -1339,16 +1339,16 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) */ numblks = howmany(cancelip->i_size, fs->fs_bsize); if ((error = (*acctfunc)(snapvp, &cancelip->i_din2->di_db[0], - &cancelip->i_din2->di_db[NDADDR], fs, 0, expungetype))) + &cancelip->i_din2->di_db[UFS_NDADDR], fs, 0, expungetype))) return (error); if ((error = (*acctfunc)(snapvp, &cancelip->i_din2->di_ib[0], - &cancelip->i_din2->di_ib[NIADDR], fs, -1, expungetype))) + &cancelip->i_din2->di_ib[UFS_NIADDR], fs, -1, expungetype))) return (error); blksperindir = 1; - lbn = -NDADDR; - len = numblks - NDADDR; - rlbn = NDADDR; - for (i = 0; len > 0 && i < NIADDR; i++) { + lbn = -UFS_NDADDR; + len = numblks - UFS_NDADDR; + rlbn = UFS_NDADDR; + for (i = 0; len > 0 && i < UFS_NIADDR; i++) { error = indiracct_ufs2(snapvp, ITOV(cancelip), i, cancelip->i_din2->di_ib[i], lbn, rlbn, len, blksperindir, fs, acctfunc, expungetype); @@ -1384,7 +1384,7 @@ indiracct_ufs2(snapvp, cancelvp, level, blkno, lbn, rlbn, remblks, { int error, num, i; ufs_lbn_t subblksperindir; - struct indir indirs[NIADDR + 2]; + struct indir indirs[UFS_NIADDR + 2]; ufs2_daddr_t last, *bap; struct buf *bp; @@ -1480,7 +1480,7 @@ snapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == 0 || blkno == BLK_NOCOPY || blkno == BLK_SNAP) continue; lbn = fragstoblks(fs, blkno); - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkp = &ip->i_din2->di_db[lbn]; ip->i_flag |= IN_CHANGE | IN_UPDATE; } else { @@ -1489,7 +1489,7 @@ snapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (error) return (error); blkp = &((ufs2_daddr_t *)(ibp->b_data)) - [(lbn - NDADDR) % NINDIR(fs)]; + [(lbn - UFS_NDADDR) % NINDIR(fs)]; } /* * If we are expunging a snapshot vnode and we @@ -1498,13 +1498,13 @@ snapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype) * we took our current snapshot and can be ignored. */ if (expungetype == BLK_SNAP && *blkp == BLK_NOCOPY) { - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) brelse(ibp); } else { if (*blkp != 0) panic("snapacct_ufs2: bad block"); *blkp = expungetype; - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) bdwrite(ibp); } } @@ -1639,7 +1639,7 @@ ffs_snapremove(vp) * Clear all BLK_NOCOPY fields. Pass any block claims to other * snapshots that want them (see ffs_snapblkfree below). */ - for (blkno = 1; blkno < NDADDR; blkno++) { + for (blkno = 1; blkno < UFS_NDADDR; blkno++) { dblk = DIP(ip, i_db[blkno]); if (dblk == 0) continue; @@ -1654,7 +1654,7 @@ ffs_snapremove(vp) } } numblks = howmany(ip->i_size, fs->fs_bsize); - for (blkno = NDADDR; blkno < numblks; blkno += NINDIR(fs)) { + for (blkno = UFS_NDADDR; blkno < numblks; blkno += NINDIR(fs)) { error = UFS_BALLOC(vp, lblktosize(fs, (off_t)blkno), fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp); if (error) @@ -1771,7 +1771,7 @@ retry: /* * Lookup block being written. */ - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkno = DIP(ip, i_db[lbn]); } else { td->td_pflags |= TDP_COWINPROGRESS; @@ -1780,7 +1780,7 @@ retry: td->td_pflags &= ~TDP_COWINPROGRESS; if (error) break; - indiroff = (lbn - NDADDR) % NINDIR(fs); + indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); if (I_IS_UFS1(ip)) blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff]; else @@ -1803,7 +1803,7 @@ retry: */ if (claimedblk) panic("snapblkfree: inconsistent block type"); - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { DIP_SET(ip, i_db[lbn], BLK_NOCOPY); ip->i_flag |= IN_CHANGE | IN_UPDATE; } else if (I_IS_UFS1(ip)) { @@ -1822,7 +1822,7 @@ retry: * (default), or does not care about the block, * it is not needed. */ - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) bqrelse(ibp); continue; } @@ -1846,13 +1846,13 @@ retry: * the work to the inode or indirect being written. */ if (wkhd != NULL) { - if (lbn < NDADDR) + if (lbn < UFS_NDADDR) softdep_inode_append(ip, curthread->td_ucred, wkhd); else softdep_buf_append(ibp, wkhd); } - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { DIP_SET(ip, i_db[lbn], bno); } else if (I_IS_UFS1(ip)) { ((ufs1_daddr_t *)(ibp->b_data))[indiroff] = bno; @@ -1866,7 +1866,7 @@ retry: lockmgr(vp->v_vnlock, LK_RELEASE, NULL); return (1); } - if (lbn >= NDADDR) + if (lbn >= UFS_NDADDR) bqrelse(ibp); /* * Allocate the block into which to do the copy. Note that this @@ -2327,7 +2327,7 @@ ffs_copyonwrite(devvp, bp) * will never require any additional allocations for the * snapshot inode. */ - if (lbn < NDADDR) { + if (lbn < UFS_NDADDR) { blkno = DIP(ip, i_db[lbn]); } else { td->td_pflags |= TDP_COWINPROGRESS | TDP_NORUNNINGBUF; @@ -2336,7 +2336,7 @@ ffs_copyonwrite(devvp, bp) td->td_pflags &= ~TDP_COWINPROGRESS; if (error) break; - indiroff = (lbn - NDADDR) % NINDIR(fs); + indiroff = (lbn - UFS_NDADDR) % NINDIR(fs); if (I_IS_UFS1(ip)) blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff]; else diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 94ac101094e3..ea0242d03e80 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -2732,7 +2732,7 @@ softdep_journal_lookup(mp, vpp) ino_t sujournal; int error; - error = VFS_VGET(mp, ROOTINO, LK_EXCLUSIVE, &dvp); + error = VFS_VGET(mp, UFS_ROOTINO, LK_EXCLUSIVE, &dvp); if (error) return (error); bzero(&cnp, sizeof(cnp)); @@ -4133,8 +4133,8 @@ newfreework(ump, freeblks, parent, lbn, nb, frags, off, journal) freework->fw_blkno = nb; freework->fw_frags = frags; freework->fw_indir = NULL; - freework->fw_ref = (MOUNTEDSUJ(UFSTOVFS(ump)) == 0 || lbn >= -NXADDR) - ? 0 : NINDIR(ump->um_fs) + 1; + freework->fw_ref = (MOUNTEDSUJ(UFSTOVFS(ump)) == 0 || + lbn >= -UFS_NXADDR) ? 0 : NINDIR(ump->um_fs) + 1; freework->fw_start = freework->fw_off = off; if (journal) newjfreeblk(freeblks, lbn, nb, frags); @@ -5296,7 +5296,7 @@ softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp) "off %jd newsize %ld oldsize %d", ip->i_number, newblkno, oldblkno, off, newsize, oldsize); ACQUIRE_LOCK(ITOUMP(ip)); - if (off >= NDADDR) { + if (off >= UFS_NDADDR) { if (lbn > 0) panic("softdep_setup_allocdirect: bad lbn %jd, off %jd", lbn, off); @@ -5464,7 +5464,7 @@ allocdirect_merge(adphead, newadp, oldadp) LOCK_OWNED(VFSTOUFS(newadp->ad_list.wk_mp)); if (newadp->ad_oldblkno != oldadp->ad_newblkno || newadp->ad_oldsize != oldadp->ad_newsize || - newadp->ad_offset >= NDADDR) + newadp->ad_offset >= UFS_NDADDR) panic("%s %jd != new %jd || old size %ld != new %ld", "allocdirect_merge: old blkno", (intmax_t)newadp->ad_oldblkno, @@ -5669,8 +5669,8 @@ softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp) ump = VFSTOUFS(mp); KASSERT(MOUNTEDSOFTDEP(mp) != 0, ("softdep_setup_allocext called on non-softdep filesystem")); - KASSERT(off < NXADDR, ("softdep_setup_allocext: lbn %lld > NXADDR", - (long long)off)); + KASSERT(off < UFS_NXADDR, + ("softdep_setup_allocext: lbn %lld > UFS_NXADDR", (long long)off)); lbn = bp->b_lblkno; if (oldblkno && oldblkno != newblkno) @@ -6430,12 +6430,12 @@ blkcount(fs, datablocks, length) totblks = 0; numblks = howmany(length, fs->fs_bsize); - if (numblks <= NDADDR) { + if (numblks <= UFS_NDADDR) { totblks = howmany(length, fs->fs_fsize); goto out; } totblks = blkstofrags(fs, numblks); - numblks -= NDADDR; + numblks -= UFS_NDADDR; /* * Count all single, then double, then triple indirects required. * Subtracting one indirects worth of blocks for each pass @@ -6553,12 +6553,12 @@ softdep_journal_freeblocks(ip, cred, length, flags) /* * Compute frags we are keeping in lastlbn. 0 means all. */ - if (lastlbn >= 0 && lastlbn < NDADDR) { + if (lastlbn >= 0 && lastlbn < UFS_NDADDR) { frags = fragroundup(fs, lastoff); /* adp offset of last valid allocdirect. */ iboff = lastlbn; } else if (lastlbn > 0) - iboff = NDADDR; + iboff = UFS_NDADDR; if (fs->fs_magic == FS_UFS2_MAGIC) extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); /* @@ -6570,9 +6570,10 @@ softdep_journal_freeblocks(ip, cred, length, flags) /* * Handle truncation of whole direct and indirect blocks. */ - for (i = iboff + 1; i < NDADDR; i++) + for (i = iboff + 1; i < UFS_NDADDR; i++) setup_freedirect(freeblks, ip, i, needj); - for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR; + for (i = 0, tmpval = NINDIR(fs), lbn = UFS_NDADDR; + i < UFS_NIADDR; i++, lbn += tmpval, tmpval *= NINDIR(fs)) { /* Release a whole indirect tree. */ if (lbn > lastlbn) { @@ -6580,7 +6581,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) needj); continue; } - iboff = i + NDADDR; + iboff = i + UFS_NDADDR; /* * Traverse partially truncated indirect tree. */ @@ -6614,7 +6615,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) * handling indirect blocks. Non-indirects need no extra * journaling. */ - if (length != 0 && lastlbn >= NDADDR) { + if (length != 0 && lastlbn >= UFS_NDADDR) { ip->i_flag |= IN_TRUNCATED; newjtrunc(freeblks, length, 0); } @@ -6626,7 +6627,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) freeblks->fb_len = length; } if ((flags & IO_EXT) != 0) { - for (i = 0; i < NXADDR; i++) + for (i = 0; i < UFS_NXADDR; i++) setup_freeext(freeblks, ip, i, needj); ip->i_din2->di_extsize = 0; datablocks += extblocks; @@ -6877,9 +6878,10 @@ softdep_setup_freeblocks(ip, length, flags) if (fs->fs_magic == FS_UFS2_MAGIC) extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); if ((flags & IO_NORMAL) != 0) { - for (i = 0; i < NDADDR; i++) + for (i = 0; i < UFS_NDADDR; i++) setup_freedirect(freeblks, ip, i, 0); - for (i = 0, tmpval = NINDIR(fs), lbn = NDADDR; i < NIADDR; + for (i = 0, tmpval = NINDIR(fs), lbn = UFS_NDADDR; + i < UFS_NIADDR; i++, lbn += tmpval, tmpval *= NINDIR(fs)) setup_freeindir(freeblks, ip, i, -lbn -i, 0); ip->i_size = 0; @@ -6887,7 +6889,7 @@ softdep_setup_freeblocks(ip, length, flags) datablocks = DIP(ip, i_blocks) - extblocks; } if ((flags & IO_EXT) != 0) { - for (i = 0; i < NXADDR; i++) + for (i = 0; i < UFS_NXADDR; i++) setup_freeext(freeblks, ip, i, 0); ip->i_din2->di_extsize = 0; datablocks += extblocks; @@ -7022,9 +7024,9 @@ trunc_pages(ip, length, extblocks, flags) * to verify how many levels are required. */ lbn = lblkno(fs, length); - if (lbn >= NDADDR) { + if (lbn >= UFS_NDADDR) { /* Calculate the virtual lbn of the triple indirect. */ - lbn = -lbn - (NIADDR - 1); + lbn = -lbn - (UFS_NIADDR - 1); end = OFF_TO_IDX(lblktosize(fs, lbn)); } else end = extend; @@ -7753,7 +7755,7 @@ freework_freeblock(freework) * blocks to expire so that we know the checker will not confuse * a re-allocated indirect block with its old contents. */ - if (needj && freework->fw_lbn <= -NDADDR) + if (needj && freework->fw_lbn <= -UFS_NDADDR) indirblk_insert(freework); /* * If we are canceling an existing jnewblk pass it to the free @@ -7926,7 +7928,7 @@ handle_workitem_freeblocks(freeblks, flags) case D_FREEWORK: freework = WK_FREEWORK(wk); - if (freework->fw_lbn <= -NDADDR) + if (freework->fw_lbn <= -UFS_NDADDR) handle_workitem_indirblk(freework); else freework_freeblock(freework); @@ -8476,7 +8478,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk) /* * Whiteouts have no dependencies. */ - if (newinum == WINO) { + if (newinum == UFS_WINO) { if (newdirbp != NULL) bdwrite(newdirbp); return (0); @@ -8493,7 +8495,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk) dap->da_newinum = newinum; dap->da_state = ATTACHED; LIST_INIT(&dap->da_jwork); - isindir = bp->b_lblkno >= NDADDR; + isindir = bp->b_lblkno >= UFS_NDADDR; newdirblk = NULL; if (isnewblk && (isindir ? blkoff(fs, diroffset) : fragoff(fs, diroffset)) == 0) { @@ -9306,7 +9308,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir) /* * Whiteouts do not need diradd dependencies. */ - if (newinum != WINO) { + if (newinum != UFS_WINO) { dap = malloc(sizeof(struct diradd), M_DIRADD, M_SOFTDEP_FLAGS|M_ZERO); workitem_alloc(&dap->da_list, D_DIRADD, mp); @@ -9340,7 +9342,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir) * Whiteouts have no additional dependencies, * so just put the dirrem on the correct list. */ - if (newinum == WINO) { + if (newinum == UFS_WINO) { if ((dirrem->dm_state & COMPLETE) == 0) { LIST_INSERT_HEAD(&pagedep->pd_dirremhd, dirrem, dm_next); @@ -10217,19 +10219,19 @@ initiate_write_inodeblock_ufs1(inodedep, bp) if (deplist != 0 && prevlbn >= adp->ad_offset) panic("softdep_write_inodeblock: lbn order"); prevlbn = adp->ad_offset; - if (adp->ad_offset < NDADDR && + if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) panic("%s: direct pointer #%jd mismatch %d != %jd", "softdep_write_inodeblock", (intmax_t)adp->ad_offset, dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); - if (adp->ad_offset >= NDADDR && - dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno) + if (adp->ad_offset >= UFS_NDADDR && + dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) panic("%s: indirect pointer #%jd mismatch %d != %jd", "softdep_write_inodeblock", - (intmax_t)adp->ad_offset - NDADDR, - dp->di_ib[adp->ad_offset - NDADDR], + (intmax_t)adp->ad_offset - UFS_NDADDR, + dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) @@ -10247,24 +10249,24 @@ initiate_write_inodeblock_ufs1(inodedep, bp) */ for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp; lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) { - if (adp->ad_offset >= NDADDR) + if (adp->ad_offset >= UFS_NDADDR) break; dp->di_db[adp->ad_offset] = adp->ad_oldblkno; /* keep going until hitting a rollback to a frag */ if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize) continue; dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize; - for (i = adp->ad_offset + 1; i < NDADDR; i++) { + for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) panic("softdep_write_inodeblock: lost dep1"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } - for (i = 0; i < NIADDR; i++) { + for (i = 0; i < UFS_NIADDR; i++) { #ifdef INVARIANTS if (dp->di_ib[i] != 0 && - (deplist & ((1 << NDADDR) << i)) == 0) + (deplist & ((1 << UFS_NDADDR) << i)) == 0) panic("softdep_write_inodeblock: lost dep2"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; @@ -10296,7 +10298,7 @@ initiate_write_inodeblock_ufs1(inodedep, bp) * postpone fsck, we are stuck with this argument. */ for (; adp; adp = TAILQ_NEXT(adp, ad_next)) - dp->di_ib[adp->ad_offset - NDADDR] = 0; + dp->di_ib[adp->ad_offset - UFS_NDADDR] = 0; } /* @@ -10416,7 +10418,7 @@ initiate_write_inodeblock_ufs2(inodedep, bp) if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize) continue; dp->di_extsize = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize; - for (i = adp->ad_offset + 1; i < NXADDR; i++) { + for (i = adp->ad_offset + 1; i < UFS_NXADDR; i++) { #ifdef INVARIANTS if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0) panic("softdep_write_inodeblock: lost dep1"); @@ -10450,19 +10452,19 @@ initiate_write_inodeblock_ufs2(inodedep, bp) if ((adp->ad_state & ATTACHED) == 0) panic("inodedep %p and adp %p not attached", inodedep, adp); prevlbn = adp->ad_offset; - if (adp->ad_offset < NDADDR && + if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) panic("%s: direct pointer #%jd mismatch %jd != %jd", "softdep_write_inodeblock", (intmax_t)adp->ad_offset, (intmax_t)dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); - if (adp->ad_offset >= NDADDR && - dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno) + if (adp->ad_offset >= UFS_NDADDR && + dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) panic("%s indirect pointer #%jd mismatch %jd != %jd", "softdep_write_inodeblock:", - (intmax_t)adp->ad_offset - NDADDR, - (intmax_t)dp->di_ib[adp->ad_offset - NDADDR], + (intmax_t)adp->ad_offset - UFS_NDADDR, + (intmax_t)dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) @@ -10480,24 +10482,24 @@ initiate_write_inodeblock_ufs2(inodedep, bp) */ for (lastadp = NULL, adp = TAILQ_FIRST(&inodedep->id_inoupdt); adp; lastadp = adp, adp = TAILQ_NEXT(adp, ad_next)) { - if (adp->ad_offset >= NDADDR) + if (adp->ad_offset >= UFS_NDADDR) break; dp->di_db[adp->ad_offset] = adp->ad_oldblkno; /* keep going until hitting a rollback to a frag */ if (adp->ad_oldsize == 0 || adp->ad_oldsize == fs->fs_bsize) continue; dp->di_size = fs->fs_bsize * adp->ad_offset + adp->ad_oldsize; - for (i = adp->ad_offset + 1; i < NDADDR; i++) { + for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) panic("softdep_write_inodeblock: lost dep2"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } - for (i = 0; i < NIADDR; i++) { + for (i = 0; i < UFS_NIADDR; i++) { #ifdef INVARIANTS if (dp->di_ib[i] != 0 && - (deplist & ((1 << NDADDR) << i)) == 0) + (deplist & ((1 << UFS_NDADDR) << i)) == 0) panic("softdep_write_inodeblock: lost dep3"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; @@ -10529,7 +10531,7 @@ initiate_write_inodeblock_ufs2(inodedep, bp) * postpone fsck, we are stuck with this argument. */ for (; adp; adp = TAILQ_NEXT(adp, ad_next)) - dp->di_ib[adp->ad_offset - NDADDR] = 0; + dp->di_ib[adp->ad_offset - UFS_NDADDR] = 0; } /* @@ -11456,7 +11458,7 @@ handle_written_inodeblock(inodedep, bp, flags) if (adp->ad_state & ATTACHED) panic("handle_written_inodeblock: new entry"); if (fstype == UFS1) { - if (adp->ad_offset < NDADDR) { + if (adp->ad_offset < UFS_NDADDR) { if (dp1->di_db[adp->ad_offset]!=adp->ad_oldblkno) panic("%s %s #%jd mismatch %d != %jd", "handle_written_inodeblock:", @@ -11466,17 +11468,20 @@ handle_written_inodeblock(inodedep, bp, flags) (intmax_t)adp->ad_oldblkno); dp1->di_db[adp->ad_offset] = adp->ad_newblkno; } else { - if (dp1->di_ib[adp->ad_offset - NDADDR] != 0) + if (dp1->di_ib[adp->ad_offset - UFS_NDADDR] != + 0) panic("%s: %s #%jd allocated as %d", "handle_written_inodeblock", "indirect pointer", - (intmax_t)adp->ad_offset - NDADDR, - dp1->di_ib[adp->ad_offset - NDADDR]); - dp1->di_ib[adp->ad_offset - NDADDR] = + (intmax_t)adp->ad_offset - + UFS_NDADDR, + dp1->di_ib[adp->ad_offset - + UFS_NDADDR]); + dp1->di_ib[adp->ad_offset - UFS_NDADDR] = adp->ad_newblkno; } } else { - if (adp->ad_offset < NDADDR) { + if (adp->ad_offset < UFS_NDADDR) { if (dp2->di_db[adp->ad_offset]!=adp->ad_oldblkno) panic("%s: %s #%jd %s %jd != %jd", "handle_written_inodeblock", @@ -11486,14 +11491,17 @@ handle_written_inodeblock(inodedep, bp, flags) (intmax_t)adp->ad_oldblkno); dp2->di_db[adp->ad_offset] = adp->ad_newblkno; } else { - if (dp2->di_ib[adp->ad_offset - NDADDR] != 0) + if (dp2->di_ib[adp->ad_offset - UFS_NDADDR] != + 0) panic("%s: %s #%jd allocated as %jd", "handle_written_inodeblock", "indirect pointer", - (intmax_t)adp->ad_offset - NDADDR, + (intmax_t)adp->ad_offset - + UFS_NDADDR, (intmax_t) - dp2->di_ib[adp->ad_offset - NDADDR]); - dp2->di_ib[adp->ad_offset - NDADDR] = + dp2->di_ib[adp->ad_offset - + UFS_NDADDR]); + dp2->di_ib[adp->ad_offset - UFS_NDADDR] = adp->ad_newblkno; } } diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index c258a202920d..0ff44efcbd5b 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1431,7 +1431,7 @@ ffs_statfs(mp, sbp) fs->fs_cstotal.cs_nffree + dbtofsb(fs, fs->fs_pendingblocks); sbp->f_bavail = freespace(fs, fs->fs_minfree) + dbtofsb(fs, fs->fs_pendingblocks); - sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; + sbp->f_files = fs->fs_ncg * fs->fs_ipg - UFS_ROOTINO; sbp->f_ffree = fs->fs_cstotal.cs_nifree + fs->fs_pendinginodes; UFS_UNLOCK(ump); sbp->f_namemax = NAME_MAX; @@ -1848,7 +1848,7 @@ ffs_fhtovp(mp, fhp, flags, vpp) ino = ufhp->ufid_ino; ump = VFSTOUFS(mp); fs = ump->um_fs; - if (ino < ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg) + if (ino < UFS_ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg) return (ESTALE); /* * Need to check if inode is initialized because UFS2 does lazy diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 0b5c61765d7a..13ed69694f17 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -271,7 +271,7 @@ loop: * active. Otherwise we must flush them with data, * since dependencies prevent data block writes. */ - if (waitfor == MNT_WAIT && bp->b_lblkno <= -NDADDR && + if (waitfor == MNT_WAIT && bp->b_lblkno <= -UFS_NDADDR && (lbn_level(bp->b_lblkno) >= passes || ((flags & DATA_ONLY) != 0 && !DOINGSOFTDEP(vp)))) continue; @@ -356,7 +356,7 @@ next: */ still_dirty = false; TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { - if (bp->b_lblkno > -NDADDR) { + if (bp->b_lblkno > -UFS_NDADDR) { still_dirty = true; break; } @@ -373,7 +373,7 @@ next: } /* switch between sync/async. */ wait = !wait; - if (wait || ++passes < NIADDR + 2) + if (wait || ++passes < UFS_NIADDR + 2) goto loop; #ifdef INVARIANTS if (!vn_isdisk(vp, NULL)) @@ -1002,7 +1002,8 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred) uio->uio_offset = dp->di_extsize; KASSERT(uio->uio_offset >= 0, ("ffs_extwrite: uio->uio_offset < 0")); KASSERT(uio->uio_resid >= 0, ("ffs_extwrite: uio->uio_resid < 0")); - if ((uoff_t)uio->uio_offset + uio->uio_resid > NXADDR * fs->fs_bsize) + if ((uoff_t)uio->uio_offset + uio->uio_resid > + UFS_NXADDR * fs->fs_bsize) return (EFBIG); resid = uio->uio_resid; @@ -1145,7 +1146,7 @@ ffs_rdextattr(u_char **p, struct vnode *vp, struct thread *td, int extra) fs = ITOFS(ip); dp = ip->i_din2; easize = dp->di_extsize; - if ((uoff_t)easize + extra > NXADDR * fs->fs_bsize) + if ((uoff_t)easize + extra > UFS_NXADDR * fs->fs_bsize) return (EFBIG); eae = malloc(easize + extra, M_TEMP, M_WAITOK); @@ -1296,7 +1297,7 @@ struct vop_strategy_args { vp = ap->a_vp; lbn = ap->a_bp->b_lblkno; - if (I_IS_UFS2(VTOI(vp)) && lbn < 0 && lbn >= -NXADDR) + if (I_IS_UFS2(VTOI(vp)) && lbn < 0 && lbn >= -UFS_NXADDR) return (VOP_STRATEGY_APV(&ufs_vnodeops, ap)); if (vp->v_type == VFIFO) return (VOP_STRATEGY_APV(&ufs_fifoops, ap)); @@ -1584,7 +1585,7 @@ vop_setextattr { return (EROFS); ealen = ap->a_uio->uio_resid; - if (ealen < 0 || ealen > lblktosize(fs, NXADDR)) + if (ealen < 0 || ealen > lblktosize(fs, UFS_NXADDR)) return (EINVAL); error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, @@ -1635,7 +1636,7 @@ vop_setextattr { easize += (ealength - ul); } } - if (easize > lblktosize(fs, NXADDR)) { + if (easize > lblktosize(fs, UFS_NXADDR)) { free(eae, M_TEMP); ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); if (ip->i_ea_area != NULL && ip->i_ea_error == 0) diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index c2f77a585561..c87c2b8f436e 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -575,7 +575,7 @@ struct cg { (((off_t)(frag)) << (fs)->fs_fshift) #define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \ (((off_t)(blk)) << (fs)->fs_bshift) -/* Use this only when `blk' is known to be small, e.g., < NDADDR. */ +/* Use this only when `blk' is known to be small, e.g., < UFS_NDADDR. */ #define smalllblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ ((blk) << (fs)->fs_bshift) #define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ @@ -608,11 +608,11 @@ struct cg { * Determining the size of a file block in the filesystem. */ #define blksize(fs, ip, lbn) \ - (((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \ + (((lbn) >= UFS_NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \ ? (fs)->fs_bsize \ : (fragroundup(fs, blkoff(fs, (ip)->i_size)))) #define sblksize(fs, size, lbn) \ - (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \ + (((lbn) >= UFS_NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \ ? (fs)->fs_bsize \ : (fragroundup(fs, blkoff(fs, (size))))) @@ -622,7 +622,7 @@ struct cg { #define NINDIR(fs) ((fs)->fs_nindir) /* - * Indirect lbns are aligned on NDADDR addresses where single indirects + * Indirect lbns are aligned on UFS_NDADDR addresses where single indirects * are the negated address of the lowest lbn reachable, double indirects * are this lbn - 1 and triple indirects are this lbn - 2. This yields * an unusual bit order to determine level. diff --git a/sys/ufs/ufs/dinode.h b/sys/ufs/ufs/dinode.h index 36a7c0da11ab..0e90ac24ab0a 100644 --- a/sys/ufs/ufs/dinode.h +++ b/sys/ufs/ufs/dinode.h @@ -74,15 +74,15 @@ * the root inode is 2. (Inode 1 is no longer used for this purpose, however * numerous dump tapes make this assumption, so we are stuck with it). */ -#define ROOTINO ((ino_t)2) +#define UFS_ROOTINO ((ino_t)2) /* * The Whiteout inode# is a dummy non-zero inode number which will * never be allocated to a real file. It is used as a place holder * in the directory entry which has been tagged as a DT_WHT entry. - * See the comments about ROOTINO above. + * See the comments about UFS_ROOTINO above. */ -#define WINO ((ino_t)1) +#define UFS_WINO ((ino_t)1) /* * The size of physical and logical block numbers and time fields in UFS. @@ -118,9 +118,9 @@ typedef int64_t ufs_time_t; * are defined by types with precise widths. */ -#define NXADDR 2 /* External addresses in inode. */ -#define NDADDR 12 /* Direct addresses in inode. */ -#define NIADDR 3 /* Indirect addresses in inode. */ +#define UFS_NXADDR 2 /* External addresses in inode. */ +#define UFS_NDADDR 12 /* Direct addresses in inode. */ +#define UFS_NIADDR 3 /* Indirect addresses in inode. */ struct ufs2_dinode { u_int16_t di_mode; /* 0: IFMT, permissions; see below. */ @@ -142,9 +142,9 @@ struct ufs2_dinode { u_int32_t di_kernflags; /* 84: Kernel flags. */ u_int32_t di_flags; /* 88: Status flags (chflags). */ u_int32_t di_extsize; /* 92: External attributes size. */ - ufs2_daddr_t di_extb[NXADDR];/* 96: External attributes block. */ - ufs2_daddr_t di_db[NDADDR]; /* 112: Direct disk blocks. */ - ufs2_daddr_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */ + ufs2_daddr_t di_extb[UFS_NXADDR];/* 96: External attributes block. */ + ufs2_daddr_t di_db[UFS_NDADDR]; /* 112: Direct disk blocks. */ + ufs2_daddr_t di_ib[UFS_NIADDR]; /* 208: Indirect disk blocks. */ u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */ uint32_t di_freelink; /* 240: SUJ: Next unlinked inode. */ uint32_t di_spare[3]; /* 244: Reserved; currently unused */ @@ -176,8 +176,8 @@ struct ufs1_dinode { int32_t di_mtimensec; /* 28: Last modified time. */ int32_t di_ctime; /* 32: Last inode change time. */ int32_t di_ctimensec; /* 36: Last inode change time. */ - ufs1_daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */ - ufs1_daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */ + ufs1_daddr_t di_db[UFS_NDADDR]; /* 40: Direct disk blocks. */ + ufs1_daddr_t di_ib[UFS_NIADDR]; /* 88: Indirect disk blocks. */ u_int32_t di_flags; /* 100: Status flags (chflags). */ u_int32_t di_blocks; /* 104: Blocks actually held. */ u_int32_t di_gen; /* 108: Generation number. */ diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c index f6a774a89fc4..cf369363ae28 100644 --- a/sys/ufs/ufs/ufs_bmap.c +++ b/sys/ufs/ufs/ufs_bmap.c @@ -115,7 +115,7 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb) struct buf *bp; struct ufsmount *ump; struct mount *mp; - struct indir a[NIADDR+1], *ap; + struct indir a[UFS_NIADDR+1], *ap; ufs2_daddr_t daddr; ufs_lbn_t metalbn; int error, num, maxrun = 0; @@ -144,9 +144,9 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb) num = *nump; if (num == 0) { - if (bn >= 0 && bn < NDADDR) { + if (bn >= 0 && bn < UFS_NDADDR) { *bnp = blkptrtodb(ump, DIP(ip, i_db[bn])); - } else if (bn < 0 && bn >= -NXADDR) { + } else if (bn < 0 && bn >= -UFS_NXADDR) { *bnp = blkptrtodb(ump, ip->i_din2->di_extb[-1 - bn]); if (*bnp == 0) *bnp = -1; @@ -175,7 +175,7 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb) *bnp = -1; } else if (runp) { ufs2_daddr_t bnb = bn; - for (++bn; bn < NDADDR && *runp < maxrun && + for (++bn; bn < UFS_NDADDR && *runp < maxrun && is_sequential(ump, DIP(ip, i_db[bn - 1]), DIP(ip, i_db[bn])); ++bn, ++*runp); @@ -330,17 +330,18 @@ ufs_getlbns(vp, bn, ap, nump) if (bn < 0) bn = -bn; - /* The first NDADDR blocks are direct blocks. */ - if (bn < NDADDR) + /* The first UFS_NDADDR blocks are direct blocks. */ + if (bn < UFS_NDADDR) return (0); /* * Determine the number of levels of indirection. After this loop * is done, blockcnt indicates the number of data blocks possible - * at the previous level of indirection, and NIADDR - i is the number - * of levels of indirection needed to locate the requested block. + * at the previous level of indirection, and UFS_NIADDR - i is the + * number of levels of indirection needed to locate the requested block. */ - for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { + for (blockcnt = 1, i = UFS_NIADDR, bn -= UFS_NDADDR; ; + i--, bn -= blockcnt) { if (i == 0) return (EFBIG); blockcnt *= MNINDIR(ump); @@ -350,9 +351,9 @@ ufs_getlbns(vp, bn, ap, nump) /* Calculate the address of the first meta-block. */ if (realbn >= 0) - metalbn = -(realbn - bn + NIADDR - i); + metalbn = -(realbn - bn + UFS_NIADDR - i); else - metalbn = -(-realbn - bn + NIADDR - i); + metalbn = -(-realbn - bn + UFS_NIADDR - i); /* * At each iteration, off is the offset into the bap array which is @@ -361,9 +362,9 @@ ufs_getlbns(vp, bn, ap, nump) * into the argument array. */ ap->in_lbn = metalbn; - ap->in_off = off = NIADDR - i; + ap->in_off = off = UFS_NIADDR - i; ap++; - for (++numlevels; i <= NIADDR; i++) { + for (++numlevels; i <= UFS_NIADDR; i++) { /* If searching for a meta-data block, quit when found. */ if (metalbn == realbn) break; diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 2f883c4f8a01..5be38cdb72dd 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1069,7 +1069,7 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename) namlen = ep->d_namlen; # endif if (ep->d_ino == 0 || - (ep->d_ino == WINO && namlen == dirp->d_namlen && + (ep->d_ino == UFS_WINO && namlen == dirp->d_namlen && bcmp(ep->d_name, dirp->d_name, dirp->d_namlen) == 0)) { if (spacefree + dsize < newentrysize) panic("ufs_direnter: compact1"); @@ -1178,12 +1178,12 @@ ufs_dirremove(dvp, ip, flags, isrmdir) } if (flags & DOWHITEOUT) { /* - * Whiteout entry: set d_ino to WINO. + * Whiteout entry: set d_ino to UFS_WINO. */ if ((error = UFS_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0) return (error); - ep->d_ino = WINO; + ep->d_ino = UFS_WINO; ep->d_type = DT_WHT; goto out; } @@ -1353,7 +1353,7 @@ ufs_dirempty(ip, parentino, cred) if (dp->d_reclen == 0) return (0); /* skip empty entries */ - if (dp->d_ino == 0 || dp->d_ino == WINO) + if (dp->d_ino == 0 || dp->d_ino == UFS_WINO) continue; /* accept only "." and ".." */ # if (BYTE_ORDER == LITTLE_ENDIAN) @@ -1445,7 +1445,7 @@ ufs_checkpath(ino_t source_ino, ino_t parent_ino, struct inode *target, struct u return (EEXIST); if (target->i_number == parent_ino) return (0); - if (target->i_number == ROOTINO) + if (target->i_number == UFS_ROOTINO) return (0); for (;;) { error = ufs_dir_dd_ino(vp, cred, &dd_ino, &vp1); @@ -1455,7 +1455,7 @@ ufs_checkpath(ino_t source_ino, ino_t parent_ino, struct inode *target, struct u error = EINVAL; break; } - if (dd_ino == ROOTINO) + if (dd_ino == UFS_ROOTINO) break; if (dd_ino == parent_ino) break; diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 5bb73ea0c81d..5135f2228a8c 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -74,7 +74,7 @@ ufs_root(mp, flags, vpp) struct vnode *nvp; int error; - error = VFS_VGET(mp, (ino_t)ROOTINO, flags, &nvp); + error = VFS_VGET(mp, (ino_t)UFS_ROOTINO, flags, &nvp); if (error) return (error); *vpp = nvp; diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index d100454f6810..6119de14df65 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1053,7 +1053,7 @@ ufs_whiteout(ap) panic("ufs_whiteout: old format filesystem"); #endif - newdir.d_ino = WINO; + newdir.d_ino = UFS_WINO; newdir.d_namlen = cnp->cn_namelen; bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1); newdir.d_type = DT_WHT; @@ -2564,7 +2564,7 @@ ufs_vinit(mntp, fifoops, vpp) if (vp->v_type == VFIFO) vp->v_op = fifoops; ASSERT_VOP_LOCKED(vp, "ufs_vinit"); - if (ip->i_number == ROOTINO) + if (ip->i_number == UFS_ROOTINO) vp->v_vflag |= VV_ROOT; *vpp = vp; return (0); diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 0887a703fc9f..e659bdf87db5 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -139,8 +139,18 @@ cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops, if (foff & PAGE_MASK) return (NULL); + /* + * Treat the mmap(2) file offset as an unsigned value for a + * device mapping. This, in effect, allows a user to pass all + * possible off_t values as the mapping cookie to the driver. At + * this point, we know that both foff and size are a multiple + * of the page size. Do a check to avoid wrap. + */ size = round_page(size); - pindex = OFF_TO_IDX(foff + size); + pindex = UOFF_TO_IDX(foff) + UOFF_TO_IDX(size); + if (pindex > OBJ_MAX_SIZE || pindex < UOFF_TO_IDX(foff) || + pindex < UOFF_TO_IDX(size)) + return (NULL); if (ops->cdev_pg_ctor(handle, size, prot, foff, cred, &color) != 0) return (NULL); diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c index 2cccb7ea1598..567304f428e3 100644 --- a/sys/vm/sg_pager.c +++ b/sys/vm/sg_pager.c @@ -96,8 +96,9 @@ sg_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot, * to map beyond that. */ size = round_page(size); - pindex = OFF_TO_IDX(foff + size); - if (pindex > npages) + pindex = UOFF_TO_IDX(foff) + UOFF_TO_IDX(size); + if (pindex > npages || pindex < UOFF_TO_IDX(foff) || + pindex < UOFF_TO_IDX(size)) return (NULL); /* diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 49553570ed79..0489b6ec74a5 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -71,16 +71,6 @@ void kmem_init(vm_offset_t, vm_offset_t); void kmem_init_zero_region(void); void kmeminit(void); -int kern_vm_mmap(struct thread *td, vm_offset_t addr, vm_size_t size, - vm_prot_t prot, int flags, int fd, off_t pos); -int kern_vm_mprotect(struct thread *td, vm_offset_t addr, vm_size_t size, - vm_prot_t prot); -int kern_vm_msync(struct thread *td, vm_offset_t addr, vm_size_t size, - int flags); -int kern_vm_munlock(struct thread *td, vm_offset_t addr, vm_size_t size); -int kern_vm_munmap(struct thread *td, vm_offset_t addr, vm_size_t size); -int kern_vm_madvise(struct thread *td, vm_offset_t addr, vm_size_t len, - int behav); void swapout_procs(int); int kernacc(void *, int, int); int useracc(void *, int, int); @@ -124,6 +114,5 @@ struct sf_buf *vm_imgact_map_page(vm_object_t object, vm_ooffset_t offset); void vm_imgact_unmap_page(struct sf_buf *sf); void vm_thread_dispose(struct thread *td); int vm_thread_new(struct thread *td, int pages); -int vm_mlock(struct proc *, struct ucred *, const void *, size_t); #endif /* _KERNEL */ #endif /* !_VM_EXTERN_H_ */ diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 822142b54afd..149b7dc89057 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -528,8 +528,8 @@ RetryFault:; fs.map_generation = fs.map->timestamp; if (fs.entry->eflags & MAP_ENTRY_NOFAULT) { - panic("vm_fault: fault on nofault entry, addr: %lx", - (u_long)vaddr); + panic("%s: fault on nofault entry, addr: %#lx", + __func__, (u_long)vaddr); } if (fs.entry->eflags & MAP_ENTRY_IN_TRANSITION && diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 81124aba54f7..f8522bd4b8a7 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -107,14 +107,8 @@ struct sbrk_args { }; #endif -/* - * MPSAFE - */ -/* ARGSUSED */ int -sys_sbrk(td, uap) - struct thread *td; - struct sbrk_args *uap; +sys_sbrk(struct thread *td, struct sbrk_args *uap) { /* Not yet implemented */ return (EOPNOTSUPP); @@ -126,14 +120,8 @@ struct sstk_args { }; #endif -/* - * MPSAFE - */ -/* ARGSUSED */ int -sys_sstk(td, uap) - struct thread *td; - struct sstk_args *uap; +sys_sstk(struct thread *td, struct sstk_args *uap) { /* Not yet implemented */ return (EOPNOTSUPP); @@ -147,11 +135,9 @@ struct getpagesize_args { #endif int -ogetpagesize(td, uap) - struct thread *td; - struct getpagesize_args *uap; +ogetpagesize(struct thread *td, struct getpagesize_args *uap) { - /* MP SAFE */ + td->td_retval[0] = PAGE_SIZE; return (0); } @@ -183,30 +169,30 @@ struct mmap_args { }; #endif -/* - * MPSAFE - */ int sys_mmap(struct thread *td, struct mmap_args *uap) { - return (kern_vm_mmap(td, (vm_offset_t)uap->addr, uap->len, - uap->prot, uap->flags, uap->fd, uap->pos)); + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, uap->prot, + uap->flags, uap->fd, uap->pos)); } int -kern_vm_mmap(struct thread *td, vm_offset_t addr, vm_size_t size, - vm_prot_t prot, int flags, int fd, off_t pos) +kern_mmap(struct thread *td, uintptr_t addr0, size_t size, int prot, int flags, + int fd, off_t pos) { + struct vmspace *vms; struct file *fp; + vm_offset_t addr; vm_size_t pageoff; vm_prot_t cap_maxprot; int align, error; - struct vmspace *vms = td->td_proc->p_vmspace; cap_rights_t rights; + vms = td->td_proc->p_vmspace; fp = NULL; AUDIT_ARG_FD(fd); + addr = addr0; /* * Ignore old flags that used to be defined but did not do anything. @@ -380,8 +366,8 @@ int freebsd6_mmap(struct thread *td, struct freebsd6_mmap_args *uap) { - return (kern_vm_mmap(td, (vm_offset_t)uap->addr, uap->len, - uap->prot, uap->flags, uap->fd, uap->pos)); + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, uap->prot, + uap->flags, uap->fd, uap->pos)); } #endif @@ -435,8 +421,8 @@ ommap(struct thread *td, struct ommap_args *uap) flags |= MAP_PRIVATE; if (uap->flags & OMAP_FIXED) flags |= MAP_FIXED; - return (kern_vm_mmap(td, (vm_offset_t)uap->addr, uap->len, - prot, flags, uap->fd, uap->pos)); + return (kern_mmap(td, (uintptr_t)uap->addr, uap->len, prot, flags, + uap->fd, uap->pos)); } #endif /* COMPAT_43 */ @@ -448,24 +434,22 @@ struct msync_args { int flags; }; #endif -/* - * MPSAFE - */ int sys_msync(struct thread *td, struct msync_args *uap) { - return (kern_vm_msync(td, (vm_offset_t)uap->addr, uap->len, - uap->flags)); + return (kern_msync(td, (uintptr_t)uap->addr, uap->len, uap->flags)); } int -kern_vm_msync(struct thread *td, vm_offset_t addr, vm_size_t size, int flags) +kern_msync(struct thread *td, uintptr_t addr0, size_t size, int flags) { + vm_offset_t addr; vm_size_t pageoff; vm_map_t map; int rv; + addr = addr0; pageoff = (addr & PAGE_MASK); addr -= pageoff; size += pageoff; @@ -503,30 +487,29 @@ struct munmap_args { size_t len; }; #endif -/* - * MPSAFE - */ int sys_munmap(struct thread *td, struct munmap_args *uap) { - return (kern_vm_munmap(td, (vm_offset_t)uap->addr, uap->len)); + return (kern_munmap(td, (uintptr_t)uap->addr, uap->len)); } int -kern_vm_munmap(struct thread *td, vm_offset_t addr, vm_size_t size) +kern_munmap(struct thread *td, uintptr_t addr0, size_t size) { #ifdef HWPMC_HOOKS struct pmckern_map_out pkm; vm_map_entry_t entry; bool pmc_handled; #endif + vm_offset_t addr; vm_size_t pageoff; vm_map_t map; if (size == 0) return (EINVAL); + addr = addr0; pageoff = (addr & PAGE_MASK); addr -= pageoff; size += pageoff; @@ -588,23 +571,20 @@ struct mprotect_args { int prot; }; #endif -/* - * MPSAFE - */ int sys_mprotect(struct thread *td, struct mprotect_args *uap) { - return (kern_vm_mprotect(td, (vm_offset_t)uap->addr, uap->len, - uap->prot)); + return (kern_mprotect(td, (uintptr_t)uap->addr, uap->len, uap->prot)); } int -kern_vm_mprotect(struct thread *td, vm_offset_t addr, vm_size_t size, - vm_prot_t prot) +kern_mprotect(struct thread *td, uintptr_t addr0, size_t size, int prot) { + vm_offset_t addr; vm_size_t pageoff; + addr = addr0; prot = (prot & VM_PROT_ALL); pageoff = (addr & PAGE_MASK); addr -= pageoff; @@ -632,13 +612,8 @@ struct minherit_args { int inherit; }; #endif -/* - * MPSAFE - */ int -sys_minherit(td, uap) - struct thread *td; - struct minherit_args *uap; +sys_minherit(struct thread *td, struct minherit_args *uap) { vm_offset_t addr; vm_size_t size, pageoff; @@ -673,24 +648,18 @@ struct madvise_args { }; #endif -/* - * MPSAFE - */ int -sys_madvise(td, uap) - struct thread *td; - struct madvise_args *uap; +sys_madvise(struct thread *td, struct madvise_args *uap) { - return (kern_vm_madvise(td, (vm_offset_t)uap->addr, uap->len, - uap->behav)); + return (kern_madvise(td, (uintptr_t)uap->addr, uap->len, uap->behav)); } int -kern_vm_madvise(struct thread *td, vm_offset_t addr, vm_size_t len, int behav) +kern_madvise(struct thread *td, uintptr_t addr0, size_t len, int behav) { - vm_offset_t start, end; vm_map_t map; + vm_offset_t addr, end, start; int flags; /* @@ -713,6 +682,7 @@ kern_vm_madvise(struct thread *td, vm_offset_t addr, vm_size_t len, int behav) * that VM_*_ADDRESS are not constants due to casts (argh). */ map = &td->td_proc->p_vmspace->vm_map; + addr = addr0; if (addr < vm_map_min(map) || addr + len > vm_map_max(map)) return (EINVAL); if ((addr + len) < addr) @@ -738,13 +708,8 @@ struct mincore_args { }; #endif -/* - * MPSAFE - */ int -sys_mincore(td, uap) - struct thread *td; - struct mincore_args *uap; +sys_mincore(struct thread *td, struct mincore_args *uap) { vm_offset_t addr, first_addr; vm_offset_t end, cend; @@ -994,20 +959,16 @@ struct mlock_args { size_t len; }; #endif -/* - * MPSAFE - */ int -sys_mlock(td, uap) - struct thread *td; - struct mlock_args *uap; +sys_mlock(struct thread *td, struct mlock_args *uap) { - return (vm_mlock(td->td_proc, td->td_ucred, uap->addr, uap->len)); + return (kern_mlock(td->td_proc, td->td_ucred, + __DECONST(uintptr_t, uap->addr), uap->len)); } int -vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len) +kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr0, size_t len) { vm_offset_t addr, end, last, start; vm_size_t npages, size; @@ -1018,7 +979,7 @@ vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len) error = priv_check_cred(cred, PRIV_VM_MLOCK, 0); if (error) return (error); - addr = (vm_offset_t)addr0; + addr = addr0; size = len; last = addr + size; start = trunc_page(addr); @@ -1066,13 +1027,8 @@ struct mlockall_args { }; #endif -/* - * MPSAFE - */ int -sys_mlockall(td, uap) - struct thread *td; - struct mlockall_args *uap; +sys_mlockall(struct thread *td, struct mlockall_args *uap) { vm_map_t map; int error; @@ -1143,13 +1099,8 @@ struct munlockall_args { }; #endif -/* - * MPSAFE - */ int -sys_munlockall(td, uap) - struct thread *td; - struct munlockall_args *uap; +sys_munlockall(struct thread *td, struct munlockall_args *uap) { vm_map_t map; int error; @@ -1184,20 +1135,17 @@ struct munlock_args { size_t len; }; #endif -/* - * MPSAFE - */ int sys_munlock(struct thread *td, struct munlock_args *uap) { - return (kern_vm_munlock(td, (vm_offset_t)uap->addr, uap->len)); + return (kern_munlock(td, (uintptr_t)uap->addr, uap->len)); } int -kern_vm_munlock(struct thread *td, vm_offset_t addr, vm_size_t size) +kern_munlock(struct thread *td, uintptr_t addr0, size_t size) { - vm_offset_t end, last, start; + vm_offset_t addr, end, last, start; #ifdef RACCT vm_map_t map; #endif @@ -1206,6 +1154,7 @@ kern_vm_munlock(struct thread *td, vm_offset_t addr, vm_size_t size) error = priv_check(td, PRIV_VM_MUNLOCK); if (error) return (error); + addr = addr0; last = addr + size; start = trunc_page(addr); end = round_page(last); @@ -1340,8 +1289,6 @@ done: /* * vm_mmap_cdev() * - * MPSAFE - * * Helper function for vm_mmap. Perform sanity check specific for mmap * operations on cdevs. */ diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index e957c4cce396..9b2192efef58 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -183,8 +183,23 @@ struct vm_object { #define OBJ_DISCONNECTWNT 0x4000 /* disconnect from vnode wanted */ #define OBJ_TMPFS 0x8000 /* has tmpfs vnode allocated */ +/* + * Helpers to perform conversion between vm_object page indexes and offsets. + * IDX_TO_OFF() converts an index into an offset. + * OFF_TO_IDX() converts an offset into an index. Since offsets are signed + * by default, the sign propagation in OFF_TO_IDX(), when applied to + * negative offsets, is intentional and returns a vm_object page index + * that cannot be created by a userspace mapping. + * UOFF_TO_IDX() treats the offset as an unsigned value and converts it + * into an index accordingly. Use it only when the full range of offset + * values are allowed. Currently, this only applies to device mappings. + * OBJ_MAX_SIZE specifies the maximum page index corresponding to the + * maximum unsigned offset. + */ #define IDX_TO_OFF(idx) (((vm_ooffset_t)(idx)) << PAGE_SHIFT) #define OFF_TO_IDX(off) ((vm_pindex_t)(((vm_ooffset_t)(off)) >> PAGE_SHIFT)) +#define UOFF_TO_IDX(off) (((vm_pindex_t)(off)) >> PAGE_SHIFT) +#define OBJ_MAX_SIZE (UOFF_TO_IDX(UINT64_MAX) + 1) #ifdef _KERNEL diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index e21ee9595d99..834d31b3703a 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -2268,12 +2268,14 @@ again: if (size >= limit) { vm_pageout_map_deactivate_pages( &vm->vm_map, limit); + size = vmspace_resident_count(vm); } #ifdef RACCT if (racct_enable) { rsize = IDX_TO_OFF(size); PROC_LOCK(p); - racct_set(p, RACCT_RSS, rsize); + if (p->p_state == PRS_NORMAL) + racct_set(p, RACCT_RSS, rsize); ravailable = racct_get_available(p, RACCT_RSS); PROC_UNLOCK(p); if (rsize > ravailable) { @@ -2299,7 +2301,8 @@ again: size = vmspace_resident_count(vm); rsize = IDX_TO_OFF(size); PROC_LOCK(p); - racct_set(p, RACCT_RSS, rsize); + if (p->p_state == PRS_NORMAL) + racct_set(p, RACCT_RSS, rsize); PROC_UNLOCK(p); if (rsize > ravailable) tryagain = 1; diff --git a/sys/x86/isa/atpic.c b/sys/x86/isa/atpic.c index fc1d2dcdd391..ea8c3e2786a6 100644 --- a/sys/x86/isa/atpic.c +++ b/sys/x86/isa/atpic.c @@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$"); #include "opt_auto_eoi.h" #include "opt_isa.h" -#include "opt_mca.h" #include <sys/param.h> #include <sys/systm.h> @@ -54,9 +53,6 @@ __FBSDID("$FreeBSD$"); #include <x86/isa/icu.h> #include <isa/isareg.h> #include <isa/isavar.h> -#ifdef DEV_MCA -#include <i386/bios/mca_machdep.h> -#endif #ifdef __amd64__ #define SDT_ATPIC SDT_SYSIGT @@ -356,13 +352,7 @@ i8259_init(struct atpic *pic, int slave) /* Reset the PIC and program with next four bytes. */ spinlock_enter(); -#ifdef DEV_MCA - /* MCA uses level triggered interrupts. */ - if (MCA_system) - outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4 | ICW1_LTIM); - else -#endif - outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4); + outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4); imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET; /* Start vector. */ @@ -419,14 +409,6 @@ atpic_startup(void) ai->at_irq, ai->at_intr, SDT_ATPIC, SEL_KPL, GSEL_ATPIC); } -#ifdef DEV_MCA - /* For MCA systems, all interrupts are level triggered. */ - if (MCA_system) - for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) - ai->at_trigger = INTR_TRIGGER_LEVEL; - else -#endif - /* * Look for an ELCR. If we find one, update the trigger modes. * If we don't find one, assume that IRQs 0, 1, 2, and 13 are diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c index 778481fb73c9..039dda1f1a3d 100644 --- a/sys/x86/isa/clock.c +++ b/sys/x86/isa/clock.c @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include "opt_clock.h" #include "opt_isa.h" -#include "opt_mca.h" #include <sys/param.h> #include <sys/systm.h> @@ -73,10 +72,6 @@ __FBSDID("$FreeBSD$"); #include <isa/isavar.h> #endif -#ifdef DEV_MCA -#include <i386/bios/mca_machdep.h> -#endif - int clkintr_pending; #ifndef TIMER_FREQ #define TIMER_FREQ 1193182 @@ -153,11 +148,6 @@ clkintr(void *arg) if (sc->et.et_active && sc->mode != MODE_STOP) sc->et.et_event_cb(&sc->et, sc->et.et_arg); -#ifdef DEV_MCA - /* Reset clock interrupt by asserting bit 7 of port 0x61 */ - if (MCA_system) - outb(0x61, inb(0x61) | 0x80); -#endif return (FILTER_HANDLED); } diff --git a/sys/x86/isa/nmi.c b/sys/x86/isa/nmi.c index db5550c63423..fd6943029a51 100644 --- a/sys/x86/isa/nmi.c +++ b/sys/x86/isa/nmi.c @@ -35,18 +35,12 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include "opt_mca.h" - #include <sys/types.h> #include <sys/syslog.h> #include <sys/systm.h> #include <machine/md_var.h> -#ifdef DEV_MCA -#include <i386/bios/mca_machdep.h> -#endif - #define NMI_PARITY (1 << 7) #define NMI_IOCHAN (1 << 6) #define ENMI_WATCHDOG (1 << 7) @@ -65,10 +59,6 @@ isa_nmi(int cd) int eisa_port = inb(0x461); log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port); -#ifdef DEV_MCA - if (MCA_system && mca_bus_nmi()) - return(0); -#endif if (isa_port & NMI_PARITY) { log(LOG_CRIT, "RAM parity error, likely hardware failure."); diff --git a/sys/x86/x86/legacy.c b/sys/x86/x86/legacy.c index e7a101fe06b5..6d3470f4d6d6 100644 --- a/sys/x86/x86/legacy.c +++ b/sys/x86/x86/legacy.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#ifdef __i386__ -#include "opt_eisa.h" -#include "opt_mca.h" -#endif #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -51,10 +47,6 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <sys/smp.h> -#ifdef DEV_MCA -#include <i386/bios/mca_machdep.h> -#endif - #include <machine/clock.h> #include <machine/resource.h> #include <x86/legacyvar.h> @@ -133,25 +125,9 @@ legacy_attach(device_t dev) bus_generic_attach(dev); /* - * If we didn't see EISA or ISA on a pci bridge, create some + * If we didn't see ISA on a pci bridge, create some * connection points now so they show up "on motherboard". */ -#ifdef DEV_EISA - if (!devclass_get_device(devclass_find("eisa"), 0)) { - child = BUS_ADD_CHILD(dev, 0, "eisa", 0); - if (child == NULL) - panic("legacy_attach eisa"); - device_probe_and_attach(child); - } -#endif -#ifdef DEV_MCA - if (MCA_system && !devclass_get_device(devclass_find("mca"), 0)) { - child = BUS_ADD_CHILD(dev, 0, "mca", 0); - if (child == 0) - panic("legacy_probe mca"); - device_probe_and_attach(child); - } -#endif if (!devclass_get_device(devclass_find("isa"), 0)) { child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c index a917cc45f26b..bece5d490051 100644 --- a/sys/x86/x86/mca.c +++ b/sys/x86/x86/mca.c @@ -533,7 +533,7 @@ cmci_update(enum scan_mode mode, int bank, int valid, struct mca_record *rec) cc = &cmc_state[PCPU_GET(cpuid)][bank]; ctl = rdmsr(MSR_MC_CTL2(bank)); count = (rec->mr_status & MC_STATUS_COR_COUNT) >> 38; - delta = (u_int)(ticks - cc->last_intr); + delta = (u_int)(time_uptime - cc->last_intr); /* * If an interrupt was received less than cmc_throttle seconds @@ -548,9 +548,9 @@ cmci_update(enum scan_mode mode, int bank, int valid, struct mca_record *rec) limit = min(limit << 1, cc->max_threshold); ctl &= ~MC_CTL2_THRESHOLD; ctl |= limit; - wrmsr(MSR_MC_CTL2(bank), limit); + wrmsr(MSR_MC_CTL2(bank), ctl); } - cc->last_intr = ticks; + cc->last_intr = time_uptime; return; } @@ -581,7 +581,7 @@ cmci_update(enum scan_mode mode, int bank, int valid, struct mca_record *rec) if ((ctl & MC_CTL2_THRESHOLD) != limit) { ctl &= ~MC_CTL2_THRESHOLD; ctl |= limit; - wrmsr(MSR_MC_CTL2(bank), limit); + wrmsr(MSR_MC_CTL2(bank), ctl); } } #endif @@ -857,7 +857,7 @@ cmci_resume(int i) return; cc = &cmc_state[PCPU_GET(cpuid)][i]; - cc->last_intr = -ticks; + cc->last_intr = 0; ctl = rdmsr(MSR_MC_CTL2(i)); ctl &= ~MC_CTL2_THRESHOLD; ctl |= MC_CTL2_CMCI_EN | 1; |