Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jacob Adams 2015-02-01 22:46:55 -05:00
commit 82d8277600
130 changed files with 5260 additions and 10801 deletions

View File

@ -2,7 +2,7 @@
COMMON_DIR:=${.PARSEDIR}
.if defined(__MINIX)
COMMON_CODEDIRS=atomic gen inet md net quad stdlib string
COMMON_CODEDIRS=atomic gen inet md net stdlib string
.else
COMMON_CODEDIRS=atomic gen gmon inet md net quad stdlib string sys
.endif

View File

@ -1,381 +0,0 @@
/* $NetBSD: divide.S,v 1.4 2013/08/19 03:47:06 matt Exp $ */
/*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __ARM_ARCH_EXT_IDIV__
#include <machine/asm.h>
/*
* stack is aligned as there's a possibility of branching to .L_overflow
* which makes a C call
*/
_ARM_ENTRY(__udivide) /* r0 = r0 / r1; r1 = r0 % r1 */
eor r0, r1, r0
eor r1, r0, r1
eor r0, r1, r0
/* r0 = r1 / r0; r1 = r1 % r0 */
cmp r0, #1
bcc .L_overflow
beq .L_divide_l0
mov ip, #0
movs r1, r1
bpl .L_divide_l1
orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
movs r1, r1, lsr #1
orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
b .L_divide_l1
.L_divide_l0: /* r0 == 1 */
mov r0, r1
mov r1, #0
RET
END(__udivide)
_ARM_ENTRY(__divide) /* r0 = r0 / r1; r1 = r0 % r1 */
eor r0, r1, r0
eor r1, r0, r1
eor r0, r1, r0
/* r0 = r1 / r0; r1 = r1 % r0 */
cmp r0, #1
bcc .L_overflow
beq .L_divide_l0
ands ip, r0, #0x80000000
rsbmi r0, r0, #0
ands r2, r1, #0x80000000
eor ip, ip, r2
rsbmi r1, r1, #0
orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
/* ip bit 0x80000000 = -ve remainder */
.L_divide_l1:
mov r2, #1
mov r3, #0
/*
* If the highest bit of the dividend is set, we have to be
* careful when shifting the divisor. Test this.
*/
movs r1,r1
bpl .L_old_code
/*
* At this point, the highest bit of r1 is known to be set.
* We abuse this below in the tst instructions.
*/
tst r1, r0 /*, lsl #0 */
bmi .L_divide_b1
tst r1, r0, lsl #1
bmi .L_divide_b2
tst r1, r0, lsl #2
bmi .L_divide_b3
tst r1, r0, lsl #3
bmi .L_divide_b4
tst r1, r0, lsl #4
bmi .L_divide_b5
tst r1, r0, lsl #5
bmi .L_divide_b6
tst r1, r0, lsl #6
bmi .L_divide_b7
tst r1, r0, lsl #7
bmi .L_divide_b8
tst r1, r0, lsl #8
bmi .L_divide_b9
tst r1, r0, lsl #9
bmi .L_divide_b10
tst r1, r0, lsl #10
bmi .L_divide_b11
tst r1, r0, lsl #11
bmi .L_divide_b12
tst r1, r0, lsl #12
bmi .L_divide_b13
tst r1, r0, lsl #13
bmi .L_divide_b14
tst r1, r0, lsl #14
bmi .L_divide_b15
tst r1, r0, lsl #15
bmi .L_divide_b16
tst r1, r0, lsl #16
bmi .L_divide_b17
tst r1, r0, lsl #17
bmi .L_divide_b18
tst r1, r0, lsl #18
bmi .L_divide_b19
tst r1, r0, lsl #19
bmi .L_divide_b20
tst r1, r0, lsl #20
bmi .L_divide_b21
tst r1, r0, lsl #21
bmi .L_divide_b22
tst r1, r0, lsl #22
bmi .L_divide_b23
tst r1, r0, lsl #23
bmi .L_divide_b24
tst r1, r0, lsl #24
bmi .L_divide_b25
tst r1, r0, lsl #25
bmi .L_divide_b26
tst r1, r0, lsl #26
bmi .L_divide_b27
tst r1, r0, lsl #27
bmi .L_divide_b28
tst r1, r0, lsl #28
bmi .L_divide_b29
tst r1, r0, lsl #29
bmi .L_divide_b30
tst r1, r0, lsl #30
bmi .L_divide_b31
/*
* instead of:
* tst r1, r0, lsl #31
* bmi .L_divide_b32
*/
b .L_divide_b32
.L_old_code:
cmp r1, r0
bcc .L_divide_b0
cmp r1, r0, lsl #1
bcc .L_divide_b1
cmp r1, r0, lsl #2
bcc .L_divide_b2
cmp r1, r0, lsl #3
bcc .L_divide_b3
cmp r1, r0, lsl #4
bcc .L_divide_b4
cmp r1, r0, lsl #5
bcc .L_divide_b5
cmp r1, r0, lsl #6
bcc .L_divide_b6
cmp r1, r0, lsl #7
bcc .L_divide_b7
cmp r1, r0, lsl #8
bcc .L_divide_b8
cmp r1, r0, lsl #9
bcc .L_divide_b9
cmp r1, r0, lsl #10
bcc .L_divide_b10
cmp r1, r0, lsl #11
bcc .L_divide_b11
cmp r1, r0, lsl #12
bcc .L_divide_b12
cmp r1, r0, lsl #13
bcc .L_divide_b13
cmp r1, r0, lsl #14
bcc .L_divide_b14
cmp r1, r0, lsl #15
bcc .L_divide_b15
cmp r1, r0, lsl #16
bcc .L_divide_b16
cmp r1, r0, lsl #17
bcc .L_divide_b17
cmp r1, r0, lsl #18
bcc .L_divide_b18
cmp r1, r0, lsl #19
bcc .L_divide_b19
cmp r1, r0, lsl #20
bcc .L_divide_b20
cmp r1, r0, lsl #21
bcc .L_divide_b21
cmp r1, r0, lsl #22
bcc .L_divide_b22
cmp r1, r0, lsl #23
bcc .L_divide_b23
cmp r1, r0, lsl #24
bcc .L_divide_b24
cmp r1, r0, lsl #25
bcc .L_divide_b25
cmp r1, r0, lsl #26
bcc .L_divide_b26
cmp r1, r0, lsl #27
bcc .L_divide_b27
cmp r1, r0, lsl #28
bcc .L_divide_b28
cmp r1, r0, lsl #29
bcc .L_divide_b29
cmp r1, r0, lsl #30
bcc .L_divide_b30
.L_divide_b32:
cmp r1, r0, lsl #31
subhs r1, r1,r0, lsl #31
addhs r3, r3,r2, lsl #31
.L_divide_b31:
cmp r1, r0, lsl #30
subhs r1, r1,r0, lsl #30
addhs r3, r3,r2, lsl #30
.L_divide_b30:
cmp r1, r0, lsl #29
subhs r1, r1,r0, lsl #29
addhs r3, r3,r2, lsl #29
.L_divide_b29:
cmp r1, r0, lsl #28
subhs r1, r1,r0, lsl #28
addhs r3, r3,r2, lsl #28
.L_divide_b28:
cmp r1, r0, lsl #27
subhs r1, r1,r0, lsl #27
addhs r3, r3,r2, lsl #27
.L_divide_b27:
cmp r1, r0, lsl #26
subhs r1, r1,r0, lsl #26
addhs r3, r3,r2, lsl #26
.L_divide_b26:
cmp r1, r0, lsl #25
subhs r1, r1,r0, lsl #25
addhs r3, r3,r2, lsl #25
.L_divide_b25:
cmp r1, r0, lsl #24
subhs r1, r1,r0, lsl #24
addhs r3, r3,r2, lsl #24
.L_divide_b24:
cmp r1, r0, lsl #23
subhs r1, r1,r0, lsl #23
addhs r3, r3,r2, lsl #23
.L_divide_b23:
cmp r1, r0, lsl #22
subhs r1, r1,r0, lsl #22
addhs r3, r3,r2, lsl #22
.L_divide_b22:
cmp r1, r0, lsl #21
subhs r1, r1,r0, lsl #21
addhs r3, r3,r2, lsl #21
.L_divide_b21:
cmp r1, r0, lsl #20
subhs r1, r1,r0, lsl #20
addhs r3, r3,r2, lsl #20
.L_divide_b20:
cmp r1, r0, lsl #19
subhs r1, r1,r0, lsl #19
addhs r3, r3,r2, lsl #19
.L_divide_b19:
cmp r1, r0, lsl #18
subhs r1, r1,r0, lsl #18
addhs r3, r3,r2, lsl #18
.L_divide_b18:
cmp r1, r0, lsl #17
subhs r1, r1,r0, lsl #17
addhs r3, r3,r2, lsl #17
.L_divide_b17:
cmp r1, r0, lsl #16
subhs r1, r1,r0, lsl #16
addhs r3, r3,r2, lsl #16
.L_divide_b16:
cmp r1, r0, lsl #15
subhs r1, r1,r0, lsl #15
addhs r3, r3,r2, lsl #15
.L_divide_b15:
cmp r1, r0, lsl #14
subhs r1, r1,r0, lsl #14
addhs r3, r3,r2, lsl #14
.L_divide_b14:
cmp r1, r0, lsl #13
subhs r1, r1,r0, lsl #13
addhs r3, r3,r2, lsl #13
.L_divide_b13:
cmp r1, r0, lsl #12
subhs r1, r1,r0, lsl #12
addhs r3, r3,r2, lsl #12
.L_divide_b12:
cmp r1, r0, lsl #11
subhs r1, r1,r0, lsl #11
addhs r3, r3,r2, lsl #11
.L_divide_b11:
cmp r1, r0, lsl #10
subhs r1, r1,r0, lsl #10
addhs r3, r3,r2, lsl #10
.L_divide_b10:
cmp r1, r0, lsl #9
subhs r1, r1,r0, lsl #9
addhs r3, r3,r2, lsl #9
.L_divide_b9:
cmp r1, r0, lsl #8
subhs r1, r1,r0, lsl #8
addhs r3, r3,r2, lsl #8
.L_divide_b8:
cmp r1, r0, lsl #7
subhs r1, r1,r0, lsl #7
addhs r3, r3,r2, lsl #7
.L_divide_b7:
cmp r1, r0, lsl #6
subhs r1, r1,r0, lsl #6
addhs r3, r3,r2, lsl #6
.L_divide_b6:
cmp r1, r0, lsl #5
subhs r1, r1,r0, lsl #5
addhs r3, r3,r2, lsl #5
.L_divide_b5:
cmp r1, r0, lsl #4
subhs r1, r1,r0, lsl #4
addhs r3, r3,r2, lsl #4
.L_divide_b4:
cmp r1, r0, lsl #3
subhs r1, r1,r0, lsl #3
addhs r3, r3,r2, lsl #3
.L_divide_b3:
cmp r1, r0, lsl #2
subhs r1, r1,r0, lsl #2
addhs r3, r3,r2, lsl #2
.L_divide_b2:
cmp r1, r0, lsl #1
subhs r1, r1,r0, lsl #1
addhs r3, r3,r2, lsl #1
.L_divide_b1:
cmp r1, r0
subhs r1, r1, r0
addhs r3, r3, r2
.L_divide_b0:
tst ip, #0x20000000
bne .L_udivide_l1
mov r0, r3
cmp ip, #0
rsbmi r1, r1, #0
movs ip, ip, lsl #1
bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
rsbmi r0, r0, #0
RET
.L_udivide_l1:
tst ip, #0x10000000
mov r1, r1, lsl #1
orrne r1, r1, #1
mov r3, r3, lsl #1
cmp r1, r0
subhs r1, r1, r0
addhs r3, r3, r2
mov r0, r3
RET
.L_overflow:
#if !defined(_KERNEL) && !defined(_STANDALONE)
#ifdef __ARM_EABI__
mov r0, r1 /* return quotient */
b PLT_SYM(__aeabi_idiv0)
#else
mov r0, #8 /* SIGFPE */
bl PLT_SYM(_C_LABEL(raise)) /* raise it */
mov r0, #0
RET
#endif
#else
/* XXX should cause a fatal error */
mvn r0, #0
RET
#endif
END(__divide)
#endif /* __ARM_ARCH_EXT_IDIV__ */

View File

@ -1,79 +0,0 @@
/* $NetBSD: divsi3.S,v 1.13 2013/09/12 15:36:14 joerg Exp $ */
/*
* 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 <machine/asm.h>
#if defined(__thumb__) && !defined(_ARM_ARCH_T2)
ARM_ENTRY(__divsi3)
#else
ENTRY(__divsi3)
#endif
#if defined(__ARM_ARCH_EXT_IDIV__)
# if defined(__ARM_EABI__)
mov r3, r0 @ save for mls
# endif
sdiv r0, r0, r1
# if defined(__ARM_EABI__)
mls r1, r0, r1, r3 @ return modulus in r1
# endif
RET
#elif defined(__ARM_EABI__) && defined(_LIBC)
cmp r1, #0 @ dividing by 0?
beq .Ldiv0 @ call __aeabi_idiv0
ldr r2, .Lhwdiv_present
#ifdef __PIC__
add r2, r2, pc @ pc = &.LPIC0
# endif
ldr r2, [r2]
.LPIC0: cmp r2, #0
beq __divide
mov r3, r0
# if defined(__ARM_ARCH_EXT_IDIV__)
sdiv r0, r0, r1
mls r1, r0, r1, r3 @ return modulus in r1
# elif defined(__thumb__) && defined(_ARM_ARCH_T2)
.inst.w 0xfb90f0f1
.inst.w 0xfb003111
# else
.inst 0xe710f110
.inst 0xe0613190
# endif
RET
.align 0
.Lhwdiv_present:
.word REL_SYM(_libc_arm_hwdiv_present, .LPIC0)
.align 0
.Ldiv0: push {r0, lr} /* save r0 */
cmp r0, #0
mvnge r0, #0x80000000 /* INT_MAX = 0x7fffffff */
movlt r0, #0x80000000 /* INT_MIN = 0x80000000 */
bl _C_LABEL(__aeabi_idiv0)
pop {r1, pc} /* restore r0 as r1 */
#else /* !__ARM_EABI__ */
b __divide
#endif
END(__divsi3)
#if defined(__ARM_EABI__)
STRONG_ALIAS(__aeabi_idivmod, __divsi3)
STRONG_ALIAS(__aeabi_idiv, __divsi3)
#if defined(PIC_SYMVER)
.symver __aeabi_idiv,__aeabi_idiv@@GCC_3.5
.symver __aeabi_idivmod,__aeabi_idivmod@@GCC_3.5
#endif
#endif

View File

@ -1,38 +0,0 @@
/* $NetBSD: modsi3.S,v 1.4 2013/08/15 21:40:11 matt Exp $ */
/*
* 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 <machine/asm.h>
#ifndef __ARM_EABI__
/*
* stack is aligned as there's a possibility of branching to .L_overflow
* which makes a C call
*/
ENTRY(__modsi3)
#ifdef __ARM_ARCH_EXT_IDIV__
sdiv r3, r0, r1
mls r0, r3, r1, r0
#else
str lr, [sp, #-8]! /* push lr */
bl PIC_SYM(__divsi3, PLT)
mov r0, r1
ldr lr, [sp], #8 /* pop lr */
#endif
RET
END(__modsi3)
#endif

View File

@ -1,74 +0,0 @@
/* $NetBSD: udivsi3.S,v 1.9 2013/09/12 15:36:14 joerg Exp $ */
/*
* 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 <machine/asm.h>
#if defined(__ARM_EABI__) && defined(__thumb__) && !defined(_ARM_ARCH_T2)
ARM_ENTRY(__udivsi3)
#else
ENTRY(__udivsi3)
#endif
#if defined(__ARM_ARCH_EXT_IDIV__)
# if defined(__ARM_EABI__)
mov r3, r0 @ save for mls
# endif
udiv r0, r0, r1
# if defined(__ARM_EABI__)
mls r1, r0, r1, r3 @ return modulus in r1
# endif
RET
#elif defined(__ARM_EABI__) && defined(_LIBC)
cmp r1, #0
beq .Ldiv0
ldr r2, .Lhwdiv_present
#ifdef __PIC__
add r2, r2, pc /* pc = &.LPIC0 */
# endif
ldr r2, [r2]
.LPIC0: cmp r2, #0
beq __udivide
mov r3, r0
# if defined(__ARM_ARCH_EXT_IDIV__)
udiv r0, r0, r1
mls r1, r0, r1, r3 /* return modulus in r1 */
# elif defined(__thumb__) && defined(_ARM_ARCH_T2)
.inst.w 0xfbb0f0f1
.inst.w 0xfb003111
# else
.inst 0xe730f110
.inst 0xe0613190
# endif
RET
.align 0
.Lhwdiv_present:
.word REL_SYM(_libc_arm_hwdiv_present, .LPIC0)
/* Handle divide by zero */
.align 0
.Ldiv0: push {r0, lr} /* save r0 */
mvns r0, #0 /* thumb2 */
bl _C_LABEL(__aeabi_idiv0)
pop {r1, pc} /* restore r0 as r1 */
#else
b __udivide
#endif
END(__udivsi3)
#ifdef __ARM_EABI__
STRONG_ALIAS(__aeabi_uidivmod, __udivsi3)
STRONG_ALIAS(__aeabi_uidiv, __udivsi3)
#endif

View File

@ -1,37 +0,0 @@
/* $NetBSD: umodsi3.S,v 1.4 2013/08/15 21:40:11 matt Exp $ */
/*
* 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 <machine/asm.h>
#ifndef __ARM_EABI__
/*
* stack is aligned as there's a possibility of branching to .L_overflow
* which makes a C call
*/
ENTRY(__umodsi3)
#ifdef __ARM_ARCH_EXT_IDIV__
udiv r3, r0, r1
mls r0, r3, r1, r0
#else
str lr, [sp, #-8]! /* push lr */
bl PIC_SYM(__udivsi3, PLT)
mov r0, r1
ldr lr, [sp], #8 /* pop lr */
#endif
RET
END(__umodsi3)
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: memset.S,v 1.6 2013/11/30 21:09:11 joerg Exp $ */
/* $NetBSD: memset.S,v 1.7 2013/12/02 21:21:33 joerg Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@ -68,8 +68,23 @@
#include <machine/asm.h>
#if defined(__ARM_EABI__) && !defined(BZER0)
STRONG_ALIAS(__aeabi_memset, memset)
#if defined(__ARM_EABI__) && !defined(_BZERO)
ENTRY(__aeabi_memset)
mov r3, r1
mov r1, r2
mov r2, r3
b memset
END(__aeabi_memset)
STRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
STRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
ENTRY(__aeabi_memclr)
mov r2, r1
mov r1, #0
b memset
END(__aeabi_memclr)
STRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
STRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
#endif
/*

View File

@ -95,12 +95,12 @@
./usr/include/i386 minix-sys
./usr/lib/libclkconf.a minix-sys
./usr/lib/libclkconf_pic.a minix-sys
./usr/lib/libc_vfp.a minix-sys
./usr/lib/libc_vfp_pic.a minix-sys
./usr/lib/libc_vfp.so.0.0 minix-sys
./usr/lib/libc_vfp.so.0 minix-sys
./usr/lib/libc_vfp.so minix-sys
./usr/lib/libgcc_eh.a minix-sys
./usr/lib/libc_vfp.a minix-sys obsolete
./usr/lib/libc_vfp_pic.a minix-sys obsolete
./usr/lib/libc_vfp.so.0.0 minix-sys obsolete
./usr/lib/libc_vfp.so.0 minix-sys obsolete
./usr/lib/libc_vfp.so minix-sys obsolete
./usr/lib/libgcc_eh.a minix-sys gcccmds
./usr/lib/libgpio.a minix-sys
./usr/lib/libgpio_pic.a minix-sys
./usr/lib/libi2cdriver.a minix-sys

View File

@ -283,12 +283,12 @@
./usr/bin/bzip2 minix-sys
./usr/bin/bzip2recover minix-sys
./usr/bin/c++ minix-sys gcccmds
./usr/bin/c++ minix-sys llvm
./usr/bin/c++ minix-sys llvm,llvmcmds
./usr/bin/cal minix-sys
./usr/bin/calendar minix-sys
./usr/bin/cawf minix-sys
./usr/bin/cc minix-sys gcccmds
./usr/bin/cc minix-sys llvm
./usr/bin/cc minix-sys llvm,llvmcmds
./usr/bin/cc1 minix-sys gcccmds
./usr/bin/cc1obj minix-sys gcccmds
./usr/bin/cc1plus minix-sys gcccmds
@ -301,10 +301,10 @@
./usr/bin/chsh minix-sys
./usr/bin/ci minix-sys
./usr/bin/cksum minix-sys
./usr/bin/clang++ minix-sys llvm
./usr/bin/clang minix-sys llvm
./usr/bin/clang-cpp minix-sys llvm
./usr/bin/clang-tblgen minix-sys llvm
./usr/bin/clang++ minix-sys llvm,llvmcmds
./usr/bin/clang minix-sys llvm,llvmcmds
./usr/bin/clang-cpp minix-sys llvm,llvmcmds
./usr/bin/clang-tblgen minix-sys llvm,llvmcmds
./usr/bin/cleantmp minix-sys
./usr/bin/clear minix-sys
./usr/bin/cmp minix-sys
@ -317,7 +317,7 @@
./usr/bin/compress minix-sys
./usr/bin/cpio minix-sys
./usr/bin/cpp minix-sys gcccmds
./usr/bin/cpp minix-sys llvm
./usr/bin/cpp minix-sys llvm,llvmcmds
./usr/bin/cprofalyze minix-sys obsolete
./usr/bin/crc minix-sys
./usr/bin/cron minix-sys
@ -412,7 +412,7 @@
./usr/bin/lessecho minix-sys
./usr/bin/lesskey minix-sys
./usr/bin/lex minix-sys
./usr/bin/llvm-tblgen minix-sys llvm
./usr/bin/llvm-tblgen minix-sys llvm,llvmcmds
./usr/bin/loadfont minix-sys
./usr/bin/loadramdisk minix-sys
./usr/bin/lock minix-sys
@ -796,36 +796,36 @@
./usr/include/cdbr.h minix-sys
./usr/include/cdbw.h minix-sys
./usr/include/clang-3.4 minix-sys
./usr/include/clang-3.4/ammintrin.h minix-sys llvm
./usr/include/clang-3.4/avx2intrin.h minix-sys llvm
./usr/include/clang-3.4/avxintrin.h minix-sys llvm
./usr/include/clang-3.4/bmi2intrin.h minix-sys llvm
./usr/include/clang-3.4/bmiintrin.h minix-sys llvm
./usr/include/clang-3.4/emmintrin.h minix-sys llvm
./usr/include/clang-3.4/f16cintrin.h minix-sys llvm
./usr/include/clang-3.4/fma4intrin.h minix-sys llvm
./usr/include/clang-3.4/fmaintrin.h minix-sys llvm
./usr/include/clang-3.4/immintrin.h minix-sys llvm
./usr/include/clang-3.4/lzcntintrin.h minix-sys llvm
./usr/include/clang-3.4/mm3dnow.h minix-sys llvm
./usr/include/clang-3.4/mmintrin.h minix-sys llvm
./usr/include/clang-3.4/mm_malloc.h minix-sys llvm
./usr/include/clang-3.4/nmmintrin.h minix-sys llvm
./usr/include/clang-3.4/pmmintrin.h minix-sys llvm
./usr/include/clang-3.4/popcntintrin.h minix-sys llvm
./usr/include/clang-3.4/prfchwintrin.h minix-sys llvm
./usr/include/clang-3.4/rdseedintrin.h minix-sys llvm
./usr/include/clang-3.4/rtmintrin.h minix-sys llvm
./usr/include/clang-3.4/shaintrin.h minix-sys llvm
./usr/include/clang-3.4/smmintrin.h minix-sys llvm
./usr/include/clang-3.4/tbmintrin.h minix-sys llvm
./usr/include/clang-3.4/tmmintrin.h minix-sys llvm
./usr/include/clang-3.4/__wmmintrin_aes.h minix-sys llvm
./usr/include/clang-3.4/wmmintrin.h minix-sys llvm
./usr/include/clang-3.4/__wmmintrin_pclmul.h minix-sys llvm
./usr/include/clang-3.4/x86intrin.h minix-sys llvm
./usr/include/clang-3.4/xmmintrin.h minix-sys llvm
./usr/include/clang-3.4/xopintrin.h minix-sys llvm
./usr/include/clang-3.4/ammintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/avx2intrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/avxintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/bmi2intrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/bmiintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/emmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/f16cintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/fma4intrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/fmaintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/immintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/lzcntintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/mm3dnow.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/mmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/mm_malloc.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/nmmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/pmmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/popcntintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/prfchwintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/rdseedintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/rtmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/shaintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/smmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/tbmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/tmmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/__wmmintrin_aes.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/wmmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/__wmmintrin_pclmul.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/x86intrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/xmmintrin.h minix-sys llvm,llvmcmds
./usr/include/clang-3.4/xopintrin.h minix-sys llvm,llvmcmds
./usr/include/compat minix-sys
./usr/include/compat/machine minix-sys
./usr/include/complex.h minix-sys
@ -1895,7 +1895,7 @@
./usr/include/ulimit.h minix-sys
./usr/include/unctrl.h minix-sys
./usr/include/unistd.h minix-sys
./usr/include/unwind.h minix-sys llvm
./usr/include/unwind.h minix-sys llvm,llvmcmds
./usr/include/util.h minix-sys
./usr/include/utime.h minix-sys
./usr/include/utmp.h minix-sys
@ -1945,7 +1945,7 @@
./usr/lib/bc/libc.a minix-sys bitcode
./usr/lib/bc/libc++.a minix-sys bitcode
./usr/lib/bc/libchardriver.a minix-sys bitcode
./usr/lib/bc/libcompat_minix.a minix-sys bitcode obsolete
./usr/lib/bc/libcompat_minix.a minix-sys bitcode,obsolete
./usr/lib/bc/libcrypt.a minix-sys bitcode
./usr/lib/bc/libcurses.a minix-sys bitcode
./usr/lib/bc/libddekit.a minix-sys bitcode
@ -1953,6 +1953,10 @@
./usr/lib/bc/libddekit_usb_server.a minix-sys bitcode
./usr/lib/bc/libdevman.a minix-sys bitcode
./usr/lib/bc/libedit.a minix-sys bitcode
./usr/lib/bc/libevent.a minix-sys bitcode
./usr/lib/bc/libexpat.a minix-sys bitcode
./usr/lib/bc/libfsdriver.a minix-sys bitcode
./usr/lib/bc/libpci.a minix-sys bitcode
./usr/lib/bc/libelf.a minix-sys bitcode
./usr/lib/bc/libexec.a minix-sys bitcode
./usr/lib/bc/libexecinfo.a minix-sys bitcode
@ -1973,7 +1977,7 @@
./usr/lib/bc/libmenu.a minix-sys bitcode
./usr/lib/bc/libminc.a minix-sys bitcode
./usr/lib/bc/libminixfs.a minix-sys bitcode
./usr/lib/bc/libminlib.a minix-sys bitcode obsolete
./usr/lib/bc/libminlib.a minix-sys bitcode,obsolete
./usr/lib/bc/libmthread.a minix-sys bitcode
./usr/lib/bc/libnetdriver.a minix-sys bitcode
./usr/lib/bc/libnetsock.a minix-sys bitcode
@ -5410,7 +5414,7 @@
./usr/share/doc/usd/03.shell/t3 minix-sys
./usr/share/doc/usd/03.shell/t4 minix-sys
./usr/share/doc/usd/03.shell/t.mac minix-sys
./usr/share/examples minix-sys atf
./usr/share/examples minix-sys
./usr/share/examples/atf minix-sys atf
./usr/share/examples/atf/atf-run.hooks minix-sys atf,!kyua
./usr/share/examples/atf/tests-results.css minix-sys atf,!kyua
@ -6309,6 +6313,7 @@
./usr/tests/minix-posix/testisofs minix-sys
./usr/tests/minix-posix/testkyua minix-sys
./usr/tests/minix-posix/testmfs minix-sys
./usr/tests/minix-posix/testrelpol minix-sys
./usr/tests/minix-posix/testsh1 minix-sys
./usr/tests/minix-posix/testsh2 minix-sys
./usr/tests/minix-posix/testvm minix-sys

View File

@ -255,7 +255,10 @@ service dp8390
SDEVIO # 22
;
pci device 10ec:8029;
uid 0;
io
300:20
;
irq 9;
};
service dpeth

View File

@ -184,7 +184,7 @@ start|autoboot)
for label in $(get_eth_labels); do
driver=$(echo $label | sed 's/\(.*\)_.*/\1/')
instance=$(echo $label | sed 's/.*_//')
eval arg=\$${label}_arg
eval arg=\$${driver}_arg
if [ ! -z "$arg" ]; then arg=" $arg"; fi
arg="-args \"instance=$instance$arg\""
eval up $driver -label $label $arg -period 5HZ

View File

@ -29,7 +29,9 @@ SUBDIR+= openldap
SUBDIR+= libc++
.endif
.if (${MKLLVM} != "no")
.if (${MKLLVMCMDS} != "no")
SUBDIR+= llvm
.endif # (${MKLLVMCMDS} != "no")
.endif
.if (${MKPCC} != "no")
SUBDIR+= pcc

View File

@ -280,8 +280,14 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
// Thumb2 is the default for V7 on Darwin.
//
// FIXME: Thumb should just be another -target-feaure, not in the triple.
#if 1
// Minix/ARM-specific force to ARMv7 and EABI.
StringRef Suffix = "v7";
Triple.setEnvironment(llvm::Triple::EABI);
#else
StringRef Suffix =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
#endif
bool ThumbDefault = Suffix.startswith("v6m") ||
(Suffix.startswith("v7") && getTriple().isOSDarwin());
std::string ArchName = "arm";

View File

@ -30,7 +30,7 @@ static const char sccsid[] = "Id: put.c,v 10.18 2001/06/25 15:19:11 skimo Exp (
* put --
* Put text buffer contents into the file.
*
* PUBLIC: int put __P((SCR *, CB *, CHAR_T *, MARK *, MARK *, int));
* PUBLIC: int put __P((SCR *, CB *, ARG_CHAR_T *, MARK *, MARK *, int));
*/
int
put(SCR *sp, CB *cbp, ARG_CHAR_T *namep, MARK *cp, MARK *rp, int append)

View File

@ -2,6 +2,11 @@
.include <bsd.own.mk>
.if defined(__MINIX)
#/usr/minix/src-clang/external/bsd/nvi/dist/ex/ex.c:533:18: error: comparison of integers of different signs: 'CHAR_T' (aka 'unsigned int') and 'ARG_CHAR_T' (aka 'int') [-Werror,-Wsign-compare]
NOCLANGERROR=yes
.endif
USE_WIDECHAR?=yes
CWARNFLAGS.clang+= -Wno-uninitialized -Wno-format-security

View File

@ -98,9 +98,11 @@ SUBDIR+= \
.if (${MACHINE_CPU} == "arm")
LIBC_MACHINE_ARCH?=${MACHINE_ARCH}
.if empty(LIBC_MACHINE_ARCH:M*hf*)
.if !defined(__MINIX)
SUBDIR+= libc_vfp
.endif
.endif
.endif
.if (${MKRUMP} != "no")
SUBDIR+= librumpclient
.endif

View File

@ -68,7 +68,7 @@ SUBDIR+= pkgconfig
.include "${.CURDIR}/db/Makefile.inc"
.include "${.CURDIR}/citrus/Makefile.inc"
.include "${.CURDIR}/compat-43/Makefile.inc"
.if ${HAVE_LIBGCC} == "no"
.if ${HAVE_LIBGCC} == "no" || defined(__MINIX)
.include "${.CURDIR}/compiler_rt/Makefile.inc"
.endif
.include "${.CURDIR}/dlfcn/Makefile.inc"
@ -89,7 +89,7 @@ SUBDIR+= pkgconfig
.include "${.CURDIR}/net/Makefile.inc"
.include "${.CURDIR}/nameser/Makefile.inc"
.include "${.CURDIR}/nls/Makefile.inc"
.if (${MACHINE_ARCH} != "alpha") && (${ARCHSUBDIR} != "sparc64")
.if (${MACHINE_ARCH} != "alpha") && (${ARCHSUBDIR} != "sparc64") && !defined(__MINIX)
.include "${.CURDIR}/quad/Makefile.inc"
.endif
.if (${USE_LIBTRE} == "yes")
@ -116,9 +116,10 @@ SUBDIR+= pkgconfig
.include "${.CURDIR}/tls/Makefile.inc"
.endif
.include "${.CURDIR}/sys/Makefile.inc"
.if ${HAVE_LIBGCC} == "no"
.if ${HAVE_LIBGCC} == "no" && ${MACHINE_ARCH} != "earm" && defined(__MINIX)
# Currently unavailable on minix/arm - BJG
.include "${NETBSDSRCDIR}/sys/lib/libunwind/Makefile.inc"
.endif
.endif # ${HAVE_LIBGCC} == "no" && ${MACHINE_ARCH} != "earm" && defined(__MINIX)
.include "${.CURDIR}/uuid/Makefile.inc"
.if (${MKYP} != "no")
.include "${.CURDIR}/yp/Makefile.inc"

View File

@ -13,10 +13,6 @@ AFLAGS+= -marm
CPPFLAGS += -I.
.if !empty(LIBC_MACHINE_ARCH:Mearm*)
SRCS+= __aeabi_ldivmod.S __aeabi_uldivmod.S
SRCS+= __aeabi_lcmp.c __aeabi_ulcmp.c
SRCS+= fixunsgen_ieee754.c fixunssfsi_ieee754.c
SRCS+= fixunsgen64_ieee754.c fixunsdfsi_ieee754.c
SRCS+= arm_initfini.c
.endif
@ -26,7 +22,7 @@ CPPFLAGS += -DSOFTFLOAT
# for earm, use the 64-bit softfloat
.if ${LIBC_MACHINE_ARCH} == "arm" || ${LIBC_MACHINE_ARCH} == "armeb"
SOFTFLOAT_BITS=32
#SRCS+= floatunsidf_ieee754.c floatunsisf_ieee754.c
SRCS+= floatunsidf_ieee754.c floatunsisf_ieee754.c
.endif
.include <softfloat/Makefile.inc>

View File

@ -1,7 +1,7 @@
# $NetBSD: Makefile.inc,v 1.25 2013/08/21 03:09:39 matt Exp $
SRCS+= alloca.S byte_swap_2.S byte_swap_4.S bswap64.c divide.S divsi3.S \
fabs.c flt_rounds.c udivsi3.S
SRCS+= alloca.S byte_swap_2.S byte_swap_4.S bswap64.c \
fabs.c flt_rounds.c
CPUFLAGS.divide.S+= -marm
@ -16,8 +16,6 @@ SRCS+= signbitf_ieee754.c signbitd_ieee754.c
.if !empty(LIBC_MACHINE_ARCH:Mearm*)
SRCS+= __aeabi_fcmpun.c __aeabi_dcmpun.c
SRCS+= __aeabi_idiv0.c __aeabi_ldiv0.c
.else
SRCS+= modsi3.S umodsi3.S
.endif
SRCS+= nanf.c

View File

@ -10,11 +10,16 @@ COMPILER_RT_CPU_DIR= ${COMPILER_RT_SRCDIR}/lib/${MACHINE_CPU}
COMPILER_RT_ARCH_DIR= ${COMPILER_RT_SRCDIR}/lib/${MACHINE_ARCH}
.endif
.if defined(__MINIX)
LIBC_MACHINE_CPU?= ${MACHINE_CPU}
.endif # defined(__MINIX)
.if !defined(__MINIX)
.if !empty(LIBC_MACHINE_ARCH:Mearm*) && defined(__MINIX)
# BJG - we skip these for minix/x86 as the .S versions give problems
# for dynamic binaries.
.PATH: ${COMPILER_RT_CPU_DIR}
.PATH: ${COMPILER_RT_ARCH_DIR}
.endif # !defined(__MINIX)
.endif # .if !empty(LIBC_MACHINE_ARCH:Mearm*) && defined(__MINIX)
.PATH: ${COMPILER_RT_SRCDIR}/lib
# Complex support needs parts of libm
@ -25,127 +30,190 @@ COMPILER_RT_ARCH_DIR= ${COMPILER_RT_SRCDIR}/lib/${MACHINE_ARCH}
# divdc3.c \
# divsc3.c
# Implemented on top of our atomic interface.
#GENERIC_SRCS+= atomic.c
.if ${HAVE_LIBGCC_EH:Uyes} == "no"
GENERIC_SRCS+= \
gcc_personality_v0.c
.endif
.if 0
# Conflicts with soft-float
GENERIC_SRCS+= \
absvdi2.c \
absvsi2.c \
absvti2.c \
adddf3.c \
addsf3.c \
addvdi3.c \
addvsi3.c \
addvti3.c \
ashldi3.c \
ashlti3.c \
ashrdi3.c \
ashrti3.c \
atomic.c \
clzdi2.c \
clzsi2.c \
clzti2.c \
cmpdi2.c \
cmpti2.c \
comparedf2.c \
comparesf2.c \
ctzdi2.c \
ctzsi2.c \
ctzti2.c \
adddf3.c \
addsf3.c \
addtf3.c \
divdf3.c \
divdi3.c \
divmoddi4.c \
divmodsi4.c \
divsf3.c \
divsi3.c \
divti3.c \
divtf3.c \
extendsfdf2.c \
ffsdi2.c \
ffsti2.c \
fixdfdi.c \
extendsftf2.c \
extenddftf2.c \
fixdfsi.c \
fixdfti.c \
fixsfdi.c \
fixsfsi.c \
fixsfti.c \
floatsidf.c \
floatsisf.c \
floatunsidf.c \
floatunsisf.c \
muldf3.c \
mulsf3.c \
multf3.c \
subdf3.c \
subsf3.c \
subtf3.c \
truncdfsf2.c \
trunctfdf2.c \
trunctfsf2.c
.endif
GENERIC_SRCS+= \
absvsi2.c \
absvti2.c \
addvsi3.c \
addvti3.c \
ashlti3.c \
ashrti3.c \
clzti2.c \
cmpti2.c \
ctzti2.c \
divti3.c \
ffsti2.c \
fixsfdi.c \
fixdfdi.c \
fixunsdfdi.c \
fixunsdfsi.c \
fixunsdfti.c \
fixunssfdi.c \
fixunssfsi.c \
fixunssfti.c \
fixunsxfdi.c \
fixunsxfsi.c \
fixunsxfti.c \
fixxfdi.c \
fixxfti.c \
floatdidf.c \
floatdisf.c \
floatdixf.c \
floatsidf.c \
floatsisf.c \
floattidf.c \
floattisf.c \
floattixf.c \
floatundidf.c \
floatundisf.c \
floatundixf.c \
floatunsidf.c \
floatunsisf.c \
floatuntidf.c \
floatuntisf.c \
floatuntixf.c \
gcc_personality_v0.c \
int_util.c \
lshrdi3.c \
lshrti3.c \
moddi3.c \
modsi3.c \
modti3.c \
muldc3.c \
muldf3.c \
muldi3.c \
mulodi4.c \
mulosi4.c \
muloti4.c \
mulsf3.c \
multi3.c \
mulvdi3.c \
mulvsi3.c \
mulvti3.c \
negdf2.c \
negdi2.c \
negsf2.c \
negti2.c \
negvdi2.c \
negvsi2.c \
negvti2.c \
paritydi2.c \
paritysi2.c \
parityti2.c \
popcountdi2.c \
popcountsi2.c \
popcountti2.c \
powidf2.c \
powisf2.c \
powitf2.c \
powixf2.c \
subdf3.c \
subsf3.c \
subvdi3.c \
subvsi3.c \
subvti3.c \
truncdfsf2.c \
ucmpdi2.c \
ucmpti2.c \
udivdi3.c \
udivmoddi4.c \
udivmodsi4.c \
udivmodti4.c \
udivsi3.c \
udivti3.c \
umoddi3.c \
umodsi3.c \
umodti3.c
.if ${MACHINE_ARCH} == "powerpc"
.if ${MACHINE_ARCH} != "aarch64"
GENERIC_SRCS+= \
fixunsdfti.c \
fixunssfti.c \
fixunsxfti.c \
fixxfti.c \
floattidf.c \
floattisf.c \
floattixf.c \
floatuntidf.c \
floatuntisf.c \
floatuntixf.c
.endif
# These have h/w instructions which are always used.
.if ${LIBC_MACHINE_ARCH} != "alpha" && ${LIBC_MACHINE_CPU} != "aarch64" \
&& ${LIBC_MACHINE_CPU} != "powerpc" && ${LIBC_MACHINE_CPU} != "or1k"
GENERIC_SRCS+= \
clzsi2.c
.endif
# These have h/w instructions which are always used.
.if ${LIBC_MACHINE_ARCH} != "alpha" && ${LIBC_MACHINE_ARCH} != "vax" \
&& ${LIBC_MACHINE_CPU} != "aarch64" && ${LIBC_MACHINE_CPU} != "powerpc" \
&& ${LIBC_MACHINE_CPU} != "or1k"
GENERIC_SRCS+= \
ctzsi2.c
.endif
# These have h/w instructions which are always used.
.if ${LIBC_MACHINE_ARCH} != "alpha" && ${LIBC_MACHINE_CPU} != "powerpc" \
&& ${LIBC_MACHINE_CPU} != "aarch64" && ${LIBC_MACHINE_ARCH} != "vax"
GENERIC_SRCS+= \
divmodsi4.c \
divsi3.c \
modsi3.c \
udivmodsi4.c \
umodsi3.c
. if ${LIBC_MACHINE_CPU} != "sh3"
# On sh3 __udivsi3 is gcc "millicode" with special calling convention
# (less registers clobbered than usual). Each DSO that needs it gets
# its own hidden copy from libgcc.a.
GENERIC_SRCS+= \
udivsi3.c
. endif
.endif
GENERIC_SRCS+= \
absvdi2.c \
addvdi3.c \
mulodi4.c \
mulvdi3.c \
negvdi2.c \
paritydi2.c \
popcountdi2.c \
subvdi3.c
# These have h/w instructions which are always used.
.if ${LIBC_MACHINE_ARCH} != "alpha" && ${LIBC_MACHINE_CPU} != "powerpc64" \
&& ${LIBC_MACHINE_ARCH} != "aarch64" && ${LIBC_MACHINE_CPU} != "or1k"
GENERIC_SRCS+= \
clzdi2.c \
ctzdi2.c \
ffsdi2.c
.endif
# Don't need these on 64-bit machines.
.if empty(LIBC_MACHINE_ARCH:M*64*) && ${LIBC_MACHINE_ARCH} != "alpha"
GENERIC_SRCS+= \
cmpdi2.c \
ashldi3.c \
ashrdi3.c \
divdi3.c \
divmoddi4.c \
lshrdi3.c \
moddi3.c \
muldi3.c \
negdi2.c \
ucmpdi2.c \
udivdi3.c \
udivmoddi4.c \
umoddi3.c
.endif
.if ${LIBC_MACHINE_ARCH} == "powerpc" || ${LIBC_MACHINE_ARCH} == "powerpc64"
GENERIC_SRCS+= \
fixtfdi.c \
fixunstfdi.c \
@ -157,6 +225,30 @@ GENERIC_SRCS+= \
gcc_qsub.c
.endif
.if ${LIBC_MACHINE_CPU} == "aarch64"
GENERIC_SRCS+= \
clear_cache.c
.endif
.if ${LIBC_MACHINE_CPU} == "arm"
.if !empty(LIBC_MACHINE_ARCH:Mearm*)
GENERIC_SRCS+= \
aeabi_idivmod.S \
aeabi_ldivmod.S \
aeabi_uidivmod.S \
aeabi_uldivmod.S
.endif
GENERIC_SRCS+= \
clear_cache.c
# Not yet, overlaps with softfloat
# aeabi_dcmp.S \
# aeabi_fcmp.S
# Not yet, requires ARMv6
#GENERIC_SRCS+= \
# bswapdi2.S \
# bswapsi2.S
.endif
.if !defined(__MINIX)
.for src in ${GENERIC_SRCS}
. if exists(${COMPILER_RT_CPU_DIR}/${src:R}.S) || \
@ -164,14 +256,26 @@ GENERIC_SRCS+= \
SRCS+= ${src:R}.S
. else
SRCS+= ${src}
COPTS.${src}+= -Wno-error=missing-prototypes
. if ${src:E} != "cc"
COPTS.${src}+= -Wno-missing-prototypes \
-Wno-old-style-definition \
-Wno-strict-prototypes \
-Wno-uninitialized \
-Wno-cast-qual
. endif
. endif
.endfor
.else
# For MINIX: do not pull in the assembly symbols, as they are not PIC ready
.for src in ${GENERIC_SRCS}
SRCS+= ${src}
COPTS.${src}+= -Wno-error=missing-prototypes
. if ${src:E} != "cc"
COPTS.${src}+= -Wno-missing-prototypes \
-Wno-old-style-definition \
-Wno-strict-prototypes \
-Wno-uninitialized \
-Wno-cast-qual
. endif
.endfor
.for src in muldc3.c

View File

@ -191,7 +191,9 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
* and smaller and such stores are atomic.
*/
dl_iterate_phdr_setup();
#ifndef __minix
membar_producer();
#endif
setup_done = true;
}

View File

@ -3,7 +3,12 @@
.include <bsd.own.mk>
.if defined(__MINIX)
# /usr/minix/src-clang/lib/libcurses/get_wch.c:646:15: error: comparison of unsigned expression < 0 is always false [-Werror,-Wtautological-compare]
WARNS=0
.else
WARNS= 2
.endif
CPPFLAGS+=-I${.CURDIR} -I${NETBSDSRCDIR}/lib/libterminfo
.if defined(DEBUG_CURSES)

View File

@ -340,11 +340,8 @@ MLINKS+=fdim.3 fdimf.3
COPTS.compat_cabs.c+= ${${ACTIVE_CC} == "clang":? -Wno-incompatible-library-redeclaration :}
COPTS.compat_cabsf.c+= ${${ACTIVE_CC} == "clang":? -Wno-incompatible-library-redeclaration :}
.include "${.CURDIR}/gen/Makefile.inc"
.if ${HAVE_LIBGCC} == "no"
.include "${.CURDIR}/compiler_rt/Makefile.inc"
.endif
.include "${.CURDIR}/gen/Makefile.inc"
.include <bsd.lib.mk>
.include <bsd.subdir.mk>

View File

@ -9,6 +9,13 @@ LIB= rmt
SRCS= rmtlib.c
MAN= rmtops.3
.if defined(__MINIX)
# rmtlib.c:451:50: error: format specifies type 'size_t' (aka 'unsigned long') \
# but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat]
WARNS=0
CFLAGS+=-Wno-format
.endif
.if !defined(__MINIX)
CPPFLAGS+= -D_REENTRANT
.endif # !defined(__MINIX)

View File

@ -453,7 +453,7 @@ _rmt_write(int fildes, const void *buf, size_t nbyte)
return -1;
pstat = signal(SIGPIPE, SIG_IGN);
if ((size_t)write(WRITE(fildes), buf, nbyte) == nbyte) {
if ((size_t)write(WRITE(fildes), buf, nbyte) == (size_t) nbyte) {
signal(SIGPIPE, pstat);
return status(fildes);
}

View File

@ -226,7 +226,7 @@ sockaddr_snprintf(char * const sbuf, const size_t len, const char * const fmt,
#if !defined(__minix)
(void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_len);
#else
(void)snprintf(nbuf, sizeof(nbuf), "%d", len);
(void)snprintf(nbuf, sizeof(nbuf), "%zu", len);
#endif /* !defined(__minix) */
ADDS(nbuf);
break;

View File

@ -109,7 +109,7 @@ cards()
card 0 "No Ethernet card (no networking)"
card 1 "3Com 501 or 3Com 509 based card"
card 2 "Realtek 8029 based card (also emulated by Qemu)" "10EC:8029"
card 3 "NE2000, 3com 503 or WD based card (also emulated by Bochs)"
card 3 "NE2000, 3com 503 or WD based card (also emulated by Qemu, Bochs)"
card 4 "lan8710a (on BeagleBone, BeagleBone Black)"
n=$first_pcicard
for pcicard in $pci_list
@ -197,10 +197,11 @@ drv_params()
test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration."
;;
2) driver=dp8390; driverargs="dp8390_arg='DPETH0=pci'"; ;;
3) driver=dp8390; driverargs="dp8390_arg='DPETH0=240:9'";
3) driver=dp8390; driverargs="dp8390_arg='DPETH0=300:9'";
test "$v" = 1 && echo ""
test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration."
test "$v" = 1 && echo " chose option 4, the defaults for emulation by Bochs have been set."
test "$v" = 1 && echo "You may then also have to edit /etc/system.conf ."
test "$v" = 1 && echo "For now, the defaults for emulation by Bochs/Qemu have been set."
;;
4) driver=lan8710a; ;;
$first_after_pci) driver="psip0"; ;;

View File

@ -18,6 +18,4 @@ SUBDIR+= virtio_net
SUBDIR+= lan8710a
.endif # ${MACHINE_ARCH} == "earm"
SUBDIR+= uds
.include <bsd.subdir.mk>

File diff suppressed because it is too large Load Diff

View File

@ -179,5 +179,3 @@
#define ATL2_TXS_ABORTCOL 0x04000000 /* collision abort */
#define ATL2_TXS_UNDERRUN 0x08000000 /* buffer underrun */
#define ATL2_TXS_UPDATE 0x80000000 /* updated by device */

File diff suppressed because it is too large Load Diff

View File

@ -11,37 +11,21 @@ Created: 09/01/2009 Nicolas Tittley (first.last @ gmail DOT com)
#include <sys/null.h>
#define DE_FKEY 7 /* Shift+ this value will dump info on console */
#define NOT(x) (~(x))
#if debug == 1
# define DEBUG(statm) statm
#else
# define DEBUG(statm)
#endif
#define SA_ADDR_LEN sizeof(ether_addr_t)
#define DE_NB_SEND_DESCR 32
#define DE_SEND_BUF_SIZE (ETH_MAX_PACK_SIZE+2)
#define DE_NB_RECV_DESCR 32
#define DE_RECV_BUF_SIZE (ETH_MAX_PACK_SIZE+2)
#define IOVEC_NR 16
#define DE_MIN_BASE_ADDR 0x0400
#define DE_SROM_EA_OFFSET 20
#define DE_SETUP_FRAME_SIZE 192
typedef struct iovec_dat_s {
iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
endpoint_t iod_proc_nr;
cp_grant_id_t iod_grant;
vir_bytes iod_iovec_offset;
} iovec_dat_s_t;
typedef struct de_descr {
u32_t des[4];
} de_descr_t;
@ -53,9 +37,6 @@ typedef struct de_local_descr {
} de_loc_descr_t;
typedef struct dpeth {
message rx_return_msg; /* Holds VREAD message until int */
message tx_return_msg; /* Holds VWRITE message until int */
char de_name[32]; /* Name of this interface */
port_t de_base_port; /* Base port, for multiple card instance */
int de_irq; /* IRQ line number */
@ -63,10 +44,7 @@ typedef struct dpeth {
int de_type; /* What kind of hardware */
ether_addr_t de_address; /* Ethernet Address */
eth_stat_t de_stat; /* Stats */
unsigned long bytes_tx; /* Number of bytes sent */
unsigned long bytes_rx; /* Number of bytes recv */
/* Space reservation. We will allocate all structures later in the code.
here we just make sure we have the space we need at compile time */
@ -81,42 +59,11 @@ typedef struct dpeth {
#define DESCR_RECV 0
#define DESCR_TRAN 1
int de_flags; /* Send/Receive mode (Configuration) */
#define DEF_EMPTY 0x0000
#define DEF_READING 0x0001
#define DEF_RECV_BUSY 0x0002
#define DEF_ACK_RECV 0x0004
#define DEF_SENDING 0x0010
#define DEF_XMIT_BUSY 0x0020
#define DEF_ACK_SEND 0x0040
#define DEF_PROMISC 0x0100
#define DEF_MULTI 0x0200
#define DEF_BROAD 0x0400
#define DEF_ENABLED 0x2000
#define DEF_STOPPED 0x4000
int de_mode; /* Status of the Interface */
#define DEM_DISABLED 0x0000
#define DEM_SINK 0x0001
#define DEM_ENABLED 0x0002
/* Serial ROM */
#define SROM_BITWIDTH 6
u8_t srom[((1<<SROM_BITWIDTH)-1)*2]; /* Space to read in
all the configuration ROM */
/* Temporary storage for RECV/SEND requests */
iovec_dat_s_t de_read_iovec;
iovec_dat_s_t de_write_iovec;
vir_bytes de_read_s;
vir_bytes de_send_s;
endpoint_t de_client;
} dpeth_t;

View File

@ -12,6 +12,7 @@
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>

View File

@ -2,7 +2,7 @@
PROG= dp8390
SRCS= 3c503.c dp8390.c ne2000.c rtl8029.c wdeth.c
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
.include <minix.service.mk>

File diff suppressed because it is too large Load Diff

View File

@ -173,45 +173,19 @@ typedef struct dp_rcvhdr
struct dpeth;
struct iovec_dat;
struct iovec_dat_s;
typedef void(*dp_initf_t) (struct dpeth *dep);
typedef void(*dp_stopf_t) (struct dpeth *dep);
typedef void(*dp_user2nicf_t) (struct dpeth *dep, struct iovec_dat
*iovp, vir_bytes offset, int nic_addr, vir_bytes count);
typedef void(*dp_user2nicf_s_t) (struct dpeth *dep, struct iovec_dat_s
*iovp, vir_bytes offset, int nic_addr, vir_bytes count);
typedef void(*dp_nic2userf_t) (struct dpeth *dep, int nic_addr, struct
iovec_dat *iovp, vir_bytes offset, vir_bytes count);
typedef void(*dp_nic2userf_s_t) (struct dpeth *dep, int nic_addr, struct
iovec_dat_s *iovp, vir_bytes offset, vir_bytes count);
#if 0
typedef void(*dp_getheaderf_t) (struct dpeth *dep, int page, struct
dp_rcvhdr *h, u16_t *eth_type);
#endif
typedef void(*dp_getblock_t) (struct dpeth *dep, int page, size_t
typedef void (*dp_initf_t)(struct dpeth *dep);
typedef void (*dp_stopf_t)(struct dpeth *dep);
typedef void (*dp_user2nicf_s_t)(struct dpeth *dep,
struct netdriver_data *data, int nic_addr, size_t offset,
size_t count);
typedef void (*dp_nic2userf_s_t)(struct dpeth *dep,
struct netdriver_data *data, int nic_addr, size_t offset,
size_t count);
typedef void (*dp_getblock_t)(struct dpeth *dep, int page, size_t
offset, size_t size, void *dst);
/* iovectors are handled IOVEC_NR entries at a time. */
#define IOVEC_NR 16
typedef int irq_hook_t;
typedef struct iovec_dat
{
iovec_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
endpoint_t iod_proc_nr;
vir_bytes iod_iovec_addr;
} iovec_dat_t;
typedef struct iovec_dat_s
{
iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
int iod_proc_nr;
cp_grant_id_t iod_grant;
vir_bytes iod_iovec_offset;
} iovec_dat_s_t;
#define SENDQ_NR 2 /* Maximum size of the send queue */
#define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */
@ -250,10 +224,8 @@ typedef struct dpeth
int de_startpage;
int de_stoppage;
#if ENABLE_PCI
/* PCI config */
char de_pci; /* TRUE iff PCI device */
#endif
/* Do it yourself send queue */
struct sendq
@ -268,14 +240,7 @@ typedef struct dpeth
/* Fields for internal use by the dp8390 driver. */
int de_flags;
int de_mode;
eth_stat_t de_stat;
iovec_dat_s_t de_read_iovec_s;
iovec_dat_s_t de_write_iovec_s;
iovec_dat_s_t de_tmp_iovec_s;
vir_bytes de_read_s;
endpoint_t de_client;
message de_sendmsg;
dp_user2nicf_s_t de_user2nicf_s;
dp_nic2userf_s_t de_nic2userf_s;
dp_getblock_t de_getblockf;
@ -283,24 +248,10 @@ typedef struct dpeth
#define DEI_DEFAULT 0x8000
#define DEF_EMPTY 0x000
#define DEF_PACK_SEND 0x001
#define DEF_PACK_RECV 0x002
#define DEF_SEND_AVAIL 0x004
#define DEF_READING 0x010
#define DEF_PROMISC 0x040
#define DEF_MULTI 0x080
#define DEF_BROAD 0x100
#define DEF_ENABLED 0x200
#define DEF_STOPPED 0x400
#define DEF_EMPTY 0x00
#define DEF_STOPPED 0x01
#define DEM_DISABLED 0x0
#define DEM_SINK 0x1
#define DEM_ENABLED 0x2
#if !__minix_vmd
#define debug 0 /* Standard Minix lacks debug variable */
#endif
#define debug 0
/*
* $PchId: dp8390.h,v 1.10 2005/02/10 17:26:06 philip Exp $

View File

@ -5,7 +5,6 @@ local.h
#define ENABLE_WDETH 1
#define ENABLE_NE2000 1
#define ENABLE_3C503 1
#define ENABLE_PCI 1
struct dpeth;

View File

@ -8,12 +8,10 @@ Created: March 15, 1994 by Philip Homburg <philip@f-mnx.phicoh.com>
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#if __minix_vmd
#include "config.h"
#endif
#include "local.h"
#include "dp8390.h"

View File

@ -7,6 +7,7 @@ Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <stdlib.h>
#include <sys/types.h>
@ -20,8 +21,6 @@ Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
#include "dp8390.h"
#include "rtl8029.h"
#if ENABLE_PCI
static void rtl_init(struct dpeth *dep);
#if 0
static u16_t get_ee_word(dpeth_t *dep, int a);
@ -312,8 +311,6 @@ dpeth_t *dep;
}
#endif
#endif /* ENABLE_PCI */
/*
* $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $
*/

View File

@ -5,6 +5,7 @@ Created: March 14, 1994 by Philip Homburg
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
@ -70,9 +71,6 @@ dpeth_t *dep;
int we_type;
int sendq_nr;
assert(dep->de_mode == DEM_ENABLED);
assert(!(dep->de_flags & DEF_ENABLED));
dep->de_address.ea_addr[0] = inb_we(dep, EPL_EA0);
dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1);
dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2);

View File

@ -10,7 +10,7 @@
*/
#include <minix/drivers.h>
#include <minix/com.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -23,17 +23,17 @@ static unsigned char StationAddress[SA_ADDR_LEN] = {0, 0, 0, 0, 0, 0,};
static buff_t *TxBuff = NULL;
/*
** Name: void el1_getstats(dpeth_t *dep)
** Name: el1_getstats
** Function: Reads statistics counters from board.
**/
static void el1_getstats(dpeth_t * dep)
{
return; /* Nothing to do */
/* Nothing to do */
}
/*
** Name: void el1_reset(dpeth_t *dep)
** Name: el1_reset
** Function: Reset function specific for Etherlink hardware.
*/
static void el1_reset(dpeth_t * dep)
@ -49,7 +49,6 @@ static void el1_reset(dpeth_t * dep)
for (ix = EL1_ADDRESS; ix < SA_ADDR_LEN; ix += 1)
outb_el1(dep, ix, StationAddress[ix]);
lock();
/* Enable DMA/Interrupt, gain control of Buffer */
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS);
/* Clear RX packet area */
@ -60,22 +59,19 @@ static void el1_reset(dpeth_t * dep)
inb_el1(dep, EL1_RECV);
inb_el1(dep, EL1_XMIT);
dep->de_flags &= NOT(DEF_XMIT_BUSY);
unlock();
return; /* Done */
}
/*
** Name: void el1_dumpstats(dpeth_t *dep, int port, vir_bytes size)
** Name: el1_dumpstats
** Function: Dumps counter on screen (support for console display).
*/
static void el1_dumpstats(dpeth_t * UNUSED(dep))
{
return;
}
/*
** Name: void el1_mode_init(dpeth_t *dep)
** Name: el1_mode_init
** Function: Initializes receicer mode
*/
static void el1_mode_init(dpeth_t * dep)
@ -95,125 +91,93 @@ static void el1_mode_init(dpeth_t * dep)
}
outb_el1(dep, EL1_RECV, dep->de_recv_mode);
inb_el1(dep, EL1_RECV);
return;
}
/*
** Name: void el1_recv(dpeth_t *dep, int from, int size)
** Name: el1_recv
** Function: Receive function. Called from interrupt handler to
** unload recv. buffer or from main (packet to client)
*/
static void el1_recv(dpeth_t * dep, int from, int size)
static ssize_t el1_recv(dpeth_t *dep, struct netdriver_data *data, size_t max)
{
buff_t *rxptr;
size_t size;
while ((dep->de_flags & DEF_READING) && (rxptr = dep->de_recvq_head)) {
if ((rxptr = dep->de_recvq_head) == NULL)
return SUSPEND;
/* Remove buffer from queue and free buffer */
lock();
if (dep->de_recvq_tail == dep->de_recvq_head)
dep->de_recvq_head = dep->de_recvq_tail = NULL;
else
dep->de_recvq_head = rxptr->next;
unlock();
/* Remove buffer from queue and free buffer */
if (dep->de_recvq_tail == dep->de_recvq_head)
dep->de_recvq_head = dep->de_recvq_tail = NULL;
else
dep->de_recvq_head = rxptr->next;
/* Copy buffer to user area */
mem2user(dep, rxptr);
/* Copy buffer to user area */
size = MIN(rxptr->size, max);
/* Reply information */
dep->de_read_s = rxptr->size;
dep->de_flags |= DEF_ACK_RECV;
dep->de_flags &= NOT(DEF_READING);
netdriver_copyout(data, 0, rxptr->buffer, size);
/* Return buffer to the idle pool */
free_buff(dep, rxptr);
}
return;
/* Return buffer to the idle pool */
free_buff(dep, rxptr);
return size;
}
/*
** Name: void el1_send(dpeth_t *dep, int from_int, int pktsize)
** Function: Send function. Called from main to transit a packet or
** from interrupt handler when a new packet was queued.
** Name: el1_send
** Function: Send function.
*/
static void el1_send(dpeth_t * dep, int from_int, int pktsize)
static int el1_send(dpeth_t *dep, struct netdriver_data *data, size_t size)
{
buff_t *txbuff;
clock_t now;
if (from_int == FALSE) {
if ((txbuff = alloc_buff(dep, pktsize + sizeof(buff_t))) != NULL) {
/* Fill transmit buffer from user area */
txbuff->next = NULL;
txbuff->size = pktsize;
txbuff->client = dep->de_client;
user2mem(dep, txbuff);
} else
panic("out of memory for Tx");
} else if ((txbuff = dep->de_xmitq_head) != NULL) {
/* Get first packet in queue */
lock();
if (dep->de_xmitq_tail == dep->de_xmitq_head)
dep->de_xmitq_head = dep->de_xmitq_tail = NULL;
else
dep->de_xmitq_head = txbuff->next;
unlock();
pktsize = txbuff->size;
} else
panic("should not be sending ");
if ((dep->de_flags & DEF_XMIT_BUSY)) {
if (from_int) panic("should not be sending ");
if (dep->de_flags & DEF_XMIT_BUSY) {
getticks(&now);
if ((now - dep->de_xmit_start) > 4) {
/* Transmitter timed out */
DEBUG(printf("3c501: transmitter timed out ... \n"));
dep->de_stat.ets_sendErr += 1;
dep->de_flags &= NOT(DEF_XMIT_BUSY);
el1_reset(dep);
}
/* Queue packet */
lock(); /* Queue packet to receive queue */
if (dep->de_xmitq_head == NULL)
dep->de_xmitq_head = txbuff;
else
dep->de_xmitq_tail->next = txbuff;
dep->de_xmitq_tail = txbuff;
unlock();
} else {
/* Save for retransmission */
TxBuff = txbuff;
dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);
/* Setup board for packet loading */
lock(); /* Buffer to processor */
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS);
inb_el1(dep, EL1_RECV); /* Clears any spurious interrupt */
inb_el1(dep, EL1_XMIT);
outw_el1(dep, EL1_RECVPTR, 0); /* Clears RX packet area */
/* Loads packet */
outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - pktsize));
outsb(dep->de_data_port, SELF, txbuff->buffer, pktsize);
/* Starts transmitter */
outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - pktsize));
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT); /* There it goes... */
unlock();
getticks(&dep->de_xmit_start);
dep->de_flags &= NOT(DEF_SENDING);
/* Try sending anyway. */
} else
return SUSPEND;
}
return;
/* Since we may have to retransmit, we need a local copy. */
if ((txbuff = alloc_buff(dep, size + sizeof(buff_t))) == NULL)
panic("out of memory");
/* Fill transmit buffer from user area */
txbuff->next = NULL;
txbuff->size = size;
netdriver_copyin(data, 0, txbuff->buffer, size);
/* Save for retransmission */
TxBuff = txbuff;
dep->de_flags |= DEF_XMIT_BUSY;
/* Setup board for packet loading */
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS);
inb_el1(dep, EL1_RECV); /* Clears any spurious interrupt */
inb_el1(dep, EL1_XMIT);
outw_el1(dep, EL1_RECVPTR, 0); /* Clears RX packet area */
/* Loads packet */
outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - size));
outsb(dep->de_data_port, txbuff->buffer, size);
/* Starts transmitter */
outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - size));
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT); /* There it goes... */
getticks(&dep->de_xmit_start);
return OK;
}
/*
** Name: void el1_stop(dpeth_t *dep)
** Name: el1_stop
** Function: Stops board and disable interrupts.
*/
static void el1_stop(dpeth_t * dep)
@ -225,11 +189,10 @@ static void el1_stop(dpeth_t * dep)
outb_el1(dep, EL1_CSR, ECSR_RESET);
outb_el1(dep, EL1_CSR, ECSR_SYS);
sys_irqdisable(&dep->de_hook); /* Disable interrupt */
return;
}
/*
** Name: void el1_interrupt(dpeth_t *dep)
** Name: el1_interrupt
** Function: Interrupt handler. Acknwledges transmit interrupts
** or unloads receive buffer to memory queue.
*/
@ -264,7 +227,6 @@ static void el1_interrupt(dpeth_t * dep)
}
DEBUG(printf("3c501: got xmit interrupt (0x%02X)\n", isr));
el1_reset(dep);
} else {
/** if (inw_el1(dep, EL1_XMITPTR) == EL1_BFRSIZ) **/
/* Packet transmitted successfully */
@ -272,12 +234,9 @@ static void el1_interrupt(dpeth_t * dep)
dep->bytes_Tx += (long) (TxBuff->size);
free_buff(dep, TxBuff);
dep->de_flags &= NOT(DEF_XMIT_BUSY);
if ((dep->de_flags & DEF_SENDING) && dep->de_xmitq_head) {
/* Pending transmit request available in queue */
el1_send(dep, TRUE, 0);
if (dep->de_flags & (DEF_XMIT_BUSY | DEF_ACK_SEND))
return;
}
netdriver_send();
if (dep->de_flags & DEF_XMIT_BUSY)
return;
}
} else if ((csr & (ECSR_RECV | ECSR_XMTBSY)) == (ECSR_RECV | ECSR_XMTBSY)) {
@ -301,21 +260,20 @@ static void el1_interrupt(dpeth_t * dep)
/* Got a good packet. Read it from buffer */
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_SYS);
outw_el1(dep, EL1_XMITPTR, 0);
insb(dep->de_data_port, SELF, rxptr->buffer, pktsize);
insb(dep->de_data_port, rxptr->buffer, pktsize);
rxptr->next = NULL;
rxptr->size = pktsize;
dep->de_stat.ets_packetR += 1;
dep->bytes_Rx += (long) pktsize;
lock(); /* Queue packet to receive queue */
/* Queue packet to receive queue */
if (dep->de_recvq_head == NULL)
dep->de_recvq_head = rxptr;
else
dep->de_recvq_tail->next = rxptr;
dep->de_recvq_tail = rxptr;
unlock();
/* Reply to pending Receive requests, if any */
el1_recv(dep, TRUE, 0);
netdriver_recv();
}
} else { /* Nasty condition, should never happen */
DEBUG(
@ -337,11 +295,10 @@ static void el1_interrupt(dpeth_t * dep)
/* Be sure that interrupts are cleared */
inb_el1(dep, EL1_RECV);
inb_el1(dep, EL1_XMIT);
return;
}
/*
** Name: void el1_init(dpeth_t *dep)
** Name: el1_init
** Function: Initalizes board hardware and driver data structures.
*/
static void el1_init(dpeth_t * dep)
@ -376,12 +333,10 @@ static void el1_init(dpeth_t * dep)
dep->de_getstatsf = el1_getstats;
dep->de_dumpstatsf = el1_dumpstats;
dep->de_interruptf = el1_interrupt;
return; /* Done */
}
/*
** Name: int el1_probe(dpeth_t *dep)
** Name: el1_probe
** Function: Checks for presence of the board.
*/
int el1_probe(dpeth_t * dep)

View File

@ -10,6 +10,7 @@
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -20,7 +21,7 @@
#include "3c503.h"
/*
** Name: void el2_init(dpeth_t *dep);
** Name: el2_init
** Function: Initalize hardware and data structures.
*/
static void el2_init(dpeth_t * dep)
@ -97,11 +98,10 @@ static void el2_init(dpeth_t * dep)
for (ix = 0; ix < SA_ADDR_LEN; ix += 1)
printf("%02X%c", dep->de_address.ea_addr[ix],
ix < SA_ADDR_LEN - 1 ? ':' : '\n');
return;
}
/*
** Name: void el2_stop(dpeth_t *dep);
** Name: el2_stop
** Function: Stops board by disabling interrupts.
*/
static void el2_stop(dpeth_t * dep)
@ -109,11 +109,10 @@ static void el2_stop(dpeth_t * dep)
outb_el2(dep, EL2_CFGR, ECFGR_IRQOFF);
sys_irqdisable(&dep->de_hook); /* disable interrupts */
return;
}
/*
** Name: void el2_probe(dpeth_t *dep);
** Name: el2_probe
** Function: Probe for the presence of an EtherLink II card.
** Initialize memory addressing if card detected.
*/
@ -132,9 +131,9 @@ int el2_probe(dpeth_t * dep)
/* Resets board */
outb_el2(dep, EL2_CNTR, ECNTR_RESET | thin);
milli_delay(1);
micro_delay(1000);
outb_el2(dep, EL2_CNTR, thin);
milli_delay(5);
micro_delay(5000);
/* Map the address PROM to lower I/O address range */
outb_el2(dep, EL2_CNTR, ECNTR_SAPROM | thin);

View File

@ -10,7 +10,7 @@
*/
#include <minix/drivers.h>
#include <minix/com.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
@ -25,7 +25,7 @@ static const char *const IfNamesMsg[] = {
};
/*
** Name: void el3_update_stats(dpeth_t *dep)
** Name: el3_update_stats
** Function: Reads statistic counters from board
** and updates local counters.
*/
@ -52,36 +52,30 @@ static void el3_update_stats(dpeth_t * dep)
/* Goes back to operating window and enables statistics */
SetWindow(WNO_Operating);
outw_el3(dep, REG_CmdStatus, CMD_StatsEnable);
return;
}
/*
** Name: void el3_getstats(dpeth_t *dep)
** Name: el3_getstats
** Function: Reads statistics counters from board.
*/
static void el3_getstats(dpeth_t * dep)
{
lock();
el3_update_stats(dep);
unlock();
return;
}
/*
** Name: void el3_dodump(dpeth_t *dep)
** Name: el3_dodump
** Function: Dumps counter on screen (support for console display).
*/
static void el3_dodump(dpeth_t * dep)
{
el3_getstats(dep);
return;
}
/*
** Name: void el3_rx_mode(dpeth_t *dep)
** Name: el3_rx_mode
** Function: Initializes receiver mode
*/
static void el3_rx_mode(dpeth_t * dep)
@ -95,85 +89,49 @@ static void el3_rx_mode(dpeth_t * dep)
outw_el3(dep, REG_CmdStatus, CMD_RxReset);
outw_el3(dep, REG_CmdStatus, CMD_SetRxFilter | dep->de_recv_mode);
outw_el3(dep, REG_CmdStatus, CMD_RxEnable);
return;
}
/*
** Name: void el3_reset(dpeth_t *dep)
** Name: el3_reset
** Function: Reset function specific for Etherlink hardware.
*/
static void el3_reset(dpeth_t * UNUSED(dep))
{
return; /* Done */
}
/*
** Name: void el3_write_fifo(dpeth_t * dep, int pktsize);
** Function: Writes a packet from user area to board.
** Remark: Writing a word/dword at a time may result faster
** but is a lot more complicated. Let's go simpler way.
*/
static void el3_write_fifo(dpeth_t * dep, int pktsize)
{
int bytes, ix = 0;
iovec_dat_s_t *iovp = &dep->de_write_iovec;
int r, padding = pktsize;
do { /* Writes chuncks of packet from user buffers */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes > pktsize) bytes = pktsize;
/* Writes from user buffer to Tx FIFO */
r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, 0, bytes);
if (r != OK)
panic("el3_write_fifo: sys_safe_outsb failed: %d", r);
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
while ((padding++ % sizeof(long)) != 0) outb(dep->de_data_port, 0x00);
return;
}
/*
** Name: void el3_recv(dpeth_t *dep, int fromint, int size)
** Name: el3_recv
** Function: Receive function. Called from interrupt handler or
** from main to unload recv. buffer (packet to client)
*/
static void el3_recv(dpeth_t *dep, int fromint, int size)
static ssize_t el3_recv(dpeth_t *dep, struct netdriver_data *data, size_t max)
{
buff_t *rxptr;
size_t size;
while ((dep->de_flags & DEF_READING) && (rxptr = dep->de_recvq_head)) {
if ((rxptr = dep->de_recvq_head) == NULL)
return SUSPEND;
lock(); /* Remove buffer from queue */
if (dep->de_recvq_tail == dep->de_recvq_head)
dep->de_recvq_head = dep->de_recvq_tail = NULL;
else
dep->de_recvq_head = rxptr->next;
unlock();
/* Remove buffer from queue */
if (dep->de_recvq_tail == dep->de_recvq_head)
dep->de_recvq_head = dep->de_recvq_tail = NULL;
else
dep->de_recvq_head = rxptr->next;
/* Copy buffer to user area and free it */
mem2user(dep, rxptr);
/* Copy buffer to user area and free it */
size = MIN(rxptr->size, max);
dep->de_read_s = rxptr->size;
dep->de_flags |= DEF_ACK_RECV;
dep->de_flags &= NOT(DEF_READING);
netdriver_copyout(data, 0, rxptr->buffer, size);
/* Return buffer to the idle pool */
free_buff(dep, rxptr);
}
return;
/* Return buffer to the idle pool */
free_buff(dep, rxptr);
return size;
}
/*
** Name: void el3_rx_complete(dpeth_t * dep);
** Name: el3_rx_complete
** Function: Upon receiving a packet, provides status checks
** and if packet is OK copies it to local buffer.
*/
@ -205,38 +163,36 @@ static void el3_rx_complete(dpeth_t * dep)
} else {
/* Good packet. Read it from FIFO */
insb(dep->de_data_port, SELF, rxptr->buffer, pktsize);
insb(dep->de_data_port, rxptr->buffer, pktsize);
rxptr->next = NULL;
rxptr->size = pktsize;
lock(); /* Queue packet to receive queue */
/* Queue packet to receive queue */
if (dep->de_recvq_head == NULL)
dep->de_recvq_head = rxptr;
else
dep->de_recvq_tail->next = rxptr;
dep->de_recvq_tail = rxptr;
unlock();
/* Reply to pending Receive requests, if any */
el3_recv(dep, TRUE, pktsize);
netdriver_recv();
}
/* Discard top packet from queue */
outw_el3(dep, REG_CmdStatus, CMD_RxDiscard);
return;
}
/*
** Name: void el3_send(dpeth_t *dep, int count)
** Name: el3_send
** Function: Send function. Called from main to transit a packet or
** from interrupt handler when Tx FIFO gets available.
*/
static void el3_send(dpeth_t * dep, int from_int, int count)
static int el3_send(dpeth_t *dep, struct netdriver_data *data, size_t size)
{
clock_t now;
int ix;
short int TxStatus;
size_t padding;
getticks(&now);
if ((dep->de_flags & DEF_XMIT_BUSY) &&
@ -249,41 +205,43 @@ static void el3_send(dpeth_t * dep, int from_int, int count)
outw_el3(dep, REG_CmdStatus, CMD_TxEnable);
dep->de_flags &= NOT(DEF_XMIT_BUSY);
}
if (!(dep->de_flags & DEF_XMIT_BUSY)) {
if (dep->de_flags & DEF_XMIT_BUSY)
return SUSPEND;
/* Writes Transmitter preamble 1st Word (packet len, no ints) */
outw_el3(dep, REG_TxFIFO, count);
/* Writes Transmitter preamble 2nd Word (all zero) */
outw_el3(dep, REG_TxFIFO, 0);
/* Writes packet */
el3_write_fifo(dep, count);
/* Writes Transmitter preamble 1st Word (packet len, no ints) */
outw_el3(dep, REG_TxFIFO, size);
/* Writes Transmitter preamble 2nd Word (all zero) */
outw_el3(dep, REG_TxFIFO, 0);
/* Writes packet */
netdriver_portoutb(data, 0, dep->de_data_port, size);
padding = size;
while ((padding++ % sizeof(long)) != 0) outb(dep->de_data_port, 0x00);
getticks(&dep->de_xmit_start);
dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);
if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) {
/* Tx has enough room for a packet of maximum size */
dep->de_flags &= NOT(DEF_XMIT_BUSY | DEF_SENDING);
} else {
/* Interrupt driver when enough room is available */
outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | ETH_MAX_PACK_SIZE);
dep->de_flags &= NOT(DEF_SENDING);
}
/* Pops Tx status stack */
for (ix = 4; --ix && (TxStatus = inb_el3(dep, REG_TxStatus)) > 0;) {
if (TxStatus & 0x38) dep->de_stat.ets_sendErr += 1;
if (TxStatus & 0x30)
outw_el3(dep, REG_CmdStatus, CMD_TxReset);
if (TxStatus & 0x3C)
outw_el3(dep, REG_CmdStatus, CMD_TxEnable);
outb_el3(dep, REG_TxStatus, 0);
}
getticks(&dep->de_xmit_start);
dep->de_flags |= DEF_XMIT_BUSY;
if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) {
/* Tx has enough room for a packet of maximum size */
dep->de_flags &= NOT(DEF_XMIT_BUSY);
} else {
/* Interrupt driver when enough room is available */
outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | ETH_MAX_PACK_SIZE);
}
return;
/* Pops Tx status stack */
for (ix = 4; --ix && (TxStatus = inb_el3(dep, REG_TxStatus)) > 0;) {
if (TxStatus & 0x38) dep->de_stat.ets_sendErr += 1;
if (TxStatus & 0x30)
outw_el3(dep, REG_CmdStatus, CMD_TxReset);
if (TxStatus & 0x3C)
outw_el3(dep, REG_CmdStatus, CMD_TxEnable);
outb_el3(dep, REG_TxStatus, 0);
}
return OK;
}
/*
** Name: void el3_close(dpeth_t *dep)
** Name: el3_close
** Function: Stops board and makes it ready to shut down.
*/
static void el3_close(dpeth_t * dep)
@ -296,24 +254,22 @@ static void el3_close(dpeth_t * dep)
if (dep->de_if_port == BNC_XCVR) {
outw_el3(dep, REG_CmdStatus, CMD_StopIntXcvr);
/* milli_delay(5); */
/* micro_delay(5000); */
} else if (dep->de_if_port == TP_XCVR) {
SetWindow(WNO_Diagnostics);
outw_el3(dep, REG_MediaStatus, inw_el3(dep, REG_MediaStatus) &
NOT((MediaLBeatEnable | MediaJabberEnable)));
/* milli_delay(5); */
/* micro_delay(5000); */
}
DEBUG(printf("%s: stopping Etherlink ... \n", dep->de_name));
/* Issues a global reset
outw_el3(dep, REG_CmdStatus, CMD_GlobalReset); */
sys_irqdisable(&dep->de_hook); /* Disable interrupt */
return;
}
/*
** Name: void el3_interrupt(dpeth_t *dep)
** Name: el3_interrupt
** Function: Interrupt handler. Acknwledges transmit interrupts
** or unloads receive buffer to memory queue.
*/
@ -332,8 +288,7 @@ static void el3_interrupt(dpeth_t * dep)
DEBUG(printf("3c509: got Tx interrupt, Status=0x%04x\n", isr);)
dep->de_flags &= NOT(DEF_XMIT_BUSY);
outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | INT_TxAvailable);
if (dep->de_flags & DEF_SENDING) /* Send pending */
el3_send(dep, TRUE, dep->de_send_s);
netdriver_send();
}
if (isr & (INT_AdapterFail | INT_RxEarly | INT_UpdateStats)) {
@ -354,11 +309,10 @@ static void el3_interrupt(dpeth_t * dep)
/* Acknowledge interrupt */
outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | (INT_Latch | INT_Requested));
}
return;
}
/*
** Name: unsigned el3_read_eeprom(port_t port, unsigned address);
** Name: el3_read_eeprom
** Function: Reads the EEPROM at specified address
*/
static unsigned el3_read_eeprom(port_t port, unsigned address)
@ -368,7 +322,7 @@ static unsigned el3_read_eeprom(port_t port, unsigned address)
address |= EL3_READ_EEPROM;
outb(port, address);
milli_delay(5); /* Allows EEPROM reads */
micro_delay(5000); /* Allows EEPROM reads */
for (result = 0, bit = 16; bit > 0; bit -= 1) {
result = (result << 1) | (inb(port) & 0x0001);
}
@ -376,7 +330,7 @@ static unsigned el3_read_eeprom(port_t port, unsigned address)
}
/*
** Name: void el3_read_StationAddress(dpeth_t *dep)
** Name: el3_read_StationAddress
** Function: Reads station address from board
*/
static void el3_read_StationAddress(dpeth_t * dep)
@ -390,11 +344,10 @@ static void el3_read_StationAddress(dpeth_t * dep)
dep->de_address.ea_addr[ix++] = (rc >> 8) & 0xFF;
dep->de_address.ea_addr[ix++] = rc & 0xFF;
}
return;
}
/*
** Name: void el3_open(dpeth_t *dep)
** Name: el3_open
** Function: Initalizes board hardware and driver data structures.
*/
static void el3_open(dpeth_t * dep)
@ -440,7 +393,7 @@ static void el3_open(dpeth_t * dep)
if (dep->de_if_port == BNC_XCVR) {
/* Start internal transceiver for Coaxial cable */
outw_el3(dep, REG_CmdStatus, CMD_StartIntXcvr);
milli_delay(5);
micro_delay(5000);
} else if (dep->de_if_port == TP_XCVR) {
/* Start internal transceiver for Twisted pair cable */
@ -497,12 +450,10 @@ static void el3_open(dpeth_t * dep)
for (ix = 0; ix < SA_ADDR_LEN; ix += 1)
printf("%02X%c", dep->de_address.ea_addr[ix],
ix < SA_ADDR_LEN - 1 ? ':' : '\n');
return; /* Done */
}
/*
** Name: unsigned int el3_checksum(port_t port);
** Name: int el3_checksum
** Function: Reads EEPROM and computes checksum.
*/
static unsigned short el3_checksum(port_t port)
@ -534,7 +485,7 @@ static unsigned short el3_checksum(port_t port)
}
/*
** Name: void el3_write_id(port_t port);
** Name: el3_write_id
** Function: Writes the ID sequence to the board.
*/
static void el3_write_id(port_t port)
@ -548,11 +499,10 @@ static void el3_write_id(port_t port)
pattern <<= 1;
pattern = (pattern & 0x0100) ? pattern ^ 0xCF : pattern;
}
return;
}
/*
** Name: int el3_probe(dpeth_t *dep)
** Name: el3_probe
** Function: Checks for presence of the board.
*/
int el3_probe(dpeth_t * dep)
@ -572,10 +522,10 @@ int el3_probe(dpeth_t * dep)
el3_write_id(id_port);
outb(id_port, EL3_ID_GLOBAL_RESET); /* Reset the board */
milli_delay(5); /* Technical reference says 162 micro sec. */
micro_delay(5000); /* Technical reference says 162 micro sec. */
el3_write_id(id_port);
outb(id_port, EL3_SET_TAG_REGISTER);
milli_delay(5);
micro_delay(5000);
dep->de_id_port = id_port; /* Stores ID port No. */
dep->de_ramsize = /* RAM size is meaningless */

View File

@ -1,4 +1,3 @@
#include <assert.h>
/*
** File: 8390.c May 02, 2000
**
@ -12,32 +11,18 @@
*/
#include <minix/drivers.h>
#include <minix/com.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <assert.h>
#include "dp.h"
#if (ENABLE_DP8390 == 1)
#define PIO16 0 /* NOTE: pio 16 functions missing */
#include "8390.h"
#if 0
#define sys_nic2mem(srcOffs,dstProc,dstOffs,length) \
sys_vircopy(SELF,dep->de_memsegm,(vir_bytes)(srcOffs),\
(dstProc),D,(vir_bytes)(dstOffs),length)
#endif
#if 0
#define sys_user2nic_s(srcProc,grant,dstOffs,length) \
sys_safecopyfrom((srcProc),(grant),0, \
(vir_bytes)(dstOffs),length,dep->de_memsegm)
#endif
static char RdmaErrMsg[] = "remote dma failed to complete";
/*
** Name: void ns_rw_setup(dpeth_t *dep, int mode, int size, u16_t offset);
** Name: ns_rw_setup
** Function: Sets the board for reading/writing.
*/
static void ns_rw_setup(const dpeth_t *dep, int mode, int size, u16_t offset)
@ -50,11 +35,10 @@ static void ns_rw_setup(const dpeth_t *dep, int mode, int size, u16_t offset)
outb_reg0(dep, DP_RSAR1, (offset >> 8) & 0xFF);
mode |= (CR_PS_P0 | CR_STA);
outb_reg0(dep, DP_CR, mode);
return;
}
/*
** Name: void ns_start_xmit(dpeth_t *dep, int size, int pageno);
** Name: ns_start_xmit
** Function: Sets the board for for transmitting and fires it.
*/
static void ns_start_xmit(const dpeth_t * dep, int size, int pageno)
@ -64,110 +48,58 @@ static void ns_start_xmit(const dpeth_t * dep, int size, int pageno)
outb_reg0(dep, DP_TBCR1, size >> 8);
outb_reg0(dep, DP_TBCR0, size & 0xFF);
outb_reg0(dep, DP_CR, CR_NO_DMA | CR_STA | CR_TXP); /* Fires transmission */
return;
}
/*
** Name: void mem_getblock(dpeth_t *dep, u16_t offset,
** int size, void *dst)
** Name: mem_getblock
** Function: Reads a block of packet from board (shared memory).
*/
static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
{
panic("mem_getblock: not converted to safecopies");
#if 0
sys_nic2mem(dep->de_linmem + offset, SELF, dst, size);
return;
#endif
assert(offset + size <= dep->de_ramsize);
memcpy(dst, dep->de_locmem + offset, size);
}
/*
** Name: void mem_nic2user(dpeth_t *dep, int pageno, int pktsize);
** Name: mem_nic2user
** Function: Copies a packet from board to user area (shared memory).
*/
static void mem_nic2user(dpeth_t * dep, int pageno, int pktsize)
static void mem_nic2user(dpeth_t *dep, int pageno, struct netdriver_data *data,
size_t size)
{
panic("mem_nic2user: not converted to safecopies");
#if 0
phys_bytes offset;
iovec_dat_s_t *iovp = &dep->de_read_iovec;
int bytes, ix = 0;
size_t offset, left;
/* Computes shared memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
do { /* Reads chuncks of packet into user area */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of a chunck */
if (bytes > pktsize) bytes = pktsize;
/* Reads from board to user area */
if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {
/* Circular buffer wrap-around */
bytes = dep->de_stoppage * DP_PAGESIZE - offset;
sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, bytes);
pktsize -= bytes;
phys_user += bytes;
bytes = iovp->iod_iovec[ix].iov_size - bytes;
if (bytes > pktsize) bytes = pktsize;
offset = dep->de_startpage * DP_PAGESIZE;
}
sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, bytes);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
#endif
if (offset + size > dep->de_stoppage * DP_PAGESIZE) {
left = dep->de_stoppage * DP_PAGESIZE - offset;
netdriver_copyout(data, 0, dep->de_locmem + offset, left);
offset = dep->de_startpage * DP_PAGESIZE;
netdriver_copyout(data, left, dep->de_locmem + offset, size - left);
} else
netdriver_copyout(data, 0, dep->de_locmem + offset, size);
}
/*
** Name: void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)
** Name: mem_user2nic
** Function: Copies a packet from user area to board (shared memory).
*/
static void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)
static void mem_user2nic(dpeth_t *dep, int pageno, struct netdriver_data *data,
size_t size)
{
#if 1
panic("mem_user2nic: not converted to safecopies");
#else
phys_bytes offset, phys_user;
iovec_dat_s_t *iovp = &dep->de_write_iovec;
int bytes, ix = 0;
size_t offset;
/* Computes shared memory address */
offset = pageno * DP_PAGESIZE;
do { /* Reads chuncks of packet from user area */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of chunck */
if (bytes > pktsize) bytes = pktsize;
/* Reads from user area to board (shared memory) */
sys_user2nic_s(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
dep->de_linmem + offset, bytes);
offset += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
#endif
netdriver_copyin(data, 0, dep->de_locmem + offset, size);
}
/*
** Name: void pio_getblock(dpeth_t *dep, u16_t offset,
** int size, void *dst)
** Name: pio_getblock
** Function: Reads a block of packet from board (Prog. I/O).
*/
static void pio_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
@ -176,110 +108,72 @@ static void pio_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
/* Sets up board for reading */
ns_rw_setup(dep, CR_DM_RR, size, offset);
#if PIO16 == 0
insb(dep->de_data_port, SELF, dst, size);
#else
if (dep->de_16bit == TRUE) {
if (dep->de_16bit == TRUE)
insw(dep->de_data_port, dst, size);
} else {
else
insb(dep->de_data_port, dst, size);
}
#endif
return;
}
/*
** Name: void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)
** Name: pio_nic2user
** Function: Copies a packet from board to user area (Prog. I/O).
*/
static void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)
static void pio_nic2user(dpeth_t *dep, int pageno, struct netdriver_data *data,
size_t size)
{
iovec_dat_s_t *iovp = &dep->de_read_iovec;
unsigned offset, iov_offset; int r, bytes, ix = 0;
size_t offset, left;
/* Computes memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
/* Sets up board for reading */
ns_rw_setup(dep, CR_DM_RR, ((offset + pktsize) > (dep->de_stoppage * DP_PAGESIZE)) ?
(dep->de_stoppage * DP_PAGESIZE) - offset : pktsize, offset);
iov_offset= 0;
do { /* Reads chuncks of packet into user area */
if (offset + size > dep->de_stoppage * DP_PAGESIZE) {
left = dep->de_stoppage * DP_PAGESIZE - offset;
bytes = iovp->iod_iovec[ix].iov_size; /* Size of a chunck */
if (bytes > pktsize) bytes = pktsize;
ns_rw_setup(dep, CR_DM_RR, left, offset);
if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {
if (dep->de_16bit)
netdriver_portinw(data, 0, dep->de_data_port, left);
else
netdriver_portinb(data, 0, dep->de_data_port, left);
/* Circular buffer wrap-around */
bytes = dep->de_stoppage * DP_PAGESIZE - offset;
r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
if (r != OK) {
panic("pio_nic2user: sys_safe_insb failed: %d", r);
}
pktsize -= bytes;
iov_offset += bytes;
bytes = iovp->iod_iovec[ix].iov_size - bytes;
if (bytes > pktsize) bytes = pktsize;
offset = dep->de_startpage * DP_PAGESIZE;
ns_rw_setup(dep, CR_DM_RR, pktsize, offset);
}
r= sys_safe_insb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, iov_offset, bytes);
if (r != OK)
panic("pio_nic2user: sys_safe_insb failed: %d", r);
offset += bytes;
offset = dep->de_startpage * DP_PAGESIZE;
} else
left = 0;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
iov_offset= 0;
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
ns_rw_setup(dep, CR_DM_RR, size - left, offset);
if (dep->de_16bit)
netdriver_portinw(data, left, dep->de_data_port, size - left);
else
netdriver_portinb(data, left, dep->de_data_port, size - left);
}
/*
** Name: void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)
** Name: pio_user2nic
** Function: Copies a packet from user area to board (Prog. I/O).
*/
static void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)
static void pio_user2nic(dpeth_t *dep, int pageno, struct netdriver_data *data,
size_t size)
{
iovec_dat_s_t *iovp = &dep->de_write_iovec;
int r, bytes, ix = 0;
int ix;
/* Sets up board for writing */
ns_rw_setup(dep, CR_DM_RW, pktsize, pageno * DP_PAGESIZE);
do { /* Reads chuncks of packet from user area */
ns_rw_setup(dep, CR_DM_RW, size, pageno * DP_PAGESIZE);
bytes = iovp->iod_iovec[ix].iov_size; /* Size of chunck */
if (bytes > pktsize) bytes = pktsize;
r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
iovp->iod_iovec[ix].iov_grant, 0, bytes);
if (r != OK)
panic("pio_user2nic: sys_safe_outsb failed: %d", r);
if (++ix >= IOVEC_NR) { /* Next buffer of I/O vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
if (dep->de_16bit)
netdriver_portoutw(data, 0, dep->de_data_port, size);
else
netdriver_portoutb(data, 0, dep->de_data_port, size);
for (ix = 0; ix < 100; ix += 1) {
if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
}
if (ix == 100) {
panic("%s", RdmaErrMsg);
}
return;
if (ix == 100)
panic("remote dma failed to complete");
}
/*
** Name: void ns_stats(dpeth_t * dep)
** Name: ns_stats
** Function: Updates counters reading from device
*/
static void ns_stats(dpeth_t * dep)
@ -288,22 +182,20 @@ static void ns_stats(dpeth_t * dep)
dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1);
dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2);
return;
}
/*
** Name: void ns_dodump(dpeth_t * dep)
** Function: Displays statistics (a request from F5 key).
** Name: ns_dodump
** Function: Displays statistics (a request from a function key).
*/
static void ns_dodump(dpeth_t * dep)
{
ns_stats(dep); /* Forces reading fo counters from board */
return;
ns_stats(dep); /* Forces reading of counters from board */
}
/*
** Name: void ns_reinit(dpeth_t *dep)
** Name: ns_reinit
** Function: Updates receiver configuration.
*/
static void ns_reinit(dpeth_t * dep)
@ -315,26 +207,24 @@ static void ns_reinit(dpeth_t * dep)
if (dep->de_flags & DEF_MULTI) dp_reg |= RCR_AM;
outb_reg0(dep, DP_CR, CR_PS_P0);
outb_reg0(dep, DP_RCR, dp_reg);
return;
}
/*
** Name: void ns_send(dpeth_t * dep, int from_int, int size)
** Name: ns_send
** Function: Transfers packet to device and starts sending.
*/
static void ns_send(dpeth_t * dep, int from_int, int size)
static int ns_send(dpeth_t *dep, struct netdriver_data *data, size_t size)
{
int queue;
if (queue = dep->de_sendq_head, dep->de_sendq[queue].sq_filled) {
if (from_int) panic("should not be sending ");
dep->de_send_s = size;
return;
}
(dep->de_user2nicf) (dep, dep->de_sendq[queue].sq_sendpage, size);
queue = dep->de_sendq_head;
if (dep->de_sendq[queue].sq_filled)
return SUSPEND;
(dep->de_user2nicf)(dep, dep->de_sendq[queue].sq_sendpage, data, size);
dep->bytes_Tx += (long) size;
dep->de_sendq[queue].sq_filled = TRUE;
dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);
dep->de_flags |= DEF_XMIT_BUSY;
if (dep->de_sendq_tail == queue) { /* there it goes.. */
ns_start_xmit(dep, size, dep->de_sendq[queue].sq_sendpage);
} else
@ -342,13 +232,12 @@ static void ns_send(dpeth_t * dep, int from_int, int size)
if (++queue == dep->de_sendq_nr) queue = 0;
dep->de_sendq_head = queue;
dep->de_flags &= NOT(DEF_SENDING);
return;
return OK;
}
/*
** Name: void ns_reset(dpeth_t *dep)
** Name: ns_reset
** Function: Resets device.
*/
static void ns_reset(dpeth_t * dep)
@ -359,14 +248,14 @@ static void ns_reset(dpeth_t * dep)
outb_reg0(dep, DP_CR, CR_STP | CR_NO_DMA);
outb_reg0(dep, DP_RBCR0, 0);
outb_reg0(dep, DP_RBCR1, 0);
for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); ix += 1)
for (ix = 0; ix < 0x1000 && (inb_reg0(dep, DP_ISR) & ISR_RST) == 0; ix += 1)
/* Do nothing */ ;
outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA);
outb_reg0(dep, DP_TCR, TCR_NORMAL | TCR_OFST);
/* Acknowledge the ISR_RDC (remote dma) interrupt. */
for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); ix += 1)
for (ix = 0; ix < 0x1000 && (inb_reg0(dep, DP_ISR) & ISR_RDC) == 0; ix += 1)
/* Do nothing */ ;
outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & NOT(ISR_RDC));
@ -376,19 +265,18 @@ static void ns_reset(dpeth_t * dep)
dep->de_sendq_head = dep->de_sendq_tail = 0;
for (ix = 0; ix < dep->de_sendq_nr; ix++)
dep->de_sendq[ix].sq_filled = FALSE;
ns_send(dep, TRUE, dep->de_send_s);
return;
netdriver_send();
}
/*
** Name: void ns_recv(dpeth_t *dep, int fromint, int size)
** Name: ns_recv
** Function: Gets a packet from device
*/
static void ns_recv(dpeth_t *dep, int fromint, int size)
static ssize_t ns_recv(dpeth_t *dep, struct netdriver_data *data, size_t max)
{
dp_rcvhdr_t header;
unsigned pageno, curr, next;
vir_bytes length;
size_t length;
int packet_processed = FALSE;
#ifdef ETH_IGN_PROTO
u16_t eth_type;
@ -403,17 +291,21 @@ static void ns_recv(dpeth_t *dep, int fromint, int size)
curr = inb_reg1(dep, DP_CURR);
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_NO_DMA | CR_STA);
if (curr == pageno) break;
if (curr == pageno)
return SUSPEND;
(dep->de_getblockf) (dep, pageno * DP_PAGESIZE, sizeof(header), &header);
(dep->de_getblockf)(dep, pageno * DP_PAGESIZE, sizeof(header),
&header);
#ifdef ETH_IGN_PROTO
(dep->de_getblockf) (dep, pageno * DP_PAGESIZE + sizeof(header) + 2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
(dep->de_getblockf)(dep, pageno * DP_PAGESIZE + sizeof(header) +
2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
#endif
length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);
length = (header.dr_rbcl | (header.dr_rbch << 8)) -
sizeof(dp_rcvhdr_t);
next = header.dr_next;
if (length < ETH_MIN_PACK_SIZE || length > ETH_MAX_PACK_SIZE) {
printf("%s: packet with strange length arrived: %ld\n",
if (length < ETH_MIN_PACK_SIZE || length > max) {
printf("%s: packet with strange length arrived: %zu\n",
dep->de_name, length);
dep->de_stat.ets_recvErr += 1;
next = curr;
@ -422,50 +314,40 @@ static void ns_recv(dpeth_t *dep, int fromint, int size)
printf("%s: strange next page\n", dep->de_name);
dep->de_stat.ets_recvErr += 1;
next = curr;
#ifdef ETH_IGN_PROTO
} else if (eth_type == eth_ign_proto) {
/* Hack: ignore packets of a given protocol */
static int first = TRUE;
if (first) {
first = FALSE;
printf("%s: dropping proto %04x packet\n", dep->de_name, ntohs(eth_ign_proto));
printf("%s: dropping proto %04x packet\n",
dep->de_name, ntohs(eth_ign_proto));
}
next = curr;
#endif
} else if (header.dr_status & RSR_FO) {
/* This is very serious, issue a warning and reset buffers */
printf("%s: fifo overrun, resetting receive buffer\n", dep->de_name);
printf("%s: fifo overrun, resetting receive buffer\n",
dep->de_name);
dep->de_stat.ets_fifoOver += 1;
next = curr;
} else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) {
if (!(dep->de_flags & DEF_READING)) break;
(dep->de_nic2userf) (dep, pageno, length);
dep->de_read_s = length;
dep->de_flags |= DEF_ACK_RECV;
dep->de_flags &= NOT(DEF_READING);
} else if (header.dr_status & RSR_PRX) {
(dep->de_nic2userf)(dep, pageno, data, length);
packet_processed = TRUE;
}
dep->bytes_Rx += (long) length;
dep->de_stat.ets_packetR += 1;
outb_reg0(dep, DP_BNRY, (next == dep->de_startpage ? dep->de_stoppage : next) - 1);
outb_reg0(dep, DP_BNRY,
(next == dep->de_startpage ? dep->de_stoppage : next) - 1);
pageno = next;
} while (!packet_processed);
#if 0
if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED))
/* The chip is stopped, and all arrived packets delivered */
(*dep->de_resetf) (dep);
dep->de_flags &= NOT(DEF_STOPPED);
#endif
return;
return length;
}
/*
** Name: void ns_interrupt(dpeth_t * dep)
** Name: ns_interrupt
** Function: Handles interrupt.
*/
static void ns_interrupt(dpeth_t * dep)
@ -487,13 +369,15 @@ static void ns_interrupt(dpeth_t * dep)
dep->de_stat.ets_fifoUnder++;
}
if ((isr & ISR_TXE) || (tsr & (TSR_CRS | TSR_CDH | TSR_OWC))) {
printf("%s: got send Error (0x%02X)\n", dep->de_name, tsr);
printf("%s: got send Error (0x%02X)\n",
dep->de_name, tsr);
dep->de_stat.ets_sendErr++;
}
queue = dep->de_sendq_tail;
if (!(dep->de_sendq[queue].sq_filled)) { /* Hardware bug? */
printf("%s: transmit interrupt, but not sending\n", dep->de_name);
if (!(dep->de_sendq[queue].sq_filled)) { /* Hardware bug? */
printf("%s: transmit interrupt, but not sending\n",
dep->de_name);
continue;
}
dep->de_sendq[queue].sq_filled = FALSE;
@ -503,15 +387,14 @@ static void ns_interrupt(dpeth_t * dep)
ns_start_xmit(dep, dep->de_sendq[queue].sq_size,
dep->de_sendq[queue].sq_sendpage);
}
if (dep->de_flags & DEF_SENDING) {
ns_send(dep, TRUE, dep->de_send_s);
}
netdriver_send();
}
if (isr & ISR_PRX) {
ns_recv(dep, TRUE, 0);
netdriver_recv();
}
if (isr & ISR_RXE) {
printf("%s: got recv Error (0x%04X)\n", dep->de_name, inb_reg0(dep, DP_RSR));
printf("%s: got recv Error (0x%04X)\n",
dep->de_name, inb_reg0(dep, DP_RSR));
dep->de_stat.ets_recvErr++;
}
if (isr & ISR_CNT) {
@ -526,26 +409,21 @@ static void ns_interrupt(dpeth_t * dep)
/* Nothing to do */
}
if (isr & ISR_RST) {
/* This means we got an interrupt but the ethernet
* chip is shutdown. We set the flag DEF_STOPPED, and
* continue processing arrived packets. When the
* receive buffer is empty, we reset the dp8390. */
/* This means we got an interrupt but the ethernet chip is shut
* down. We reset the chip right away, possibly losing received
* packets in the process. There used to be a more elaborate
* approach of resetting only after all pending packets had
* been accepted, but it was broken and this is simpler anyway.
*/
printf("%s: network interface stopped\n", dep->de_name);
dep->de_flags |= DEF_STOPPED;
ns_reset(dep);
break;
}
}
if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED)) {
/* The chip is stopped, and all arrived packets delivered */
ns_reset(dep);
dep->de_flags &= NOT(DEF_STOPPED);
}
return;
}
/*
** Name: void ns_init(dpeth_t *dep)
** Name: ns_init
** Function: Initializes the NS 8390
*/
void ns_init(dpeth_t * dep)
@ -555,12 +433,8 @@ void ns_init(dpeth_t * dep)
/* NS8390 initialization (as recommended in National Semiconductor specs) */
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_NO_DMA); /* 0x21 */
#if PIO16 == 0
outb_reg0(dep, DP_DCR, (DCR_BYTEWIDE | DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS));
#else
outb_reg0(dep, DP_DCR, (((dep->de_16bit) ? DCR_WORDWIDE : DCR_BYTEWIDE) |
DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS));
#endif
outb_reg0(dep, DP_RBCR0, 0);
outb_reg0(dep, DP_RBCR1, 0);
outb_reg0(dep, DP_RCR, RCR_MON); /* Sets Monitor mode */
@ -609,13 +483,9 @@ void ns_init(dpeth_t * dep)
dep->de_nic2userf = mem_nic2user;
dep->de_getblockf = mem_getblock;
} else {
#if PIO16 == 0
dep->de_user2nicf = pio_user2nic;
dep->de_nic2userf = pio_nic2user;
dep->de_getblockf = pio_getblock;
#else
#error Missing I/O functions for pio 16 bits
#endif
}
dep->de_recvf = ns_recv;
dep->de_sendf = ns_send;
@ -624,135 +494,8 @@ void ns_init(dpeth_t * dep)
dep->de_getstatsf = ns_stats;
dep->de_dumpstatsf = ns_dodump;
dep->de_interruptf = ns_interrupt;
return; /* Done */
}
#if PIO16 == 1
/*
** Name: void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
** Function: Copies a packet from user area to board (Prog. I/O, 16bits).
*/
static void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)
{
u8_t two_bytes[2];
phys_bytes phys_user, phys_2bytes = vir2phys(two_bytes);
vir_bytes ecount = (pktsize + 1) & NOT(0x0001);
int bytes, ix = 0, odd_byte = 0;
iovec_dat_t *iovp = &dep->de_write_iovec;
outb_reg0(dep, DP_ISR, ISR_RDC);
dp_read_setup(dep, ecount, pageno * DP_PAGESIZE);
do {
bytes = iovp->iod_iovec[ix].iov_size;
if (bytes > pktsize) bytes = pktsize;
phys_user = numap(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);
if (!phys_user) panic(UmapErrMsg);
if (odd_byte) {
phys_copy(phys_user, phys_2bytes + 1, (phys_bytes) 1);
out_word(dep->de_data_port, *(u16_t *)two_bytes);
pktsize--;
bytes--;
phys_user++;
odd_byte = 0;
if (!bytes) continue;
}
ecount = bytes & NOT(0x0001);
if (ecount != 0) {
phys_outsw(dep->de_data_port, phys_user, ecount);
pktsize -= ecount;
bytes -= ecount;
phys_user += ecount;
}
if (bytes) {
phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);
pktsize--;
bytes--;
phys_user++;
odd_byte = 1;
}
if (++ix >= IOVEC_NR) { /* Next buffer of I/O vector */
dp_next_iovec(iovp);
ix = 0;
}
} while (bytes > 0);
if (odd_byte) out_word(dep->de_data_port, *(u16_t *) two_bytes);
for (ix = 0; ix < 100; ix++) {
if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
}
if (ix == 100) {
panic(RdmaErrMsg);
}
return;
}
/*
** Name: void dp_pio16_nic2user(dpeth_t *dep, int pageno, int pktsize)
** Function: Copies a packet from board to user area (Prog. I/O, 16bits).
*/
static void dp_pio16_nic2user(dpeth_t * dep, int nic_addr, int count)
{
phys_bytes phys_user;
vir_bytes ecount;
int bytes, i;
u8_t two_bytes[2];
phys_bytes phys_2bytes;
int odd_byte;
ecount = (count + 1) & ~1;
phys_2bytes = vir2phys(two_bytes);
odd_byte = 0;
dp_read_setup(dep, ecount, nic_addr);
i = 0;
while (count > 0) {
if (i >= IOVEC_NR) {
dp_next_iovec(iovp);
i = 0;
continue;
}
bytes = iovp->iod_iovec[i].iov_size;
if (bytes > count) bytes = count;
phys_user = numap(iovp->iod_proc_nr,
iovp->iod_iovec[i].iov_addr, bytes);
if (!phys_user) panic(UmapErrMsg);
if (odd_byte) {
phys_copy(phys_2bytes + 1, phys_user, (phys_bytes) 1);
count--;
bytes--;
phys_user++;
odd_byte = 0;
if (!bytes) continue;
}
ecount = bytes & ~1;
if (ecount != 0) {
phys_insw(dep->de_data_port, phys_user, ecount);
count -= ecount;
bytes -= ecount;
phys_user += ecount;
}
if (bytes) {
*(u16_t *) two_bytes = in_word(dep->de_data_port);
phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);
count--;
bytes--;
phys_user++;
odd_byte = 1;
}
}
return;
}
#endif /* PIO16 == 1 */
#endif /* ENABLE_DP8390 */
/** end 8390.c **/

View File

@ -5,6 +5,6 @@ SRCS= 3c501.c 3c509.c 3c503.c ne.c wd.c 8390.c devio.c netbuff.c dp.c
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
CPPFLAGS+= -Ddebug=0
CPPFLAGS+= -DVERBOSE=0
.include <minix.service.mk>

View File

@ -3,11 +3,12 @@
**
** Author: Giovanni Falzoni <gfalzoni@inwind.it>
**
** This file contains the routines for readind/writing
** This file contains the routines for reading/writing
** from/to the device registers.
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -18,11 +19,10 @@ static void warning(const char *type, int err)
{
printf("Warning: eth#0 sys_%s failed (%d)\n", type, err);
return;
}
/*
** Name: unsigned int inb(unsigned short int port);
** Name: inb
** Function: Reads a byte from specified i/o port.
*/
unsigned int inb(unsigned short port)
@ -35,7 +35,7 @@ unsigned int inb(unsigned short port)
}
/*
** Name: unsigned int inw(unsigned short int port);
** Name: inw
** Function: Reads a word from specified i/o port.
*/
unsigned int inw(unsigned short port)
@ -48,22 +48,31 @@ unsigned int inw(unsigned short port)
}
/*
** Name: unsigned int insb(unsigned short int port, int proc_nr, void *buffer, int count);
** Function: Reads a sequence of bytes from specified i/o port to user space buffer.
** Name: insb
** Function: Reads a sequence of bytes from an i/o port.
*/
void insb(unsigned short int port, endpoint_t proc_nr,
void *buffer, int count)
void insb(unsigned short int port, void *buffer, int count)
{
int rc;
if ((rc = sys_insb(port, proc_nr, buffer, count)) != OK)
if ((rc = sys_insb(port, SELF, buffer, count)) != OK)
warning("insb", rc);
return;
}
/*
** Name: insw
** Function: Reads a sequence of words from an i/o port.
*/
void insw(unsigned short int port, void *buffer, int count)
{
int rc;
if ((rc = sys_insw(port, SELF, buffer, count)) != OK)
warning("insw", rc);
}
/*
** Name: void outb(unsigned short int port, unsigned long value);
** Name: outb
** Function: Writes a byte to specified i/o port.
*/
void outb(unsigned short port, unsigned long value)
@ -71,11 +80,10 @@ void outb(unsigned short port, unsigned long value)
int rc;
if ((rc = sys_outb(port, value)) != OK) warning("outb", rc);
return;
}
/*
** Name: void outw(unsigned short int port, unsigned long value);
** Name: outw
** Function: Writes a word to specified i/o port.
*/
void outw(unsigned short port, unsigned long value)
@ -83,20 +91,18 @@ void outw(unsigned short port, unsigned long value)
int rc;
if ((rc = sys_outw(port, value)) != OK) warning("outw", rc);
return;
}
/*
** Name: void outsb(unsigned short int port, int proc_nr, void *buffer, int count);
** Function: Writes a sequence of bytes from user space to specified i/o port.
** Name: outsb
** Function: Writes a sequence of bytes to an i/o port.
*/
void outsb(unsigned short port, endpoint_t proc_nr, void *buffer, int count)
void outsb(unsigned short port, void *buffer, int count)
{
int rc;
if ((rc = sys_outsb(port, proc_nr, buffer, count)) != OK)
if ((rc = sys_outsb(port, SELF, buffer, count)) != OK)
warning("outsb", rc);
return;
}
#else

View File

@ -14,9 +14,10 @@
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <minix/endpoint.h>
#include <minix/ds.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <sys/mman.h>
#include <assert.h>
#include "dp.h"
@ -24,7 +25,6 @@
** Local data
*/
static dpeth_t de_state;
static int de_instance;
typedef struct dp_conf { /* Configuration description structure */
port_t dpc_port;
@ -41,90 +41,43 @@ static dp_conf_t dp_conf[DP_CONF_NR] = {
{ 0x000, 0, 0x00000, },
};
static char CopyErrMsg[] = "unable to read/write user data";
static char RecvErrMsg[] = "netdriver_receive failed";
static char SendErrMsg[] = "send failed";
static char SizeErrMsg[] = "illegal packet size";
static char TypeErrMsg[] = "illegal message type";
static char DevName[] = "eth#?";
static int do_init(unsigned int instance, ether_addr_t *addr);
static void do_stop(void);
static void do_mode(unsigned int mode);
static int do_send(struct netdriver_data *data, size_t size);
static ssize_t do_recv(struct netdriver_data *data, size_t max);
static void do_stat(eth_stat_t *stat);
static void do_intr(unsigned int mask);
static void do_other(const message *m_ptr, int ipc_status);
static const struct netdriver dp_table = {
.ndr_init = do_init,
.ndr_stop = do_stop,
.ndr_mode = do_mode,
.ndr_recv = do_recv,
.ndr_send = do_send,
.ndr_stat = do_stat,
.ndr_intr = do_intr,
.ndr_other = do_other
};
/*
** Name: void reply(dpeth_t *dep, int err, int m_type)
** Function: Fills a reply message and sends it.
*/
static void reply(dpeth_t * dep)
{
message reply;
int r, flags;
flags = DL_NOFLAGS;
if (dep->de_flags & DEF_ACK_SEND) flags |= DL_PACK_SEND;
if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY;
reply.m_netdrv_net_dl_task.flags = flags;
reply.m_netdrv_net_dl_task.count = dep->de_read_s;
DEBUG(printf("\t reply %d (%lx)\n", reply.m_type,
reply.m_netdrv_net_dl_task.flags));
if ((r = ipc_send(dep->de_client, &reply)) != OK)
panic(SendErrMsg, r);
dep->de_read_s = 0;
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
return;
}
/*
** Name: void dp_confaddr(dpeth_t *dep)
** Function: Checks environment for a User defined ethernet address.
*/
static void dp_confaddr(dpeth_t * dep)
{
static char ea_fmt[] = "x:x:x:x:x:x";
char ea_key[16];
int ix;
long val;
strlcpy(ea_key, "DPETH0_EA", sizeof(ea_key));
ea_key[5] += de_instance;
for (ix = 0; ix < SA_ADDR_LEN; ix++) {
val = dep->de_address.ea_addr[ix];
if (env_parse(ea_key, ea_fmt, ix, &val, 0x00L, 0xFFL) != EP_SET)
break;
dep->de_address.ea_addr[ix] = val;
}
if (ix != 0 && ix != SA_ADDR_LEN)
/* It's all or nothing, force a panic */
env_parse(ea_key, "?", 0, &val, 0L, 0L);
return;
}
/*
** Name: void update_conf(dpeth_t *dep, dp_conf_t *dcp)
** Name: update_conf
** Function: Gets the default settings from 'dp_conf' table and
** modifies them from the environment.
*/
static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
static void update_conf(dpeth_t * dep, const dp_conf_t * dcp,
unsigned int instance)
{
static char dpc_fmt[] = "x:d:x";
char ec_key[16];
long val;
strlcpy(ec_key, "DPETH0", sizeof(ec_key));
ec_key[5] += de_instance;
ec_key[5] += instance;
dep->de_mode = DEM_SINK;
val = dcp->dpc_port; /* Get I/O port address */
switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
case EP_ON:
case EP_SET: dep->de_mode = DEM_ENABLED; break;
}
env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL);
dep->de_base_port = val;
val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */
@ -134,15 +87,13 @@ static void update_conf(dpeth_t * dep, const dp_conf_t * dcp)
val = dcp->dpc_mem; /* Get shared memory address */
env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX);
dep->de_linmem = val;
return;
}
/*
** Name: void do_dump(message *mp)
** Name: do_dump
** Function: Displays statistics on screen (SFx key from console)
*/
static void do_dump(const message *mp)
static void do_dump(void)
{
dpeth_t *dep;
@ -150,14 +101,12 @@ static void do_dump(const message *mp)
printf("\n\n");
if (dep->de_mode == DEM_DISABLED) return;
printf("%s statistics:\t\t", dep->de_name);
/* Network interface status */
printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);
printf("Status: 0x%04x\n\n", dep->de_flags);
(*dep->de_dumpstatsf) (dep);
(*dep->de_dumpstatsf)(dep);
/* Transmitted/received bytes */
printf("Tx bytes:%10ld\t", dep->bytes_Tx);
@ -178,40 +127,31 @@ static void do_dump(const message *mp)
/* Transmit collisions/receive CRC errors */
printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr);
return;
}
/*
** Name: void get_userdata_s(int user_proc, vir_bytes user_addr, int count, void *loc_addr)
** Function: Copies data from user area.
*/
static void get_userdata_s(int user_proc, cp_grant_id_t grant,
vir_bytes offset, int count, void *loc_addr)
{
int rc;
vir_bytes len;
len = (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_t);
if ((rc = sys_safecopyfrom(user_proc, grant, 0, (vir_bytes)loc_addr, len)) != OK)
panic(CopyErrMsg, rc);
return;
}
/*
** Name: void do_first_init(dpeth_t *dep, dp_conf_t *dcp);
** Name: do_first_init
** Function: Init action to setup task
*/
static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp)
{
dep->de_linmem = 0xFFFF0000;
dep->de_linmem = 0xFFFF0000; /* FIXME: this overrides update_conf, why? */
/* Make sure statisics are cleared */
memset((void *) &(dep->de_stat), 0, sizeof(eth_stat_t));
memset(&dep->de_stat, 0, sizeof(dep->de_stat));
/* Device specific initialization */
(*dep->de_initf) (dep);
(*dep->de_initf)(dep);
/* Map memory if requested */
if (dep->de_linmem != 0) {
assert(dep->de_ramsize > 0);
dep->de_locmem =
vm_map_phys(SELF, (void *)dep->de_linmem, dep->de_ramsize);
if (dep->de_locmem == MAP_FAILED)
panic("unable to map memory");
}
/* Set the interrupt handler policy. Request interrupts not to be reenabled
* automatically. Return the IRQ line number when an interrupt occurs.
@ -219,402 +159,160 @@ static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp)
dep->de_hook = dep->de_irq;
if (sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook) != OK)
panic("unable to set IRQ policy");
dep->de_int_pending = FALSE;
sys_irqenable(&dep->de_hook);
return;
}
/*
** Name: void do_init(message *mp)
** Name: do_init
** Function: Checks for hardware presence.
** Provides initialization of hardware and data structures
** Initialize hardware and data structures.
** Return status and ethernet address.
*/
static void do_init(const message * mp)
static int do_init(unsigned int instance, ether_addr_t *addr)
{
dpeth_t *dep;
dp_conf_t *dcp;
message reply_mess;
int r, confnr;
int confnr, fkeys, sfkeys;
dep = &de_state;
strlcpy(dep->de_name, "dpeth#?", sizeof(dep->de_name));
dep->de_name[4] = '0' + instance;
/* Pick a default configuration for this instance. */
confnr = MIN(de_instance, DP_CONF_NR-1);
confnr = MIN(instance, DP_CONF_NR-1);
dcp = &dp_conf[confnr];
strlcpy(dep->de_name, DevName, sizeof(dep->de_name));
dep->de_name[4] = '0' + de_instance;
if (dep->de_mode == DEM_DISABLED) {
update_conf(dep, dcp, instance);
update_conf(dep, dcp); /* First time thru */
if (dep->de_mode == DEM_ENABLED &&
!el1_probe(dep) && /* Probe for 3c501 */
!wdeth_probe(dep) && /* Probe for WD80x3 */
!ne_probe(dep) && /* Probe for NEx000 */
!el2_probe(dep) && /* Probe for 3c503 */
!el3_probe(dep)) { /* Probe for 3c509 */
printf("%s: warning no ethernet card found at 0x%04X\n",
dep->de_name, dep->de_base_port);
dep->de_mode = DEM_DISABLED;
}
if (!el1_probe(dep) && /* Probe for 3c501 */
!wdeth_probe(dep) && /* Probe for WD80x3 */
!ne_probe(dep) && /* Probe for NEx000 */
!el2_probe(dep) && /* Probe for 3c503 */
!el3_probe(dep)) { /* Probe for 3c509 */
printf("%s: warning no ethernet card found at 0x%04X\n",
dep->de_name, dep->de_base_port);
return ENXIO;
}
r = OK;
do_first_init(dep, dcp);
/* 'de_mode' may change if probe routines fail, test again */
switch (dep->de_mode) {
/* Request function key for debug dumps */
fkeys = sfkeys = 0; bit_set(sfkeys, 7);
if (fkey_map(&fkeys, &sfkeys) != OK)
printf("%s: couldn't bind Shift+F7 key (%d)\n", dep->de_name, errno);
case DEM_DISABLED:
/* Device is configured OFF or hardware probe failed */
r = ENXIO;
break;
case DEM_ENABLED:
/* Device is present and probed */
if (dep->de_flags == DEF_EMPTY) {
/* These actions only the first time */
do_first_init(dep, dcp);
dep->de_flags |= DEF_ENABLED;
}
dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ)
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ)
dep->de_flags |= DEF_MULTI;
if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ)
dep->de_flags |= DEF_BROAD;
(*dep->de_flagsf) (dep);
break;
case DEM_SINK:
/* Device not present (sink mode) */
memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
dp_confaddr(dep); /* Station address from env. */
break;
default: break;
}
reply_mess.m_type = DL_CONF_REPLY;
reply_mess.m_netdrv_net_dl_conf.stat = r;
if (r == OK)
memcpy(reply_mess.m_netdrv_net_dl_conf.hw_addr, dep->de_address.ea_addr,
sizeof(reply_mess.m_netdrv_net_dl_conf.hw_addr));
DEBUG(printf("\t reply %d\n", reply_mess.m_type));
if (ipc_send(mp->m_source, &reply_mess) != OK) /* Can't send */
panic(SendErrMsg, mp->m_source);
return;
memcpy(addr, dep->de_address.ea_addr, sizeof(*addr));
return OK;
}
/*
** Name: void dp_next_iovec(iovec_dat_t *iovp)
** Function: Retrieves data from next iovec element.
** Name: de_mode
** Function: Sets packet receipt mode.
*/
void dp_next_iovec(iovec_dat_s_t * iovp)
static void do_mode(unsigned int mode)
{
iovp->iod_iovec_s -= IOVEC_NR;
iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant, iovp->iod_iovec_offset,
iovp->iod_iovec_s, iovp->iod_iovec);
return;
}
/*
** Name: int calc_iovec_size(iovec_dat_t *iovp)
** Function: Compute the size of a request.
*/
static int calc_iovec_size(iovec_dat_s_t * iovp)
{
int size, ix;
size = ix = 0;
do {
size += iovp->iod_iovec[ix].iov_size;
if (++ix >= IOVEC_NR) {
dp_next_iovec(iovp);
ix = 0;
}
/* Till all vectors added */
} while (ix < iovp->iod_iovec_s);
return size;
}
/*
** Name: void do_vwrite_s(message *mp)
** Function:
*/
static void do_vwrite_s(const message * mp)
{
int size;
dpeth_t *dep;
dep = &de_state;
dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
if (dep->de_flags & DEF_SENDING) /* Is sending in progress? */
panic("send already in progress ");
dep->de_write_iovec.iod_proc_nr = mp->m_source;
get_userdata_s(mp->m_source, mp->m_net_netdrv_dl_writev_s.grant, 0,
mp->m_net_netdrv_dl_writev_s.count, dep->de_write_iovec.iod_iovec);
dep->de_write_iovec.iod_iovec_s = mp->m_net_netdrv_dl_writev_s.count;
dep->de_write_iovec.iod_grant = mp->m_net_netdrv_dl_writev_s.grant;
dep->de_write_iovec.iod_iovec_offset = 0;
size = calc_iovec_size(&dep->de_write_iovec);
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
panic(SizeErrMsg, size);
dep->de_flags |= DEF_SENDING;
(*dep->de_sendf) (dep, FALSE, size);
} else if (dep->de_mode == DEM_SINK)
dep->de_flags |= DEF_ACK_SEND;
reply(dep);
return;
dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
if (mode & NDEV_PROMISC)
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
if (mode & NDEV_MULTI)
dep->de_flags |= DEF_MULTI;
if (mode & NDEV_BROAD)
dep->de_flags |= DEF_BROAD;
(*dep->de_flagsf)(dep);
}
/*
** Name: void do_vread_s(message *mp, int vectored)
** Function:
** Name: do_send
** Function: Send a packet, if possible.
*/
static void do_vread_s(const message * mp)
static int do_send(struct netdriver_data *data, size_t size)
{
int size;
dpeth_t *dep;
dep = &de_state;
dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
if (dep->de_flags & DEF_READING) /* Reading in progress */
panic("read already in progress");
dep->de_read_iovec.iod_proc_nr = mp->m_source;
get_userdata_s(mp->m_source, mp->m_net_netdrv_dl_readv_s.grant, 0,
mp->m_net_netdrv_dl_readv_s.count, dep->de_read_iovec.iod_iovec);
dep->de_read_iovec.iod_iovec_s = mp->m_net_netdrv_dl_readv_s.count;
dep->de_read_iovec.iod_grant = mp->m_net_netdrv_dl_readv_s.grant;
dep->de_read_iovec.iod_iovec_offset = 0;
size = calc_iovec_size(&dep->de_read_iovec);
if (size < ETH_MAX_PACK_SIZE) panic(SizeErrMsg, size);
dep->de_flags |= DEF_READING;
(*dep->de_recvf) (dep, FALSE, size);
#if 0
if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED))
/* The chip is stopped, and all arrived packets delivered */
(*dep->de_resetf) (dep);
dep->de_flags &= NOT(DEF_STOPPED);
#endif
}
reply(dep);
return;
return (*dep->de_sendf)(dep, data, size);
}
/*
** Name: void do_getstat_s(message *mp)
** Name: do_recv
** Function: Receive a packet, if possible.
*/
static ssize_t do_recv(struct netdriver_data *data, size_t max)
{
dpeth_t *dep;
dep = &de_state;
return (*dep->de_recvf)(dep, data, max);
}
/*
** Name: do_stat
** Function: Reports device statistics.
*/
static void do_getstat_s(const message * mp)
static void do_stat(eth_stat_t *stat)
{
int rc;
dpeth_t *dep;
message reply_mess;
dep = &de_state;
if (dep->de_mode == DEM_ENABLED) (*dep->de_getstatsf) (dep);
if ((rc = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0,
(vir_bytes)&dep->de_stat,
(vir_bytes)sizeof(dep->de_stat))) != OK)
panic(CopyErrMsg, rc);
reply_mess.m_type = DL_STAT_REPLY;
rc= ipc_send(mp->m_source, &reply_mess);
if (rc != OK)
panic("do_getname: ipc_send failed: %d", rc);
return;
memcpy(stat, &de_state.de_stat, sizeof(*stat));
}
/*
** Name: void dp_stop(dpeth_t *dep)
** Name: do_stop
** Function: Stops network interface.
*/
static void dp_stop(dpeth_t * dep)
static void do_stop(void)
{
dpeth_t *dep;
if (dep->de_mode == DEM_ENABLED && (dep->de_flags & DEF_ENABLED)) {
dep = &de_state;
/* Stop device */
(dep->de_stopf) (dep);
dep->de_flags = DEF_EMPTY;
dep->de_mode = DEM_DISABLED;
}
return;
/* Stop device */
(dep->de_stopf)(dep);
}
static void do_watchdog(const void *UNUSED(message))
{
DEBUG(printf("\t no reply"));
return;
}
static void handle_hw_intr(void)
/*
** Name: do_intr
** Function; Handles interrupts.
*/
static void do_intr(unsigned int __unused mask)
{
dpeth_t *dep;
dep = &de_state;
/* If device is enabled and interrupt pending */
if (dep->de_mode == DEM_ENABLED) {
dep->de_int_pending = TRUE;
(*dep->de_interruptf) (dep);
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
reply(dep);
dep->de_int_pending = FALSE;
sys_irqenable(&dep->de_hook);
}
(*dep->de_interruptf)(dep);
sys_irqenable(&dep->de_hook);
}
/* SEF functions and variables. */
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
static void sef_cb_signal_handler(int signo);
/*
** Name: do_other
** Function: Processes miscellaneous messages.
*/
static void do_other(const message *m_ptr, int ipc_status)
{
if (is_ipc_notify(ipc_status) && m_ptr->m_source == TTY_PROC_NR)
do_dump();
}
/*
** Name: int dpeth_task(void)
** Name: main
** Function: Main entry for dp task
*/
int main(int argc, char **argv)
{
message m;
int ipc_status;
int rc;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
while (TRUE) {
if ((rc = netdriver_receive(ANY, &m, &ipc_status)) != OK){
panic(RecvErrMsg, rc);
}
netdriver_task(&dp_table);
DEBUG(printf("eth: got message %d, ", m.m_type));
if (is_ipc_notify(ipc_status)) {
switch(_ENDPOINT_P(m.m_source)) {
case CLOCK:
/* to be defined */
do_watchdog(&m);
break;
case HARDWARE:
/* Interrupt from device */
handle_hw_intr();
break;
case TTY_PROC_NR:
/* Function key pressed */
do_dump(&m);
break;
default:
/* Invalid message type */
panic(TypeErrMsg, m.m_type);
break;
}
/* message processed, get another one */
continue;
}
switch (m.m_type) {
case DL_WRITEV_S: /* Write message to device */
do_vwrite_s(&m);
break;
case DL_READV_S: /* Read message from device */
do_vread_s(&m);
break;
case DL_CONF: /* Initialize device */
do_init(&m);
break;
case DL_GETSTAT_S: /* Get device statistics */
do_getstat_s(&m);
break;
default: /* Invalid message type */
panic(TypeErrMsg, m.m_type);
break;
}
}
return OK; /* Never reached, but keeps compiler happy */
return 0;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_lu(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_fresh);
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the dpeth driver. */
int fkeys, sfkeys;
long v;
/* Request function key for debug dumps */
fkeys = sfkeys = 0; bit_set(sfkeys, 8);
if ((fkey_map(&fkeys, &sfkeys)) != OK)
printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);
v = 0;
(void) env_parse("instance", "d", 0, &v, 0, 255);
de_instance = (int) v;
/* Announce we are up! */
netdriver_announce();
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
static void sef_cb_signal_handler(int signo)
{
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
if (de_state.de_mode == DEM_ENABLED)
dp_stop(&de_state);
exit(0);
}
/** dp.c **/

View File

@ -51,7 +51,7 @@
#define NOT(x) (~(x))
#if debug == 1
#if VERBOSE == 1
# define DEBUG(statm) statm
#else
# define DEBUG(statm)
@ -70,26 +70,19 @@ typedef struct _buff_t { /* Receive/Transmit buffer header */
} buff_t;
struct dpeth;
struct iovec_dat;
typedef void (*dp_eth_t) (struct dpeth *);
typedef void (*dp_send_recv_t) (struct dpeth *, int, int);
typedef void (*dp_eth_t)(struct dpeth *);
typedef int (*dp_send_t)(struct dpeth *, struct netdriver_data *, size_t);
typedef ssize_t (*dp_recv_t)(struct dpeth *, struct netdriver_data *, size_t);
#if ENABLE_DP8390 == 1
typedef void (*dp_user2nicf_t) (struct dpeth *, int, int);
typedef void (*dp_nic2userf_t) (struct dpeth *, int, int);
typedef void (*dp_getblock_t) (struct dpeth *, u16_t, int, void *);
typedef void (*dp_user2nicf_t)(struct dpeth *, int, struct netdriver_data *,
size_t);
typedef void (*dp_nic2userf_t)(struct dpeth *, int, struct netdriver_data *,
size_t);
typedef void (*dp_getblock_t)(struct dpeth *, u16_t, int, void *);
#endif
#define SENDQ_NR 2 /* Size of the send queue */
#define IOVEC_NR 16 /* Number of IOVEC entries at a time */
typedef struct iovec_dat_s {
iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
endpoint_t iod_proc_nr;
cp_grant_id_t iod_grant;
vir_bytes iod_iovec_offset;
} iovec_dat_s_t;
typedef struct dpeth {
/* The de_base_port field is the starting point of the probe. The
@ -109,7 +102,6 @@ typedef struct dpeth {
port_t de_data_port; /* For boards using Prog. I/O for xmit/recv */
int de_irq;
int de_int_pending;
int de_hook; /* interrupt hook at kernel */
char de_name[8];
@ -117,7 +109,7 @@ typedef struct dpeth {
#define DEI_DEFAULT 0x8000
phys_bytes de_linmem; /* For boards using shared memory */
vir_bytes de_memoffs;
char *de_locmem; /* Locally mapped (virtual) address */
int de_ramsize; /* Size of on board memory */
int de_offset_page; /* Offset of shared memory page */
@ -129,8 +121,8 @@ typedef struct dpeth {
dp_eth_t de_getstatsf;
dp_eth_t de_dumpstatsf;
dp_eth_t de_interruptf;
dp_send_recv_t de_recvf;
dp_send_recv_t de_sendf;
dp_recv_t de_recvf;
dp_send_t de_sendf;
ether_addr_t de_address; /* Ethernet Address */
eth_stat_t de_stat; /* Ethernet Statistics */
@ -141,35 +133,12 @@ typedef struct dpeth {
int de_flags; /* Send/Receive mode (Configuration) */
#define DEF_EMPTY 0x0000
#define DEF_READING 0x0001
#define DEF_RECV_BUSY 0x0002
#define DEF_ACK_RECV 0x0004
#define DEF_SENDING 0x0010
#define DEF_XMIT_BUSY 0x0020
#define DEF_ACK_SEND 0x0040
#define DEF_PROMISC 0x0100
#define DEF_MULTI 0x0200
#define DEF_BROAD 0x0400
#define DEF_ENABLED 0x2000
#define DEF_STOPPED 0x4000
#define DEF_EMPTY 0x00
#define DEF_XMIT_BUSY 0x01
#define DEF_PROMISC 0x02
#define DEF_MULTI 0x04
#define DEF_BROAD 0x08
int de_mode; /* Status of the Interface */
#define DEM_DISABLED 0x0000
#define DEM_SINK 0x0001
#define DEM_ENABLED 0x0002
/* Temporary storage for RECV/SEND requests */
iovec_dat_s_t de_read_iovec;
iovec_dat_s_t de_write_iovec;
vir_bytes de_read_s;
vir_bytes de_send_s;
int de_client;
/*
message de_sendmsg;
iovec_dat_t de_tmp_iovec;
*/
#if ENABLE_DP8390 == 1
/* For use by NS DP8390 driver */
port_t de_dp8390_port;
@ -203,8 +172,6 @@ typedef struct dpeth {
/* For use by 3Com Etherlink (3c501 and 3c509) driver */
buff_t *de_recvq_head;
buff_t *de_recvq_tail;
buff_t *de_xmitq_head;
buff_t *de_xmitq_tail;
u16_t de_recv_mode;
clock_t de_xmit_start;
#endif
@ -215,29 +182,23 @@ typedef struct dpeth {
* Function definitions
*/
/* dp.c */
void dp_next_iovec(iovec_dat_s_t * iovp);
/* devio.c */
#if defined USE_IOPL
#include <machine/portio.h>
#else
unsigned int inb(unsigned short int);
unsigned int inw(unsigned short int);
void insb(unsigned short int, endpoint_t, void *, int);
void insw(unsigned short int, int, void *, int);
void insb(unsigned short int, void *, int);
void insw(unsigned short int, void *, int);
void outb(unsigned short int, unsigned long);
void outw(unsigned short int, unsigned long);
void outsb(unsigned short int, endpoint_t, void *, int);
void outsw(unsigned short int, int, void *, int);
void outsb(unsigned short int, void *, int);
#endif
/* netbuff.c */
void *alloc_buff(dpeth_t *, int);
void free_buff(dpeth_t *, void *);
void init_buff(dpeth_t *, buff_t **);
void mem2user(dpeth_t *, buff_t *);
void user2mem(dpeth_t *, buff_t *);
/* 3c501.c */
#if ENABLE_3C501 == 1
@ -274,8 +235,4 @@ int wdeth_probe(dpeth_t * dep);
#define wdeth_probe(x) (0)
#endif
#define lock() (++dep->de_int_pending,sys_irqdisable(&dep->de_hook))
#define unlock() do{int i=(--dep->de_int_pending)?0:sys_irqenable(&dep->de_hook);(void) i;}while(0)
#define milli_delay(t) tickdelay(1)
/** dp.h **/

View File

@ -13,6 +13,7 @@
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -23,7 +24,7 @@
#include "ne.h"
/*
** Name: void ne_reset(dpeth_t * dep);
** Name: ne_reset
** Function: Resets the board and checks if reset cycle completes
*/
static int ne_reset(dpeth_t * dep)
@ -34,13 +35,13 @@ static int ne_reset(dpeth_t * dep)
outb_ne(dep, NE_RESET, inb_ne(dep, NE_RESET));
do {
if (++count > 10) return FALSE; /* 20 mSecs. timeout */
milli_delay(2);
micro_delay(2000);
} while ((inb_ne(dep, DP_ISR) & ISR_RST) == 0);
return TRUE;
}
/*
** Name: void ne_close(dpeth_t * dep);
** Name: ne_close
** Function: Stops the board by resetting it and masking interrupts.
*/
static void ne_close(dpeth_t * dep)
@ -49,11 +50,10 @@ static void ne_close(dpeth_t * dep)
(void)ne_reset(dep);
outb_ne(dep, DP_ISR, 0xFF);
sys_irqdisable(&dep->de_hook);
return;
}
/*
** Name: void ne_init(dpeth_t * dep);
** Name: ne_init
** Function: Initialize the board making it ready to work.
*/
static void ne_init(dpeth_t * dep)
@ -90,12 +90,12 @@ static void ne_init(dpeth_t * dep)
dep->de_ramsize / 1024,
dep->de_base_port, dep->de_irq);
for (ix = 0; ix < SA_ADDR_LEN; ix += 1)
printf("%02X%c", dep->de_address.ea_addr[ix], ix < SA_ADDR_LEN - 1 ? ':' : '\n');
return;
printf("%02X%c", dep->de_address.ea_addr[ix],
ix < SA_ADDR_LEN - 1 ? ':' : '\n');
}
/*
** Name: int ne_probe(dpeth_t * dep);
** Name: ne_probe
** Function: Probe for the presence of a NE*000 card by testing
** whether the board is reachable through the dp8390.
** Note that the NE1000 is an 8bit card and has a memory

View File

@ -8,6 +8,7 @@
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -18,7 +19,7 @@ static m_hdr_t *allocptr = NULL;
static char tx_rx_buff[8192];
/*
** Name: void *alloc_buff(dpeth_t *dep, int size)
** Name: alloc_buff
** Function: Allocates a buffer from the common pool.
*/
void *alloc_buff(dpeth_t *dep, int size)
@ -26,7 +27,6 @@ void *alloc_buff(dpeth_t *dep, int size)
m_hdr_t *ptr, *wrk = allocptr;
int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1;
lock();
for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) {
if (ptr->size >= units) {
/* Memory is available, carve requested size from pool */
@ -39,24 +39,22 @@ void *alloc_buff(dpeth_t *dep, int size)
ptr->size = units;
}
allocptr = wrk;
unlock();
return ptr + 1;
}
if (ptr == allocptr) break;
}
unlock();
return NULL; /* No memory available */
}
/*
** Name: void free_buff(dpeth_t *dep, void *blk)
** Name: free_buff
** Function: Returns a buffer to the common pool.
*/
void free_buff(dpeth_t *dep, void *blk)
{
m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1;
lock(); /* Scan linked list for the correct place */
/* Scan linked list for the correct place */
for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next)
if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break;
@ -72,12 +70,10 @@ void free_buff(dpeth_t *dep, void *blk)
} else
wrk->next = ptr;
allocptr = wrk; /* Point allocptr to block just released */
unlock();
return;
}
/*
** Name: void init_buff(dpeth_t *dep, buff_t **tx_buff)
** Name: init_buff
** Function: Initalizes driver data structures.
*/
void init_buff(dpeth_t *dep, buff_t **tx_buff)
@ -98,69 +94,6 @@ void init_buff(dpeth_t *dep, buff_t **tx_buff)
(*tx_buff)->size = 0;
}
}
return; /* Done */
}
/*
** Name: void mem2user(dpeth_t *dep, buff_t *rxbuff);
** Function: Copies a packet from local buffer to user area.
*/
void mem2user(dpeth_t *dep, buff_t *rxbuff)
{
int bytes, ix = 0;
iovec_dat_s_t *iovp = &dep->de_read_iovec;
int r, pktsize = rxbuff->size;
char *buffer = rxbuff->buffer;
do { /* Reads chuncks of packet into user buffers */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes > pktsize) bytes = pktsize;
/* Reads from Rx buffer to user area */
r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
(vir_bytes)buffer, bytes);
if (r != OK)
panic("mem2user: sys_safecopyto failed: %d", r);
buffer += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
}
/*
** Name: void user2mem(dpeth_t *dep, buff_t *txbuff)
** Function: Copies a packet from user area to local buffer.
*/
void user2mem(dpeth_t *dep, buff_t *txbuff)
{
int bytes, ix = 0;
iovec_dat_s_t *iovp = &dep->de_write_iovec;
int r, pktsize = txbuff->size;
char *buffer = txbuff->buffer;
do { /* Reads chuncks of packet from user buffers */
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes > pktsize) bytes = pktsize;
r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
0, (vir_bytes)buffer, bytes);
if (r != OK)
panic("user2mem: sys_safecopyfrom failed: %d", r);
buffer += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
dp_next_iovec(iovp);
ix = 0;
}
/* Till packet done */
} while ((pktsize -= bytes) > 0);
return;
}
#endif /* HAVE_BUFFERS */

View File

@ -13,6 +13,7 @@
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include "dp.h"
@ -43,8 +44,7 @@ static int we_ultra(dpeth_t * dep);
/*===========================================================================*
* wdeth_probe *
*===========================================================================*/
int wdeth_probe(dep)
dpeth_t *dep;
int wdeth_probe(dpeth_t *dep)
{
int sum;
@ -67,8 +67,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_init *
*===========================================================================*/
static void we_init(dep)
dpeth_t *dep;
static void we_init(dpeth_t *dep)
{
int i, int_indx, int_nr;
int tlb, rambit, revision;
@ -212,8 +211,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_stop *
*===========================================================================*/
static void we_stop(dep)
dpeth_t *dep;
static void we_stop(dpeth_t *dep)
{
if (dep->de_16bit) outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_LAN16E);
@ -226,8 +224,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_aliasing *
*===========================================================================*/
static int we_aliasing(dep)
dpeth_t *dep;
static int we_aliasing(dpeth_t *dep)
{
/* Determine whether wd8003 hardware performs register aliasing. This implies
* an old WD8003E board. */
@ -243,8 +240,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_interface_chip *
*===========================================================================*/
static int we_interface_chip(dep)
dpeth_t *dep;
static int we_interface_chip(dpeth_t *dep)
{
/* Determine if the board has an interface chip. */
@ -258,8 +254,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_16bitboard *
*===========================================================================*/
static int we_16bitboard(dep)
dpeth_t *dep;
static int we_16bitboard(dpeth_t *dep)
{
/* Determine whether the board is capable of doing 16 bit memory moves.
* If the 16 bit enable bit is unchangable by software we'll assume an
@ -286,8 +281,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_16bitslot *
*===========================================================================*/
static int we_16bitslot(dep)
dpeth_t *dep;
static int we_16bitslot(dpeth_t *dep)
{
/* Determine if the 16 bit board in plugged into a 16 bit slot. */
@ -297,8 +291,7 @@ dpeth_t *dep;
/*===========================================================================*
* we_ultra *
*===========================================================================*/
static int we_ultra(dep)
dpeth_t *dep;
static int we_ultra(dpeth_t *dep)
{
/* Determine if we has an '790 chip. */
u8_t tlb;

View File

@ -6,7 +6,7 @@ FILES=$(PROG).conf
FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
.include <minix.service.mk>

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@ service e1000
;
pci device 8086:100e;
pci device 8086:100f;
pci device 8086:101e;
pci device 8086:107c;
pci device 8086:10cd;
pci device 8086:10d3;

View File

@ -18,13 +18,6 @@
#ifndef __E1000_H
#define __E1000_H
#include <minix/drivers.h>
#include <stdlib.h>
#include <net/hton.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <machine/pci.h>
#include <minix/ds.h>
#include "e1000_hw.h"
/**
@ -38,14 +31,11 @@
/** Number of transmit descriptors per card. */
#define E1000_TXDESC_NR 256
/** Number of I/O vectors to use. */
#define E1000_IOVEC_NR 16
/** Size of each I/O buffer per descriptor. */
#define E1000_IOBUF_SIZE 2048
/** Debug verbosity. */
#define E1000_VERBOSE 1
#define E1000_VERBOSE 0
/** MAC address override variable. */
#define E1000_ENVVAR "E1000ETH"
@ -59,24 +49,6 @@
* @{
*/
/** Card has been detected on the PCI bus. */
#define E1000_DETECTED (1 << 0)
/** Card is enabled. */
#define E1000_ENABLED (1 << 1)
/** Client has requested to receive packets. */
#define E1000_READING (1 << 2)
/** Client has requested to write packets. */
#define E1000_WRITING (1 << 3)
/** Received some packets on the card. */
#define E1000_RECEIVED (1 << 4)
/** Transmitted some packets on the card. */
#define E1000_TRANSMIT (1 << 5)
/**
* @}
*/
@ -141,36 +113,25 @@
typedef struct e1000
{
char name[8]; /**< String containing the device name. */
int status; /**< Describes the card's current state. */
int irq; /**< Interrupt Request Vector. */
int irq_hook; /**< Interrupt Request Vector Hook. */
int revision; /**< Hardware Revision Number. */
u8_t *regs; /**< Memory mapped hardware registers. */
u8_t *flash; /**< Optional flash memory. */
u32_t flash_base_addr; /**< Flash base address. */
ether_addr_t address; /**< Ethernet MAC address. */
u16_t (*eeprom_read)(void *, int reg); /**< Function to read
the EEPROM. */
u16_t (*eeprom_read)(struct e1000 *, int reg);
/**< Function to read the EEPROM. */
int eeprom_done_bit; /**< Offset of the EERD.DONE bit. */
int eeprom_addr_off; /**< Offset of the EERD.ADDR field. */
e1000_rx_desc_t *rx_desc; /**< Receive Descriptor table. */
phys_bytes rx_desc_p; /**< Physical Receive Descriptor Address. */
int rx_desc_count; /**< Number of Receive Descriptors. */
char *rx_buffer; /**< Receive buffer returned by malloc(). */
int rx_buffer_size; /**< Size of the receive buffer. */
e1000_tx_desc_t *tx_desc; /**< Transmit Descriptor table. */
phys_bytes tx_desc_p; /**< Physical Transmit Descriptor Address. */
int tx_desc_count; /**< Number of Transmit Descriptors. */
char *tx_buffer; /**< Transmit buffer returned by malloc(). */
int tx_buffer_size; /**< Size of the transmit buffer. */
int client; /**< Process ID being served by e1000. */
message rx_message; /**< Read message received from client. */
message tx_message; /**< Write message received from client. */
size_t rx_size; /**< Size of one packet received. */
}
e1000_t;
} e1000_t;
#endif /* __E1000_H */

View File

@ -6,7 +6,7 @@ FILES=$(PROG).conf
FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
.include <minix.service.mk>

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ FILES=$(PROG).conf
FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
.include <minix.service.mk>

View File

@ -1,31 +1,28 @@
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <minix/sysutil.h>
#include <minix/board.h>
#include <sys/mman.h>
#include "assert.h"
#include "lan8710a.h"
#include "lan8710a_reg.h"
/* Local functions */
static void lan8710a_readv_s(message *m, int from_int);
static void lan8710a_writev_s(message *m, int from_int);
static void lan8710a_conf(message *m);
static void lan8710a_getstat(message *m);
static void lan8710a_init(void);
static void lan8710a_enable_interrupt(int interrupt);
static void lan8710a_interrupt(message *m);
static void lan8710a_map_regs(void);
static int lan8710a_init(unsigned int instance, ether_addr_t *addr);
static void lan8710a_stop(void);
static ssize_t lan8710a_recv(struct netdriver_data *data, size_t max);
static int lan8710a_send(struct netdriver_data *data, size_t size);
static void lan8710a_stat(eth_stat_t *stat);
static void lan8710a_intr(unsigned int mask);
static void lan8710a_enable_interrupt(int interrupt);
static void lan8710a_map_regs(void);
static void lan8710a_dma_config_tx(u8_t desc_idx);
static void lan8710a_dma_reset_init(void);
static void lan8710a_init_addr(void);
static void lan8710a_init_addr(ether_addr_t *addr);
static void lan8710a_init_desc(void);
static void lan8710a_init_mdio(void);
static int lan8710a_init_hw(void);
static void lan8710a_reset_hw();
static int lan8710a_init_hw(ether_addr_t *addr);
static void lan8710a_reset_hw(void);
static void lan8710a_phy_write(u32_t reg, u32_t value);
static u32_t lan8710a_phy_read(u32_t reg);
@ -35,16 +32,17 @@ static void lan8710a_reg_write(volatile u32_t *reg, u32_t value);
static void lan8710a_reg_set(volatile u32_t *reg, u32_t value);
static void lan8710a_reg_unset(volatile u32_t *reg, u32_t value);
static void mess_reply(message *req, message *reply);
static void reply(lan8710a_t *e);
/* Local variables */
static lan8710a_t lan8710a_state;
/* SEF functions and variables. */
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
static void sef_cb_signal_handler(int signal);
static const struct netdriver lan8710a_table = {
.ndr_init = lan8710a_init,
.ndr_stop = lan8710a_stop,
.ndr_recv = lan8710a_recv,
.ndr_send = lan8710a_send,
.ndr_stat = lan8710a_stat,
.ndr_intr = lan8710a_intr
};
/*============================================================================*
* main *
@ -52,122 +50,45 @@ static void sef_cb_signal_handler(int signal);
int
main(int argc, char *argv[])
{
/* Local variables */
message m;
int r;
int ipc_status;
struct machine machine ;
struct machine machine;
env_setargs(argc, argv);
sys_getmachine(&machine);
if ( BOARD_IS_BB(machine.board_id)) {
if (BOARD_IS_BB(machine.board_id))
netdriver_task(&lan8710a_table);
/* SEF local startup */
env_setargs(argc, argv);
sef_local_startup();
/* Main driver loop */
for (;;) {
r = netdriver_receive(ANY, &m, &ipc_status);
if (r != OK) {
panic("netdriver_receive failed: %d", r);
}
if (is_ipc_notify(ipc_status)) {
switch (_ENDPOINT_P(m.m_source)) {
case HARDWARE:
lan8710a_interrupt(&m);
break;
}
} else {
switch (m.m_type) {
case DL_WRITEV_S:
lan8710a_writev_s(&m, FALSE);
break;
case DL_READV_S:
lan8710a_readv_s(&m, FALSE);
break;
case DL_CONF:
lan8710a_conf(&m);
break;
case DL_GETSTAT_S:
lan8710a_getstat(&m);
break;
default:
panic("Illegal message: %d", m.m_type);
}
}
}
}
return EXIT_SUCCESS;
}
/*============================================================================*
* sef_local_startup *
*============================================================================*/
static void
sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_lu(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_fresh);
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
/*============================================================================*
* sef_cb_init_fresh *
* lan8710a_init *
*============================================================================*/
static int
sef_cb_init_fresh(int UNUSED( type), sef_init_info_t *UNUSED( info))
lan8710a_init(unsigned int instance, ether_addr_t * addr)
{
/* Initialize the ethernet driver. */
long v = 0;
/* Clear state. */
memset(&lan8710a_state, 0, sizeof(lan8710a_state));
strlcpy(lan8710a_state.name, "lan8710a#0", LAN8710A_NAME_LEN);
lan8710a_state.name[9] += instance;
lan8710a_state.instance = instance;
/* Initialize driver. */
lan8710a_init();
lan8710a_map_regs();
/* Get instance of ethernet device */
env_parse("instance", "d", 0, &v, 0, 255);
lan8710a_state.instance = (int) v;
/* Announce we are up! */
netdriver_announce();
lan8710a_init_hw(addr);
return OK;
}
/*============================================================================*
* sef_cb_signal_handler *
*============================================================================*/
static void
sef_cb_signal_handler(int signal)
{
/* Only check for termination signal, ignore anything else. */
if (signal != SIGTERM)
return;
lan8710a_stop();
}
/*============================================================================*
* lan8710a_enable_interrupt *
*============================================================================*/
static void
lan8710a_enable_interrupt(interrupt)
u8_t interrupt;
lan8710a_enable_interrupt(int interrupt)
{
int r;
@ -182,14 +103,13 @@ u8_t interrupt;
}
}
}
/*============================================================================*
* lan8710a_interrupt *
* lan8710a_intr *
*============================================================================*/
static void
lan8710a_interrupt(m)
message *m;
lan8710a_intr(unsigned int mask)
{
lan8710a_t *e = &lan8710a_state;
u32_t dma_status;
/* Check the card for interrupt reason(s). */
@ -201,7 +121,7 @@ message *m;
if (rx_stat) {
cp = lan8710a_reg_read(CPDMA_STRAM_RX_CP(0));
lan8710a_readv_s(&(e->rx_message), TRUE);
netdriver_recv();
lan8710a_reg_write(CPDMA_STRAM_RX_CP(0), cp);
lan8710a_reg_write(CPDMA_EOI_VECTOR, RX_INT);
@ -212,7 +132,7 @@ message *m;
/* Disabling channels, where Tx interrupt occurred */
lan8710a_reg_set(CPDMA_TX_INTMASK_CLEAR, tx_stat);
lan8710a_writev_s(&(e->tx_message), TRUE);
netdriver_send();
lan8710a_reg_write(CPDMA_STRAM_TX_CP(0), cp);
lan8710a_reg_write(CPDMA_EOI_VECTOR, TX_INT);
@ -226,61 +146,19 @@ message *m;
}
/* Re-enable Rx interrupt. */
if(m->m_notify.interrupts & (1 << RX_INT))
if (mask & (1 << RX_INT))
lan8710a_enable_interrupt(RX_INT);
/* Re-enable Tx interrupt. */
if(m->m_notify.interrupts & (1 << TX_INT))
if (mask & (1 << TX_INT))
lan8710a_enable_interrupt(TX_INT);
}
/*============================================================================*
* lan8710a_conf *
*============================================================================*/
static void
lan8710a_conf(m)
message *m;
{
message reply;
if (!(lan8710a_state.status & LAN8710A_ENABLED) &&
!(lan8710a_init_hw())) {
reply.m_type = DL_CONF_REPLY;
reply.m_netdrv_net_dl_conf.stat = ENXIO;
mess_reply(m, &reply);
return;
}
/* Reply back to INET. */
reply.m_type = DL_CONF_REPLY;
reply.m_netdrv_net_dl_conf.stat = OK;
memcpy(reply.m_netdrv_net_dl_conf.hw_addr,
lan8710a_state.address.ea_addr,
sizeof(reply.m_netdrv_net_dl_conf.hw_addr));
mess_reply(m, &reply);
}
/*============================================================================*
* lan8710a_init *
*============================================================================*/
static void
lan8710a_init(void)
{
lan8710a_map_regs();
strlcpy(lan8710a_state.name, "lan8710a#0", LAN8710A_NAME_LEN);
lan8710a_state.name[9] += lan8710a_state.instance;
lan8710a_state.status |= LAN8710A_DETECTED;
if (!(lan8710a_state.status & LAN8710A_ENABLED) &&
!(lan8710a_init_hw())) {
return;
}
}
/*============================================================================*
* lan8710a_init_addr *
*============================================================================*/
static void
lan8710a_init_addr(void)
lan8710a_init_addr(ether_addr_t * addr)
{
static char eakey[]= LAN8710A_ENVVAR "#_EA";
static char eafmt[]= "x:x:x:x:x:x";
@ -296,22 +174,20 @@ lan8710a_init_addr(void)
if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
break;
else
lan8710a_state.address.ea_addr[i] = v;
}
if (i != 6) {
lan8710a_state.address.ea_addr[0] =
(lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF);
lan8710a_state.address.ea_addr[1] =
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF00) >> 8);
lan8710a_state.address.ea_addr[2] =
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF0000) >> 16);
lan8710a_state.address.ea_addr[3] =
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF000000) >> 24);
lan8710a_state.address.ea_addr[4] =
(lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF);
lan8710a_state.address.ea_addr[5] =
((lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF00) >> 8);
addr->ea_addr[i] = v;
}
if (i == 6)
return;
/*
* No; get the address from the chip itself.
*/
addr->ea_addr[0] = lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF;
addr->ea_addr[1] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 8) & 0xFF;
addr->ea_addr[2] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 16) & 0xFF;
addr->ea_addr[3] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 24) & 0xFF;
addr->ea_addr[4] = lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF;
addr->ea_addr[5] = (lan8710a_reg_read(CTRL_MAC_ID0_LO) >> 8) & 0xFF;
}
/*============================================================================*
@ -411,40 +287,28 @@ lan8710a_map_regs(void)
}
/*============================================================================*
* lan8710a_getstat *
* lan8710a_stat *
*============================================================================*/
static void
lan8710a_getstat(mp)
message *mp;
lan8710a_stat(eth_stat_t * stat)
{
int r;
eth_stat_t stats;
stats.ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
stat->ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
+ lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR)
+ lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE);
stats.ets_sendErr = 0;
stats.ets_OVW = 0;
stats.ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR);
stats.ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR);
stats.ets_missedP = 0;
stats.ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD);
stats.ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD);
stats.ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS);
stats.ets_transAb = 0;
stats.ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR);
stats.ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN);
stats.ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN);
stats.ets_CDheartbeat = 0;
stats.ets_OWC = 0;
sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0,
(vir_bytes)&stats, sizeof(stats));
mp->m_type = DL_STAT_REPLY;
if ((r=ipc_send(mp->m_source, mp)) != OK) {
panic("lan8710a_getstat: ipc_send() failed: %d", r);
}
stat->ets_sendErr = 0;
stat->ets_OVW = 0;
stat->ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR);
stat->ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR);
stat->ets_missedP = 0;
stat->ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD);
stat->ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD);
stat->ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS);
stat->ets_transAb = 0;
stat->ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR);
stat->ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN);
stat->ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN);
stat->ets_CDheartbeat = 0;
stat->ets_OWC = 0;
}
/*============================================================================*
@ -455,17 +319,13 @@ lan8710a_stop(void)
{
/* Reset hardware. */
lan8710a_reset_hw();
/* Exit driver. */
exit(EXIT_SUCCESS);
}
/*============================================================================*
* lan8710a_dma_config_tx *
*============================================================================*/
static void
lan8710a_dma_config_tx(desc_idx)
u8_t desc_idx;
lan8710a_dma_config_tx(u8_t desc_idx)
{
phys_bytes phys_addr;
int i;
@ -585,12 +445,10 @@ lan8710a_init_desc(void)
* lan8710a_init_hw *
*============================================================================*/
static int
lan8710a_init_hw(void)
lan8710a_init_hw(ether_addr_t * addr)
{
int r, i;
lan8710a_state.status |= LAN8710A_ENABLED;
/*
* Set the interrupt handler and policy. Do not automatically
* re-enable interrupts. Return the IRQ line number on interrupts.
@ -757,7 +615,7 @@ lan8710a_init_hw(void)
lan8710a_init_mdio();
/* Getting MAC Address */
lan8710a_init_addr();
lan8710a_init_addr(addr);
/* Initialize descriptors */
lan8710a_init_desc();
@ -825,244 +683,145 @@ lan8710a_init_mdio(void)
}
/*============================================================================*
* lan8710a_writev_s *
* lan8710a_send *
*============================================================================*/
static void
lan8710a_writev_s(mp, from_int)
message *mp;
int from_int;
static int
lan8710a_send(struct netdriver_data * data, size_t size)
{
iovec_s_t iovec[LAN8710A_IOVEC_NR];
lan8710a_t *e = &lan8710a_state;
lan8710a_desc_t *p_tx_desc;
u8_t *p_buf;
int r, size, buf_data_len, i;
u8_t *buf;
/* Are we called from the interrupt handler? */
if (!from_int) {
/* We cannot write twice simultaneously. */
assert(!(e->status & LAN8710A_WRITING));
/* setup descriptors */
p_tx_desc = &(e->tx_desc[e->tx_desc_idx]);
/* Copy write message. */
e->tx_message = *mp;
e->client = mp->m_source;
e->status |= LAN8710A_WRITING;
/*
* Check if descriptor is available for host and suspend if not.
*/
if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags)
return SUSPEND;
/* verify vector count */
assert(mp->m_net_netdrv_dl_writev_s.count > 0);
assert(mp->m_net_netdrv_dl_writev_s.count < LAN8710A_IOVEC_NR);
/* Drop packets that exceed the size of our transmission buffer. */
if (size > LAN8710A_IOBUF_SIZE) {
printf("%s: dropping large packet (%zu)\n", e->name, size);
/*
* Copy the I/O vector table.
*/
if ((r = sys_safecopyfrom(mp->m_source,
mp->m_net_netdrv_dl_writev_s.grant, 0,
(vir_bytes) iovec,
mp->m_net_netdrv_dl_writev_s.count *
sizeof(iovec_s_t))) != OK) {
panic("sys_safecopyfrom() failed: %d", r);
}
/* setup descriptors */
p_tx_desc = &(e->tx_desc[e->tx_desc_idx]);
/*
* Check if descriptor is available for host
* and drop the packet if not.
*/
if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags) {
panic("No available transmit descriptor.");
}
/* virtual address of buffer */
p_buf = e->p_tx_buf + e->tx_desc_idx * LAN8710A_IOBUF_SIZE;
buf_data_len = 0;
for (i = 0; i < mp->m_net_netdrv_dl_writev_s.count; i++) {
if ((buf_data_len + iovec[i].iov_size)
> LAN8710A_IOBUF_SIZE) {
panic("packet too long");
}
/* copy data to buffer */
size = iovec[i].iov_size
< (LAN8710A_IOBUF_SIZE - buf_data_len) ?
iovec[i].iov_size
: (LAN8710A_IOBUF_SIZE - buf_data_len);
/* Copy bytes to TX queue buffers. */
if ((r = sys_safecopyfrom(mp->m_source,
iovec[i].iov_grant, 0,
(vir_bytes) p_buf, size)) != OK) {
panic("sys_safecopyfrom() failed: %d", r);
}
p_buf += size;
buf_data_len += size;
}
/* set descriptor length */
p_tx_desc->buffer_length_off = buf_data_len;
/* set flags */
p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN |
LAN8710A_DESC_FLAG_SOP |
LAN8710A_DESC_FLAG_EOP |
TX_DESC_TO_PORT1 |
TX_DESC_TO_PORT_EN);
p_tx_desc->pkt_len_flags |= buf_data_len;
/* setup DMA transfer */
lan8710a_dma_config_tx(e->tx_desc_idx);
e->tx_desc_idx++;
if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx) {
e->tx_desc_idx = 0;
}
} else {
e->status |= LAN8710A_TRANSMIT;
return OK;
}
reply(e);
/* virtual address of buffer */
buf = e->p_tx_buf + e->tx_desc_idx * LAN8710A_IOBUF_SIZE;
netdriver_copyin(data, 0, buf, size);
/* set descriptor length */
p_tx_desc->buffer_length_off = size;
/* set flags */
p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN |
LAN8710A_DESC_FLAG_SOP |
LAN8710A_DESC_FLAG_EOP |
TX_DESC_TO_PORT1 |
TX_DESC_TO_PORT_EN);
p_tx_desc->pkt_len_flags |= size;
/* setup DMA transfer */
lan8710a_dma_config_tx(e->tx_desc_idx);
e->tx_desc_idx++;
if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx)
e->tx_desc_idx = 0;
return OK;
}
/*============================================================================*
* lan8710a_readv_s *
* lan8710a_recv *
*============================================================================*/
static void
lan8710a_readv_s(mp, from_int)
message *mp;
int from_int;
static ssize_t
lan8710a_recv(struct netdriver_data * data, size_t max)
{
iovec_s_t iovec[LAN8710A_IOVEC_NR];
lan8710a_t *e = &lan8710a_state;
lan8710a_desc_t *p_rx_desc;
u32_t flags;
u8_t *p_buf;
u16_t pkt_data_len;
u16_t buf_bytes, buf_len;
int i, r, size;
u32_t flags;
u8_t *buf;
size_t off, size, chunk;
/* Are we called from the interrupt handler? */
if (!from_int) {
e->rx_message = *mp;
e->client = mp->m_source;
e->status |= LAN8710A_READING;
e->rx_size = 0;
/*
* Only handle one packet at a time.
*/
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
/* find next OWN descriptor with SOP flag */
while ((0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) &&
(0 == (LAN8710A_DESC_FLAG_OWN & p_rx_desc->pkt_len_flags))) {
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current descriptor to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
assert(e->rx_message.m_net_netdrv_dl_readv_s.count > 0);
assert(e->rx_message.m_net_netdrv_dl_readv_s.count < LAN8710A_IOVEC_NR);
}
if (e->status & LAN8710A_READING) {
/*
* Copy the I/O vector table first.
*/
if ((r = sys_safecopyfrom(e->rx_message.m_source,
e->rx_message.m_net_netdrv_dl_readv_s.grant, 0,
(vir_bytes) iovec,
e->rx_message.m_net_netdrv_dl_readv_s.count *
sizeof(iovec_s_t))) != OK) {
panic("sys_safecopyfrom() failed: %d", r);
}
/*
* Only handle one packet at a time.
*/
e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
/* find next OWN descriptor with SOP flag */
while ((0 == (LAN8710A_DESC_FLAG_SOP &
p_rx_desc->pkt_len_flags)) &&
(0 == (LAN8710A_DESC_FLAG_OWN &
p_rx_desc->pkt_len_flags))) {
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current descriptor to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
}
if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) {
/* SOP was not found */
reply(e);
return;
}
/*
* Copy to vector elements.
*/
pkt_data_len = 0;
buf_bytes = 0;
p_buf = e->p_rx_buf + e->rx_desc_idx * LAN8710A_IOBUF_SIZE;
for (i = 0; i < e->rx_message.m_net_netdrv_dl_readv_s.count; i++) {
buf_len = p_rx_desc->buffer_length_off & 0xFFFF;
if (buf_bytes == buf_len) {
/* Whole buffer move to the next descriptor */
p_rx_desc->buffer_length_off =
LAN8710A_IOBUF_SIZE;
/* set ownership of current desc to EMAC */
p_rx_desc->pkt_len_flags =
LAN8710A_DESC_FLAG_OWN;
buf_bytes = 0;
e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
p_buf = e->p_rx_buf + (e->rx_desc_idx *
LAN8710A_IOBUF_SIZE) +
(p_rx_desc->buffer_length_off >> 16);
buf_len = p_rx_desc->buffer_length_off & 0xFFFF;
}
size = iovec[i].iov_size < (buf_len - buf_bytes) ?
iovec[i].iov_size :
(buf_len - buf_bytes);
if ((r = sys_safecopyto(e->rx_message.m_source,
iovec[i].iov_grant, 0,
(vir_bytes) p_buf,
size)) != OK) {
panic("sys_safecopyto() failed: %d", r);
}
p_buf += size;
buf_bytes += size;
pkt_data_len += size;
/* if EOP flag is set -> stop processing */
if ((LAN8710A_DESC_FLAG_EOP & p_rx_desc->pkt_len_flags) &&
(buf_bytes == buf_len)) {
/* end of packet */
break;
}
}
do {
/* reset owned descriptors up to EOP flag */
flags = p_rx_desc->pkt_len_flags;
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current descriptor to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
}
while (0 == (flags & LAN8710A_DESC_FLAG_EOP));
/*
* Update state.
*/
e->status |= LAN8710A_RECEIVED;
e->rx_size = pkt_data_len;
}
reply(e);
if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) {
/* SOP was not found */
return SUSPEND;
}
/*
* Copy data from descriptors, from SOP to EOP inclusive.
* TODO: make sure that the presence of a SOP slot implies the presence
* of an EOP slot, because we are not checking for ownership below..
*/
size = 0;
off = 0;
for (;;) {
buf = e->p_rx_buf + e->rx_desc_idx * LAN8710A_IOBUF_SIZE + off;
chunk = p_rx_desc->buffer_length_off & 0xFFFF;
/* Truncate packets that are too large. */
if (chunk > max - size)
chunk = max - size;
if (chunk > 0) {
netdriver_copyout(data, size, buf, chunk);
size += chunk;
}
flags = p_rx_desc->pkt_len_flags;
/* Whole buffer move to the next descriptor */
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current desc to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
/* if EOP flag is set -> stop processing */
if (flags & LAN8710A_DESC_FLAG_EOP)
break;
/*
* TODO: the upper 16 bits of buffer_length_off are used *only*
* for descriptors *after* the first one; I'm retaining this
* behavior because I don't have the chip's spec, but it may be
* better to simplify/correct this behavior. --David
*/
off = p_rx_desc->buffer_length_off >> 16;
}
return size;
}
/*============================================================================*
* lan8710a_phy_write *
*============================================================================*/
static void
lan8710a_phy_write(reg, value)
u32_t reg;
u32_t value;
lan8710a_phy_write(u32_t reg, u32_t value)
{
if (!(lan8710a_reg_read(MDIOUSERACCESS0) & MDIO_GO)) {
/* Clearing MDIOUSERACCESS0 register */
@ -1073,7 +832,8 @@ u32_t value;
lan8710a_reg_set(MDIOUSERACCESS0,
lan8710a_state.phy_address << MDIO_PHYADR);
/* Data written only 16 bits. */
lan8710a_reg_set(MDIOUSERACCESS0, (value & 0xFFFF) << MDIO_DATA);
lan8710a_reg_set(MDIOUSERACCESS0,
(value & 0xFFFF) << MDIO_DATA);
lan8710a_reg_set(MDIOUSERACCESS0, MDIO_GO);
/* Waiting for writing completion */
@ -1085,8 +845,7 @@ u32_t value;
* lan8710a_phy_read *
*============================================================================*/
static u32_t
lan8710a_phy_read(reg)
u32_t reg;
lan8710a_phy_read(u32_t reg)
{
u32_t value = 0xFFFFFFFF;
@ -1116,7 +875,7 @@ u32_t reg;
* lan8710a_reset_hw *
*============================================================================*/
static void
lan8710a_reset_hw()
lan8710a_reset_hw(void)
{
/* Assert a Device Reset signal. */
lan8710a_phy_write(LAN8710A_CTRL_REG, LAN8710A_SOFT_RESET);
@ -1129,8 +888,7 @@ lan8710a_reset_hw()
* lan8710a_reg_read *
*============================================================================*/
static u32_t
lan8710a_reg_read(reg)
volatile u32_t *reg;
lan8710a_reg_read(volatile u32_t *reg)
{
u32_t value;
@ -1145,9 +903,7 @@ volatile u32_t *reg;
* lan8710a_reg_write *
*============================================================================*/
static void
lan8710a_reg_write(reg, value)
volatile u32_t *reg;
u32_t value;
lan8710a_reg_write(volatile u32_t *reg, u32_t value)
{
/* Write to memory mapped register. */
*reg = value;
@ -1157,9 +913,7 @@ u32_t value;
* lan8710a_reg_set *
*============================================================================*/
static void
lan8710a_reg_set(reg, value)
volatile u32_t *reg;
u32_t value;
lan8710a_reg_set(volatile u32_t *reg, u32_t value)
{
u32_t data;
@ -1174,9 +928,7 @@ u32_t value;
* lan8710a_reg_unset *
*============================================================================*/
static void
lan8710a_reg_unset(reg, value)
volatile u32_t *reg;
u32_t value;
lan8710a_reg_unset(volatile u32_t *reg, u32_t value)
{
u32_t data;
@ -1186,61 +938,3 @@ u32_t value;
/* Unset value, and write back. */
lan8710a_reg_write(reg, data & ~value);
}
/*============================================================================*
* mess_reply *
*============================================================================*/
static void
mess_reply(req, reply)
message *req;message *reply;
{
if (ipc_send(req->m_source, reply) != OK) {
panic("unable to send reply message");
}
}
/*============================================================================*
* reply *
*============================================================================*/
static void
reply(e)
lan8710a_t *e;
{
message msg;
int r;
/* Only reply to client for read/write request. */
if (!(e->status & LAN8710A_READING ||
e->status & LAN8710A_WRITING)) {
return;
}
/* Construct reply message. */
msg.m_type = DL_TASK_REPLY;
msg.m_netdrv_net_dl_task.flags = DL_NOFLAGS;
msg.m_netdrv_net_dl_task.count = 0;
/* Did we successfully receive packet(s)? */
if (e->status & LAN8710A_READING &&
e->status & LAN8710A_RECEIVED) {
msg.m_netdrv_net_dl_task.flags |= DL_PACK_RECV;
msg.m_netdrv_net_dl_task.count =
e->rx_size >= ETH_MIN_PACK_SIZE ?
e->rx_size : ETH_MIN_PACK_SIZE;
/* Clear flags. */
e->status &= ~(LAN8710A_READING | LAN8710A_RECEIVED);
}
/* Did we successfully transmit packet(s)? */
if (e->status & LAN8710A_TRANSMIT &&
e->status & LAN8710A_WRITING) {
msg.m_netdrv_net_dl_task.flags |= DL_PACK_SEND;
/* Clear flags. */
e->status &= ~(LAN8710A_WRITING | LAN8710A_TRANSMIT);
}
/* Acknowledge to INET. */
if ((r = ipc_send(e->client, &msg) != OK)) {
panic("ipc_send() failed: %d", r);
}
}

View File

@ -16,26 +16,9 @@
#define LAN8710A_DEBUG_PRINT(args)
#endif
#ifndef ERR
#define ERR (-1) /* general error flag */
#endif
#ifndef OK
#define OK 0 /* general OK flag */
#endif
#define MAP_FAILED ((void *) -1) /* mmap() failed */
/* Ethernet driver defines */
#define LAN8710A_NAME_LEN (11)
/* Ethernet driver states */
#define LAN8710A_DETECTED (1 << 0)
#define LAN8710A_ENABLED (1 << 1)
#define LAN8710A_READING (1 << 2)
#define LAN8710A_WRITING (1 << 3)
#define LAN8710A_RECEIVED (1 << 4)
#define LAN8710A_TRANSMIT (1 << 5)
/* Descriptors flags */
#define LAN8710A_DESC_FLAG_OWN (1 << 29) /* ownership flag */
#define LAN8710A_DESC_FLAG_SOP (1 << 31) /* start of packet flag */
@ -58,9 +41,6 @@
/** Number of receive descriptors */
#define LAN8710A_NUM_RX_DESC (255)
/** Number of I/O vectors to use. */
#define LAN8710A_IOVEC_NR (16)
/** Size of each I/O buffer per descriptor. */
#define LAN8710A_IOBUF_SIZE (1520)
@ -89,11 +69,9 @@ typedef struct lan8710a_t
phys_bytes rx_desc_phy;
phys_bytes tx_desc_phy;
char name[LAN8710A_NAME_LEN];
int status;
int irq_rx_hook; /* Rx interrupt Request Vector Hook. */
int irq_tx_hook; /* Tx interrupt Request Vector Hook. */
int instance;
ether_addr_t address; /* Ethernet MAC address. */
u8_t *regs;
u32_t phy_address;
u8_t *p_rx_buf; /* pointer to the buffer with receive frames */
@ -101,10 +79,6 @@ typedef struct lan8710a_t
u16_t tx_desc_idx; /* index of the next transmit desciptor */
u16_t rx_desc_idx; /* index of the next receive desciptor */
int client;
message tx_message;
message rx_message;
unsigned int rx_size;
/* register mapping */
vir_bytes regs_cp_per;

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,8 @@
/* macros for 'mode' */
#define EC_DISABLED 0x0
#define EC_SINK 0x1
#define EC_ENABLED 0x2
/* macros for 'flags' */
#define ECF_EMPTY 0x000
#define ECF_PACK_SEND 0x001
#define ECF_PACK_RECV 0x002
#define ECF_SEND_AVAIL 0x004
#define ECF_READING 0x010
#define ECF_PROMISC 0x040
#define ECF_MULTI 0x080
#define ECF_BROAD 0x100
#define ECF_ENABLED 0x200
#define ECF_STOPPED 0x400
/* === macros for ether cards (our generalized version) === */
#define EC_ISR_RINT 0x0001
#define EC_ISR_WINT 0x0002
#define EC_ISR_RERR 0x0010
#define EC_ISR_WERR 0x0020
#define EC_ISR_ERR 0x0040
#define EC_ISR_RST 0x0100
/* IOVEC */
#define IOVEC_NR 16
typedef struct iovec_dat
{
iovec_s_t iod_iovec[IOVEC_NR];
int iod_iovec_s;
endpoint_t iod_proc_nr;
cp_grant_id_t iod_grant;
vir_bytes iod_iovec_offset;
} iovec_dat_t;
#define ECF_PROMISC 0x01
#define ECF_MULTI 0x02
#define ECF_BROAD 0x04
/* ====== ethernet card info. ====== */
typedef struct ether_card
@ -41,35 +10,14 @@ typedef struct ether_card
/* ####### MINIX style ####### */
char port_name[sizeof("lance#n")];
int flags;
int mode;
int transfer_mode;
eth_stat_t eth_stat;
iovec_dat_t read_iovec;
iovec_dat_t write_iovec;
iovec_dat_t tmp_iovec;
vir_bytes write_s;
vir_bytes read_s;
int client;
message sendmsg;
/* ######## device info. ####### */
port_t ec_port;
phys_bytes ec_linmem;
int ec_irq;
int ec_int_pending;
int ec_hook;
int ec_ramsize;
/* Addrassing */
u16_t ec_memseg;
vir_bytes ec_memoff;
ether_addr_t mac_address;
} ether_card_t;
#define DEI_DEFAULT 0x8000
/*
* NOTE: Not all the CSRs are defined. Just the ones that were deemed
* necessary or potentially useful.

View File

@ -2,8 +2,8 @@
PROG= orinoco
SRCS= orinoco.c hermes.c
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
CPPFLAGS.orinoco.c+= -I${NETBSDSRCDIR}/minix

File diff suppressed because it is too large Load Diff

View File

@ -26,74 +26,39 @@ typedef struct s_or
{
int or_irq;
int or_hook_id;
int or_mode;
int or_flags;
char *or_model;
int or_client;
int or_link_up;
int or_got_int;
int or_tx_alive;
int or_send_int;
int or_clear_rx;
u32_t or_base_port;
int or_need_reset;
int or_report_link;
/* Events */
int or_ev_rx;
int or_ev_tx;
int or_ev_info;
int or_ev_txexc;
int or_ev_alloc;
int connected;
u16_t channel_mask;
u16_t channel;
u16_t ap_density;
u16_t rts_thresh;
int bitratemode;
int last_linkstatus;
int max_data_len;
int port_type;
/* Rx */
phys_bytes or_rx_buf;
vir_bytes or_read_s;
u16_t rxfid[NR_RX_BUFS];
int rx_length[NR_RX_BUFS];
u8_t rx_buf[NR_RX_BUFS][IEEE802_11_FRAME_LEN];
u8_t rx_offset[NR_RX_BUFS];
int rx_first;
int rx_last;
int rx_current;
/* Tx */
u16_t or_nicbuf_size;
vir_bytes or_transm_s;
int or_tx_head;
int or_tx_tail;
int or_tx_busy;
struct
{
int ret_busy;
u16_t or_txfid;
} or_tx;
u32_t or_ertxth;
/* PCI related */
int or_seen;
int devind;
/* 'large' items */
irq_hook_t or_hook;
eth_stat_t or_stat;
message or_rx_mess;
message or_tx_mess;
ether_addr_t or_address;
iovec_t or_iovec[IOVEC_NR];
iovec_s_t or_iovec_s[IOVEC_NR];
char or_name[sizeof (OR_NAME)];
char or_name[sizeof(OR_NAME)];
hermes_t hw;
char nick[IW_ESSID_MAX_SIZE + 1];
} t_or;

View File

@ -1,13 +1,13 @@
# Makefile for the Realtek RTL8139 ethernet driver (RTL8139)
PROG= rtl8139
SRCS= rtl8139.c liveupdate.c
SRCS= rtl8139.c
FILES=$(PROG).conf
FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
CPPFLAGS+= -I${NETBSDSRCDIR}/minix

View File

@ -1,3 +1,5 @@
/* Code left here for historical purposes only. TODO: move into libnetdriver */
#include "rtl8139.h"
/* State management variables. */

File diff suppressed because it is too large Load Diff

View File

@ -6,32 +6,9 @@ Created: Aug 2003 by Philip Homburg <philip@cs.vu.nl>
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <minix/com.h>
#include <minix/ds.h>
#include <minix/keymap.h>
#include <minix/syslib.h>
#include <minix/type.h>
#include <minix/sysutil.h>
#include <minix/endpoint.h>
#include <minix/timers.h>
#include <net/hton.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <machine/pci.h>
#include <sys/types.h>
#include <fcntl.h>
#include <minix/ds.h>
#include <assert.h>
#include <unistd.h>
#include <sys/ioc_memory.h>
#include "kernel/const.h"
#include "kernel/config.h"
#include "kernel/type.h"
#define RL_IDR 0x00 /* Ethernet address
* Note: RL_9346CR_EEM_CONFIG mode is
@ -453,18 +430,12 @@ d8 R/W Config5 Configuration register 5
d9-ff reserved
#endif
#define Proc_number(p) proc_number(p)
#define debug 0
#define printW() ((void)0)
#define vm_1phys2bus(p) (p)
#define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE
#define RX_BUFBITS RL_RCR_RBLEN_64K
#define N_TX_BUF RL_N_TX
/* I/O vectors are handled IOVEC_NR entries at a time. */
#define IOVEC_NR 16
/* Configuration */
#define RL_ENVVAR "RTLETH"
@ -473,8 +444,6 @@ typedef struct re
port_t re_base_port;
int re_irq;
int re_mode;
int re_flags;
int re_client;
int re_link_up;
int re_got_int;
int re_send_int;
@ -482,12 +451,12 @@ typedef struct re
int re_clear_rx;
int re_need_reset;
int re_tx_alive;
char *re_model;
int re_tx_busy;
const char *re_model;
/* Rx */
phys_bytes re_rx_buf;
char *v_re_rx_buf;
vir_bytes re_read_s;
/* Tx */
int re_tx_head;
@ -500,33 +469,10 @@ typedef struct re
} re_tx[N_TX_BUF];
u32_t re_ertxth; /* Early Tx Threshold */
/* PCI related */
int re_seen; /* TRUE iff device available */
/* 'large' items */
int re_hook_id; /* IRQ hook id at kernel */
eth_stat_t re_stat;
ether_addr_t re_address;
message re_rx_mess;
message re_tx_mess;
char re_name[sizeof("rtl8139#n")];
iovec_t re_iovec[IOVEC_NR];
iovec_s_t re_iovec_s[IOVEC_NR];
}
re_t;
#define REM_DISABLED 0x0
#define REM_ENABLED 0x1
#define REF_PACK_SENT 0x001
#define REF_PACK_RECV 0x002
#define REF_SEND_AVAIL 0x004
#define REF_READING 0x010
#define REF_EMPTY 0x000
#define REF_PROMISC 0x040
#define REF_MULTI 0x080
#define REF_BROAD 0x100
#define REF_ENABLED 0x200
} re_t;
/*
* $PchId: rtl8139.h,v 1.1 2003/09/05 10:58:50 philip Exp $

View File

@ -6,8 +6,8 @@ FILES=$(PROG).conf
FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
LDADD+= -lnetdriver -lsys -ltimers
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys
CPPFLAGS+= -I${NETBSDSRCDIR}/minix

File diff suppressed because it is too large Load Diff

View File

@ -22,11 +22,18 @@
#include "virtio_net.h"
#define VERBOSE 0
#if VERBOSE
#define dput(s) do { dprintf(s); printf("\n"); } while (0)
#define dprintf(s) do { \
printf("%s: ", name); \
printf s; \
} while (0)
#else
#define dput(s)
#define dprintf(s)
#endif
static struct virtio_device *net_dev;
@ -50,6 +57,7 @@ struct packet {
phys_bytes phdr;
char *vdata;
phys_bytes pdata;
size_t len;
STAILQ_ENTRY(packet) next;
};
@ -60,7 +68,6 @@ static struct virtio_net_hdr *hdrs_vir;
static phys_bytes hdrs_phys;
static struct packet *packets;
static int in_rx;
static int started;
/* Packets on this list can be given to the host */
static STAILQ_HEAD(free_list, packet) free_list;
@ -68,21 +75,13 @@ static STAILQ_HEAD(free_list, packet) free_list;
/* Packets on this list are to be given to inet */
static STAILQ_HEAD(recv_list, packet) recv_list;
/* State about pending inet messages */
static int rx_pending;
static message pending_rx_msg;
static int tx_pending;
static message pending_tx_msg;
/* Various state data */
static u8_t virtio_net_mac[6];
static eth_stat_t virtio_net_stats;
static int spurious_interrupt;
/* Prototypes */
static int virtio_net_probe(int skip);
static int virtio_net_config(void);
static int virtio_net_probe(unsigned int skip);
static void virtio_net_config(ether_addr_t *addr);
static int virtio_net_alloc_bufs(void);
static void virtio_net_init_queues(void);
@ -90,28 +89,24 @@ static void virtio_net_refill_rx_queue(void);
static void virtio_net_check_queues(void);
static void virtio_net_check_pending(void);
static void virtio_net_fetch_iovec(iovec_s_t *iov, message *m,
cp_grant_id_t grant, size_t count);
static int virtio_net_cpy_to_user(message *m);
static int virtio_net_cpy_from_user(message *m);
static void virtio_net_intr(message *m);
static void virtio_net_write(message *m);
static void virtio_net_read(message *m);
static void virtio_net_conf(message *m);
static void virtio_net_getstat(message *m);
static void virtio_net_notify(message *m);
static void virtio_net_msg(message *m);
static void virtio_net_main_loop(void);
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
static void sef_cb_signal_handler(int signo);
static int virtio_net_init(unsigned int instance, ether_addr_t *addr);
static void virtio_net_stop(void);
static int virtio_net_send(struct netdriver_data *data, size_t len);
static ssize_t virtio_net_recv(struct netdriver_data *data, size_t max);
static void virtio_net_stat(eth_stat_t *stat);
static void virtio_net_intr(unsigned int mask);
static const struct netdriver virtio_net_table = {
.ndr_init = virtio_net_init,
.ndr_stop = virtio_net_stop,
.ndr_recv = virtio_net_recv,
.ndr_send = virtio_net_send,
.ndr_stat = virtio_net_stat,
.ndr_intr = virtio_net_intr,
};
/* TODO: Features are pretty much ignored */
struct virtio_feature netf[] = {
static struct virtio_feature netf[] = {
{ "partial csum", VIRTIO_NET_F_CSUM, 0, 0 },
{ "given mac", VIRTIO_NET_F_MAC, 0, 1 },
{ "status ", VIRTIO_NET_F_STATUS, 0, 0 },
@ -120,7 +115,7 @@ struct virtio_feature netf[] = {
};
static int
virtio_net_probe(int skip)
virtio_net_probe(unsigned int skip)
{
/* virtio-net has at least 2 queues */
int queues = 2;
@ -142,8 +137,8 @@ virtio_net_probe(int skip)
return OK;
}
static int
virtio_net_config(void)
static void
virtio_net_config(ether_addr_t * addr)
{
u32_t mac14;
u32_t mac56;
@ -153,12 +148,12 @@ virtio_net_config(void)
dprintf(("Mac set by host: "));
mac14 = virtio_sread32(net_dev, 0);
mac56 = virtio_sread32(net_dev, 4);
*(u32_t*)virtio_net_mac = mac14;
*(u16_t*)(virtio_net_mac + 4) = mac56;
memcpy(&addr->ea_addr[0], &mac14, 4);
memcpy(&addr->ea_addr[4], &mac56, 2);
for (i = 0; i < 6; i++)
printf("%02x%s", virtio_net_mac[i],
i == 5 ? "\n" : ":");
dprintf(("%02x%s", addr->ea_addr[i],
i == 5 ? "\n" : ":"));
} else {
dput(("No mac"));
}
@ -174,8 +169,6 @@ virtio_net_config(void)
if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_RX))
dput(("Host supports control channel for RX"));
return OK;
}
static int
@ -233,7 +226,6 @@ virtio_net_refill_rx_queue(void)
struct packet *p;
while ((in_rx < BUF_PACKETS / 2) && !STAILQ_EMPTY(&free_list)) {
/* peek */
p = STAILQ_FIRST(&free_list);
/* remove */
@ -253,7 +245,6 @@ virtio_net_refill_rx_queue(void)
virtio_to_queue(net_dev, RX_Q, phys, 2, p);
in_rx++;
}
if (in_rx == 0 && STAILQ_EMPTY(&free_list)) {
@ -266,18 +257,21 @@ static void
virtio_net_check_queues(void)
{
struct packet *p;
size_t len;
/* Put the received packets into the recv list */
while (virtio_from_queue(net_dev, RX_Q, (void **)&p) == 0) {
while (virtio_from_queue(net_dev, RX_Q, (void **)&p, &len) == 0) {
p->len = len;
STAILQ_INSERT_TAIL(&recv_list, p, next);
in_rx--;
virtio_net_stats.ets_packetR++;
}
/* Packets from the TX queue just indicated they are free to
/*
* Packets from the TX queue just indicated they are free to
* be reused now. inet already knows about them as being sent.
*/
while (virtio_from_queue(net_dev, TX_Q, (void **)&p) == 0) {
while (virtio_from_queue(net_dev, TX_Q, (void **)&p, NULL) == 0) {
memset(p->vhdr, 0, sizeof(*p->vhdr));
memset(p->vdata, 0, MAX_PACK_SIZE);
STAILQ_INSERT_HEAD(&free_list, p, next);
@ -288,173 +282,19 @@ virtio_net_check_queues(void)
static void
virtio_net_check_pending(void)
{
int dst = 0xDEAD;
int r;
message reply;
reply.m_type = DL_TASK_REPLY;
reply.m_netdrv_net_dl_task.flags = DL_NOFLAGS;
reply.m_netdrv_net_dl_task.count = 0;
/* Pending read and something in recv_list? */
if (!STAILQ_EMPTY(&recv_list) && rx_pending) {
dst = pending_rx_msg.m_source;
reply.m_netdrv_net_dl_task.count =
virtio_net_cpy_to_user(&pending_rx_msg);
reply.m_netdrv_net_dl_task.flags |= DL_PACK_RECV;
rx_pending = 0;
}
if (!STAILQ_EMPTY(&recv_list))
netdriver_recv();
if (!STAILQ_EMPTY(&free_list) && tx_pending) {
dst = pending_tx_msg.m_source;
virtio_net_cpy_from_user(&pending_tx_msg);
reply.m_netdrv_net_dl_task.flags |= DL_PACK_SEND;
tx_pending = 0;
}
/* Only reply if a pending request was handled */
if (reply.m_netdrv_net_dl_task.flags != DL_NOFLAGS)
if ((r = ipc_send(dst, &reply)) != OK)
panic("%s: ipc_send to %d failed (%d)", name, dst, r);
if (!STAILQ_EMPTY(&free_list))
netdriver_send();
}
static void
virtio_net_fetch_iovec(iovec_s_t *iov, message *m, cp_grant_id_t grant, size_t count)
virtio_net_intr(unsigned int __unused mask)
{
int r;
r = sys_safecopyfrom(m->m_source, grant, 0, (vir_bytes)iov,
count * sizeof(iov[0]));
if (r != OK)
panic("%s: iovec fail for %d (%d)", name, m->m_source, r);
}
static int
virtio_net_cpy_to_user(message *m)
{
/* Hmm, this looks so similar to cpy_from_user... TODO */
int i, r, size, ivsz;
int left = MAX_PACK_SIZE; /* Try copying the whole packet */
int bytes = 0;
iovec_s_t iovec[NR_IOREQS];
struct packet *p;
/* This should only be called if recv_list has some entries */
assert(!STAILQ_EMPTY(&recv_list));
p = STAILQ_FIRST(&recv_list);
STAILQ_REMOVE_HEAD(&recv_list, next);
virtio_net_fetch_iovec(iovec, m, m->m_net_netdrv_dl_readv_s.grant,
m->m_net_netdrv_dl_readv_s.count);
for (i = 0; i < m->m_net_netdrv_dl_readv_s.count && left > 0; i++) {
ivsz = iovec[i].iov_size;
size = left > ivsz ? ivsz : left;
r = sys_safecopyto(m->m_source, iovec[i].iov_grant, 0,
(vir_bytes) p->vdata + bytes, size);
if (r != OK)
panic("%s: copy to %d failed (%d)", name,
m->m_source,
r);
left -= size;
bytes += size;
}
if (left != 0)
dput(("Uhm... left=%d", left));
/* Clean the packet */
memset(p->vhdr, 0, sizeof(*p->vhdr));
memset(p->vdata, 0, MAX_PACK_SIZE);
STAILQ_INSERT_HEAD(&free_list, p, next);
return bytes;
}
static int
sys_easy_vsafecopy_from(endpoint_t src_proc, iovec_s_t *iov, int count,
vir_bytes dst, size_t max, size_t *copied)
{
int i, r;
size_t left = max;
vir_bytes cur_off = 0;
struct vscp_vec vv[NR_IOREQS];
for (i = 0; i < count && left > 0; i++) {
vv[i].v_from = src_proc;
vv[i].v_to = SELF;
vv[i].v_gid = iov[i].iov_grant;
vv[i].v_offset = 0;
vv[i].v_addr = dst + cur_off;
vv[i].v_bytes = iov[i].iov_size;
/* More data in iov than the buffer can hold, this should be
* manageable by the caller.
*/
if (left - vv[i].v_bytes > left) {
printf("sys_easy_vsafecopy_from: buf too small!\n");
return ENOMEM;
}
left -= iov[i].iov_size;
cur_off += iov[i].iov_size;
}
/* Now that we prepared the vscp_vec, we can call vsafecopy() */
if ((r = sys_vsafecopy(vv, count)) != OK)
printf("sys_vsafecopy: failed: (%d)\n", r);
if (copied)
*copied = cur_off;
return OK;
}
static int
virtio_net_cpy_from_user(message *m)
{
/* Put user bytes into a a free packet buffer and
* then forward this packet to the TX queue.
*/
int r;
iovec_s_t iovec[NR_IOREQS];
struct vumap_phys phys[2];
struct packet *p;
size_t bytes;
/* This should only be called if free_list has some entries */
assert(!STAILQ_EMPTY(&free_list));
p = STAILQ_FIRST(&free_list);
STAILQ_REMOVE_HEAD(&free_list, next);
virtio_net_fetch_iovec(iovec, m, m->m_net_netdrv_dl_writev_s.grant,
m->m_net_netdrv_dl_writev_s.count);
r = sys_easy_vsafecopy_from(m->m_source, iovec,
m->m_net_netdrv_dl_writev_s.count, (vir_bytes)p->vdata,
MAX_PACK_SIZE, &bytes);
if (r != OK)
panic("%s: copy from %d failed", name, m->m_source);
phys[0].vp_addr = p->phdr;
assert(!(phys[0].vp_addr & 1));
phys[0].vp_size = sizeof(struct virtio_net_hdr);
phys[1].vp_addr = p->pdata;
assert(!(phys[1].vp_addr & 1));
phys[1].vp_size = bytes;
virtio_to_queue(net_dev, TX_Q, phys, 2, p);
return bytes;
}
static void
virtio_net_intr(message *m)
{
/* Check and clear interrupt flag */
if (virtio_had_irq(net_dev)) {
virtio_net_check_queues();
@ -468,202 +308,131 @@ virtio_net_intr(message *m)
virtio_net_check_pending();
virtio_irq_enable(net_dev);
/* Readd packets to the receive queue as necessary. */
virtio_net_refill_rx_queue();
}
static void
virtio_net_write(message *m)
{
int r;
message reply;
reply.m_type = DL_TASK_REPLY;
reply.m_netdrv_net_dl_task.flags = DL_NOFLAGS;
reply.m_netdrv_net_dl_task.count = 0;
if (!STAILQ_EMPTY(&free_list)) {
/* free_list contains at least one packet, use it */
reply.m_netdrv_net_dl_task.count = virtio_net_cpy_from_user(m);
reply.m_netdrv_net_dl_task.flags = DL_PACK_SEND;
} else {
pending_tx_msg = *m;
tx_pending = 1;
}
if ((r = ipc_send(m->m_source, &reply)) != OK)
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r);
}
static void
virtio_net_read(message *m)
{
int r;
message reply;
reply.m_type = DL_TASK_REPLY;
reply.m_netdrv_net_dl_task.flags = DL_NOFLAGS;
reply.m_netdrv_net_dl_task.count = 0;
if (!STAILQ_EMPTY(&recv_list)) {
/* recv_list contains at least one packet, copy it */
reply.m_netdrv_net_dl_task.count = virtio_net_cpy_to_user(m);
reply.m_netdrv_net_dl_task.flags = DL_PACK_RECV;
} else {
rx_pending = 1;
pending_rx_msg = *m;
}
if ((r = ipc_send(m->m_source, &reply)) != OK)
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r);
}
static void
virtio_net_conf(message *m)
{
/* TODO: Add the multicast, broadcast filtering etc. */
int i, r;
message reply;
/* If this is the first CONF message we see, fully initialize
* the device now.
*/
if (!started) {
started = 1;
virtio_device_ready(net_dev);
virtio_irq_enable(net_dev);
}
/* Prepare reply */
memcpy(reply.m_netdrv_net_dl_conf.hw_addr, virtio_net_mac,
sizeof(reply.m_netdrv_net_dl_conf.hw_addr));
reply.m_type = DL_CONF_REPLY;
reply.m_netdrv_net_dl_conf.stat = OK;
if ((r = ipc_send(m->m_source, &reply)) != OK)
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r);
}
static void
virtio_net_getstat(message *m)
{
int r;
message reply;
reply.m_type = DL_STAT_REPLY;
r = sys_safecopyto(m->m_source, m->m_net_netdrv_dl_getstat_s.grant, 0,
(vir_bytes)&virtio_net_stats,
sizeof(virtio_net_stats));
if (r != OK)
panic("%s: copy to %d failed (%d)", name, m->m_source, r);
if ((r = ipc_send(m->m_source, &reply)) != OK)
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r);
}
static void
virtio_net_notify(message *m)
{
if (_ENDPOINT_P(m->m_source) == HARDWARE)
virtio_net_intr(m);
}
static void
virtio_net_msg(message *m)
{
switch (m->m_type) {
case DL_WRITEV_S:
virtio_net_write(m);
break;
case DL_READV_S:
virtio_net_read(m);
break;
case DL_CONF:
virtio_net_conf(m);
break;
case DL_GETSTAT_S:
virtio_net_getstat(m);
break;
default:
panic("%s: illegal message: %d", name, m->m_type);
}
}
static void
virtio_net_main_loop(void)
{
message m;
int ipc_status;
int r;
while (TRUE) {
virtio_net_refill_rx_queue();
if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK)
panic("%s: netdriver_receive failed: %d", name, r);
if (is_ipc_notify(ipc_status))
virtio_net_notify(&m);
else
virtio_net_msg(&m);
}
}
int
main(int argc, char *argv[])
{
env_setargs(argc, argv);
sef_local_startup();
virtio_net_main_loop();
}
static void
sef_local_startup()
{
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_lu(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_fresh);
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
sef_setcb_signal_handler(sef_cb_signal_handler);
sef_startup();
}
/*
* Put user bytes into a free packet buffer, forward this packet to the TX
* queue, and return OK. If there are no free packet buffers, return SUSPEND.
*/
static int
sef_cb_init_fresh(int type, sef_init_info_t *info)
virtio_net_send(struct netdriver_data * data, size_t len)
{
long instance = 0;
env_parse("instance", "d", 0, &instance, 0, 255);
struct vumap_phys phys[2];
struct packet *p;
if (virtio_net_probe((int)instance) != OK)
panic("%s: No device found", name);
if (STAILQ_EMPTY(&free_list))
return SUSPEND;
if (virtio_net_config() != OK)
panic("%s: No device found", name);
p = STAILQ_FIRST(&free_list);
STAILQ_REMOVE_HEAD(&free_list, next);
if (len > MAX_PACK_SIZE)
panic("%s: packet too large to send: %zu", name, len);
netdriver_copyin(data, 0, p->vdata, len);
phys[0].vp_addr = p->phdr;
assert(!(phys[0].vp_addr & 1));
phys[0].vp_size = sizeof(struct virtio_net_hdr);
phys[1].vp_addr = p->pdata;
assert(!(phys[1].vp_addr & 1));
phys[1].vp_size = len;
virtio_to_queue(net_dev, TX_Q, phys, 2, p);
return OK;
}
/*
* Put a packet receive from the RX queue into a user buffer, and return the
* packet length. If there are no received packets, return SUSPEND.
*/
static ssize_t
virtio_net_recv(struct netdriver_data * data, size_t max)
{
struct packet *p;
ssize_t len;
/* Get the first received packet, if any. */
if (STAILQ_EMPTY(&recv_list))
return SUSPEND;
p = STAILQ_FIRST(&recv_list);
STAILQ_REMOVE_HEAD(&recv_list, next);
/* Copy out the packet contents. */
len = p->len - sizeof(struct virtio_net_hdr);
if (len > max)
len = max;
/*
* HACK: due to lack of padding, received packets may in fact be
* smaller than the minimum ethernet packet size. Inet will accept the
* packets just fine if we increase the length to its minimum. We
* already zeroed out the rest of the packet data, so this is safe.
*/
if (len < ETH_MIN_PACK_SIZE)
len = ETH_MIN_PACK_SIZE;
netdriver_copyout(data, 0, p->vdata, len);
/* Clean the packet. */
memset(p->vhdr, 0, sizeof(*p->vhdr));
memset(p->vdata, 0, MAX_PACK_SIZE);
STAILQ_INSERT_HEAD(&free_list, p, next);
/* Readd packets to the receive queue as necessary. */
virtio_net_refill_rx_queue();
return len;
}
/*
* Return statistics.
*/
static void
virtio_net_stat(eth_stat_t *stat)
{
memcpy(stat, &virtio_net_stats, sizeof(*stat));
}
/*
* Initialize the driver and the virtual hardware.
*/
static int
virtio_net_init(unsigned int instance, ether_addr_t *addr)
{
int r;
if ((r = virtio_net_probe(instance)) != OK)
return r;
virtio_net_config(addr);
if (virtio_net_alloc_bufs() != OK)
panic("%s: Buffer allocation failed", name);
virtio_net_init_queues();
netdriver_announce();
/* Add packets to the receive queue. */
virtio_net_refill_rx_queue();
virtio_device_ready(net_dev);
virtio_irq_enable(net_dev);
return(OK);
}
/*
* The driver is terminating. Clean up.
*/
static void
sef_cb_signal_handler(int signo)
virtio_net_stop(void)
{
if (signo != SIGTERM)
return;
dput(("Terminating"));
@ -675,6 +444,18 @@ sef_cb_signal_handler(int signo)
virtio_free_queues(net_dev);
virtio_free_device(net_dev);
net_dev = NULL;
exit(1);
}
/*
* The virtio-net device driver.
*/
int
main(int argc, char *argv[])
{
env_setargs(argc, argv);
netdriver_task(&virtio_net_table);
return 0;
}

View File

@ -7,4 +7,6 @@ LDADD+= -li2cdriver -lchardriver -lsys -ltimers
CPPFLAGS+= -I${NETBSDSRCDIR}
NOCLANGERROR=yes
.include <minix.service.mk>

View File

@ -99,7 +99,7 @@ mmc_write32(vir_bytes reg, u32_t value)
write32(mmchs->io_base + reg, value);
}
int
void
mmchs_set_bus_freq(u32_t freq)
{
u32_t freq_in = HSMMCSD_0_IN_FREQ;
@ -971,7 +971,7 @@ dump(uint8_t * data, int len)
}
}
int
void
mmc_switch(int function, int value, uint8_t * data)
{
struct mmc_command command;
@ -990,7 +990,7 @@ mmc_switch(int function, int value, uint8_t * data)
command.args |= (value << fshift);
if (mmc_send_cmd(&command)) {
log_warn(&log, "Failed to set device in high speed mode\n");
return 1;
return;
}
// dump(data,64);
}

View File

@ -439,7 +439,7 @@ virtio_blk_device_intr(void)
thread_id_t *tid;
/* Multiple requests might have finished */
while (!virtio_from_queue(blk_dev, 0, (void**)&tid))
while (!virtio_from_queue(blk_dev, 0, (void**)&tid, NULL))
blockdriver_mt_wakeup(*tid);
}

View File

@ -127,7 +127,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
"for 'hub port LS attach' event");
USB_MSG("Low speed device connected at "
"hub 0x%08X, port %u", device, val);
"hub 0x%p, port %u", device, val);
hcd_add_child(device, val, HCD_SPEED_LOW);
break;
@ -138,7 +138,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
"for 'hub port FS attach' event");
USB_MSG("Full speed device connected at "
"hub 0x%08X, port %u", device, val);
"hub 0x%p, port %u", device, val);
hcd_add_child(device, val, HCD_SPEED_FULL);
break;
@ -149,7 +149,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
"for 'hub port HS attach' event");
USB_MSG("High speed device connected at "
"hub 0x%08X, port %u", device, val);
"hub 0x%p, port %u", device, val);
hcd_add_child(device, val, HCD_SPEED_HIGH);
break;
@ -162,7 +162,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
hcd_delete_child(device, val);
USB_MSG("Device disconnected from "
"hub 0x%08X, port %u", device, val);
"hub 0x%p, port %u", device, val);
break;
@ -456,7 +456,7 @@ hcd_dump_tree(hcd_device_state * device, hcd_reg1 level)
/* DEBUG_DUMP; */ /* Let's keep tree output cleaner */
USB_MSG("Device on level %03u: 0x%08X", level, device);
USB_MSG("Device on level %03u: 0x%p", level, device);
/* Traverse device tree recursively */
for (child_num = 0; child_num < HCD_CHILDREN; child_num++) {

View File

@ -254,8 +254,8 @@ ddekit_usb_init(struct ddekit_usb_driver * drv,
connect_cb = drv->connect;
disconnect_cb = drv->disconnect;
*_m = malloc;
*_f = free;
*_m = (ddekit_usb_malloc_fn) malloc;
*_f = (ddekit_usb_free_fn) free;
return EXIT_SUCCESS;
}

View File

@ -283,7 +283,7 @@ arch_put_varscreeninfo(int minor, struct fb_var_screeninfo *fbvsp)
/* For now we only allow to play with the yoffset setting */
if (fbvsp->yoffset != omap_fbvs[minor].yoffset) {
if (fbvsp->yoffset < 0 || fbvsp->yoffset > omap_fbvs[minor].yres) {
if (/* fbvsp->yoffset < 0 || */ fbvsp->yoffset > omap_fbvs[minor].yres) {
return EINVAL;
}

View File

@ -6,39 +6,154 @@
#include "rs/const.h"
#include "rs/type.h"
enum policy {
POL_NONE = 0x00, /* user | endpoint */
POL_RESET = 0x01, /* visible | change */
POL_RESTART = 0x02, /* transparent | preserved */
POL_LIVE_UPDATE = 0x04 /* transparent | preserved */
};
struct policies {
#define MAX_POL_FORMAT_SZ 20
char formatted[MAX_POL_FORMAT_SZ];
enum policy supported;
};
static struct rprocpub rprocpub[NR_SYS_PROCS];
static struct rproc rproc[NR_SYS_PROCS];
static struct policies policies[NR_SYS_PROCS];
static struct inode *service_node;
/*
* Initialize the service directory.
*/
void
service_init(void)
/* Updates the policies state from RS. Always returns an ASCIIZ string. */
static const char *
service_get_policies(struct policies * pol, index_t slot)
{
struct inode *root, *node;
struct inode_stat stat;
#if 1 /* The following should be retrieved from RS and formated instead. */
int pos;
char *ref_label;
static const struct {
const char *label;
const char *policy_str;
} def_pol[] = {
/* audio */
{ .label = "es1370", .policy_str = "reset" },
{ .label = "es1371", .policy_str = "reset" },
{ .label = "sb16", .policy_str = "reset" },
/* bus */
{ .label = "i2c", .policy_str = "restart" },
{ .label = "pci", .policy_str = "restart" },
{ .label = "ti1225", .policy_str = "restart" },
/* clock */
{ .label = "readclock.drv", .policy_str = "restart" },
/* eeprom */
{ .label = "cat24c256", .policy_str = "restart" },
/* examples */
{ .label = "hello", .policy_str = "restart" },
/* hid */
{ .label = "pckbd", .policy_str = "reset" },
/* iommu */
{ .label = "amddev", .policy_str = "" },
/* net */
{ .label = "atl2", .policy_str = "restart" },
{ .label = "dec21140A", .policy_str = "restart" },
{ .label = "dp8390", .policy_str = "restart" },
{ .label = "dpeth", .policy_str = "restart" },
{ .label = "e1000", .policy_str = "restart" },
{ .label = "fxp", .policy_str = "restart" },
{ .label = "lance", .policy_str = "restart" },
{ .label = "lan8710a", .policy_str = "restart" },
{ .label = "orinoco", .policy_str = "restart" },
{ .label = "rtl8139", .policy_str = "restart" },
{ .label = "rtl8169", .policy_str = "restart" },
{ .label = "uds", .policy_str = "reset" },
{ .label = "virtio_net", .policy_str = "restart" },
/* power */
{ .label = "acpi", .policy_str = "" },
{ .label = "tps65217", .policy_str = "" },
{ .label = "tps65590", .policy_str = "" },
/* printer */
{ .label = "printer", .policy_str = "restart" },
/* sensors */
{ .label = "bmp085", .policy_str = "" },
{ .label = "sht21", .policy_str = "restart" },
{ .label = "tsl2550", .policy_str = "restart" },
/* storage */
{ .label = "ahci", .policy_str = "reset" },
{ .label = "at_wini", .policy_str = "reset" },
{ .label = "fbd", .policy_str = "reset" },
{ .label = "filter", .policy_str = "reset" },
{ .label = "floppy", .policy_str = "reset" },
{ .label = "memory", .policy_str = "restart" },
{ .label = "mmc", .policy_str = "reset" },
{ .label = "virtio_blk", .policy_str = "reset" },
{ .label = "vnd", .policy_str = "reset" },
/* system */
{ .label = "gpio", .policy_str = "restart" },
{ .label = "log", .policy_str = "restart" },
{ .label = "random", .policy_str = "restart" },
/* tty */
{ .label = "pty", .policy_str = "restart" },
{ .label = "tty", .policy_str = "" },
/* usb */
{ .label = "usbd", .policy_str = "" },
{ .label = "usb_hub", .policy_str = "" },
{ .label = "usb_storage", .policy_str = "" },
/* video */
{ .label = "fb", .policy_str = "" },
{ .label = "tda19988", .policy_str = "" },
/* vmm_guest */
{ .label = "vbox", .policy_str = "" },
/* fs */
{ .label = "ext2", .policy_str = "" },
{ .label = "hgfs", .policy_str = "" },
{ .label = "isofs", .policy_str = "" },
{ .label = "mfs", .policy_str = "" },
{ .label = "pfs", .policy_str = "" },
{ .label = "procfs", .policy_str = "" },
{ .label = "vbfs", .policy_str = "" },
/* net */
{ .label = "inet", .policy_str = "reset" },
{ .label = "lwip", .policy_str = "" },
/* servers */
{ .label = "devman", .policy_str = "" },
{ .label = "ds", .policy_str = "" },
{ .label = "input", .policy_str = "reset" },
{ .label = "ipc", .policy_str = "restart" },
{ .label = "is", .policy_str = "restart" },
{ .label = "pm", .policy_str = "" },
{ .label = "rs", .policy_str = "" },
{ .label = "sched", .policy_str = "" },
{ .label = "vfs", .policy_str = "" },
{ .label = "vm", .policy_str = "" },
//{ .label = "", .policy_str = "" },
};
root = get_root_inode();
/* Find the related policy, based on the file name of the service. */
ref_label = strrchr(rprocpub[slot].proc_name, '/');
if (NULL == ref_label)
ref_label = rprocpub[slot].proc_name;
memset(&stat, 0, sizeof(stat));
stat.mode = DIR_ALL_MODE;
stat.uid = SUPER_USER;
stat.gid = SUPER_USER;
memset(pol[slot].formatted, 0, MAX_POL_FORMAT_SZ);
for(pos = 0; pos < (sizeof(def_pol) / sizeof(def_pol[0])); pos++) {
if (0 == strcmp(ref_label, def_pol[pos].label)) {
(void)strncpy(pol[slot].formatted, def_pol[pos].policy_str, MAX_POL_FORMAT_SZ);
pol[slot].formatted[MAX_POL_FORMAT_SZ-1] = '\0';
break;
}
}
#else
/* Should do something sensible, based on flags from RS/SEF. */
#endif
service_node = add_inode(root, "service", NO_INDEX, &stat,
NR_SYS_PROCS, NULL);
if (service_node == NULL)
panic("unable to create service node");
return pol[slot].formatted;
}
/*
* Update the contents of the service directory, by first updating the RS
* tables and then updating the directory contents.
*/
void
static void
service_update(void)
{
struct inode *node;
@ -86,6 +201,29 @@ service_update(void)
}
}
/*
* Initialize the service directory.
*/
void
service_init(void)
{
struct inode *root, *node;
struct inode_stat stat;
root = get_root_inode();
memset(&stat, 0, sizeof(stat));
stat.mode = DIR_ALL_MODE;
stat.uid = SUPER_USER;
stat.gid = SUPER_USER;
service_node = add_inode(root, "service", NO_INDEX, &stat,
NR_SYS_PROCS, NULL);
if (service_node == NULL)
panic("unable to create service node");
}
/*
* A lookup request is being performed. If it is in the service directory,
* update the tables. We do this lazily, to reduce overhead.
@ -141,5 +279,8 @@ service_read(struct inode * node)
rp = &rproc[slot];
/* TODO: add a large number of other fields! */
buf_printf("%d %d\n", rpub->endpoint, rp->r_restarts);
buf_printf("filename: %s\n", rpub->proc_name);
buf_printf("endpoint: %d\n", rpub->endpoint);
buf_printf("restarts: %d\n", rp->r_restarts);
buf_printf("policies: %s\n", service_get_policies(policies, slot));
}

View File

@ -5,9 +5,63 @@
#include <minix/endpoint.h>
#include <minix/ipc.h>
#include <minix/com.h>
/* Functions defined by netdriver.c: */
void netdriver_announce(void);
int netdriver_receive(endpoint_t src, message *m_ptr, int *status_ptr);
/* The flags that make up the requested receive mode. */
#define NDEV_NOMODE DL_NOMODE /* targeted packets only */
#define NDEV_PROMISC DL_PROMISC_REQ /* promiscuous mode */
#define NDEV_MULTI DL_MULTI_REQ /* receive multicast packets */
#define NDEV_BROAD DL_BROAD_REQ /* receive broadcast packets */
/*
* For now, only ethernet-type network drivers are supported, and thus, we use
* some ethernet-specific data structures.
*/
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
/* Opaque data structure for copying in and out actual packet data. */
struct netdriver_data;
/* Function call table for network drivers. */
struct netdriver {
int (*ndr_init)(unsigned int instance, ether_addr_t *addr);
void (*ndr_stop)(void);
void (*ndr_mode)(unsigned int mode);
ssize_t (*ndr_recv)(struct netdriver_data *data, size_t max);
int (*ndr_send)(struct netdriver_data *data, size_t size);
void (*ndr_stat)(eth_stat_t *stat);
void (*ndr_intr)(unsigned int mask);
void (*ndr_alarm)(clock_t stamp);
void (*ndr_other)(const message *m_ptr, int ipc_status);
};
/* Functions defined by libnetdriver. */
void netdriver_task(const struct netdriver *ndp);
void netdriver_announce(void); /* legacy; deprecated */
int netdriver_init(const struct netdriver *ndp);
void netdriver_process(const struct netdriver * __restrict ndp,
const message * __restrict m_ptr, int ipc_status);
void netdriver_terminate(void);
void netdriver_recv(void);
void netdriver_send(void);
void netdriver_copyin(struct netdriver_data * __restrict data, size_t off,
void * __restrict ptr, size_t size);
void netdriver_copyout(struct netdriver_data * __restrict data, size_t off,
const void * __restrict ptr, size_t size);
void netdriver_portinb(struct netdriver_data *data, size_t off, long port,
size_t size);
void netdriver_portoutb(struct netdriver_data *data, size_t off, long port,
size_t size);
void netdriver_portinw(struct netdriver_data *data, size_t off, long port,
size_t size);
void netdriver_portoutw(struct netdriver_data *data, size_t off, long port,
size_t size);
#define netdriver_receive sef_receive_status /* legacy; deprecated */
#endif /* _MINIX_NETDRIVER_H */

View File

@ -98,11 +98,12 @@ int virtio_to_queue(struct virtio_device *dev, int qidx,
struct vumap_phys *bufs, size_t num, void *data);
/*
* If the host used a chain of descriptors, return 0 and set data
* as was given to virtio_to_queue(). If the host has not processed
* any element returns -1.
* If the host used a chain of descriptors, return 0, set data as was given to
* virtio_to_queue(), and if len is not NULL, set it to the resulting length.
* If the host has not processed any element, return -1.
*/
int virtio_from_queue(struct virtio_device *dev, int qidx, void **data);
int virtio_from_queue(struct virtio_device *dev, int qidx, void **data,
size_t *len);
/* IRQ related functions */
void virtio_irq_enable(struct virtio_device *dev);

View File

@ -5,6 +5,11 @@ PROG= kernel
BINDIR= /usr/sbin
MAN=
.if ${MACHINE_ARCH} == "earm" && ${MKLLVM:Uno} == "yes"
# BJG - problems with optimisation of the kernel by llvm
DBG=-O0
.endif
.include "arch/${MACHINE_ARCH}/Makefile.inc"
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \

View File

@ -17,9 +17,10 @@ stacktrace.o: ${NETBSDSRCDIR}/minix/lib/libsys/stacktrace.c
MINC_OBJS_UNPAGED= atoi.o \
printf.o subr_prf.o \
strcmp.o strcpy.o strlen.o strncmp.o \
memcpy.o memmove.o memset.o \
udivdi3.o umoddi3.o qdivrem.o
MINC_OBJS_UNPAGED+= __aeabi_ldiv0.o __aeabi_idiv0.o __aeabi_uldivmod.o divide.o divsi3.o udivsi3.o
memcpy.o memmove.o memset.o
MINC_OBJS_UNPAGED+= divsi3.o udivsi3.o umodsi3.o \
umoddi3.o udivmoddi4.o aeabi_uidivmod.o \
udivmodsi4.o aeabi_uldivmod.o
atoi.o: ${NETBSDSRCDIR}/minix/lib/libminc/atoi.c
printf.o: ${NETBSDSRCDIR}/sys/lib/libsa/printf.c
subr_prf.o: ${NETBSDSRCDIR}/sys/lib/libsa/subr_prf.c
@ -30,25 +31,18 @@ strlen.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strlen.S
strcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcpy.S
strcmp.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcmp.S
#strcat.o: ${NETBSDSRCDIR}/common/lib/libc/string/strcat.c
__aeabi_idiv0.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/__aeabi_idiv0.c
__aeabi_ldiv0.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/__aeabi_ldiv0.c
__aeabi_uldivmod.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/quad/__aeabi_uldivmod.S
divide.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/divide.S
divsi3.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/divsi3.S
udivsi3.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/udivsi3.S
divsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/divsi3.c
udivsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/udivsi3.c
umodsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/umodsi3.c
umoddi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/umoddi3.c
udivmoddi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/udivmoddi4.c
udivmodsi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/arm/udivmodsi4.S
aeabi_uidivmod.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/arm/aeabi_uidivmod.S
aeabi_uldivmod.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/arm/aeabi_uldivmod.S
# the following is required by pre_init.c
strncmp.o: ${NETBSDSRCDIR}/common/lib/libc/string/strncmp.c
# these are required by kprintn.o:
udivdi3.o: ${NETBSDSRCDIR}/common/lib/libc/quad/udivdi3.c
umoddi3.o: ${NETBSDSRCDIR}/common/lib/libc/quad/umoddi3.c
qdivrem.o: ${NETBSDSRCDIR}/common/lib/libc/quad/qdivrem.c
CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE
CPPFLAGS.__aeabi_ldiv0.c+= -D_STANDALONE
# LSC: putchar and kputc have the same signature. A bit hackish.
CPPFLAGS.subr_prf.c+= -Dputchar=kputc

View File

@ -2,15 +2,15 @@
#include "hw_intr.h"
#include "bsp_intr.h"
int hw_intr_mask(int irq){
void hw_intr_mask(int irq){
bsp_irq_mask(irq);
}
int hw_intr_unmask(int irq){
void hw_intr_unmask(int irq){
bsp_irq_unmask(irq);
}
int hw_intr_ack(int irq){};
int hw_intr_used(int irq){};
int hw_intr_not_used(int irq){};
int hw_intr_disable_all(){};
void hw_intr_ack(int irq){};
void hw_intr_used(int irq){};
void hw_intr_not_used(int irq){};
void hw_intr_disable_all(){};

View File

@ -5,11 +5,11 @@
#include "kernel/kernel.h"
void irq_handle(int irq);
int hw_intr_mask(int irq);
int hw_intr_unmask(int irq);
int hw_intr_ack(int irq);
int hw_intr_used(int irq);
int hw_intr_not_used(int irq);
int hw_intr_disable_all();
void hw_intr_mask(int irq);
void hw_intr_unmask(int irq);
void hw_intr_ack(int irq);
void hw_intr_used(int irq);
void hw_intr_not_used(int irq);
void hw_intr_disable_all();
#endif /* __HW_INTR_ARM_H__ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: memset.S,v 1.1 2005/12/20 19:28:49 christos Exp $ */
/* $NetBSD: memset.S,v 1.7 2013/12/02 21:21:33 joerg Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@ -68,6 +68,27 @@
#include <machine/asm.h>
#if 0 && defined(__minix)
#if defined(__ARM_EABI__) && !defined(_BZERO)
ENTRY(__aeabi_memset)
mov r3, r1
mov r1, r2
mov r2, r3
b memset
END(__aeabi_memset)
STRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
STRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
ENTRY(__aeabi_memclr)
mov r2, r1
mov r1, #0
b memset
END(__aeabi_memclr)
STRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
STRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
#endif
#endif /* #if 0 && defined(__minix) */
/*
* memset: Sets a block of memory to the specified value
*
@ -107,7 +128,7 @@ ENTRY(memset)
#ifndef _BZERO
orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */
#endif
#ifdef __XSCALE__
#ifdef _ARM_ARCH_DWORD_OK
tst ip, #0x04 /* Quad-align for Xscale */
#else
cmp r1, #0x10
@ -115,7 +136,7 @@ ENTRY(memset)
#ifndef _BZERO
orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */
#endif
#ifdef __XSCALE__
#ifdef _ARM_ARCH_DWORD_OK
subne r1, r1, #0x04 /* Quad-align if necessary */
strne r3, [ip], #0x04
cmp r1, #0x10
@ -128,40 +149,40 @@ ENTRY(memset)
/* Do 128 bytes at a time */
.Lmemset_loop128:
subs r1, r1, #0x80
#ifdef __XSCALE__
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
#ifdef _ARM_ARCH_DWORD_OK
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
#else
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
#endif
bgt .Lmemset_loop128
#if defined(__minix)
@ -174,16 +195,16 @@ ENTRY(memset)
/* Do 32 bytes at a time */
.Lmemset_loop32:
subs r1, r1, #0x20
#ifdef __XSCALE__
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
strged r2, [ip], #0x08
#ifdef _ARM_ARCH_DWORD_OK
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
#else
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
#endif
bgt .Lmemset_loop32
#if defined(__minix)
@ -194,15 +215,15 @@ ENTRY(memset)
adds r1, r1, #0x10 /* Partially adjust for extra sub */
/* Deal with 16 bytes or more */
#ifdef __XSCALE__
strged r2, [ip], #0x08
strged r2, [ip], #0x08
#ifdef _ARM_ARCH_DWORD_OK
strdge r2, r3, [ip], #0x08
strdge r2, r3, [ip], #0x08
#else
stmgeia ip!, {r2-r3}
stmgeia ip!, {r2-r3}
stmiage ip!, {r2-r3}
stmiage ip!, {r2-r3}
#endif
#if defined(__minix)
moveq r0, #0
moveq r0, #0
#endif
RETc(eq) /* Zero length so just exit */
@ -218,7 +239,7 @@ ENTRY(memset)
#endif
RETc(eq) /* Zero length so just exit */
#ifdef __XSCALE__
#ifdef _ARM_ARCH_DWORD_OK
/* Compensate for 64-bit alignment check */
adds r1, r1, #0x04
#if defined(__minix)
@ -231,8 +252,8 @@ ENTRY(memset)
#endif
strb r3, [ip], #0x01 /* Set 1 byte */
strgeb r3, [ip], #0x01 /* Set another byte */
strgtb r3, [ip] /* and a third */
strbge r3, [ip], #0x01 /* Set another byte */
strbgt r3, [ip] /* and a third */
#if defined(__minix)
mov r0, #0
#endif
@ -242,9 +263,9 @@ ENTRY(memset)
rsb r2, r2, #0x004
strb r3, [ip], #0x01 /* Set 1 byte */
cmp r2, #0x02
strgeb r3, [ip], #0x01 /* Set another byte */
strbge r3, [ip], #0x01 /* Set another byte */
sub r1, r1, r2
strgtb r3, [ip], #0x01 /* and a third */
strbgt r3, [ip], #0x01 /* and a third */
cmp r1, #0x04 /* More than 4 bytes left? */
bge .Lmemset_wordaligned /* Yup */
@ -256,12 +277,21 @@ ENTRY(memset)
RETc(eq) /* Zero length so exit */
strb r3, [ip], #0x01 /* Set 1 byte */
cmp r1, #0x02
strgeb r3, [ip], #0x01 /* Set another byte */
strgtb r3, [ip] /* and a third */
strbge r3, [ip], #0x01 /* Set another byte */
strbgt r3, [ip] /* and a third */
#if defined(__minix)
mov r0, #0
mov r0, #0
#endif
RET /* Exit */
#ifdef _BZERO
END(bzero)
#else
#if !defined(__minix)
END(memset)
#else
END(phys_memset)
#endif
#endif
#if defined(__minix)
LABEL(memset_fault) /* kernel can send us here */

View File

@ -422,5 +422,5 @@ void minix_shutdown(minix_timer_t *t) { arch_shutdown(0); }
void busy_delay_ms(int x) { }
int raise(int n) { panic("raise(%d)\n", n); }
int kern_phys_map_ptr( phys_bytes base_address, vir_bytes io_size, int vm_flags,
struct kern_phys_map * priv, vir_bytes ptr) {};
struct kern_phys_map * priv, vir_bytes ptr) { return -1; };
struct machine machine; /* pre init stage machine */

View File

@ -418,11 +418,17 @@ ENTRY(restore_user_context_syscall)
* enabling interrupts, and of course sysret instead of sysexit.
*/
mov 4(%esp), %ebp /* retrieve proc ptr arg */
/* restore PSW (before we switch to user stack!) */
movl PSWREG(%ebp), %edi /* load desired PSW to EDI */
push %edi
popf
mov PCREG(%ebp), %ecx /* sysret restores EIP using ECX */
mov SPREG(%ebp), %esp /* restore ESP directly */
mov AXREG(%ebp), %eax /* trap return value */
mov BXREG(%ebp), %ebx /* secondary return value */
movl PSWREG(%ebp), %edi /* load desired PSW to EDI */
sysret /* jump to EIP in user */
ENTRY(restore_user_context_int)

View File

@ -43,8 +43,6 @@ ENTRY(usermapped_ ## name ## _sysenter) ;\
SETARGS /* call-specific register setup */ ;\
sysenter /* disappear into kernel */ ;\
0: ;\
push %edi /* kernel has desired PSW in %edi */ ;\
popf /* set PSW kernel wants us to have */ ;\
mov %ebx, %ecx /* return w. state mangled; save %ebx */;\
pop %edi ;\
pop %esi ;\
@ -69,8 +67,6 @@ ENTRY(usermapped_ ## name ## _syscall) ;\
SETARGS /* call-specific register setup */ ;\
movl %ecx, %edx /* %ecx is clobbered by SYSCALL */ ;\
syscall /* disappear into kernel */ ;\
push %edi /* kernel has desired PSW in %edi */ ;\
popf /* set PSW kernel wants us to have */ ;\
mov %ebx, %ecx /* return w. state mangled; save %ebx */;\
pop %edi ;\
pop %esi ;\

View File

@ -1095,7 +1095,7 @@ int mini_notify(
#define ASCOMPLAIN(caller, entry, field) \
printf("kernel:%s:%d: asyn failed for %s in %s " \
"(%d/%d, tab 0x%lx)\n",__FILE__,__LINE__, \
"(%d/%zu, tab 0x%lx)\n",__FILE__,__LINE__, \
field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
#define A_RETR_FLD(entry, field) \

View File

@ -127,12 +127,22 @@ CPPFLAGS.sha2.c+= -D_STANDALONE
CPPFLAGS.sha2.c+= -I${NETBSDSRCDIR}/sys
.for f in \
ashrdi3.o divdi3.o lshldi3.o lshrdi3.o moddi3.o \
udivdi3.o umoddi3.o qdivrem.o
${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/quad/${f:C/\.o/.c/}
ashrdi3.o divdi3.o lshrdi3.o moddi3.o \
udivdi3.o umoddi3.o umodsi3.o udivsi3.o \
udivmoddi4.o divsi3.o modsi3.o divmoddi4.o \
divmodsi4.o udivmodsi4.o #qdivrem.o lshldi3.o
${f} ${f:C/\.o/.bc/}: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/${f:C/\.o/.c/}
OBJS+= ${f}
CLEANFILES+= ${f}
COPTS+= -Wno-missing-prototypes \
-Wno-old-style-definition \
-Wno-strict-prototypes \
-Wno-uninitialized \
-Wno-cast-qual
.if ${USE_BITCODE:Uno} == "yes"
OBJS+= ${f:C/\.o/.bc/}
CLEANFILES+= ${f:C/\.o/.bc/}

View File

@ -11,7 +11,7 @@ CLEANFILES+= ${f}
.endfor
.for f in \
byte_swap_2.o byte_swap_4.o divsi3.o divide.o udivsi3.o
byte_swap_2.o byte_swap_4.o
${f}: ${LIBCOMMONCARCHDIR}/gen/${f:C/\.o/.S/}
OBJS+= ${f}
CLEANFILES+= ${f}
@ -29,12 +29,12 @@ CLEANFILES+= ${f}
CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE
CPPFLAGS.__aeabi_ldiv0.c+= -D_STANDALONE
.for f in \
__aeabi_ldivmod.o __aeabi_uldivmod.o
${f}: ${LIBCOMMONCARCHDIR}/quad/${f:C/\.o/.S/}
OBJS+= ${f}
CLEANFILES+= ${f}
.endfor
#.for f in \
# __aeabi_ldivmod.o __aeabi_uldivmod.o
#${f}: ${LIBCOMMONCARCHDIR}/quad/${f:C/\.o/.S/}
#OBJS+= ${f}
#CLEANFILES+= ${f}
#.endfor
.for f in \
memcmp.o memcpy.o memmove.o memset.o \
@ -72,6 +72,13 @@ OBJS+= ${f}
CLEANFILES+= ${f}
.endfor
.for f in \
aeabi_uidivmod.o aeabi_ldivmod.o aeabi_uldivmod.o aeabi_idivmod.o
${f}: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/arm/${f:C/\.o/.S/}
OBJS+= ${f}
CLEANFILES+= ${f}
.endfor
.for f in \
fpgetround.o fpsetround.o fpgetmask.o fpsetmask.o \
fpgetsticky.o fpsetsticky.o

View File

@ -6,6 +6,6 @@ CPPFLAGS+= -D_MINIX_SYSTEM
LIB= netdriver
SRCS= netdriver.c
SRCS= netdriver.c portio.c
.include <bsd.lib.mk>

View File

@ -1,82 +1,620 @@
/* This file contains device independent network device driver interface.
*
* Changes:
* Apr 01, 2010 Created (Cristiano Giuffrida)
*
* The file contains the following entry points:
*
* netdriver_announce: called by a network driver to announce it is up
* netdriver_receive: receive() interface for network drivers
*/
/* The device-independent network driver framework. */
#include <minix/drivers.h>
#include <minix/endpoint.h>
#include <minix/netdriver.h>
#include <minix/ds.h>
#include <assert.h>
static int conf_expected = TRUE;
#include "netdriver.h"
/*===========================================================================*
* netdriver_announce *
*===========================================================================*/
void netdriver_announce()
static const struct netdriver *netdriver_table = NULL;
static int running;
static int conf_expected;
static endpoint_t pending_endpt;
static struct netdriver_data pending_recv, pending_send;
static int defer_reply;
static unsigned int pending_flags;
static size_t pending_size;
static ether_addr_t hw_addr;
/*
* Announce we are up after a fresh start or restart.
*/
void
netdriver_announce(void)
{
/* Announce we are up after a fresh start or restart. */
int r;
char key[DS_MAX_KEYLEN];
char label[DS_MAX_KEYLEN];
const char *driver_prefix = "drv.net.";
const char *driver_prefix = "drv.net.";
char label[DS_MAX_KEYLEN];
char key[DS_MAX_KEYLEN];
int r;
/* Publish a driver up event. */
r = ds_retrieve_label_name(label, sef_self());
if (r != OK) {
panic("driver_announce: unable to get own label: %d\n", r);
}
snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label);
r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE);
if (r != OK) {
panic("driver_announce: unable to publish driver up event: %d\n", r);
}
/* Publish a driver up event. */
if ((r = ds_retrieve_label_name(label, sef_self())) != OK)
panic("netdriver: unable to get own label: %d", r);
conf_expected = TRUE;
snprintf(key, sizeof(key), "%s%s", driver_prefix, label);
if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK)
panic("netdriver: unable to publish driver up event: %d", r);
}
/*===========================================================================*
* netdriver_receive *
*===========================================================================*/
int netdriver_receive(src, m_ptr, status_ptr)
endpoint_t src;
message *m_ptr;
int *status_ptr;
/*
* Prepare for copying. Given a flat offset, return the vector element index
* and an offset into that element. Panic if the request does not fall
* entirely within the vector.
*/
size_t
netdriver_prepare_copy(struct netdriver_data * data, size_t off, size_t size,
unsigned int * indexp)
{
/* receive() interface for drivers. */
int r;
unsigned int i;
while (TRUE) {
/* Wait for a request. */
r = sef_receive_status(src, m_ptr, status_ptr);
if (r != OK) {
return r;
assert(data->size > 0);
/*
* In theory we could truncate when copying out, but this creates a
* problem for port-based I/O, where the size of the transfer is
* typically specified in advance. We could do extra port-based I/O
* to discard the extra bytes, but the driver is better off doing such
* truncation itself. Thus, we disallow copying (in and out) beyond
* the given data vector altogether.
*/
if (off + size > data->size)
panic("netdriver: request to copy beyond data size");
/*
* Find the starting offset in the vector. If this turns out to be
* expensive, this can be adapted to store the last <element,offset>
* pair in the "data" structure (this is the reason it is not 'const').
*/
for (i = 0; i < data->count; i++) {
assert(data->iovec[i].iov_size > 0);
if (off >= data->iovec[i].iov_size)
off -= data->iovec[i].iov_size;
else
break;
}
/* Let non-datalink requests through regardless. */
if (!IS_DL_RQ(m_ptr->m_type)) {
return r;
}
assert(i < data->count);
/* See if only DL_CONF is to be expected. */
if(conf_expected) {
if(m_ptr->m_type == DL_CONF) {
conf_expected = FALSE;
}
else {
continue;
}
}
break;
}
return OK;
*indexp = i;
return off;
}
/*
* Copy in or out packet data from/to a vector of grants.
*/
static void
netdriver_copy(struct netdriver_data * data, size_t off, vir_bytes addr,
size_t size, int copyin)
{
struct vscp_vec vec[SCPVEC_NR];
size_t chunk;
unsigned int i, v;
int r;
off = netdriver_prepare_copy(data, off, size, &i);
/* Generate a new vector with all the individual copies to make. */
for (v = 0; size > 0; v++) {
chunk = data->iovec[i].iov_size - off;
if (chunk > size)
chunk = size;
assert(chunk > 0);
/*
* We should be able to fit the entire I/O request in a single
* copy vector. If not, MINIX3 has been misconfigured.
*/
if (v >= SCPVEC_NR)
panic("netdriver: invalid vector size constant");
if (copyin) {
vec[v].v_from = data->endpt;
vec[v].v_to = SELF;
} else {
vec[v].v_from = SELF;
vec[v].v_to = data->endpt;
}
vec[v].v_gid = data->iovec[i].iov_grant;
vec[v].v_offset = off;
vec[v].v_addr = addr;
vec[v].v_bytes = chunk;
i++;
off = 0;
addr += chunk;
size -= chunk;
}
assert(v > 0 && v <= SCPVEC_NR);
/*
* If only one vector element was generated, use a direct copy. This
* saves the kernel from having to copy in the vector.
*/
if (v == 1) {
if (copyin)
r = sys_safecopyfrom(vec->v_from, vec->v_gid,
vec->v_offset, vec->v_addr, vec->v_bytes);
else
r = sys_safecopyto(vec->v_to, vec->v_gid,
vec->v_offset, vec->v_addr, vec->v_bytes);
} else
r = sys_vsafecopy(vec, v);
if (r != OK)
panic("netdriver: unable to copy data: %d", r);
}
/*
* Copy in packet data.
*/
void
netdriver_copyin(struct netdriver_data * __restrict data, size_t off,
void * __restrict ptr, size_t size)
{
netdriver_copy(data, off, (vir_bytes)ptr, size, TRUE /*copyin*/);
}
/*
* Copy out packet data.
*/
void
netdriver_copyout(struct netdriver_data * __restrict data, size_t off,
const void * __restrict ptr, size_t size)
{
netdriver_copy(data, off, (vir_bytes)ptr, size, FALSE /*copyin*/);
}
/*
* Send a reply to a request.
*/
static void
send_reply(endpoint_t endpt, message * m_ptr)
{
int r;
if ((r = ipc_send(endpt, m_ptr)) != OK)
panic("netdriver: unable to send to %d: %d", endpt, r);
}
/*
* Defer sending any replies to task requests until the next call to
* check_replies(). The purpose of this is aggregation of task replies to both
* send and receive requests into a single reply message, which saves on
* messages, in particular when processing interrupts.
*/
static void
defer_replies(void)
{
assert(netdriver_table != NULL);
assert(defer_reply == FALSE);
defer_reply = TRUE;
}
/*
* Check if we have to reply to earlier task (I/O) requests, and if so, send
* the reply. If deferred is FALSE and the call to this function was preceded
* by a call to defer_replies(), do not send a reply yet. If always_send is
* TRUE, send a reply even if no tasks have completed yet.
*/
static void
check_replies(int deferred, int always_send)
{
message m_reply;
if (defer_reply && !deferred)
return;
defer_reply = FALSE;
if (pending_flags == 0 && !always_send)
return;
assert(pending_endpt != NONE);
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DL_TASK_REPLY;
m_reply.m_netdrv_net_dl_task.flags = pending_flags;
m_reply.m_netdrv_net_dl_task.count = pending_size;
send_reply(pending_endpt, &m_reply);
pending_flags = 0;
pending_size = 0;
}
/*
* Resume receiving packets. In particular, if a receive request was pending,
* call the driver's receive function. If the call is successful, schedule
* sending a reply to the requesting party.
*/
void
netdriver_recv(void)
{
ssize_t r;
if (pending_recv.size == 0)
return;
assert(netdriver_table != NULL);
/*
* For convenience of driver writers: if the receive function returns
* zero, simply call it again, to simplify discarding invalid packets.
*/
do {
r = netdriver_table->ndr_recv(&pending_recv,
pending_recv.size);
/*
* The default policy is: drop undersized packets, panic on
* oversized packets. The driver may implement any other
* policy (e.g., pad small packets, drop or truncate large
* packets), but it should at least test against the given
* 'max' value. The reason that truncation should be
* implemented in the driver rather than here, is explained in
* an earlier comment about truncating copy operations.
*/
if (r >= 0 && r < ETH_MIN_PACK_SIZE)
r = 0;
else if (r > (ssize_t)pending_recv.size)
panic("netdriver: oversized packet returned: %zd", r);
} while (r == 0);
if (r == SUSPEND)
return;
if (r < 0)
panic("netdriver: driver reported receive failure: %d", r);
assert(r >= ETH_MIN_PACK_SIZE && (size_t)r <= pending_recv.size);
pending_flags |= DL_PACK_RECV;
pending_size = r;
pending_recv.size = 0;
check_replies(FALSE /*deferred*/, FALSE /*always_send*/);
}
/*
* Resume sending packets. In particular, if a send request was pending, call
* the driver's send function. If the call is successful, schedule sending a
* reply to the requesting party. This function relies on being called
* between init_pending() and check_pending().
*/
void
netdriver_send(void)
{
int r;
if (pending_send.size == 0)
return;
assert(netdriver_table != NULL);
r = netdriver_table->ndr_send(&pending_send, pending_send.size);
if (r == SUSPEND)
return;
if (r < 0)
panic("netdriver: driver reported send failure: %d", r);
pending_flags |= DL_PACK_SEND;
pending_send.size = 0;
check_replies(FALSE /*deferred*/, FALSE /*always_send*/);
}
/*
* Process a request to receive or send a packet.
*/
static void
do_readwrite(const struct netdriver * __restrict ndp, endpoint_t endpt,
cp_grant_id_t grant, unsigned int count, int write)
{
struct netdriver_data *data;
unsigned int i;
int r;
/* Copy in the I/O vector. */
data = (write) ? &pending_send : &pending_recv;
if (data->size != 0)
panic("netdriver: multiple concurrent requests");
if (count == 0 || count > NR_IOREQS)
panic("netdriver: bad I/O vector count: %u", count);
data->endpt = endpt;
data->count = count;
if ((r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)data->iovec,
sizeof(data->iovec[0]) * count)) != OK)
panic("netdriver: unable to copy in I/O vector: %d", r);
for (i = 0; i < count; i++)
data->size += data->iovec[i].iov_size;
if (data->size < ETH_MIN_PACK_SIZE ||
(!write && data->size < ETH_MAX_PACK_SIZE_TAGGED))
panic("netdriver: invalid I/O vector size: %zu\n", data->size);
/* Save the endpoint to which we should reply. */
if (pending_endpt != NONE && pending_endpt != endpt)
panic("netdriver: multiple request sources");
pending_endpt = endpt;
/* Resume sending or receiving. */
defer_replies();
if (write)
netdriver_send();
else
netdriver_recv();
/* Always send a reply in this case, even if no flags are set. */
check_replies(TRUE /*deferred*/, TRUE /*always_send*/);
}
/*
* Process a request to configure the driver, by setting its mode and obtaining
* its ethernet hardware address. We already have the latter as a result of
* calling the ndr_init callback function.
*/
static void
do_conf(const struct netdriver * __restrict ndp,
const message * __restrict m_ptr)
{
message m_reply;
if (ndp->ndr_mode != NULL)
ndp->ndr_mode(m_ptr->m_net_netdrv_dl_conf.mode);
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DL_CONF_REPLY;
m_reply.m_netdrv_net_dl_conf.stat = OK; /* legacy */
memcpy(&m_reply.m_netdrv_net_dl_conf.hw_addr, &hw_addr,
sizeof(m_reply.m_netdrv_net_dl_conf.hw_addr));
send_reply(m_ptr->m_source, &m_reply);
}
/*
* Process a request to obtain statistics from the driver.
*/
static void
do_getstat(const struct netdriver * __restrict ndp,
const message * __restrict m_ptr)
{
message m_reply;
eth_stat_t stat;
int r;
memset(&stat, 0, sizeof(stat));
if (ndp->ndr_stat != NULL)
ndp->ndr_stat(&stat);
if ((r = sys_safecopyto(m_ptr->m_source,
m_ptr->m_net_netdrv_dl_getstat_s.grant, 0, (vir_bytes)&stat,
sizeof(stat))) != OK)
panic("netdriver: unable to copy out statistics: %d", r);
memset(&m_reply, 0, sizeof(m_reply));
m_reply.m_type = DL_STAT_REPLY;
send_reply(m_ptr->m_source, &m_reply);
}
/*
* Process an incoming message, and send a reply.
*/
void
netdriver_process(const struct netdriver * __restrict ndp,
const message * __restrict m_ptr, int ipc_status)
{
netdriver_table = ndp;
/* Check for notifications first. */
if (is_ipc_notify(ipc_status)) {
defer_replies();
switch (_ENDPOINT_P(m_ptr->m_source)) {
case HARDWARE:
if (ndp->ndr_intr != NULL)
ndp->ndr_intr(m_ptr->m_notify.interrupts);
break;
case CLOCK:
if (ndp->ndr_alarm != NULL)
ndp->ndr_alarm(m_ptr->m_notify.timestamp);
break;
default:
if (ndp->ndr_other != NULL)
ndp->ndr_other(m_ptr, ipc_status);
}
/*
* Any of the above calls may end up invoking netdriver_send()
* and/or netdriver_recv(), which may in turn have deferred
* sending a reply to an earlier request. See if we have to
* send the reply now.
*/
check_replies(TRUE /*deferred*/, FALSE /*always_send*/);
}
/*
* Discard datalink requests preceding a first DL_CONF request, so that
* after a driver restart, any in-flight request is discarded. This is
* a rather blunt approach and must be revised if the protocol is ever
* made less inefficient (i.e. not strictly serialized). Note that for
* correct driver operation it is important that non-datalink requests,
* interrupts in particular, do not go through this check.
*/
if (IS_DL_RQ(m_ptr->m_type) && conf_expected) {
if (m_ptr->m_type != DL_CONF)
return; /* do not send a reply */
conf_expected = FALSE;
}
switch (m_ptr->m_type) {
case DL_CONF:
do_conf(ndp, m_ptr);
break;
case DL_GETSTAT_S:
do_getstat(ndp, m_ptr);
break;
case DL_READV_S:
do_readwrite(ndp, m_ptr->m_source,
m_ptr->m_net_netdrv_dl_readv_s.grant,
m_ptr->m_net_netdrv_dl_readv_s.count, FALSE /*write*/);
break;
case DL_WRITEV_S:
do_readwrite(ndp, m_ptr->m_source,
m_ptr->m_net_netdrv_dl_writev_s.grant,
m_ptr->m_net_netdrv_dl_writev_s.count, TRUE /*write*/);
break;
default:
defer_replies();
if (ndp->ndr_other != NULL)
ndp->ndr_other(m_ptr, ipc_status);
/* As above: see if we have to send a reply now. */
check_replies(TRUE /*deferred*/, FALSE /*always_send*/);
}
}
/*
* Perform initialization. Return OK or an error code.
*/
int
netdriver_init(const struct netdriver * ndp)
{
unsigned int instance;
long v;
int r;
/* Initialize global variables. */
pending_recv.size = 0;
pending_send.size = 0;
pending_endpt = NONE;
defer_reply = FALSE;
pending_flags = 0;
pending_size = 0;
conf_expected = TRUE;
/* Get the card instance number. */
v = 0;
(void)env_parse("instance", "d", 0, &v, 0, 255);
instance = (unsigned int)v;
/* Call the initialization routine. */
memset(&hw_addr, 0, sizeof(hw_addr));
if (ndp->ndr_init != NULL &&
(r = ndp->ndr_init(instance, &hw_addr)) != OK)
return r;
/* Announce we are up! */
netdriver_announce();
return OK;
}
/*
* SEF initialization function.
*/
static int
do_init(int __unused type, sef_init_info_t * __unused info)
{
const struct netdriver *ndp;
ndp = netdriver_table;
assert(ndp != NULL);
return netdriver_init(ndp);
}
/*
* Break out of the main loop after finishing the current request.
*/
void
netdriver_terminate(void)
{
if (netdriver_table != NULL && netdriver_table->ndr_stop != NULL)
netdriver_table->ndr_stop();
running = FALSE;
sef_cancel();
}
/*
* The process has received a signal. See if we have to terminate.
*/
static void
got_signal(int sig)
{
if (sig != SIGTERM)
return;
netdriver_terminate();
}
/*
* Main program of any network driver.
*/
void
netdriver_task(const struct netdriver * ndp)
{
message mess;
int r, ipc_status;
/* Perform SEF initialization. */
sef_setcb_init_fresh(do_init);
sef_setcb_init_restart(do_init); /* TODO: revisit this */
sef_setcb_signal_handler(got_signal);
netdriver_table = ndp;
sef_startup();
netdriver_table = NULL;
/* The main message loop. */
running = TRUE;
while (running) {
if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK) {
if (r == EINTR)
continue; /* sef_cancel() was called */
panic("netdriver: sef_receive_status failed: %d", r);
}
netdriver_process(ndp, &mess, ipc_status);
}
}

View File

@ -0,0 +1,15 @@
#ifndef _MINIX_LIB_NETDRIVER_NETDRIVER_H
#define _MINIX_LIB_NETDRIVER_NETDRIVER_H
/* Data (I/O) structure. */
struct netdriver_data {
endpoint_t endpt;
size_t size;
unsigned int count;
iovec_s_t iovec[NR_IOREQS];
};
size_t netdriver_prepare_copy(struct netdriver_data *data, size_t offp,
size_t size, unsigned int * indexp);
#endif /* !_MINIX_LIB_NETDRIVER_NETDRIVER_H */

View File

@ -0,0 +1,193 @@
/*
* Port-based I/O routines. These are in a separate module because most
* drivers will not use them, and system services are statically linked.
*/
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <assert.h>
#include "netdriver.h"
/*
* Port-based I/O byte sequence copy routine.
*/
static void
netdriver_portb(struct netdriver_data * data, size_t off, long port,
size_t size, int portin)
{
size_t chunk;
unsigned int i;
int r, req;
off = netdriver_prepare_copy(data, off, size, &i);
req = portin ? DIO_SAFE_INPUT_BYTE : DIO_SAFE_OUTPUT_BYTE;
while (size > 0) {
chunk = data->iovec[i].iov_size - off;
if (chunk > size)
chunk = size;
assert(chunk > 0);
if ((r = sys_sdevio(req, port, data->endpt,
(void *)data->iovec[i].iov_grant, chunk, off)) != OK)
panic("netdriver: port I/O failed: %d", r);
i++;
off = 0;
size -= chunk;
}
}
/*
* Transfer bytes from hardware to a destination buffer using port-based I/O.
*/
void
netdriver_portinb(struct netdriver_data * data, size_t off, long port,
size_t size)
{
return netdriver_portb(data, off, port, size, TRUE /*portin*/);
}
/*
* Transfer bytes from a source buffer to hardware using port-based I/O.
*/
void
netdriver_portoutb(struct netdriver_data * data, size_t off, long port,
size_t size)
{
return netdriver_portb(data, off, port, size, FALSE /*portin*/);
}
/*
* Transfer words from hardware to a destination buffer using port-based I/O.
*/
void
netdriver_portinw(struct netdriver_data * data, size_t off, long port,
size_t size)
{
uint8_t buf[2];
uint32_t value;
size_t chunk;
unsigned int i;
int r, odd_byte;
off = netdriver_prepare_copy(data, off, size, &i);
odd_byte = 0;
while (size > 0) {
chunk = data->iovec[i].iov_size - off;
if (chunk > size)
chunk = size;
assert(chunk > 0);
if (odd_byte) {
if ((r = sys_safecopyto(data->endpt,
data->iovec[i].iov_grant, off, (vir_bytes)&buf[1],
1)) != OK)
panic("netdriver: unable to copy data: %d", r);
off++;
size--;
chunk--;
}
odd_byte = chunk & 1;
chunk -= odd_byte;
if (chunk > 0) {
if ((r = sys_safe_insw(port, data->endpt,
data->iovec[i].iov_grant, off, chunk)) != OK)
panic("netdriver: port input failed: %d", r);
off += chunk;
size -= chunk;
}
if (odd_byte) {
if ((r = sys_inw(port, &value)) != OK)
panic("netdriver: port input failed: %d", r);
*(uint16_t *)buf = (uint16_t)value;
if ((r = sys_safecopyto(data->endpt,
data->iovec[i].iov_grant, off, (vir_bytes)&buf[0],
1)) != OK)
panic("netdriver: unable to copy data: %d", r);
size--;
}
i++;
off = 0;
}
}
/*
* Transfer words from a source buffer to hardware using port-based I/O.
*/
void
netdriver_portoutw(struct netdriver_data * data, size_t off, long port,
size_t size)
{
uint8_t buf[2];
size_t chunk;
unsigned int i;
int r, odd_byte;
off = netdriver_prepare_copy(data, off, size, &i);
odd_byte = 0;
while (size > 0) {
chunk = data->iovec[i].iov_size - off;
if (chunk > size)
chunk = size;
assert(chunk > 0);
if (odd_byte) {
if ((r = sys_safecopyfrom(data->endpt,
data->iovec[i].iov_grant, off, (vir_bytes)&buf[1],
1)) != OK)
panic("netdriver: unable to copy data: %d", r);
if ((r = sys_outw(port, *(uint16_t *)buf)) != OK)
panic("netdriver: port output failed: %d", r);
off++;
size--;
chunk--;
}
odd_byte = chunk & 1;
chunk -= odd_byte;
if (chunk > 0) {
if ((r = sys_safe_outsw(port, data->endpt,
data->iovec[i].iov_grant, off, chunk)) != OK)
panic("netdriver: port output failed: %d", r);
off += chunk;
size -= chunk;
}
if (odd_byte) {
if ((r = sys_safecopyfrom(data->endpt,
data->iovec[i].iov_grant, off, (vir_bytes)&buf[0],
1)) != OK)
panic("netdriver: unable to copy data: %d", r);
size--;
}
i++;
off = 0;
}
if (odd_byte) {
buf[1] = 0;
if ((r = sys_outw(port, *(uint16_t *)buf)) != OK)
panic("netdriver: port output failed: %d", r);
}
}

View File

@ -639,7 +639,8 @@ virtio_to_queue(struct virtio_device *dev, int qidx, struct vumap_phys *bufs,
}
int
virtio_from_queue(struct virtio_device *dev, int qidx, void **data)
virtio_from_queue(struct virtio_device *dev, int qidx, void **data,
size_t *len)
{
struct virtio_queue *q;
struct vring *vring;
@ -718,6 +719,9 @@ virtio_from_queue(struct virtio_device *dev, int qidx, void **data)
*data = q->data[uel->id];
q->data[uel->id] = NULL;
if (len != NULL)
*len = uel->len;
return 0;
}

View File

@ -6,6 +6,8 @@ SUBDIR+= inet
. if ${MKLWIP} == "yes"
SUBDIR+= lwip
. endif # ${MKLWIP} == "yes"
SUBDIR+= uds
.endif # ${MKIMAGEONLY} == "no"
.include <bsd.subdir.mk>

View File

@ -14,6 +14,8 @@ SRCS= buf.c clock.c inet.c inet_config.c \
WARNS=
NOCLANGERROR=yes
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
LDADD+= -lchardriver -lsys

View File

@ -1149,7 +1149,7 @@ acc_t *acc;
}
if (acc->acc_offset + acc->acc_length > buffer->buf_size)
{
printf("%d + %d > %d for buffer %p, and acc %p\n",
printf("%d + %d > %zu for buffer %p, and acc %p\n",
acc->acc_offset, acc->acc_length,
buffer->buf_size, buffer, acc);
return 0;

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