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} COMMON_DIR:=${.PARSEDIR}
.if defined(__MINIX) .if defined(__MINIX)
COMMON_CODEDIRS=atomic gen inet md net quad stdlib string COMMON_CODEDIRS=atomic gen inet md net stdlib string
.else .else
COMMON_CODEDIRS=atomic gen gmon inet md net quad stdlib string sys COMMON_CODEDIRS=atomic gen gmon inet md net quad stdlib string sys
.endif .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. * Copyright 2003 Wasabi Systems, Inc.
@ -68,8 +68,23 @@
#include <machine/asm.h> #include <machine/asm.h>
#if defined(__ARM_EABI__) && !defined(BZER0) #if defined(__ARM_EABI__) && !defined(_BZERO)
STRONG_ALIAS(__aeabi_memset, memset) 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
/* /*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -280,8 +280,14 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
// Thumb2 is the default for V7 on Darwin. // Thumb2 is the default for V7 on Darwin.
// //
// FIXME: Thumb should just be another -target-feaure, not in the triple. // 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 = StringRef Suffix =
getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
#endif
bool ThumbDefault = Suffix.startswith("v6m") || bool ThumbDefault = Suffix.startswith("v6m") ||
(Suffix.startswith("v7") && getTriple().isOSDarwin()); (Suffix.startswith("v7") && getTriple().isOSDarwin());
std::string ArchName = "arm"; 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 --
* Put text buffer contents into the file. * 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 int
put(SCR *sp, CB *cbp, ARG_CHAR_T *namep, MARK *cp, MARK *rp, int append) 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> .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 USE_WIDECHAR?=yes
CWARNFLAGS.clang+= -Wno-uninitialized -Wno-format-security CWARNFLAGS.clang+= -Wno-uninitialized -Wno-format-security

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
# $NetBSD: Makefile.inc,v 1.25 2013/08/21 03:09:39 matt Exp $ # $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 \ SRCS+= alloca.S byte_swap_2.S byte_swap_4.S bswap64.c \
fabs.c flt_rounds.c udivsi3.S fabs.c flt_rounds.c
CPUFLAGS.divide.S+= -marm CPUFLAGS.divide.S+= -marm
@ -16,8 +16,6 @@ SRCS+= signbitf_ieee754.c signbitd_ieee754.c
.if !empty(LIBC_MACHINE_ARCH:Mearm*) .if !empty(LIBC_MACHINE_ARCH:Mearm*)
SRCS+= __aeabi_fcmpun.c __aeabi_dcmpun.c SRCS+= __aeabi_fcmpun.c __aeabi_dcmpun.c
SRCS+= __aeabi_idiv0.c __aeabi_ldiv0.c SRCS+= __aeabi_idiv0.c __aeabi_ldiv0.c
.else
SRCS+= modsi3.S umodsi3.S
.endif .endif
SRCS+= nanf.c 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} COMPILER_RT_ARCH_DIR= ${COMPILER_RT_SRCDIR}/lib/${MACHINE_ARCH}
.endif .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_CPU_DIR}
.PATH: ${COMPILER_RT_ARCH_DIR} .PATH: ${COMPILER_RT_ARCH_DIR}
.endif # !defined(__MINIX) .endif # .if !empty(LIBC_MACHINE_ARCH:Mearm*) && defined(__MINIX)
.PATH: ${COMPILER_RT_SRCDIR}/lib .PATH: ${COMPILER_RT_SRCDIR}/lib
# Complex support needs parts of libm # Complex support needs parts of libm
@ -25,127 +30,190 @@ COMPILER_RT_ARCH_DIR= ${COMPILER_RT_SRCDIR}/lib/${MACHINE_ARCH}
# divdc3.c \ # divdc3.c \
# divsc3.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+= \ 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 \ comparedf2.c \
comparesf2.c \ comparesf2.c \
ctzdi2.c \ adddf3.c \
ctzsi2.c \ addsf3.c \
ctzti2.c \ addtf3.c \
divdf3.c \ divdf3.c \
divdi3.c \
divmoddi4.c \
divmodsi4.c \
divsf3.c \ divsf3.c \
divsi3.c \ divtf3.c \
divti3.c \
extendsfdf2.c \ extendsfdf2.c \
ffsdi2.c \ extendsftf2.c \
ffsti2.c \ extenddftf2.c \
fixdfdi.c \
fixdfsi.c \ fixdfsi.c \
fixdfti.c \ fixdfti.c \
fixsfdi.c \
fixsfsi.c \ fixsfsi.c \
fixsfti.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 \ fixunsdfdi.c \
fixunsdfsi.c \ fixunsdfsi.c \
fixunsdfti.c \
fixunssfdi.c \ fixunssfdi.c \
fixunssfsi.c \ fixunssfsi.c \
fixunssfti.c \
fixunsxfdi.c \ fixunsxfdi.c \
fixunsxfsi.c \ fixunsxfsi.c \
fixunsxfti.c \
fixxfdi.c \ fixxfdi.c \
fixxfti.c \
floatdidf.c \ floatdidf.c \
floatdisf.c \ floatdisf.c \
floatdixf.c \ floatdixf.c \
floatsidf.c \
floatsisf.c \
floattidf.c \
floattisf.c \
floattixf.c \
floatundidf.c \ floatundidf.c \
floatundisf.c \ floatundisf.c \
floatundixf.c \ floatundixf.c \
floatunsidf.c \
floatunsisf.c \
floatuntidf.c \
floatuntisf.c \
floatuntixf.c \
gcc_personality_v0.c \
int_util.c \ int_util.c \
lshrdi3.c \
lshrti3.c \ lshrti3.c \
moddi3.c \
modsi3.c \
modti3.c \ modti3.c \
muldc3.c \ muldc3.c \
muldf3.c \
muldi3.c \
mulodi4.c \
mulosi4.c \ mulosi4.c \
muloti4.c \ muloti4.c \
mulsf3.c \
multi3.c \ multi3.c \
mulvdi3.c \
mulvsi3.c \ mulvsi3.c \
mulvti3.c \ mulvti3.c \
negdf2.c \ negdf2.c \
negdi2.c \
negsf2.c \ negsf2.c \
negti2.c \ negti2.c \
negvdi2.c \
negvsi2.c \ negvsi2.c \
negvti2.c \ negvti2.c \
paritydi2.c \
paritysi2.c \ paritysi2.c \
parityti2.c \ parityti2.c \
popcountdi2.c \
popcountsi2.c \ popcountsi2.c \
popcountti2.c \ popcountti2.c \
powidf2.c \ powidf2.c \
powisf2.c \ powisf2.c \
powitf2.c \ powitf2.c \
powixf2.c \ powixf2.c \
subdf3.c \
subsf3.c \
subvdi3.c \
subvsi3.c \ subvsi3.c \
subvti3.c \ subvti3.c \
truncdfsf2.c \
ucmpdi2.c \
ucmpti2.c \ ucmpti2.c \
udivdi3.c \
udivmoddi4.c \
udivmodsi4.c \
udivmodti4.c \ udivmodti4.c \
udivsi3.c \
udivti3.c \ udivti3.c \
umoddi3.c \
umodsi3.c \
umodti3.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+= \ GENERIC_SRCS+= \
fixtfdi.c \ fixtfdi.c \
fixunstfdi.c \ fixunstfdi.c \
@ -157,6 +225,30 @@ GENERIC_SRCS+= \
gcc_qsub.c gcc_qsub.c
.endif .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) .if !defined(__MINIX)
.for src in ${GENERIC_SRCS} .for src in ${GENERIC_SRCS}
. if exists(${COMPILER_RT_CPU_DIR}/${src:R}.S) || \ . if exists(${COMPILER_RT_CPU_DIR}/${src:R}.S) || \
@ -164,14 +256,26 @@ GENERIC_SRCS+= \
SRCS+= ${src:R}.S SRCS+= ${src:R}.S
. else . else
SRCS+= ${src} 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 . endif
.endfor .endfor
.else .else
# For MINIX: do not pull in the assembly symbols, as they are not PIC ready # For MINIX: do not pull in the assembly symbols, as they are not PIC ready
.for src in ${GENERIC_SRCS} .for src in ${GENERIC_SRCS}
SRCS+= ${src} 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 .endfor
.for src in muldc3.c .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. * and smaller and such stores are atomic.
*/ */
dl_iterate_phdr_setup(); dl_iterate_phdr_setup();
#ifndef __minix
membar_producer(); membar_producer();
#endif
setup_done = true; setup_done = true;
} }

View File

@ -3,7 +3,12 @@
.include <bsd.own.mk> .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 WARNS= 2
.endif
CPPFLAGS+=-I${.CURDIR} -I${NETBSDSRCDIR}/lib/libterminfo CPPFLAGS+=-I${.CURDIR} -I${NETBSDSRCDIR}/lib/libterminfo
.if defined(DEBUG_CURSES) .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_cabs.c+= ${${ACTIVE_CC} == "clang":? -Wno-incompatible-library-redeclaration :}
COPTS.compat_cabsf.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" .include "${.CURDIR}/compiler_rt/Makefile.inc"
.endif .include "${.CURDIR}/gen/Makefile.inc"
.include <bsd.lib.mk> .include <bsd.lib.mk>
.include <bsd.subdir.mk> .include <bsd.subdir.mk>

View File

@ -9,6 +9,13 @@ LIB= rmt
SRCS= rmtlib.c SRCS= rmtlib.c
MAN= rmtops.3 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) .if !defined(__MINIX)
CPPFLAGS+= -D_REENTRANT CPPFLAGS+= -D_REENTRANT
.endif # !defined(__MINIX) .endif # !defined(__MINIX)

View File

@ -453,7 +453,7 @@ _rmt_write(int fildes, const void *buf, size_t nbyte)
return -1; return -1;
pstat = signal(SIGPIPE, SIG_IGN); 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); signal(SIGPIPE, pstat);
return status(fildes); 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) #if !defined(__minix)
(void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_len); (void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_len);
#else #else
(void)snprintf(nbuf, sizeof(nbuf), "%d", len); (void)snprintf(nbuf, sizeof(nbuf), "%zu", len);
#endif /* !defined(__minix) */ #endif /* !defined(__minix) */
ADDS(nbuf); ADDS(nbuf);
break; break;

View File

@ -109,7 +109,7 @@ cards()
card 0 "No Ethernet card (no networking)" card 0 "No Ethernet card (no networking)"
card 1 "3Com 501 or 3Com 509 based card" card 1 "3Com 501 or 3Com 509 based card"
card 2 "Realtek 8029 based card (also emulated by Qemu)" "10EC:8029" 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)" card 4 "lan8710a (on BeagleBone, BeagleBone Black)"
n=$first_pcicard n=$first_pcicard
for pcicard in $pci_list for pcicard in $pci_list
@ -197,10 +197,11 @@ drv_params()
test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration." test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration."
;; ;;
2) driver=dp8390; driverargs="dp8390_arg='DPETH0=pci'"; ;; 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 ""
test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration." 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; ;; 4) driver=lan8710a; ;;
$first_after_pci) driver="psip0"; ;; $first_after_pci) driver="psip0"; ;;

View File

@ -18,6 +18,4 @@ SUBDIR+= virtio_net
SUBDIR+= lan8710a SUBDIR+= lan8710a
.endif # ${MACHINE_ARCH} == "earm" .endif # ${MACHINE_ARCH} == "earm"
SUBDIR+= uds
.include <bsd.subdir.mk> .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_ABORTCOL 0x04000000 /* collision abort */
#define ATL2_TXS_UNDERRUN 0x08000000 /* buffer underrun */ #define ATL2_TXS_UNDERRUN 0x08000000 /* buffer underrun */
#define ATL2_TXS_UPDATE 0x80000000 /* updated by device */ #define ATL2_TXS_UPDATE 0x80000000 /* updated by device */

View File

@ -12,288 +12,105 @@
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/netdriver.h> #include <minix/netdriver.h>
#include <assert.h>
#include <machine/pci.h> #include <machine/pci.h>
#include <minix/syslib.h> #include <assert.h>
#include <minix/endpoint.h>
#include <minix/com.h>
#include <minix/sef.h>
#include <minix/ds.h>
#include <net/gen/ether.h>
#include <net/gen/eth_io.h>
#include <stdlib.h>
#include "dec21140A.h" #include "dec21140A.h"
static u32_t io_inl(u16_t); static u32_t io_inl(u16_t);
static void io_outl(u16_t, u32_t); static void io_outl(u16_t, u32_t);
static void do_conf(const message *);
static void do_get_stat_s(message *);
static void do_interrupt(const dpeth_t *);
static void do_reply(dpeth_t *);
static void do_vread_s(const message *, int);
static void do_watchdog(void *);
static void de_update_conf(dpeth_t *); static int do_init(unsigned int, ether_addr_t *);
static int de_probe(dpeth_t *, int skip); static void do_stop(void);
static void de_conf_addr(dpeth_t *); static int do_send(struct netdriver_data *, size_t);
static void de_first_init(dpeth_t *); static ssize_t do_recv(struct netdriver_data *, size_t);
static void do_stat(eth_stat_t *);
static void do_intr(unsigned int);
static int de_probe(dpeth_t *, unsigned int skip);
static void de_conf_addr(dpeth_t *, ether_addr_t *);
static void de_init_buf(dpeth_t *);
static void de_reset(const dpeth_t *); static void de_reset(const dpeth_t *);
static void de_hw_conf(const dpeth_t *); static void de_hw_conf(const dpeth_t *);
static void de_start(const dpeth_t *); static void de_start(const dpeth_t *);
static void de_setup_frame(const dpeth_t *); static void de_setup_frame(const dpeth_t *, const ether_addr_t *);
static u16_t de_read_rom(const dpeth_t *, u8_t, u8_t); static u16_t de_read_rom(const dpeth_t *, u8_t, u8_t);
static int de_calc_iov_size(iovec_dat_s_t *);
static void de_next_iov(iovec_dat_s_t *);
static void do_vwrite_s(const message *, int);
static void de_get_userdata_s(int, cp_grant_id_t, vir_bytes, int, void
*);
/* Error messages */
static char str_CopyErrMsg[] = "unable to read/write user data";
static char str_SendErrMsg[] = "send failed";
static char str_SizeErrMsg[] = "illegal packet size";
static char str_UmapErrMsg[] = "Unable to sys_umap";
static char str_BusyErrMsg[] = "Send/Recv failed: busy";
static char str_StatErrMsg[] = "Unable to send stats";
static char str_AlignErrMsg[] = "Bad align of buffer/descriptor";
static char str_DevName[] = "dec21140A:eth#?";
static dpeth_t de_state; static dpeth_t de_state;
static int de_instance; static int de_instance;
/* SEF functions and variables. */ static const struct netdriver de_table = {
static void sef_local_startup(void); .ndr_init = do_init,
static int sef_cb_init_fresh(int type, sef_init_info_t *info); .ndr_stop = do_stop,
.ndr_recv = do_recv,
.ndr_send = do_send,
.ndr_stat = do_stat,
.ndr_intr = do_intr
};
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
dpeth_t *dep;
message m;
int ipc_status;
int r;
/* SEF local startup. */
env_setargs(argc, argv); env_setargs(argc, argv);
sef_local_startup();
while (TRUE) netdriver_task(&de_table);
{
if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK)
panic("netdriver_receive failed: %d", r);
if(is_ipc_notify(ipc_status)) { return 0;
switch(_ENDPOINT_P(m.m_source)) {
case CLOCK:
do_watchdog(&m);
break;
case HARDWARE:
dep = &de_state;
if (dep->de_mode == DEM_ENABLED) {
do_interrupt(dep);
if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV))
do_reply(dep);
sys_irqenable(&dep->de_hook);
}
break;
default:
printf("ignoring notify from %d\n", m.m_source);
break;
}
continue;
}
switch (m.m_type)
{
case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break;
case DL_READV_S: do_vread_s(&m, FALSE); break;
case DL_CONF: do_conf(&m); break;
case DL_GETSTAT_S: do_get_stat_s(&m); break;
default:
printf("message 0x%x; %d from %d\n",
m.m_type, m.m_type-DL_RQ_BASE, m.m_source);
panic("illegal message: %d", m.m_type);
}
}
} }
/*===========================================================================* static void de_init_hw(dpeth_t *dep, ether_addr_t *addr)
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{ {
/* Register init callbacks. */ de_reset(dep);
sef_setcb_init_fresh(sef_cb_init_fresh); de_conf_addr(dep, addr);
sef_setcb_init_lu(sef_cb_init_fresh); de_init_buf(dep);
sef_setcb_init_restart(sef_cb_init_fresh);
/* Register live update callbacks. */ /* Set the interrupt handler policy. Request interrupts not to be reenabled
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); * automatically. Return the IRQ line number when an interrupt occurs.
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); */
dep->de_hook = dep->de_irq;
sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
sys_irqenable(&dep->de_hook);
/* Register signal callbacks. */ de_reset(dep);
sef_setcb_signal_handler(sef_cb_signal_handler_term); de_hw_conf(dep);
de_setup_frame(dep, addr);
/* Let SEF perform startup. */ de_start(dep);
sef_startup();
} }
/*===========================================================================* static int do_init(unsigned int instance, ether_addr_t *addr)
* sef_cb_init_fresh *
*===========================================================================*/
static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{ {
/* Initialize the DEC 21140A driver. */ /* Initialize the DEC 21140A driver. */
int fkeys, sfkeys; dpeth_t *dep;
long v;
v = 0; dep = &de_state;
(void) env_parse("instance", "d", 0, &v, 0, 255); memset(dep, 0, sizeof(*dep));
de_instance = (int) v;
/* Request function key for debug dumps */ strlcpy(dep->de_name, "dec21140A:?", sizeof(dep->de_name));
fkeys = sfkeys = 0; dep->de_name[strlen(dep->de_name)-1] = '0' + instance;
bit_set(sfkeys, DE_FKEY);
if ((fkey_map(&fkeys, &sfkeys)) != OK)
printf("%s: error using Shift+F%d key(%d)\n", str_DevName, DE_FKEY, errno);
/* Announce we are up! */ de_instance = instance;
netdriver_announce();
if (!de_probe(dep, instance))
return ENXIO;
de_init_hw(dep, addr);
return OK; return OK;
} }
static void do_get_stat_s(message * mp) static void do_stat(eth_stat_t *stat)
{ {
int rc; memcpy(stat, &de_state.de_stat, sizeof(*stat));
dpeth_t *dep;
dep = &de_state;
if ((rc = sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant,
0, (vir_bytes)&dep->de_stat, sizeof(dep->de_stat))) != OK)
panic("%s %d", str_CopyErrMsg, rc);
mp->m_type = DL_STAT_REPLY;
rc = ipc_send(mp->m_source, mp);
if( rc != OK )
panic("%s %d", str_StatErrMsg, rc);
return;
} }
static void do_conf(const message * mp) static int de_probe(dpeth_t *dep, unsigned int skip)
{ {
int r; int r, devind;
dpeth_t *dep; u16_t vid, did;
message reply_mess;
dep = &de_state;
strncpy(dep->de_name, str_DevName, strlen(str_DevName));
dep->de_name[strlen(dep->de_name)-1] = '0' + de_instance;
if (dep->de_mode == DEM_DISABLED) {
de_update_conf(dep);
pci_init();
if (dep->de_mode == DEM_ENABLED && !de_probe(dep, de_instance)) {
printf("%s: warning no ethernet card found at 0x%04X\n",
dep->de_name, dep->de_base_port);
dep->de_mode = DEM_DISABLED;
}
}
r = OK;
/* 'de_mode' may change if probe routines fail, test again */
switch (dep->de_mode) {
case DEM_DISABLED:
r = ENXIO; /* Device is OFF or hardware probe failed */
break;
case DEM_ENABLED:
if (dep->de_flags == DEF_EMPTY) {
de_first_init(dep);
dep->de_flags |= DEF_ENABLED;
de_reset(dep);
de_hw_conf(dep);
de_setup_frame(dep);
de_start(dep);
}
/* TODO CHECK PROMISC AND MULTI */
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;
break;
case DEM_SINK:
DEBUG(printf("%s running in sink mode\n", str_DevName));
memset(dep->de_address.ea_addr, 0, sizeof(ether_addr_t));
de_conf_addr(dep);
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));
}
if (ipc_send(mp->m_source, &reply_mess) != OK)
panic("%s %d", str_SendErrMsg, mp->m_source);
return;
}
static void do_reply(dpeth_t * dep)
{
message reply;
int r, 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;
r = ipc_send(dep->de_client, &reply);
if(r < 0)
panic("%s %d", str_SendErrMsg, r);
dep->de_read_s = 0;
dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);
return;
}
static void do_watchdog(void *UNUSED(message))
{
/* nothing here yet */
return;
}
static int de_probe(dpeth_t *dep, int skip)
{
int i, r, devind;
u16_t vid, did, temp16;
DEBUG(printf("PROBING...")); DEBUG(printf("PROBING..."));
pci_init();
r= pci_first_dev(&devind, &vid, &did); r= pci_first_dev(&devind, &vid, &did);
if (r == 0) if (r == 0)
return FALSE; return FALSE;
@ -321,33 +138,15 @@ static int de_probe(dpeth_t *dep, int skip)
/* device validation. We support only the DEC21140A */ /* device validation. We support only the DEC21140A */
if(dep->de_type != DEC_21140A){ if(dep->de_type != DEC_21140A){
dep->de_type = DE_TYPE_UNKNOWN; printf("%s: unsupported card type %x\n", dep->de_name, dep->de_type);
printf("%s: unsupported device\n", str_DevName);
return FALSE; return FALSE;
} }
de_reset(dep);
DEBUG(printf("Reading SROM...\n"));
for(i=0;i<(1<<SROM_BITWIDTH)-1;i++){
temp16 = de_read_rom(dep, i, SROM_BITWIDTH);
dep->srom[i*2] = temp16 & 0xFF;
dep->srom[i*2+1] = temp16 >> 8;
}
/* TODO: validate SROM content */
/* acquire MAC addr */
DEBUG(printf("Using MAC addr= "));
for(i=0;i<6;i++){
dep->de_address.ea_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET];
DEBUG(printf("%02X%c",dep->de_address.ea_addr[i],i!=5?'-':'\n'));
}
DEBUG(printf("probe success\n"));
return TRUE; return TRUE;
} }
static u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits){ static u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits)
{
u16_t retVal = 0; u16_t retVal = 0;
int i; int i;
u32_t csr = 0; u32_t csr = 0;
@ -356,7 +155,11 @@ static u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits){
more readable, the following macro is also just more readable, the following macro is also just
to clear up the code a little.*/ to clear up the code a little.*/
#define EMIT do { io_outl(CSR_ADDR(dep, CSR9), csr | csr2); io_outl(CSR_ADDR(dep, CSR1), 0);} while(0) #define EMIT \
do { \
io_outl(CSR_ADDR(dep, CSR9), csr | csr2); \
io_outl(CSR_ADDR(dep, CSR1), 0); \
} while(0)
/* init */ /* init */
csr = 0; EMIT; csr = 0; EMIT;
@ -404,49 +207,21 @@ static u16_t de_read_rom(const dpeth_t *dep, u8_t addr, u8_t nbAddrBits){
return retVal; return retVal;
} }
static void de_update_conf(dpeth_t * dep) static ssize_t do_recv(struct netdriver_data *data, size_t max)
{ {
static char dpc_fmt[] = "x:d:x";
char ec_key[16];
long val;
strlcpy(ec_key, "DEETH0", sizeof(ec_key));
ec_key[5] += de_instance;
dep->de_mode = DEM_ENABLED;
switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {
case EP_OFF: dep->de_mode = DEM_DISABLED; break;
case EP_ON: dep->de_mode = DEM_SINK; break;
}
dep->de_base_port = 0;
return;
}
static void do_vread_s(const message * mp, int from_int)
{
u8_t *buffer;
u32_t size; u32_t size;
int r, ix = 0; dpeth_t *dep;
vir_bytes bytes; de_loc_descr_t *descr;
dpeth_t *dep = NULL;
de_loc_descr_t *descr = NULL;
iovec_dat_s_t *iovp = NULL;
dep = &de_state; dep = &de_state;
dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
descr = &dep->descr[DESCR_RECV][dep->cur_descr[DESCR_RECV]]; descr = &dep->descr[DESCR_RECV][dep->cur_descr[DESCR_RECV]];
/* check if packet is in the current descr and only there */ /* check if packet is in the current descr and only there */
if( !( !(descr->descr->des[DES0] & DES0_OWN) && if ((descr->descr->des[DES0] & DES0_OWN) ||
(descr->descr->des[DES0] & DES0_FS) && !(descr->descr->des[DES0] & DES0_FS) ||
(descr->descr->des[DES0] & DES0_LS) )) !(descr->descr->des[DES0] & DES0_LS))
goto suspend; return SUSPEND;
/*TODO: multi-descr msgs...*/ /*TODO: multi-descr msgs...*/
/* We only support packets contained in a single descriptor. /* We only support packets contained in a single descriptor.
@ -454,9 +229,6 @@ static void do_vread_s(const message * mp, int from_int)
ETH_MAX_PACK_SIZE will result in multi-descriptor ETH_MAX_PACK_SIZE will result in multi-descriptor
packets that we won't be able to handle packets that we won't be able to handle
*/ */
assert(!(descr->descr->des[DES0]&DES0_OWN));
assert(descr->descr->des[DES0]&DES0_FS);
assert(descr->descr->des[DES0]&DES0_LS);
/* Check for abnormal messages. We assert here /* Check for abnormal messages. We assert here
because this driver is for a virtualized because this driver is for a virtualized
@ -465,65 +237,22 @@ static void do_vread_s(const message * mp, int from_int)
assert(!(descr->descr->des[DES0]&DES0_ES)); assert(!(descr->descr->des[DES0]&DES0_ES));
assert(!(descr->descr->des[DES0]&DES0_RE)); assert(!(descr->descr->des[DES0]&DES0_RE));
/* Setup the iovec entry to allow copying into
client layer
*/
dep->de_read_iovec.iod_proc_nr = mp->m_source;
de_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 = de_calc_iov_size(&dep->de_read_iovec);
if (size < ETH_MAX_PACK_SIZE)
panic("%s %d", str_SizeErrMsg, size);
/* Copy buffer to user area and clear ownage */ /* Copy buffer to user area and clear ownage */
size = (descr->descr->des[DES0]&DES0_FL)>>DES0_FL_SHIFT; size = (descr->descr->des[DES0]&DES0_FL)>>DES0_FL_SHIFT;
/*TODO: Complain to MS */ /* HACK: VPC2007 sends short-sized packets, pad to minimum ethernet length */
/*HACK: VPC2007 returns packet of invalid size. Ethernet standard
specify 46 bytes as the minimum for valid payload. However, this is
artificial in so far as for certain packet types, notably ARP, less
then 46 bytes are needed to contain the full information. In a non
virtualized environment the 46 bytes rule is enforced in order to give
guarantee in the collison detection scheme. Of course, this being a
driver for a VPC2007, we won't have collisions and I can only suppose
MS decided to cut packet size to true minimum, regardless of the
46 bytes payload standard. Note that this seems to not happen in
bridged mode. Note also, that the card does not return runt or
incomplete frames to us, so this hack is safe
*/
if(size<60){ if(size<60){
memset(&descr->buf1[size], 0, 60-size); memset(&descr->buf1[size], 0, 60-size);
size=60; size=60;
} }
/* End ugly hack */
iovp = &dep->de_read_iovec; /* Truncate large packets */
buffer = descr->buf1; if (size > max)
dep->bytes_rx += size; size = max;
netdriver_copyout(data, 0, descr->buf1, size);
dep->de_stat.ets_packetR++; dep->de_stat.ets_packetR++;
dep->de_read_s = size;
do {
bytes = iovp->iod_iovec[ix].iov_size; /* Size of buffer */
if (bytes >= size)
bytes = size;
r= sys_safecopyto(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant, 0,
(vir_bytes)buffer, bytes);
if (r != OK)
panic("%s %d", str_CopyErrMsg, r);
buffer += bytes;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */
de_next_iov(iovp);
ix = 0;
}
} while ((size -= bytes) > 0);
descr->descr->des[DES0]=DES0_OWN; descr->descr->des[DES0]=DES0_OWN;
dep->cur_descr[DESCR_RECV]++; dep->cur_descr[DESCR_RECV]++;
@ -532,52 +261,33 @@ static void do_vread_s(const message * mp, int from_int)
DEBUG(printf("Read returned size = %d\n", size)); DEBUG(printf("Read returned size = %d\n", size));
/* Reply information */ return size;
dep->de_flags |= DEF_ACK_RECV;
dep->de_flags &= NOT(DEF_READING);
}
if(!from_int){
do_reply(dep);
}
return;
suspend:
if(from_int){
assert(dep->de_flags & DEF_READING);
return;
}
assert(!(dep->de_flags & DEF_READING));
dep->rx_return_msg = *mp;
dep->de_flags |= DEF_READING;
do_reply(dep);
return;
} }
static void de_conf_addr(dpeth_t * dep) static void de_conf_addr(dpeth_t *dep, ether_addr_t *addr)
{ {
static char ea_fmt[] = "x:x:x:x:x:x"; u16_t temp16;
char ea_key[16]; int i;
int ix;
long val;
strlcpy(ea_key, "DEETH0_EA", sizeof(ea_key)); DEBUG(printf("Reading SROM...\n"));
ea_key[5] += de_instance;
for (ix = 0; ix < SA_ADDR_LEN; ix++) { for(i=0;i<(1<<SROM_BITWIDTH)-1;i++){
val = dep->de_address.ea_addr[ix]; temp16 = de_read_rom(dep, i, SROM_BITWIDTH);
if (env_parse(ea_key, ea_fmt, ix, &val, 0x00L, 0xFFL) != EP_SET) dep->srom[i*2] = temp16 & 0xFF;
break; dep->srom[i*2+1] = temp16 >> 8;
dep->de_address.ea_addr[ix] = val;
} }
if (ix != 0 && ix != SA_ADDR_LEN) /* TODO: validate SROM content */
env_parse(ea_key, "?", 0, &val, 0L, 0L); /* acquire MAC addr */
return; DEBUG(printf("Using MAC addr= "));
for(i=0;i<6;i++){
addr->ea_addr[i] = dep->srom[i+DE_SROM_EA_OFFSET];
DEBUG(printf("%02X%c", addr->ea_addr[i],i!=5?'-':'\n'));
}
DEBUG(printf("probe success\n"));
} }
static void de_first_init(dpeth_t *dep) static void de_init_buf(dpeth_t *dep)
{ {
int i,j,r; int i,j,r;
vir_bytes descr_vir = (vir_bytes)dep->sendrecv_descr_buf; vir_bytes descr_vir = (vir_bytes)dep->sendrecv_descr_buf;
@ -585,7 +295,6 @@ static void de_first_init(dpeth_t *dep)
de_loc_descr_t *loc_descr; de_loc_descr_t *loc_descr;
phys_bytes temp; phys_bytes temp;
for(i=0;i<2;i++){ for(i=0;i<2;i++){
loc_descr = &dep->descr[i][0]; loc_descr = &dep->descr[i][0];
for(j=0; j < (i==DESCR_RECV ? DE_NB_RECV_DESCR : DE_NB_SEND_DESCR); j++){ for(j=0; j < (i==DESCR_RECV ? DE_NB_RECV_DESCR : DE_NB_SEND_DESCR); j++){
@ -627,11 +336,11 @@ static void de_first_init(dpeth_t *dep)
/* record physical location of two first descriptor */ /* record physical location of two first descriptor */
r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_RECV][0].descr, r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_RECV][0].descr,
sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_RECV]); sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_RECV]);
if(r != OK) panic("%s %d", str_UmapErrMsg, r); if(r != OK) panic("sys_umap failed: %d", r);
r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_TRAN][0].descr, r = sys_umap(SELF, VM_D, (vir_bytes)dep->descr[DESCR_TRAN][0].descr,
sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_TRAN]); sizeof(de_descr_t), &dep->sendrecv_descr_phys_addr[DESCR_TRAN]);
if(r != OK) panic("%s %d", str_UmapErrMsg, r); if(r != OK) panic("sys_umap failed: %d", r);
DEBUG(printf("Descr: head tran=[%08X] head recv=[%08X]\n", DEBUG(printf("Descr: head tran=[%08X] head recv=[%08X]\n",
dep->sendrecv_descr_phys_addr[DESCR_TRAN], dep->sendrecv_descr_phys_addr[DESCR_TRAN],
@ -643,13 +352,12 @@ static void de_first_init(dpeth_t *dep)
for(j=0;j< (i==DESCR_RECV?DE_NB_RECV_DESCR:DE_NB_SEND_DESCR);j++){ for(j=0;j< (i==DESCR_RECV?DE_NB_RECV_DESCR:DE_NB_SEND_DESCR);j++){
r = sys_umap(SELF, VM_D, (vir_bytes)&(loc_descr->descr), r = sys_umap(SELF, VM_D, (vir_bytes)&(loc_descr->descr),
sizeof(de_descr_t), &temp); sizeof(de_descr_t), &temp);
if(r != OK) if(r != OK) panic("sys_umap failed: %d", r);
panic("%s %d", str_UmapErrMsg, r);
if( ((loc_descr->descr->des[DES_BUF1] & 0x3) != 0) || if( ((loc_descr->descr->des[DES_BUF1] & 0x3) != 0) ||
((loc_descr->descr->des[DES_BUF2] & 0x3) != 0) || ((loc_descr->descr->des[DES_BUF2] & 0x3) != 0) ||
((temp&0x3)!=0) ) ((temp&0x3)!=0) )
panic("%s 0x%lx", str_AlignErrMsg, temp); panic("alignment error: 0x%lx", temp);
loc_descr++; loc_descr++;
} }
@ -658,43 +366,45 @@ static void de_first_init(dpeth_t *dep)
/* Init default values */ /* Init default values */
dep->cur_descr[DESCR_TRAN]=1; dep->cur_descr[DESCR_TRAN]=1;
dep->cur_descr[DESCR_RECV]=0; dep->cur_descr[DESCR_RECV]=0;
dep->bytes_rx = 0;
dep->bytes_tx = 0;
/* Set the interrupt handler policy. Request interrupts not to be reenabled
* automatically. Return the IRQ line number when an interrupt occurs.
*/
dep->de_hook = dep->de_irq;
sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
sys_irqenable(&dep->de_hook);
} }
static void do_interrupt(const dpeth_t *dep){ static void do_intr(unsigned int __unused mask)
{
dpeth_t *dep;
u32_t val; u32_t val;
dep = &de_state;
val = io_inl(CSR_ADDR(dep, CSR5)); val = io_inl(CSR_ADDR(dep, CSR5));
if(val & CSR5_AIS){ if(val & CSR5_AIS){
panic("Abnormal Int CSR5=: %d", val); panic("Abnormal Int CSR5=: %d", val);
} }
if( (dep->de_flags & DEF_READING) && (val & CSR5_RI) ){ if (val & CSR5_RI)
do_vread_s(&dep->rx_return_msg, TRUE); netdriver_recv();
}
if( (dep->de_flags & DEF_SENDING) && (val & CSR5_TI) ){ if (val & CSR5_TI)
do_vwrite_s(&dep->tx_return_msg, TRUE); netdriver_send();
}
/* ack and reset interrupts */ /* ack and reset interrupts */
io_outl(CSR_ADDR(dep, CSR5), 0xFFFFFFFF); io_outl(CSR_ADDR(dep, CSR5), 0xFFFFFFFF);
return;
sys_irqenable(&dep->de_hook);
} }
static void de_reset(const dpeth_t *dep){ static void de_reset(const dpeth_t *dep)
{
io_outl(CSR_ADDR(dep, CSR0), CSR0_SWR); io_outl(CSR_ADDR(dep, CSR0), CSR0_SWR);
} }
static void de_hw_conf(const dpeth_t *dep){ static void do_stop(void)
{
de_reset(&de_state);
}
static void de_hw_conf(const dpeth_t *dep)
{
u32_t val; u32_t val;
/* CSR0 - global host bus prop */ /* CSR0 - global host bus prop */
@ -719,13 +429,15 @@ static void de_hw_conf(const dpeth_t *dep){
io_outl(CSR_ADDR(dep, CSR6), val); io_outl(CSR_ADDR(dep, CSR6), val);
} }
static void de_start(const dpeth_t *dep){ static void de_start(const dpeth_t *dep)
{
u32_t val; u32_t val;
val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST | CSR6_SR; val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST | CSR6_SR;
io_outl(CSR_ADDR(dep, CSR6), val); io_outl(CSR_ADDR(dep, CSR6), val);
} }
static void de_setup_frame(const dpeth_t *dep){ static void de_setup_frame(const dpeth_t *dep, const ether_addr_t *addr)
{
int i; int i;
u32_t val; u32_t val;
@ -739,12 +451,12 @@ static void de_setup_frame(const dpeth_t *dep){
dep->descr[DESCR_TRAN][0].buf1[9] = 0xFF; dep->descr[DESCR_TRAN][0].buf1[9] = 0xFF;
for(i=1;i<16;i++){ for(i=1;i<16;i++){
memset(&(dep->descr[DESCR_TRAN][0].buf1[12*i]), 0, 12); memset(&(dep->descr[DESCR_TRAN][0].buf1[12*i]), 0, 12);
dep->descr[DESCR_TRAN][0].buf1[12*i+0] = dep->de_address.ea_addr[0]; dep->descr[DESCR_TRAN][0].buf1[12*i+0] = addr->ea_addr[0];
dep->descr[DESCR_TRAN][0].buf1[12*i+1] = dep->de_address.ea_addr[1]; dep->descr[DESCR_TRAN][0].buf1[12*i+1] = addr->ea_addr[1];
dep->descr[DESCR_TRAN][0].buf1[12*i+4] = dep->de_address.ea_addr[2]; dep->descr[DESCR_TRAN][0].buf1[12*i+4] = addr->ea_addr[2];
dep->descr[DESCR_TRAN][0].buf1[12*i+5] = dep->de_address.ea_addr[3]; dep->descr[DESCR_TRAN][0].buf1[12*i+5] = addr->ea_addr[3];
dep->descr[DESCR_TRAN][0].buf1[12*i+8] = dep->de_address.ea_addr[4]; dep->descr[DESCR_TRAN][0].buf1[12*i+8] = addr->ea_addr[4];
dep->descr[DESCR_TRAN][0].buf1[12*i+9] = dep->de_address.ea_addr[5]; dep->descr[DESCR_TRAN][0].buf1[12*i+9] = addr->ea_addr[5];
} }
dep->descr[DESCR_TRAN][0].descr->des[DES0] = DES0_OWN; dep->descr[DESCR_TRAN][0].descr->des[DES0] = DES0_OWN;
@ -755,107 +467,30 @@ static void de_setup_frame(const dpeth_t *dep){
val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST; val = io_inl(CSR_ADDR(dep, CSR6)) | CSR6_ST;
io_outl(CSR_ADDR(dep, CSR6), val); io_outl(CSR_ADDR(dep, CSR6), val);
io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF); io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF);
return;
} }
static int de_calc_iov_size(iovec_dat_s_t * iovp){ static int do_send(struct netdriver_data *data, size_t size)
int size, ix; {
size = ix = 0; static int setup_done = 0;
do{
size += iovp->iod_iovec[ix].iov_size;
if (++ix >= IOVEC_NR) {
de_next_iov(iovp);
ix = 0;
}
} while (ix < iovp->iod_iovec_s);
return size;
}
static void de_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);
rc = sys_safecopyfrom(user_proc, grant, 0, (vir_bytes)loc_addr, len);
if (rc != OK)
panic("%s %d", str_CopyErrMsg, rc);
return;
}
static void de_next_iov(iovec_dat_s_t * iovp){
iovp->iod_iovec_s -= IOVEC_NR;
iovp->iod_iovec_offset += IOVEC_NR * sizeof(iovec_t);
de_get_userdata_s(iovp->iod_proc_nr, iovp->iod_grant, iovp->iod_iovec_offset,
iovp->iod_iovec_s, iovp->iod_iovec);
return;
}
static void do_vwrite_s(const message * mp, int from_int){
static u8_t setupDone = 0;
int size, r, bytes, ix, totalsize;
dpeth_t *dep; dpeth_t *dep;
iovec_dat_s_t *iovp = NULL;
de_loc_descr_t *descr = NULL; de_loc_descr_t *descr = NULL;
u8_t *buffer = NULL;
dep = &de_state; dep = &de_state;
dep->de_client = mp->m_source;
if (dep->de_mode == DEM_ENABLED) {
if (!from_int && (dep->de_flags & DEF_SENDING))
panic("%s", str_BusyErrMsg);
descr = &dep->descr[DESCR_TRAN][dep->cur_descr[DESCR_TRAN]]; descr = &dep->descr[DESCR_TRAN][dep->cur_descr[DESCR_TRAN]];
if(( descr->descr->des[DES0] & DES0_OWN)!=0) if(( descr->descr->des[DES0] & DES0_OWN)!=0)
goto suspend; return SUSPEND;
if(!setupDone && (dep->cur_descr[DESCR_TRAN] == 0) ){ if(!setup_done && (dep->cur_descr[DESCR_TRAN] == 0) ){
dep->descr[DESCR_TRAN][0].descr->des[DES0] = 0; dep->descr[DESCR_TRAN][0].descr->des[DES0] = 0;
setupDone=1; setup_done=1;
} }
buffer = descr->buf1; netdriver_copyin(data, 0, descr->buf1, size);
iovp = &dep->de_write_iovec;
iovp->iod_proc_nr = mp->m_source;
de_get_userdata_s(mp->m_source, mp->m_net_netdrv_dl_writev_s.grant, 0,
mp->m_net_netdrv_dl_writev_s.count, iovp->iod_iovec);
iovp->iod_iovec_s = mp->m_net_netdrv_dl_writev_s.count;
iovp->iod_grant = mp->m_net_netdrv_dl_writev_s.grant;
iovp->iod_iovec_offset = 0;
totalsize = size = de_calc_iov_size(iovp);
if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE)
panic("%s %d", str_SizeErrMsg, size);
dep->bytes_tx += size;
dep->de_stat.ets_packetT++;
ix=0;
do {
bytes = iovp->iod_iovec[ix].iov_size;
if (bytes >= size)
bytes = size;
r= sys_safecopyfrom(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_grant,
0, (vir_bytes)buffer, bytes);
if (r != OK)
panic("%s %d", str_CopyErrMsg, r);
buffer += bytes;
if (++ix >= IOVEC_NR) {
de_next_iov(iovp);
ix = 0;
}
} while ((size -= bytes) > 0);
descr->descr->des[DES1] = (descr->descr->des[DES1]&DES1_ER) | descr->descr->des[DES1] = (descr->descr->des[DES1]&DES1_ER) |
DES1_FS | DES1_LS | DES1_IC | totalsize; DES1_FS | DES1_LS | DES1_IC | size;
descr->descr->des[DES0] = DES0_OWN; descr->descr->des[DES0] = DES0_OWN;
dep->cur_descr[DESCR_TRAN]++; dep->cur_descr[DESCR_TRAN]++;
@ -863,41 +498,24 @@ static void do_vwrite_s(const message * mp, int from_int){
dep->cur_descr[DESCR_TRAN] = 0; dep->cur_descr[DESCR_TRAN] = 0;
io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF); io_outl(CSR_ADDR(dep, CSR1), 0xFFFFFFFF);
}
dep->de_flags |= DEF_ACK_SEND; dep->de_stat.ets_packetT++;
if(from_int){
dep->de_flags &= NOT(DEF_SENDING);
return;
}
do_reply(dep);
return;
suspend: return OK;
if(from_int)
panic("should not happen: %d", 0);
dep->de_stat.ets_transDef++;
dep->de_flags |= DEF_SENDING;
dep->de_stat.ets_transDef++;
dep->tx_return_msg = *mp;
do_reply(dep);
} }
static void warning(const char *type, int err){ static u32_t io_inl(u16_t port)
printf("Warning: %s sys_%s failed (%d)\n", str_DevName, type, err); {
return;
}
static u32_t io_inl(u16_t port){
u32_t value; u32_t value;
int rc; int rc;
if ((rc = sys_inl(port, &value)) != OK) warning("inl", rc); if ((rc = sys_inl(port, &value)) != OK)
panic("sys_inl failed: %d", rc);
return value; return value;
} }
static void io_outl(u16_t port, u32_t value){ static void io_outl(u16_t port, u32_t value)
{
int rc; int rc;
if ((rc = sys_outl(port, value)) != OK) warning("outl", rc); if ((rc = sys_outl(port, value)) != OK)
return; panic("sys_outl failed: %d", rc);
} }

View File

@ -11,37 +11,21 @@ Created: 09/01/2009 Nicolas Tittley (first.last @ gmail DOT com)
#include <sys/null.h> #include <sys/null.h>
#define DE_FKEY 7 /* Shift+ this value will dump info on console */
#define NOT(x) (~(x))
#if debug == 1 #if debug == 1
# define DEBUG(statm) statm # define DEBUG(statm) statm
#else #else
# define DEBUG(statm) # define DEBUG(statm)
#endif #endif
#define SA_ADDR_LEN sizeof(ether_addr_t)
#define DE_NB_SEND_DESCR 32 #define DE_NB_SEND_DESCR 32
#define DE_SEND_BUF_SIZE (ETH_MAX_PACK_SIZE+2) #define DE_SEND_BUF_SIZE (ETH_MAX_PACK_SIZE+2)
#define DE_NB_RECV_DESCR 32 #define DE_NB_RECV_DESCR 32
#define DE_RECV_BUF_SIZE (ETH_MAX_PACK_SIZE+2) #define DE_RECV_BUF_SIZE (ETH_MAX_PACK_SIZE+2)
#define IOVEC_NR 16
#define DE_MIN_BASE_ADDR 0x0400 #define DE_MIN_BASE_ADDR 0x0400
#define DE_SROM_EA_OFFSET 20 #define DE_SROM_EA_OFFSET 20
#define DE_SETUP_FRAME_SIZE 192 #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 { typedef struct de_descr {
u32_t des[4]; u32_t des[4];
} de_descr_t; } de_descr_t;
@ -53,9 +37,6 @@ typedef struct de_local_descr {
} de_loc_descr_t; } de_loc_descr_t;
typedef struct dpeth { 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 */ char de_name[32]; /* Name of this interface */
port_t de_base_port; /* Base port, for multiple card instance */ port_t de_base_port; /* Base port, for multiple card instance */
int de_irq; /* IRQ line number */ int de_irq; /* IRQ line number */
@ -63,10 +44,7 @@ typedef struct dpeth {
int de_type; /* What kind of hardware */ int de_type; /* What kind of hardware */
ether_addr_t de_address; /* Ethernet Address */
eth_stat_t de_stat; /* Stats */ 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. /* 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 */ 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_RECV 0
#define DESCR_TRAN 1 #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 */ /* Serial ROM */
#define SROM_BITWIDTH 6 #define SROM_BITWIDTH 6
u8_t srom[((1<<SROM_BITWIDTH)-1)*2]; /* Space to read in u8_t srom[((1<<SROM_BITWIDTH)-1)*2]; /* Space to read in
all the configuration ROM */ 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; } dpeth_t;

View File

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

View File

@ -2,7 +2,7 @@
PROG= dp8390 PROG= dp8390
SRCS= 3c503.c dp8390.c ne2000.c rtl8029.c wdeth.c SRCS= 3c503.c dp8390.c ne2000.c rtl8029.c wdeth.c
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys -ltimers LDADD+= -lnetdriver -lsys
.include <minix.service.mk> .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 dpeth;
struct iovec_dat; struct iovec_dat;
struct iovec_dat_s; struct iovec_dat_s;
typedef void(*dp_initf_t) (struct dpeth *dep); typedef void (*dp_initf_t)(struct dpeth *dep);
typedef void(*dp_stopf_t) (struct dpeth *dep); typedef void (*dp_stopf_t)(struct dpeth *dep);
typedef void(*dp_user2nicf_t) (struct dpeth *dep, struct iovec_dat typedef void (*dp_user2nicf_s_t)(struct dpeth *dep,
*iovp, vir_bytes offset, int nic_addr, vir_bytes count); struct netdriver_data *data, int nic_addr, size_t offset,
typedef void(*dp_user2nicf_s_t) (struct dpeth *dep, struct iovec_dat_s size_t count);
*iovp, vir_bytes offset, int nic_addr, vir_bytes count); typedef void (*dp_nic2userf_s_t)(struct dpeth *dep,
typedef void(*dp_nic2userf_t) (struct dpeth *dep, int nic_addr, struct struct netdriver_data *data, int nic_addr, size_t offset,
iovec_dat *iovp, vir_bytes offset, vir_bytes count); size_t count);
typedef void(*dp_nic2userf_s_t) (struct dpeth *dep, int nic_addr, struct typedef void (*dp_getblock_t)(struct dpeth *dep, int page, size_t
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
offset, size_t size, void *dst); 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 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_NR 2 /* Maximum size of the send queue */
#define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */ #define SENDQ_PAGES 6 /* 6 * DP_PAGESIZE >= 1514 bytes */
@ -250,10 +224,8 @@ typedef struct dpeth
int de_startpage; int de_startpage;
int de_stoppage; int de_stoppage;
#if ENABLE_PCI
/* PCI config */ /* PCI config */
char de_pci; /* TRUE iff PCI device */ char de_pci; /* TRUE iff PCI device */
#endif
/* Do it yourself send queue */ /* Do it yourself send queue */
struct sendq struct sendq
@ -268,14 +240,7 @@ typedef struct dpeth
/* Fields for internal use by the dp8390 driver. */ /* Fields for internal use by the dp8390 driver. */
int de_flags; int de_flags;
int de_mode;
eth_stat_t de_stat; 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_user2nicf_s_t de_user2nicf_s;
dp_nic2userf_s_t de_nic2userf_s; dp_nic2userf_s_t de_nic2userf_s;
dp_getblock_t de_getblockf; dp_getblock_t de_getblockf;
@ -283,24 +248,10 @@ typedef struct dpeth
#define DEI_DEFAULT 0x8000 #define DEI_DEFAULT 0x8000
#define DEF_EMPTY 0x000 #define DEF_EMPTY 0x00
#define DEF_PACK_SEND 0x001 #define DEF_STOPPED 0x01
#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 DEM_DISABLED 0x0 #define debug 0
#define DEM_SINK 0x1
#define DEM_ENABLED 0x2
#if !__minix_vmd
#define debug 0 /* Standard Minix lacks debug variable */
#endif
/* /*
* $PchId: dp8390.h,v 1.10 2005/02/10 17:26:06 philip Exp $ * $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_WDETH 1
#define ENABLE_NE2000 1 #define ENABLE_NE2000 1
#define ENABLE_3C503 1 #define ENABLE_3C503 1
#define ENABLE_PCI 1
struct dpeth; 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/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
#if __minix_vmd
#include "config.h"
#endif
#include "local.h" #include "local.h"
#include "dp8390.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/drivers.h>
#include <minix/netdriver.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -20,8 +21,6 @@ Created: April 2000 by Philip Homburg <philip@f-mnx.phicoh.com>
#include "dp8390.h" #include "dp8390.h"
#include "rtl8029.h" #include "rtl8029.h"
#if ENABLE_PCI
static void rtl_init(struct dpeth *dep); static void rtl_init(struct dpeth *dep);
#if 0 #if 0
static u16_t get_ee_word(dpeth_t *dep, int a); static u16_t get_ee_word(dpeth_t *dep, int a);
@ -312,8 +311,6 @@ dpeth_t *dep;
} }
#endif #endif
#endif /* ENABLE_PCI */
/* /*
* $PchId: rtl8029.c,v 1.7 2004/08/03 12:16:58 philip Exp $ * $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/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
@ -70,9 +71,6 @@ dpeth_t *dep;
int we_type; int we_type;
int sendq_nr; 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[0] = inb_we(dep, EPL_EA0);
dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1); dep->de_address.ea_addr[1] = inb_we(dep, EPL_EA1);
dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2); dep->de_address.ea_addr[2] = inb_we(dep, EPL_EA2);

View File

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

View File

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

View File

@ -10,7 +10,7 @@
*/ */
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/com.h> #include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.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 ** Function: Reads statistic counters from board
** and updates local counters. ** and updates local counters.
*/ */
@ -52,36 +52,30 @@ static void el3_update_stats(dpeth_t * dep)
/* Goes back to operating window and enables statistics */ /* Goes back to operating window and enables statistics */
SetWindow(WNO_Operating); SetWindow(WNO_Operating);
outw_el3(dep, REG_CmdStatus, CMD_StatsEnable); outw_el3(dep, REG_CmdStatus, CMD_StatsEnable);
return;
} }
/* /*
** Name: void el3_getstats(dpeth_t *dep) ** Name: el3_getstats
** Function: Reads statistics counters from board. ** Function: Reads statistics counters from board.
*/ */
static void el3_getstats(dpeth_t * dep) static void el3_getstats(dpeth_t * dep)
{ {
lock();
el3_update_stats(dep); 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). ** Function: Dumps counter on screen (support for console display).
*/ */
static void el3_dodump(dpeth_t * dep) static void el3_dodump(dpeth_t * dep)
{ {
el3_getstats(dep); el3_getstats(dep);
return;
} }
/* /*
** Name: void el3_rx_mode(dpeth_t *dep) ** Name: el3_rx_mode
** Function: Initializes receiver mode ** Function: Initializes receiver mode
*/ */
static void el3_rx_mode(dpeth_t * dep) 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_RxReset);
outw_el3(dep, REG_CmdStatus, CMD_SetRxFilter | dep->de_recv_mode); outw_el3(dep, REG_CmdStatus, CMD_SetRxFilter | dep->de_recv_mode);
outw_el3(dep, REG_CmdStatus, CMD_RxEnable); 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. ** Function: Reset function specific for Etherlink hardware.
*/ */
static void el3_reset(dpeth_t * UNUSED(dep)) static void el3_reset(dpeth_t * UNUSED(dep))
{ {
return; /* Done */
} }
/* /*
** Name: void el3_write_fifo(dpeth_t * dep, int pktsize); ** Name: el3_recv
** 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)
** Function: Receive function. Called from interrupt handler or ** Function: Receive function. Called from interrupt handler or
** from main to unload recv. buffer (packet to client) ** 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; 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 */ /* Remove buffer from queue */
if (dep->de_recvq_tail == dep->de_recvq_head) if (dep->de_recvq_tail == dep->de_recvq_head)
dep->de_recvq_head = dep->de_recvq_tail = NULL; dep->de_recvq_head = dep->de_recvq_tail = NULL;
else else
dep->de_recvq_head = rxptr->next; dep->de_recvq_head = rxptr->next;
unlock();
/* Copy buffer to user area and free it */ /* Copy buffer to user area and free it */
mem2user(dep, rxptr); size = MIN(rxptr->size, max);
dep->de_read_s = rxptr->size; netdriver_copyout(data, 0, rxptr->buffer, size);
dep->de_flags |= DEF_ACK_RECV;
dep->de_flags &= NOT(DEF_READING);
/* Return buffer to the idle pool */ /* Return buffer to the idle pool */
free_buff(dep, rxptr); free_buff(dep, rxptr);
}
return; return size;
} }
/* /*
** Name: void el3_rx_complete(dpeth_t * dep); ** Name: el3_rx_complete
** Function: Upon receiving a packet, provides status checks ** Function: Upon receiving a packet, provides status checks
** and if packet is OK copies it to local buffer. ** and if packet is OK copies it to local buffer.
*/ */
@ -205,38 +163,36 @@ static void el3_rx_complete(dpeth_t * dep)
} else { } else {
/* Good packet. Read it from FIFO */ /* 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->next = NULL;
rxptr->size = pktsize; rxptr->size = pktsize;
lock(); /* Queue packet to receive queue */ /* Queue packet to receive queue */
if (dep->de_recvq_head == NULL) if (dep->de_recvq_head == NULL)
dep->de_recvq_head = rxptr; dep->de_recvq_head = rxptr;
else else
dep->de_recvq_tail->next = rxptr; dep->de_recvq_tail->next = rxptr;
dep->de_recvq_tail = rxptr; dep->de_recvq_tail = rxptr;
unlock();
/* Reply to pending Receive requests, if any */ /* Reply to pending Receive requests, if any */
el3_recv(dep, TRUE, pktsize); netdriver_recv();
} }
/* Discard top packet from queue */ /* Discard top packet from queue */
outw_el3(dep, REG_CmdStatus, CMD_RxDiscard); 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 ** Function: Send function. Called from main to transit a packet or
** from interrupt handler when Tx FIFO gets available. ** 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; clock_t now;
int ix; int ix;
short int TxStatus; short int TxStatus;
size_t padding;
getticks(&now); getticks(&now);
if ((dep->de_flags & DEF_XMIT_BUSY) && if ((dep->de_flags & DEF_XMIT_BUSY) &&
@ -249,24 +205,26 @@ static void el3_send(dpeth_t * dep, int from_int, int count)
outw_el3(dep, REG_CmdStatus, CMD_TxEnable); outw_el3(dep, REG_CmdStatus, CMD_TxEnable);
dep->de_flags &= NOT(DEF_XMIT_BUSY); 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) */ /* Writes Transmitter preamble 1st Word (packet len, no ints) */
outw_el3(dep, REG_TxFIFO, count); outw_el3(dep, REG_TxFIFO, size);
/* Writes Transmitter preamble 2nd Word (all zero) */ /* Writes Transmitter preamble 2nd Word (all zero) */
outw_el3(dep, REG_TxFIFO, 0); outw_el3(dep, REG_TxFIFO, 0);
/* Writes packet */ /* Writes packet */
el3_write_fifo(dep, count); 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); getticks(&dep->de_xmit_start);
dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND); dep->de_flags |= DEF_XMIT_BUSY;
if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) { if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) {
/* Tx has enough room for a packet of maximum size */ /* Tx has enough room for a packet of maximum size */
dep->de_flags &= NOT(DEF_XMIT_BUSY | DEF_SENDING); dep->de_flags &= NOT(DEF_XMIT_BUSY);
} else { } else {
/* Interrupt driver when enough room is available */ /* Interrupt driver when enough room is available */
outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | ETH_MAX_PACK_SIZE); outw_el3(dep, REG_CmdStatus, CMD_SetTxAvailable | ETH_MAX_PACK_SIZE);
dep->de_flags &= NOT(DEF_SENDING);
} }
/* Pops Tx status stack */ /* Pops Tx status stack */
@ -278,12 +236,12 @@ static void el3_send(dpeth_t * dep, int from_int, int count)
outw_el3(dep, REG_CmdStatus, CMD_TxEnable); outw_el3(dep, REG_CmdStatus, CMD_TxEnable);
outb_el3(dep, REG_TxStatus, 0); outb_el3(dep, REG_TxStatus, 0);
} }
}
return; return OK;
} }
/* /*
** Name: void el3_close(dpeth_t *dep) ** Name: el3_close
** Function: Stops board and makes it ready to shut down. ** Function: Stops board and makes it ready to shut down.
*/ */
static void el3_close(dpeth_t * dep) 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) { if (dep->de_if_port == BNC_XCVR) {
outw_el3(dep, REG_CmdStatus, CMD_StopIntXcvr); outw_el3(dep, REG_CmdStatus, CMD_StopIntXcvr);
/* milli_delay(5); */ /* micro_delay(5000); */
} else if (dep->de_if_port == TP_XCVR) { } else if (dep->de_if_port == TP_XCVR) {
SetWindow(WNO_Diagnostics); SetWindow(WNO_Diagnostics);
outw_el3(dep, REG_MediaStatus, inw_el3(dep, REG_MediaStatus) & outw_el3(dep, REG_MediaStatus, inw_el3(dep, REG_MediaStatus) &
NOT((MediaLBeatEnable | MediaJabberEnable))); NOT((MediaLBeatEnable | MediaJabberEnable)));
/* milli_delay(5); */ /* micro_delay(5000); */
} }
DEBUG(printf("%s: stopping Etherlink ... \n", dep->de_name)); DEBUG(printf("%s: stopping Etherlink ... \n", dep->de_name));
/* Issues a global reset /* Issues a global reset
outw_el3(dep, REG_CmdStatus, CMD_GlobalReset); */ outw_el3(dep, REG_CmdStatus, CMD_GlobalReset); */
sys_irqdisable(&dep->de_hook); /* Disable interrupt */ sys_irqdisable(&dep->de_hook); /* Disable interrupt */
return;
} }
/* /*
** Name: void el3_interrupt(dpeth_t *dep) ** Name: el3_interrupt
** Function: Interrupt handler. Acknwledges transmit interrupts ** Function: Interrupt handler. Acknwledges transmit interrupts
** or unloads receive buffer to memory queue. ** 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);) DEBUG(printf("3c509: got Tx interrupt, Status=0x%04x\n", isr);)
dep->de_flags &= NOT(DEF_XMIT_BUSY); dep->de_flags &= NOT(DEF_XMIT_BUSY);
outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | INT_TxAvailable); outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | INT_TxAvailable);
if (dep->de_flags & DEF_SENDING) /* Send pending */ netdriver_send();
el3_send(dep, TRUE, dep->de_send_s);
} }
if (isr & (INT_AdapterFail | INT_RxEarly | INT_UpdateStats)) { if (isr & (INT_AdapterFail | INT_RxEarly | INT_UpdateStats)) {
@ -354,11 +309,10 @@ static void el3_interrupt(dpeth_t * dep)
/* Acknowledge interrupt */ /* Acknowledge interrupt */
outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | (INT_Latch | INT_Requested)); 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 ** Function: Reads the EEPROM at specified address
*/ */
static unsigned el3_read_eeprom(port_t port, unsigned 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; address |= EL3_READ_EEPROM;
outb(port, address); outb(port, address);
milli_delay(5); /* Allows EEPROM reads */ micro_delay(5000); /* Allows EEPROM reads */
for (result = 0, bit = 16; bit > 0; bit -= 1) { for (result = 0, bit = 16; bit > 0; bit -= 1) {
result = (result << 1) | (inb(port) & 0x0001); 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 ** Function: Reads station address from board
*/ */
static void el3_read_StationAddress(dpeth_t * dep) 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 >> 8) & 0xFF;
dep->de_address.ea_addr[ix++] = rc & 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. ** Function: Initalizes board hardware and driver data structures.
*/ */
static void el3_open(dpeth_t * dep) 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) { if (dep->de_if_port == BNC_XCVR) {
/* Start internal transceiver for Coaxial cable */ /* Start internal transceiver for Coaxial cable */
outw_el3(dep, REG_CmdStatus, CMD_StartIntXcvr); outw_el3(dep, REG_CmdStatus, CMD_StartIntXcvr);
milli_delay(5); micro_delay(5000);
} else if (dep->de_if_port == TP_XCVR) { } else if (dep->de_if_port == TP_XCVR) {
/* Start internal transceiver for Twisted pair cable */ /* 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) for (ix = 0; ix < SA_ADDR_LEN; ix += 1)
printf("%02X%c", dep->de_address.ea_addr[ix], printf("%02X%c", dep->de_address.ea_addr[ix],
ix < SA_ADDR_LEN - 1 ? ':' : '\n'); 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. ** Function: Reads EEPROM and computes checksum.
*/ */
static unsigned short el3_checksum(port_t port) 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. ** Function: Writes the ID sequence to the board.
*/ */
static void el3_write_id(port_t port) static void el3_write_id(port_t port)
@ -548,11 +499,10 @@ static void el3_write_id(port_t port)
pattern <<= 1; pattern <<= 1;
pattern = (pattern & 0x0100) ? pattern ^ 0xCF : pattern; pattern = (pattern & 0x0100) ? pattern ^ 0xCF : pattern;
} }
return;
} }
/* /*
** Name: int el3_probe(dpeth_t *dep) ** Name: el3_probe
** Function: Checks for presence of the board. ** Function: Checks for presence of the board.
*/ */
int el3_probe(dpeth_t * dep) int el3_probe(dpeth_t * dep)
@ -572,10 +522,10 @@ int el3_probe(dpeth_t * dep)
el3_write_id(id_port); el3_write_id(id_port);
outb(id_port, EL3_ID_GLOBAL_RESET); /* Reset the board */ 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); el3_write_id(id_port);
outb(id_port, EL3_SET_TAG_REGISTER); 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_id_port = id_port; /* Stores ID port No. */
dep->de_ramsize = /* RAM size is meaningless */ dep->de_ramsize = /* RAM size is meaningless */

View File

@ -1,4 +1,3 @@
#include <assert.h>
/* /*
** File: 8390.c May 02, 2000 ** File: 8390.c May 02, 2000
** **
@ -12,32 +11,18 @@
*/ */
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/com.h> #include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
#include <assert.h>
#include "dp.h" #include "dp.h"
#if (ENABLE_DP8390 == 1) #if (ENABLE_DP8390 == 1)
#define PIO16 0 /* NOTE: pio 16 functions missing */
#include "8390.h" #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. ** Function: Sets the board for reading/writing.
*/ */
static void ns_rw_setup(const dpeth_t *dep, int mode, int size, u16_t offset) 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); outb_reg0(dep, DP_RSAR1, (offset >> 8) & 0xFF);
mode |= (CR_PS_P0 | CR_STA); mode |= (CR_PS_P0 | CR_STA);
outb_reg0(dep, DP_CR, mode); 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. ** Function: Sets the board for for transmitting and fires it.
*/ */
static void ns_start_xmit(const dpeth_t * dep, int size, int pageno) 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_TBCR1, size >> 8);
outb_reg0(dep, DP_TBCR0, size & 0xFF); outb_reg0(dep, DP_TBCR0, size & 0xFF);
outb_reg0(dep, DP_CR, CR_NO_DMA | CR_STA | CR_TXP); /* Fires transmission */ 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, ** Name: mem_getblock
** int size, void *dst)
** Function: Reads a block of packet from board (shared memory). ** Function: Reads a block of packet from board (shared memory).
*/ */
static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst) static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst)
{ {
panic("mem_getblock: not converted to safecopies");
#if 0 assert(offset + size <= dep->de_ramsize);
sys_nic2mem(dep->de_linmem + offset, SELF, dst, size);
return; memcpy(dst, dep->de_locmem + offset, size);
#endif
} }
/* /*
** 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). ** 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"); size_t offset, left;
#if 0
phys_bytes offset;
iovec_dat_s_t *iovp = &dep->de_read_iovec;
int bytes, ix = 0;
/* Computes shared memory address (skipping receive header) */ /* Computes shared memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t); offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);
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 */ netdriver_copyout(data, 0, dep->de_locmem + offset, left);
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; offset = dep->de_startpage * DP_PAGESIZE;
} netdriver_copyout(data, left, dep->de_locmem + offset, size - left);
sys_nic2mem_s(dep->de_linmem + offset, iovp->iod_proc_nr, } else
iovp->iod_iovec[ix].iov_grant, bytes); netdriver_copyout(data, 0, dep->de_locmem + offset, size);
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
} }
/* /*
** 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). ** 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 size_t offset;
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;
/* Computes shared memory address */ /* Computes shared memory address */
offset = pageno * DP_PAGESIZE; offset = pageno * DP_PAGESIZE;
do { /* Reads chuncks of packet from user area */ netdriver_copyin(data, 0, dep->de_locmem + offset, size);
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
} }
/* /*
** Name: void pio_getblock(dpeth_t *dep, u16_t offset, ** Name: pio_getblock
** int size, void *dst)
** Function: Reads a block of packet from board (Prog. I/O). ** 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) 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 */ /* Sets up board for reading */
ns_rw_setup(dep, CR_DM_RR, size, offset); ns_rw_setup(dep, CR_DM_RR, size, offset);
#if PIO16 == 0 if (dep->de_16bit == TRUE)
insb(dep->de_data_port, SELF, dst, size);
#else
if (dep->de_16bit == TRUE) {
insw(dep->de_data_port, dst, size); insw(dep->de_data_port, dst, size);
} else { else
insb(dep->de_data_port, dst, size); 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). ** 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; size_t offset, left;
unsigned offset, iov_offset; int r, bytes, ix = 0;
/* Computes memory address (skipping receive header) */ /* Computes memory address (skipping receive header) */
offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t); 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; if (offset + size > dep->de_stoppage * DP_PAGESIZE) {
do { /* Reads chuncks of packet into user area */ left = dep->de_stoppage * DP_PAGESIZE - offset;
bytes = iovp->iod_iovec[ix].iov_size; /* Size of a chunck */ ns_rw_setup(dep, CR_DM_RR, left, offset);
if (bytes > pktsize) bytes = pktsize;
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; offset = dep->de_startpage * DP_PAGESIZE;
ns_rw_setup(dep, CR_DM_RR, pktsize, offset); } else
} left = 0;
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;
if (++ix >= IOVEC_NR) { /* Next buffer of IO vector */ ns_rw_setup(dep, CR_DM_RR, size - left, offset);
dp_next_iovec(iovp);
ix = 0; if (dep->de_16bit)
} netdriver_portinw(data, left, dep->de_data_port, size - left);
iov_offset= 0; else
/* Till packet done */ netdriver_portinb(data, left, dep->de_data_port, size - left);
} while ((pktsize -= bytes) > 0);
return;
} }
/* /*
** 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). ** 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 ix;
int r, bytes, ix = 0;
/* Sets up board for writing */ /* Sets up board for writing */
ns_rw_setup(dep, CR_DM_RW, pktsize, pageno * DP_PAGESIZE); ns_rw_setup(dep, CR_DM_RW, size, pageno * DP_PAGESIZE);
do { /* Reads chuncks of packet from user area */ if (dep->de_16bit)
netdriver_portoutw(data, 0, dep->de_data_port, size);
bytes = iovp->iod_iovec[ix].iov_size; /* Size of chunck */ else
if (bytes > pktsize) bytes = pktsize; netdriver_portoutb(data, 0, dep->de_data_port, size);
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);
for (ix = 0; ix < 100; ix += 1) { for (ix = 0; ix < 100; ix += 1) {
if (inb_reg0(dep, DP_ISR) & ISR_RDC) break; if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;
} }
if (ix == 100) { if (ix == 100)
panic("%s", RdmaErrMsg); panic("remote dma failed to complete");
}
return;
} }
/* /*
** Name: void ns_stats(dpeth_t * dep) ** Name: ns_stats
** Function: Updates counters reading from device ** Function: Updates counters reading from device
*/ */
static void ns_stats(dpeth_t * dep) 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_CRCerr += inb_reg0(dep, DP_CNTR0);
dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1); dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1);
dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2); dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2);
return;
} }
/* /*
** Name: void ns_dodump(dpeth_t * dep) ** Name: ns_dodump
** Function: Displays statistics (a request from F5 key). ** Function: Displays statistics (a request from a function key).
*/ */
static void ns_dodump(dpeth_t * dep) static void ns_dodump(dpeth_t * dep)
{ {
ns_stats(dep); /* Forces reading fo counters from board */ ns_stats(dep); /* Forces reading of counters from board */
return;
} }
/* /*
** Name: void ns_reinit(dpeth_t *dep) ** Name: ns_reinit
** Function: Updates receiver configuration. ** Function: Updates receiver configuration.
*/ */
static void ns_reinit(dpeth_t * dep) 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; if (dep->de_flags & DEF_MULTI) dp_reg |= RCR_AM;
outb_reg0(dep, DP_CR, CR_PS_P0); outb_reg0(dep, DP_CR, CR_PS_P0);
outb_reg0(dep, DP_RCR, dp_reg); 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. ** 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; int queue;
if (queue = dep->de_sendq_head, dep->de_sendq[queue].sq_filled) { queue = dep->de_sendq_head;
if (from_int) panic("should not be sending "); if (dep->de_sendq[queue].sq_filled)
dep->de_send_s = size; return SUSPEND;
return;
} (dep->de_user2nicf)(dep, dep->de_sendq[queue].sq_sendpage, data, size);
(dep->de_user2nicf) (dep, dep->de_sendq[queue].sq_sendpage, size);
dep->bytes_Tx += (long) size; dep->bytes_Tx += (long) size;
dep->de_sendq[queue].sq_filled = TRUE; 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.. */ if (dep->de_sendq_tail == queue) { /* there it goes.. */
ns_start_xmit(dep, size, dep->de_sendq[queue].sq_sendpage); ns_start_xmit(dep, size, dep->de_sendq[queue].sq_sendpage);
} else } 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; if (++queue == dep->de_sendq_nr) queue = 0;
dep->de_sendq_head = queue; 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. ** Function: Resets device.
*/ */
static void ns_reset(dpeth_t * dep) 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_CR, CR_STP | CR_NO_DMA);
outb_reg0(dep, DP_RBCR0, 0); outb_reg0(dep, DP_RBCR0, 0);
outb_reg0(dep, DP_RBCR1, 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 */ ; /* Do nothing */ ;
outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST); outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA); outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA);
outb_reg0(dep, DP_TCR, TCR_NORMAL | TCR_OFST); outb_reg0(dep, DP_TCR, TCR_NORMAL | TCR_OFST);
/* Acknowledge the ISR_RDC (remote dma) interrupt. */ /* 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 */ ; /* Do nothing */ ;
outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & NOT(ISR_RDC)); 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; dep->de_sendq_head = dep->de_sendq_tail = 0;
for (ix = 0; ix < dep->de_sendq_nr; ix++) for (ix = 0; ix < dep->de_sendq_nr; ix++)
dep->de_sendq[ix].sq_filled = FALSE; dep->de_sendq[ix].sq_filled = FALSE;
ns_send(dep, TRUE, dep->de_send_s); netdriver_send();
return;
} }
/* /*
** Name: void ns_recv(dpeth_t *dep, int fromint, int size) ** Name: ns_recv
** Function: Gets a packet from device ** 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; dp_rcvhdr_t header;
unsigned pageno, curr, next; unsigned pageno, curr, next;
vir_bytes length; size_t length;
int packet_processed = FALSE; int packet_processed = FALSE;
#ifdef ETH_IGN_PROTO #ifdef ETH_IGN_PROTO
u16_t eth_type; 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); curr = inb_reg1(dep, DP_CURR);
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_NO_DMA | CR_STA); 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 #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 #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; next = header.dr_next;
if (length < ETH_MIN_PACK_SIZE || length > ETH_MAX_PACK_SIZE) { if (length < ETH_MIN_PACK_SIZE || length > max) {
printf("%s: packet with strange length arrived: %ld\n", printf("%s: packet with strange length arrived: %zu\n",
dep->de_name, length); dep->de_name, length);
dep->de_stat.ets_recvErr += 1; dep->de_stat.ets_recvErr += 1;
next = curr; 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); printf("%s: strange next page\n", dep->de_name);
dep->de_stat.ets_recvErr += 1; dep->de_stat.ets_recvErr += 1;
next = curr; next = curr;
#ifdef ETH_IGN_PROTO #ifdef ETH_IGN_PROTO
} else if (eth_type == eth_ign_proto) { } else if (eth_type == eth_ign_proto) {
/* Hack: ignore packets of a given protocol */ /* Hack: ignore packets of a given protocol */
static int first = TRUE; static int first = TRUE;
if (first) { if (first) {
first = FALSE; 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; next = curr;
#endif #endif
} else if (header.dr_status & RSR_FO) { } else if (header.dr_status & RSR_FO) {
/* This is very serious, issue a warning and reset buffers */ /* 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; dep->de_stat.ets_fifoOver += 1;
next = curr; next = curr;
} else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) { } else if (header.dr_status & RSR_PRX) {
(dep->de_nic2userf)(dep, pageno, data, length);
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);
packet_processed = TRUE; packet_processed = TRUE;
} }
dep->bytes_Rx += (long) length; dep->bytes_Rx += (long) length;
dep->de_stat.ets_packetR += 1; 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; pageno = next;
} while (!packet_processed); } while (!packet_processed);
#if 0
if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED)) return length;
/* The chip is stopped, and all arrived packets delivered */
(*dep->de_resetf) (dep);
dep->de_flags &= NOT(DEF_STOPPED);
#endif
return;
} }
/* /*
** Name: void ns_interrupt(dpeth_t * dep) ** Name: ns_interrupt
** Function: Handles interrupt. ** Function: Handles interrupt.
*/ */
static void ns_interrupt(dpeth_t * dep) static void ns_interrupt(dpeth_t * dep)
@ -487,13 +369,15 @@ static void ns_interrupt(dpeth_t * dep)
dep->de_stat.ets_fifoUnder++; dep->de_stat.ets_fifoUnder++;
} }
if ((isr & ISR_TXE) || (tsr & (TSR_CRS | TSR_CDH | TSR_OWC))) { 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++; dep->de_stat.ets_sendErr++;
} }
queue = dep->de_sendq_tail; queue = dep->de_sendq_tail;
if (!(dep->de_sendq[queue].sq_filled)) { /* Hardware bug? */ if (!(dep->de_sendq[queue].sq_filled)) { /* Hardware bug? */
printf("%s: transmit interrupt, but not sending\n", dep->de_name); printf("%s: transmit interrupt, but not sending\n",
dep->de_name);
continue; continue;
} }
dep->de_sendq[queue].sq_filled = FALSE; 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, ns_start_xmit(dep, dep->de_sendq[queue].sq_size,
dep->de_sendq[queue].sq_sendpage); dep->de_sendq[queue].sq_sendpage);
} }
if (dep->de_flags & DEF_SENDING) { netdriver_send();
ns_send(dep, TRUE, dep->de_send_s);
}
} }
if (isr & ISR_PRX) { if (isr & ISR_PRX) {
ns_recv(dep, TRUE, 0); netdriver_recv();
} }
if (isr & ISR_RXE) { 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++; dep->de_stat.ets_recvErr++;
} }
if (isr & ISR_CNT) { if (isr & ISR_CNT) {
@ -526,26 +409,21 @@ static void ns_interrupt(dpeth_t * dep)
/* Nothing to do */ /* Nothing to do */
} }
if (isr & ISR_RST) { if (isr & ISR_RST) {
/* This means we got an interrupt but the ethernet /* This means we got an interrupt but the ethernet chip is shut
* chip is shutdown. We set the flag DEF_STOPPED, and * down. We reset the chip right away, possibly losing received
* continue processing arrived packets. When the * packets in the process. There used to be a more elaborate
* receive buffer is empty, we reset the dp8390. */ * 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); printf("%s: network interface stopped\n", dep->de_name);
dep->de_flags |= DEF_STOPPED; ns_reset(dep);
break; 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 ** Function: Initializes the NS 8390
*/ */
void ns_init(dpeth_t * dep) void ns_init(dpeth_t * dep)
@ -555,12 +433,8 @@ void ns_init(dpeth_t * dep)
/* NS8390 initialization (as recommended in National Semiconductor specs) */ /* NS8390 initialization (as recommended in National Semiconductor specs) */
outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_NO_DMA); /* 0x21 */ 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) | outb_reg0(dep, DP_DCR, (((dep->de_16bit) ? DCR_WORDWIDE : DCR_BYTEWIDE) |
DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS)); DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS));
#endif
outb_reg0(dep, DP_RBCR0, 0); outb_reg0(dep, DP_RBCR0, 0);
outb_reg0(dep, DP_RBCR1, 0); outb_reg0(dep, DP_RBCR1, 0);
outb_reg0(dep, DP_RCR, RCR_MON); /* Sets Monitor mode */ 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_nic2userf = mem_nic2user;
dep->de_getblockf = mem_getblock; dep->de_getblockf = mem_getblock;
} else { } else {
#if PIO16 == 0
dep->de_user2nicf = pio_user2nic; dep->de_user2nicf = pio_user2nic;
dep->de_nic2userf = pio_nic2user; dep->de_nic2userf = pio_nic2user;
dep->de_getblockf = pio_getblock; dep->de_getblockf = pio_getblock;
#else
#error Missing I/O functions for pio 16 bits
#endif
} }
dep->de_recvf = ns_recv; dep->de_recvf = ns_recv;
dep->de_sendf = ns_send; dep->de_sendf = ns_send;
@ -624,135 +494,8 @@ void ns_init(dpeth_t * dep)
dep->de_getstatsf = ns_stats; dep->de_getstatsf = ns_stats;
dep->de_dumpstatsf = ns_dodump; dep->de_dumpstatsf = ns_dodump;
dep->de_interruptf = ns_interrupt; 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 */ #endif /* ENABLE_DP8390 */
/** end 8390.c **/ /** 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} DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys LDADD+= -lnetdriver -lsys
CPPFLAGS+= -Ddebug=0 CPPFLAGS+= -DVERBOSE=0
.include <minix.service.mk> .include <minix.service.mk>

View File

@ -3,11 +3,12 @@
** **
** Author: Giovanni Falzoni <gfalzoni@inwind.it> ** 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. ** from/to the device registers.
*/ */
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
#include "dp.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); 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. ** Function: Reads a byte from specified i/o port.
*/ */
unsigned int inb(unsigned short 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. ** Function: Reads a word from specified i/o port.
*/ */
unsigned int inw(unsigned short 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); ** Name: insb
** Function: Reads a sequence of bytes from specified i/o port to user space buffer. ** Function: Reads a sequence of bytes from an i/o port.
*/ */
void insb(unsigned short int port, endpoint_t proc_nr, void insb(unsigned short int port, void *buffer, int count)
void *buffer, int count)
{ {
int rc; int rc;
if ((rc = sys_insb(port, proc_nr, buffer, count)) != OK) if ((rc = sys_insb(port, SELF, buffer, count)) != OK)
warning("insb", rc); 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. ** Function: Writes a byte to specified i/o port.
*/ */
void outb(unsigned short port, unsigned long value) void outb(unsigned short port, unsigned long value)
@ -71,11 +80,10 @@ void outb(unsigned short port, unsigned long value)
int rc; int rc;
if ((rc = sys_outb(port, value)) != OK) warning("outb", 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. ** Function: Writes a word to specified i/o port.
*/ */
void outw(unsigned short port, unsigned long value) void outw(unsigned short port, unsigned long value)
@ -83,20 +91,18 @@ void outw(unsigned short port, unsigned long value)
int rc; int rc;
if ((rc = sys_outw(port, value)) != OK) warning("outw", 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); ** Name: outsb
** Function: Writes a sequence of bytes from user space to specified i/o port. ** 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; int rc;
if ((rc = sys_outsb(port, proc_nr, buffer, count)) != OK) if ((rc = sys_outsb(port, SELF, buffer, count)) != OK)
warning("outsb", rc); warning("outsb", rc);
return;
} }
#else #else

View File

@ -14,9 +14,10 @@
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/netdriver.h> #include <minix/netdriver.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/ds.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
#include <sys/mman.h>
#include <assert.h>
#include "dp.h" #include "dp.h"
@ -24,7 +25,6 @@
** Local data ** Local data
*/ */
static dpeth_t de_state; static dpeth_t de_state;
static int de_instance;
typedef struct dp_conf { /* Configuration description structure */ typedef struct dp_conf { /* Configuration description structure */
port_t dpc_port; port_t dpc_port;
@ -41,90 +41,43 @@ static dp_conf_t dp_conf[DP_CONF_NR] = {
{ 0x000, 0, 0x00000, }, { 0x000, 0, 0x00000, },
}; };
static char CopyErrMsg[] = "unable to read/write user data"; static int do_init(unsigned int instance, ether_addr_t *addr);
static char RecvErrMsg[] = "netdriver_receive failed"; static void do_stop(void);
static char SendErrMsg[] = "send failed"; static void do_mode(unsigned int mode);
static char SizeErrMsg[] = "illegal packet size"; static int do_send(struct netdriver_data *data, size_t size);
static char TypeErrMsg[] = "illegal message type"; static ssize_t do_recv(struct netdriver_data *data, size_t max);
static char DevName[] = "eth#?"; 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) ** Name: update_conf
** 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)
** Function: Gets the default settings from 'dp_conf' table and ** Function: Gets the default settings from 'dp_conf' table and
** modifies them from the environment. ** 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"; static char dpc_fmt[] = "x:d:x";
char ec_key[16]; char ec_key[16];
long val; long val;
strlcpy(ec_key, "DPETH0", sizeof(ec_key)); 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 */ val = dcp->dpc_port; /* Get I/O port address */
switch (env_parse(ec_key, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) { 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;
}
dep->de_base_port = val; dep->de_base_port = val;
val = dcp->dpc_irq | DEI_DEFAULT; /* Get Interrupt line (IRQ) */ 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 */ val = dcp->dpc_mem; /* Get shared memory address */
env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX); env_parse(ec_key, dpc_fmt, 2, &val, 0L, LONG_MAX);
dep->de_linmem = val; dep->de_linmem = val;
return;
} }
/* /*
** Name: void do_dump(message *mp) ** Name: do_dump
** Function: Displays statistics on screen (SFx key from console) ** Function: Displays statistics on screen (SFx key from console)
*/ */
static void do_dump(const message *mp) static void do_dump(void)
{ {
dpeth_t *dep; dpeth_t *dep;
@ -150,14 +101,12 @@ static void do_dump(const message *mp)
printf("\n\n"); printf("\n\n");
if (dep->de_mode == DEM_DISABLED) return;
printf("%s statistics:\t\t", dep->de_name); printf("%s statistics:\t\t", dep->de_name);
/* Network interface status */ /* 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 */ /* Transmitted/received bytes */
printf("Tx bytes:%10ld\t", dep->bytes_Tx); printf("Tx bytes:%10ld\t", dep->bytes_Tx);
@ -178,40 +127,31 @@ static void do_dump(const message *mp)
/* Transmit collisions/receive CRC errors */ /* Transmit collisions/receive CRC errors */
printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision); printf("Tx Coll: %8ld\t", dep->de_stat.ets_collision);
printf("Rx CRC: %8ld\n", dep->de_stat.ets_CRCerr); 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) ** Name: do_first_init
** 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);
** Function: Init action to setup task ** Function: Init action to setup task
*/ */
static void do_first_init(dpeth_t *dep, const dp_conf_t *dcp) 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 */ /* 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 */ /* 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 /* Set the interrupt handler policy. Request interrupts not to be reenabled
* automatically. Return the IRQ line number when an interrupt occurs. * 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; dep->de_hook = dep->de_irq;
if (sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook) != OK) if (sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook) != OK)
panic("unable to set IRQ policy"); panic("unable to set IRQ policy");
dep->de_int_pending = FALSE;
sys_irqenable(&dep->de_hook); sys_irqenable(&dep->de_hook);
return;
} }
/* /*
** Name: void do_init(message *mp) ** Name: do_init
** Function: Checks for hardware presence. ** 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; dpeth_t *dep;
dp_conf_t *dcp; dp_conf_t *dcp;
message reply_mess; int confnr, fkeys, sfkeys;
int r, confnr;
dep = &de_state; 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. */ /* 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]; 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 (!el1_probe(dep) && /* Probe for 3c501 */
if (dep->de_mode == DEM_ENABLED &&
!el1_probe(dep) && /* Probe for 3c501 */
!wdeth_probe(dep) && /* Probe for WD80x3 */ !wdeth_probe(dep) && /* Probe for WD80x3 */
!ne_probe(dep) && /* Probe for NEx000 */ !ne_probe(dep) && /* Probe for NEx000 */
!el2_probe(dep) && /* Probe for 3c503 */ !el2_probe(dep) && /* Probe for 3c503 */
!el3_probe(dep)) { /* Probe for 3c509 */ !el3_probe(dep)) { /* Probe for 3c509 */
printf("%s: warning no ethernet card found at 0x%04X\n", printf("%s: warning no ethernet card found at 0x%04X\n",
dep->de_name, dep->de_base_port); dep->de_name, dep->de_base_port);
dep->de_mode = DEM_DISABLED; return ENXIO;
}
} }
r = OK;
/* 'de_mode' may change if probe routines fail, test again */
switch (dep->de_mode) {
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); do_first_init(dep, dcp);
dep->de_flags |= DEF_ENABLED;
} /* 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);
memcpy(addr, dep->de_address.ea_addr, sizeof(*addr));
return OK;
}
/*
** Name: de_mode
** Function: Sets packet receipt mode.
*/
static void do_mode(unsigned int mode)
{
dpeth_t *dep;
dep = &de_state;
dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD); dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
if (mp->m_net_netdrv_dl_conf.mode & DL_PROMISC_REQ) if (mode & NDEV_PROMISC)
dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD; dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
if (mp->m_net_netdrv_dl_conf.mode & DL_MULTI_REQ) if (mode & NDEV_MULTI)
dep->de_flags |= DEF_MULTI; dep->de_flags |= DEF_MULTI;
if (mp->m_net_netdrv_dl_conf.mode & DL_BROAD_REQ) if (mode & NDEV_BROAD)
dep->de_flags |= DEF_BROAD; dep->de_flags |= DEF_BROAD;
(*dep->de_flagsf) (dep); (*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;
} }
/* /*
** Name: void dp_next_iovec(iovec_dat_t *iovp) ** Name: do_send
** Function: Retrieves data from next iovec element. ** Function: Send a packet, if possible.
*/ */
void dp_next_iovec(iovec_dat_s_t * iovp) static int do_send(struct netdriver_data *data, size_t size)
{ {
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; dpeth_t *dep;
dep = &de_state; dep = &de_state;
dep->de_client = mp->m_source; return (*dep->de_sendf)(dep, data, size);
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;
} }
/* /*
** Name: void do_vread_s(message *mp, int vectored) ** Name: do_recv
** Function: ** Function: Receive a packet, if possible.
*/ */
static void do_vread_s(const message * mp) static ssize_t do_recv(struct netdriver_data *data, size_t max)
{ {
int size;
dpeth_t *dep; dpeth_t *dep;
dep = &de_state; dep = &de_state;
dep->de_client = mp->m_source; return (*dep->de_recvf)(dep, data, max);
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;
} }
/* /*
** Name: void do_getstat_s(message *mp) ** Name: do_stat
** Function: Reports device statistics. ** 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; memcpy(stat, &de_state.de_stat, sizeof(*stat));
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;
} }
/* /*
** Name: void dp_stop(dpeth_t *dep) ** Name: do_stop
** Function: Stops network interface. ** 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 */ /* Stop device */
(dep->de_stopf) (dep); (dep->de_stopf)(dep);
dep->de_flags = DEF_EMPTY;
dep->de_mode = DEM_DISABLED;
}
return;
} }
static void do_watchdog(const void *UNUSED(message)) /*
{ ** Name: do_intr
** Function; Handles interrupts.
DEBUG(printf("\t no reply")); */
return; static void do_intr(unsigned int __unused mask)
}
static void handle_hw_intr(void)
{ {
dpeth_t *dep; dpeth_t *dep;
dep = &de_state; dep = &de_state;
/* If device is enabled and interrupt pending */ /* If device is enabled and interrupt pending */
if (dep->de_mode == DEM_ENABLED) { (*dep->de_interruptf)(dep);
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); sys_irqenable(&dep->de_hook);
}
} }
/* SEF functions and variables. */ /*
static void sef_local_startup(void); ** Name: do_other
static int sef_cb_init_fresh(int type, sef_init_info_t *info); ** Function: Processes miscellaneous messages.
static void sef_cb_signal_handler(int signo); */
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 ** Function: Main entry for dp task
*/ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
message m;
int ipc_status;
int rc;
/* SEF local startup. */
env_setargs(argc, argv); env_setargs(argc, argv);
sef_local_startup();
while (TRUE) { netdriver_task(&dp_table);
if ((rc = netdriver_receive(ANY, &m, &ipc_status)) != OK){
panic(RecvErrMsg, rc);
}
DEBUG(printf("eth: got message %d, ", m.m_type)); return 0;
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 */
} }
/*===========================================================================*
* 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)) #define NOT(x) (~(x))
#if debug == 1 #if VERBOSE == 1
# define DEBUG(statm) statm # define DEBUG(statm) statm
#else #else
# define DEBUG(statm) # define DEBUG(statm)
@ -70,26 +70,19 @@ typedef struct _buff_t { /* Receive/Transmit buffer header */
} buff_t; } buff_t;
struct dpeth; struct dpeth;
struct iovec_dat; typedef void (*dp_eth_t)(struct dpeth *);
typedef void (*dp_eth_t) (struct dpeth *); typedef int (*dp_send_t)(struct dpeth *, struct netdriver_data *, size_t);
typedef void (*dp_send_recv_t) (struct dpeth *, int, int); typedef ssize_t (*dp_recv_t)(struct dpeth *, struct netdriver_data *, size_t);
#if ENABLE_DP8390 == 1 #if ENABLE_DP8390 == 1
typedef void (*dp_user2nicf_t) (struct dpeth *, int, int); typedef void (*dp_user2nicf_t)(struct dpeth *, int, struct netdriver_data *,
typedef void (*dp_nic2userf_t) (struct dpeth *, int, int); size_t);
typedef void (*dp_getblock_t) (struct dpeth *, u16_t, int, void *); 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 #endif
#define SENDQ_NR 2 /* Size of the send queue */ #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 { typedef struct dpeth {
/* The de_base_port field is the starting point of the probe. The /* 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 */ port_t de_data_port; /* For boards using Prog. I/O for xmit/recv */
int de_irq; int de_irq;
int de_int_pending;
int de_hook; /* interrupt hook at kernel */ int de_hook; /* interrupt hook at kernel */
char de_name[8]; char de_name[8];
@ -117,7 +109,7 @@ typedef struct dpeth {
#define DEI_DEFAULT 0x8000 #define DEI_DEFAULT 0x8000
phys_bytes de_linmem; /* For boards using shared memory */ 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_ramsize; /* Size of on board memory */
int de_offset_page; /* Offset of shared memory page */ 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_getstatsf;
dp_eth_t de_dumpstatsf; dp_eth_t de_dumpstatsf;
dp_eth_t de_interruptf; dp_eth_t de_interruptf;
dp_send_recv_t de_recvf; dp_recv_t de_recvf;
dp_send_recv_t de_sendf; dp_send_t de_sendf;
ether_addr_t de_address; /* Ethernet Address */ ether_addr_t de_address; /* Ethernet Address */
eth_stat_t de_stat; /* Ethernet Statistics */ eth_stat_t de_stat; /* Ethernet Statistics */
@ -141,35 +133,12 @@ typedef struct dpeth {
int de_flags; /* Send/Receive mode (Configuration) */ int de_flags; /* Send/Receive mode (Configuration) */
#define DEF_EMPTY 0x0000 #define DEF_EMPTY 0x00
#define DEF_READING 0x0001 #define DEF_XMIT_BUSY 0x01
#define DEF_RECV_BUSY 0x0002 #define DEF_PROMISC 0x02
#define DEF_ACK_RECV 0x0004 #define DEF_MULTI 0x04
#define DEF_SENDING 0x0010 #define DEF_BROAD 0x08
#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
/* 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 #if ENABLE_DP8390 == 1
/* For use by NS DP8390 driver */ /* For use by NS DP8390 driver */
port_t de_dp8390_port; port_t de_dp8390_port;
@ -203,8 +172,6 @@ typedef struct dpeth {
/* For use by 3Com Etherlink (3c501 and 3c509) driver */ /* For use by 3Com Etherlink (3c501 and 3c509) driver */
buff_t *de_recvq_head; buff_t *de_recvq_head;
buff_t *de_recvq_tail; buff_t *de_recvq_tail;
buff_t *de_xmitq_head;
buff_t *de_xmitq_tail;
u16_t de_recv_mode; u16_t de_recv_mode;
clock_t de_xmit_start; clock_t de_xmit_start;
#endif #endif
@ -215,29 +182,23 @@ typedef struct dpeth {
* Function definitions * Function definitions
*/ */
/* dp.c */
void dp_next_iovec(iovec_dat_s_t * iovp);
/* devio.c */ /* devio.c */
#if defined USE_IOPL #if defined USE_IOPL
#include <machine/portio.h> #include <machine/portio.h>
#else #else
unsigned int inb(unsigned short int); unsigned int inb(unsigned short int);
unsigned int inw(unsigned short int); unsigned int inw(unsigned short int);
void insb(unsigned short int, endpoint_t, void *, int); void insb(unsigned short int, void *, int);
void insw(unsigned short int, int, void *, int); void insw(unsigned short int, void *, int);
void outb(unsigned short int, unsigned long); void outb(unsigned short int, unsigned long);
void outw(unsigned short int, unsigned long); void outw(unsigned short int, unsigned long);
void outsb(unsigned short int, endpoint_t, void *, int); void outsb(unsigned short int, void *, int);
void outsw(unsigned short int, int, void *, int);
#endif #endif
/* netbuff.c */ /* netbuff.c */
void *alloc_buff(dpeth_t *, int); void *alloc_buff(dpeth_t *, int);
void free_buff(dpeth_t *, void *); void free_buff(dpeth_t *, void *);
void init_buff(dpeth_t *, buff_t **); void init_buff(dpeth_t *, buff_t **);
void mem2user(dpeth_t *, buff_t *);
void user2mem(dpeth_t *, buff_t *);
/* 3c501.c */ /* 3c501.c */
#if ENABLE_3C501 == 1 #if ENABLE_3C501 == 1
@ -274,8 +235,4 @@ int wdeth_probe(dpeth_t * dep);
#define wdeth_probe(x) (0) #define wdeth_probe(x) (0)
#endif #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 **/ /** dp.h **/

View File

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

View File

@ -8,6 +8,7 @@
*/ */
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/netdriver.h>
#include <net/gen/ether.h> #include <net/gen/ether.h>
#include <net/gen/eth_io.h> #include <net/gen/eth_io.h>
#include "dp.h" #include "dp.h"
@ -18,7 +19,7 @@ static m_hdr_t *allocptr = NULL;
static char tx_rx_buff[8192]; 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. ** Function: Allocates a buffer from the common pool.
*/ */
void *alloc_buff(dpeth_t *dep, int size) 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; m_hdr_t *ptr, *wrk = allocptr;
int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1; int units = ((size + sizeof(m_hdr_t) - 1) / sizeof(m_hdr_t)) + 1;
lock();
for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) { for (ptr = wrk->next;; wrk = ptr, ptr = ptr->next) {
if (ptr->size >= units) { if (ptr->size >= units) {
/* Memory is available, carve requested size from pool */ /* Memory is available, carve requested size from pool */
@ -39,24 +39,22 @@ void *alloc_buff(dpeth_t *dep, int size)
ptr->size = units; ptr->size = units;
} }
allocptr = wrk; allocptr = wrk;
unlock();
return ptr + 1; return ptr + 1;
} }
if (ptr == allocptr) break; if (ptr == allocptr) break;
} }
unlock();
return NULL; /* No memory available */ 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. ** Function: Returns a buffer to the common pool.
*/ */
void free_buff(dpeth_t *dep, void *blk) void free_buff(dpeth_t *dep, void *blk)
{ {
m_hdr_t *wrk, *ptr = (m_hdr_t *) blk - 1; 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) for (wrk = allocptr; !(ptr > wrk && ptr < wrk->next); wrk = wrk->next)
if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break; if (wrk >= wrk->next && (ptr > wrk || ptr < wrk->next)) break;
@ -72,12 +70,10 @@ void free_buff(dpeth_t *dep, void *blk)
} else } else
wrk->next = ptr; wrk->next = ptr;
allocptr = wrk; /* Point allocptr to block just released */ 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. ** Function: Initalizes driver data structures.
*/ */
void init_buff(dpeth_t *dep, buff_t **tx_buff) 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; (*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 */ #endif /* HAVE_BUFFERS */

View File

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

View File

@ -6,7 +6,7 @@ FILES=$(PROG).conf
FILESNAME=$(PROG) FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys -ltimers LDADD+= -lnetdriver -lsys
.include <minix.service.mk> .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:100e;
pci device 8086:100f; pci device 8086:100f;
pci device 8086:101e;
pci device 8086:107c; pci device 8086:107c;
pci device 8086:10cd; pci device 8086:10cd;
pci device 8086:10d3; pci device 8086:10d3;

View File

@ -18,13 +18,6 @@
#ifndef __E1000_H #ifndef __E1000_H
#define __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" #include "e1000_hw.h"
/** /**
@ -38,14 +31,11 @@
/** Number of transmit descriptors per card. */ /** Number of transmit descriptors per card. */
#define E1000_TXDESC_NR 256 #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. */ /** Size of each I/O buffer per descriptor. */
#define E1000_IOBUF_SIZE 2048 #define E1000_IOBUF_SIZE 2048
/** Debug verbosity. */ /** Debug verbosity. */
#define E1000_VERBOSE 1 #define E1000_VERBOSE 0
/** MAC address override variable. */ /** MAC address override variable. */
#define E1000_ENVVAR "E1000ETH" #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 typedef struct e1000
{ {
char name[8]; /**< String containing the device name. */ char name[8]; /**< String containing the device name. */
int status; /**< Describes the card's current state. */
int irq; /**< Interrupt Request Vector. */ int irq; /**< Interrupt Request Vector. */
int irq_hook; /**< Interrupt Request Vector Hook. */ int irq_hook; /**< Interrupt Request Vector Hook. */
int revision; /**< Hardware Revision Number. */
u8_t *regs; /**< Memory mapped hardware registers. */ u8_t *regs; /**< Memory mapped hardware registers. */
u8_t *flash; /**< Optional flash memory. */ u8_t *flash; /**< Optional flash memory. */
u32_t flash_base_addr; /**< Flash base address. */ u32_t flash_base_addr; /**< Flash base address. */
ether_addr_t address; /**< Ethernet MAC address. */ u16_t (*eeprom_read)(struct e1000 *, int reg);
u16_t (*eeprom_read)(void *, int reg); /**< Function to read /**< Function to read the EEPROM. */
the EEPROM. */
int eeprom_done_bit; /**< Offset of the EERD.DONE bit. */ int eeprom_done_bit; /**< Offset of the EERD.DONE bit. */
int eeprom_addr_off; /**< Offset of the EERD.ADDR field. */ int eeprom_addr_off; /**< Offset of the EERD.ADDR field. */
e1000_rx_desc_t *rx_desc; /**< Receive Descriptor table. */ 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. */ int rx_desc_count; /**< Number of Receive Descriptors. */
char *rx_buffer; /**< Receive buffer returned by malloc(). */ char *rx_buffer; /**< Receive buffer returned by malloc(). */
int rx_buffer_size; /**< Size of the receive buffer. */ int rx_buffer_size; /**< Size of the receive buffer. */
e1000_tx_desc_t *tx_desc; /**< Transmit Descriptor table. */ 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. */ int tx_desc_count; /**< Number of Transmit Descriptors. */
char *tx_buffer; /**< Transmit buffer returned by malloc(). */ char *tx_buffer; /**< Transmit buffer returned by malloc(). */
int tx_buffer_size; /**< Size of the transmit buffer. */ int tx_buffer_size; /**< Size of the transmit buffer. */
} e1000_t;
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;
#endif /* __E1000_H */ #endif /* __E1000_H */

View File

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

View File

@ -1,31 +1,28 @@
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/netdriver.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 <minix/board.h>
#include <sys/mman.h>
#include "assert.h" #include "assert.h"
#include "lan8710a.h" #include "lan8710a.h"
#include "lan8710a_reg.h" #include "lan8710a_reg.h"
/* Local functions */ /* Local functions */
static void lan8710a_readv_s(message *m, int from_int); static int lan8710a_init(unsigned int instance, ether_addr_t *addr);
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 void lan8710a_stop(void); 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_config_tx(u8_t desc_idx);
static void lan8710a_dma_reset_init(void); 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_desc(void);
static void lan8710a_init_mdio(void); static void lan8710a_init_mdio(void);
static int lan8710a_init_hw(void); static int lan8710a_init_hw(ether_addr_t *addr);
static void lan8710a_reset_hw(); static void lan8710a_reset_hw(void);
static void lan8710a_phy_write(u32_t reg, u32_t value); static void lan8710a_phy_write(u32_t reg, u32_t value);
static u32_t lan8710a_phy_read(u32_t reg); 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_set(volatile u32_t *reg, u32_t value);
static void lan8710a_reg_unset(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 */ /* Local variables */
static lan8710a_t lan8710a_state; static lan8710a_t lan8710a_state;
/* SEF functions and variables. */ static const struct netdriver lan8710a_table = {
static void sef_local_startup(void); .ndr_init = lan8710a_init,
static int sef_cb_init_fresh(int type, sef_init_info_t *info); .ndr_stop = lan8710a_stop,
static void sef_cb_signal_handler(int signal); .ndr_recv = lan8710a_recv,
.ndr_send = lan8710a_send,
.ndr_stat = lan8710a_stat,
.ndr_intr = lan8710a_intr
};
/*============================================================================* /*============================================================================*
* main * * main *
@ -52,122 +50,45 @@ static void sef_cb_signal_handler(int signal);
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct machine machine;
/* Local variables */ env_setargs(argc, argv);
message m;
int r;
int ipc_status;
struct machine machine ;
sys_getmachine(&machine); 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; return EXIT_SUCCESS;
} }
/*============================================================================* /*============================================================================*
* sef_local_startup * * lan8710a_init *
*============================================================================*/
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 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. */ /* Initialize the ethernet driver. */
long v = 0;
/* Clear state. */ /* Clear state. */
memset(&lan8710a_state, 0, sizeof(lan8710a_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. */ /* Initialize driver. */
lan8710a_init(); lan8710a_map_regs();
/* Get instance of ethernet device */ lan8710a_init_hw(addr);
env_parse("instance", "d", 0, &v, 0, 255);
lan8710a_state.instance = (int) v;
/* Announce we are up! */
netdriver_announce();
return OK; 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 * * lan8710a_enable_interrupt *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_enable_interrupt(interrupt) lan8710a_enable_interrupt(int interrupt)
u8_t interrupt;
{ {
int r; int r;
@ -182,14 +103,13 @@ u8_t interrupt;
} }
} }
} }
/*============================================================================* /*============================================================================*
* lan8710a_interrupt * * lan8710a_intr *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_interrupt(m) lan8710a_intr(unsigned int mask)
message *m;
{ {
lan8710a_t *e = &lan8710a_state;
u32_t dma_status; u32_t dma_status;
/* Check the card for interrupt reason(s). */ /* Check the card for interrupt reason(s). */
@ -201,7 +121,7 @@ message *m;
if (rx_stat) { if (rx_stat) {
cp = lan8710a_reg_read(CPDMA_STRAM_RX_CP(0)); 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_STRAM_RX_CP(0), cp);
lan8710a_reg_write(CPDMA_EOI_VECTOR, RX_INT); lan8710a_reg_write(CPDMA_EOI_VECTOR, RX_INT);
@ -212,7 +132,7 @@ message *m;
/* Disabling channels, where Tx interrupt occurred */ /* Disabling channels, where Tx interrupt occurred */
lan8710a_reg_set(CPDMA_TX_INTMASK_CLEAR, tx_stat); 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_STRAM_TX_CP(0), cp);
lan8710a_reg_write(CPDMA_EOI_VECTOR, TX_INT); lan8710a_reg_write(CPDMA_EOI_VECTOR, TX_INT);
@ -226,61 +146,19 @@ message *m;
} }
/* Re-enable Rx interrupt. */ /* Re-enable Rx interrupt. */
if(m->m_notify.interrupts & (1 << RX_INT)) if (mask & (1 << RX_INT))
lan8710a_enable_interrupt(RX_INT); lan8710a_enable_interrupt(RX_INT);
/* Re-enable Tx interrupt. */ /* Re-enable Tx interrupt. */
if(m->m_notify.interrupts & (1 << TX_INT)) if (mask & (1 << TX_INT))
lan8710a_enable_interrupt(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 * * lan8710a_init_addr *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_init_addr(void) lan8710a_init_addr(ether_addr_t * addr)
{ {
static char eakey[]= LAN8710A_ENVVAR "#_EA"; static char eakey[]= LAN8710A_ENVVAR "#_EA";
static char eafmt[]= "x:x:x:x:x:x"; 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) if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
break; break;
else else
lan8710a_state.address.ea_addr[i] = v; addr->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);
} }
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 static void
lan8710a_getstat(mp) lan8710a_stat(eth_stat_t * stat)
message *mp;
{ {
int r; stat->ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
eth_stat_t stats;
stats.ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
+ lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR) + lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR)
+ lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE); + lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE);
stats.ets_sendErr = 0; stat->ets_sendErr = 0;
stats.ets_OVW = 0; stat->ets_OVW = 0;
stats.ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR); stat->ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR);
stats.ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR); stat->ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR);
stats.ets_missedP = 0; stat->ets_missedP = 0;
stats.ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD); stat->ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD);
stats.ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD); stat->ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD);
stats.ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS); stat->ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS);
stats.ets_transAb = 0; stat->ets_transAb = 0;
stats.ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR); stat->ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR);
stats.ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN); stat->ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN);
stats.ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN); stat->ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN);
stats.ets_CDheartbeat = 0; stat->ets_CDheartbeat = 0;
stats.ets_OWC = 0; stat->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);
}
} }
/*============================================================================* /*============================================================================*
@ -455,17 +319,13 @@ lan8710a_stop(void)
{ {
/* Reset hardware. */ /* Reset hardware. */
lan8710a_reset_hw(); lan8710a_reset_hw();
/* Exit driver. */
exit(EXIT_SUCCESS);
} }
/*============================================================================* /*============================================================================*
* lan8710a_dma_config_tx * * lan8710a_dma_config_tx *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_dma_config_tx(desc_idx) lan8710a_dma_config_tx(u8_t desc_idx)
u8_t desc_idx;
{ {
phys_bytes phys_addr; phys_bytes phys_addr;
int i; int i;
@ -585,12 +445,10 @@ lan8710a_init_desc(void)
* lan8710a_init_hw * * lan8710a_init_hw *
*============================================================================*/ *============================================================================*/
static int static int
lan8710a_init_hw(void) lan8710a_init_hw(ether_addr_t * addr)
{ {
int r, i; int r, i;
lan8710a_state.status |= LAN8710A_ENABLED;
/* /*
* Set the interrupt handler and policy. Do not automatically * Set the interrupt handler and policy. Do not automatically
* re-enable interrupts. Return the IRQ line number on interrupts. * re-enable interrupts. Return the IRQ line number on interrupts.
@ -757,7 +615,7 @@ lan8710a_init_hw(void)
lan8710a_init_mdio(); lan8710a_init_mdio();
/* Getting MAC Address */ /* Getting MAC Address */
lan8710a_init_addr(); lan8710a_init_addr(addr);
/* Initialize descriptors */ /* Initialize descriptors */
lan8710a_init_desc(); lan8710a_init_desc();
@ -825,150 +683,75 @@ lan8710a_init_mdio(void)
} }
/*============================================================================* /*============================================================================*
* lan8710a_writev_s * * lan8710a_send *
*============================================================================*/ *============================================================================*/
static void static int
lan8710a_writev_s(mp, from_int) lan8710a_send(struct netdriver_data * data, size_t size)
message *mp;
int from_int;
{ {
iovec_s_t iovec[LAN8710A_IOVEC_NR];
lan8710a_t *e = &lan8710a_state; lan8710a_t *e = &lan8710a_state;
lan8710a_desc_t *p_tx_desc; lan8710a_desc_t *p_tx_desc;
u8_t *p_buf; u8_t *buf;
int r, size, buf_data_len, i;
/* Are we called from the interrupt handler? */
if (!from_int) {
/* We cannot write twice simultaneously. */
assert(!(e->status & LAN8710A_WRITING));
/* Copy write message. */
e->tx_message = *mp;
e->client = mp->m_source;
e->status |= LAN8710A_WRITING;
/* 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);
/*
* 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 */ /* setup descriptors */
p_tx_desc = &(e->tx_desc[e->tx_desc_idx]); p_tx_desc = &(e->tx_desc[e->tx_desc_idx]);
/* /*
* Check if descriptor is available for host * Check if descriptor is available for host and suspend if not.
* and drop the packet if not.
*/ */
if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags) { if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags)
panic("No available transmit descriptor."); return SUSPEND;
/* 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);
return OK;
} }
/* virtual address of buffer */ /* virtual address of buffer */
p_buf = e->p_tx_buf + e->tx_desc_idx * LAN8710A_IOBUF_SIZE; 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 */ netdriver_copyin(data, 0, buf, size);
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 */ /* set descriptor length */
p_tx_desc->buffer_length_off = buf_data_len; p_tx_desc->buffer_length_off = size;
/* set flags */ /* set flags */
p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN | p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN |
LAN8710A_DESC_FLAG_SOP | LAN8710A_DESC_FLAG_SOP |
LAN8710A_DESC_FLAG_EOP | LAN8710A_DESC_FLAG_EOP |
TX_DESC_TO_PORT1 | TX_DESC_TO_PORT1 |
TX_DESC_TO_PORT_EN); TX_DESC_TO_PORT_EN);
p_tx_desc->pkt_len_flags |= buf_data_len; p_tx_desc->pkt_len_flags |= size;
/* setup DMA transfer */ /* setup DMA transfer */
lan8710a_dma_config_tx(e->tx_desc_idx); lan8710a_dma_config_tx(e->tx_desc_idx);
e->tx_desc_idx++; e->tx_desc_idx++;
if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx) { if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx)
e->tx_desc_idx = 0; e->tx_desc_idx = 0;
}
} else { return OK;
e->status |= LAN8710A_TRANSMIT;
}
reply(e);
} }
/*============================================================================* /*============================================================================*
* lan8710a_readv_s * * lan8710a_recv *
*============================================================================*/ *============================================================================*/
static void static ssize_t
lan8710a_readv_s(mp, from_int) lan8710a_recv(struct netdriver_data * data, size_t max)
message *mp;
int from_int;
{ {
iovec_s_t iovec[LAN8710A_IOVEC_NR];
lan8710a_t *e = &lan8710a_state; lan8710a_t *e = &lan8710a_state;
lan8710a_desc_t *p_rx_desc; lan8710a_desc_t *p_rx_desc;
u32_t flags; u32_t flags;
u8_t *p_buf; u8_t *buf;
u16_t pkt_data_len; size_t off, size, chunk;
u16_t buf_bytes, buf_len;
int i, r, size;
/* 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;
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. * Only handle one packet at a time.
*/ */
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]); p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
/* find next OWN descriptor with SOP flag */ /* find next OWN descriptor with SOP flag */
while ((0 == (LAN8710A_DESC_FLAG_SOP & while ((0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) &&
p_rx_desc->pkt_len_flags)) && (0 == (LAN8710A_DESC_FLAG_OWN & 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; p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current descriptor to EMAC */ /* set ownership of current descriptor to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN; p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
@ -978,91 +761,67 @@ int from_int;
e->rx_desc_idx = 0; e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]); p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
} }
if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) { if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) {
/* SOP was not found */ /* SOP was not found */
reply(e); return SUSPEND;
return;
} }
/* /*
* Copy to vector elements. * 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..
*/ */
pkt_data_len = 0; size = 0;
buf_bytes = 0; off = 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++; for (;;) {
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx) buf = e->p_rx_buf + e->rx_desc_idx * LAN8710A_IOBUF_SIZE + off;
e->rx_desc_idx = 0; chunk = p_rx_desc->buffer_length_off & 0xFFFF;
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, /* Truncate packets that are too large. */
iovec[i].iov_grant, 0, if (chunk > max - size)
(vir_bytes) p_buf, chunk = max - size;
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 (chunk > 0) {
if ((LAN8710A_DESC_FLAG_EOP & p_rx_desc->pkt_len_flags) && netdriver_copyout(data, size, buf, chunk);
(buf_bytes == buf_len)) {
/* end of packet */ size += chunk;
break;
} }
}
do {
/* reset owned descriptors up to EOP flag */
flags = p_rx_desc->pkt_len_flags; flags = p_rx_desc->pkt_len_flags;
/* Whole buffer move to the next descriptor */
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE; p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
/* set ownership of current descriptor to EMAC */ /* set ownership of current desc to EMAC */
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN; p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
e->rx_desc_idx++; e->rx_desc_idx++;
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx) if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
e->rx_desc_idx = 0; e->rx_desc_idx = 0;
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]); p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
}
while (0 == (flags & LAN8710A_DESC_FLAG_EOP)); /* if EOP flag is set -> stop processing */
if (flags & LAN8710A_DESC_FLAG_EOP)
break;
/* /*
* Update state. * 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
*/ */
e->status |= LAN8710A_RECEIVED; off = p_rx_desc->buffer_length_off >> 16;
e->rx_size = pkt_data_len;
} }
reply(e);
return size;
} }
/*============================================================================* /*============================================================================*
* lan8710a_phy_write * * lan8710a_phy_write *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_phy_write(reg, value) lan8710a_phy_write(u32_t reg, u32_t value)
u32_t reg;
u32_t value;
{ {
if (!(lan8710a_reg_read(MDIOUSERACCESS0) & MDIO_GO)) { if (!(lan8710a_reg_read(MDIOUSERACCESS0) & MDIO_GO)) {
/* Clearing MDIOUSERACCESS0 register */ /* Clearing MDIOUSERACCESS0 register */
@ -1073,7 +832,8 @@ u32_t value;
lan8710a_reg_set(MDIOUSERACCESS0, lan8710a_reg_set(MDIOUSERACCESS0,
lan8710a_state.phy_address << MDIO_PHYADR); lan8710a_state.phy_address << MDIO_PHYADR);
/* Data written only 16 bits. */ /* 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); lan8710a_reg_set(MDIOUSERACCESS0, MDIO_GO);
/* Waiting for writing completion */ /* Waiting for writing completion */
@ -1085,8 +845,7 @@ u32_t value;
* lan8710a_phy_read * * lan8710a_phy_read *
*============================================================================*/ *============================================================================*/
static u32_t static u32_t
lan8710a_phy_read(reg) lan8710a_phy_read(u32_t reg)
u32_t reg;
{ {
u32_t value = 0xFFFFFFFF; u32_t value = 0xFFFFFFFF;
@ -1116,7 +875,7 @@ u32_t reg;
* lan8710a_reset_hw * * lan8710a_reset_hw *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_reset_hw() lan8710a_reset_hw(void)
{ {
/* Assert a Device Reset signal. */ /* Assert a Device Reset signal. */
lan8710a_phy_write(LAN8710A_CTRL_REG, LAN8710A_SOFT_RESET); lan8710a_phy_write(LAN8710A_CTRL_REG, LAN8710A_SOFT_RESET);
@ -1129,8 +888,7 @@ lan8710a_reset_hw()
* lan8710a_reg_read * * lan8710a_reg_read *
*============================================================================*/ *============================================================================*/
static u32_t static u32_t
lan8710a_reg_read(reg) lan8710a_reg_read(volatile u32_t *reg)
volatile u32_t *reg;
{ {
u32_t value; u32_t value;
@ -1145,9 +903,7 @@ volatile u32_t *reg;
* lan8710a_reg_write * * lan8710a_reg_write *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_reg_write(reg, value) lan8710a_reg_write(volatile u32_t *reg, u32_t value)
volatile u32_t *reg;
u32_t value;
{ {
/* Write to memory mapped register. */ /* Write to memory mapped register. */
*reg = value; *reg = value;
@ -1157,9 +913,7 @@ u32_t value;
* lan8710a_reg_set * * lan8710a_reg_set *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_reg_set(reg, value) lan8710a_reg_set(volatile u32_t *reg, u32_t value)
volatile u32_t *reg;
u32_t value;
{ {
u32_t data; u32_t data;
@ -1174,9 +928,7 @@ u32_t value;
* lan8710a_reg_unset * * lan8710a_reg_unset *
*============================================================================*/ *============================================================================*/
static void static void
lan8710a_reg_unset(reg, value) lan8710a_reg_unset(volatile u32_t *reg, u32_t value)
volatile u32_t *reg;
u32_t value;
{ {
u32_t data; u32_t data;
@ -1186,61 +938,3 @@ u32_t value;
/* Unset value, and write back. */ /* Unset value, and write back. */
lan8710a_reg_write(reg, data & ~value); 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) #define LAN8710A_DEBUG_PRINT(args)
#endif #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 */ /* Ethernet driver defines */
#define LAN8710A_NAME_LEN (11) #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 */ /* Descriptors flags */
#define LAN8710A_DESC_FLAG_OWN (1 << 29) /* ownership flag */ #define LAN8710A_DESC_FLAG_OWN (1 << 29) /* ownership flag */
#define LAN8710A_DESC_FLAG_SOP (1 << 31) /* start of packet flag */ #define LAN8710A_DESC_FLAG_SOP (1 << 31) /* start of packet flag */
@ -58,9 +41,6 @@
/** Number of receive descriptors */ /** Number of receive descriptors */
#define LAN8710A_NUM_RX_DESC (255) #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. */ /** Size of each I/O buffer per descriptor. */
#define LAN8710A_IOBUF_SIZE (1520) #define LAN8710A_IOBUF_SIZE (1520)
@ -89,11 +69,9 @@ typedef struct lan8710a_t
phys_bytes rx_desc_phy; phys_bytes rx_desc_phy;
phys_bytes tx_desc_phy; phys_bytes tx_desc_phy;
char name[LAN8710A_NAME_LEN]; char name[LAN8710A_NAME_LEN];
int status;
int irq_rx_hook; /* Rx interrupt Request Vector Hook. */ int irq_rx_hook; /* Rx interrupt Request Vector Hook. */
int irq_tx_hook; /* Tx interrupt Request Vector Hook. */ int irq_tx_hook; /* Tx interrupt Request Vector Hook. */
int instance; int instance;
ether_addr_t address; /* Ethernet MAC address. */
u8_t *regs; u8_t *regs;
u32_t phy_address; u32_t phy_address;
u8_t *p_rx_buf; /* pointer to the buffer with receive frames */ 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 tx_desc_idx; /* index of the next transmit desciptor */
u16_t rx_desc_idx; /* index of the next receive 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 */ /* register mapping */
vir_bytes regs_cp_per; 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' */ /* macros for 'flags' */
#define ECF_EMPTY 0x000 #define ECF_PROMISC 0x01
#define ECF_PACK_SEND 0x001 #define ECF_MULTI 0x02
#define ECF_PACK_RECV 0x002 #define ECF_BROAD 0x04
#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;
/* ====== ethernet card info. ====== */ /* ====== ethernet card info. ====== */
typedef struct ether_card typedef struct ether_card
@ -41,35 +10,14 @@ typedef struct ether_card
/* ####### MINIX style ####### */ /* ####### MINIX style ####### */
char port_name[sizeof("lance#n")]; char port_name[sizeof("lance#n")];
int flags; int flags;
int mode;
int transfer_mode;
eth_stat_t eth_stat; 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. ####### */ /* ######## device info. ####### */
port_t ec_port; port_t ec_port;
phys_bytes ec_linmem;
int ec_irq; int ec_irq;
int ec_int_pending;
int ec_hook; int ec_hook;
int ec_ramsize;
/* Addrassing */
u16_t ec_memseg;
vir_bytes ec_memoff;
ether_addr_t mac_address;
} ether_card_t; } ether_card_t;
#define DEI_DEFAULT 0x8000
/* /*
* NOTE: Not all the CSRs are defined. Just the ones that were deemed * NOTE: Not all the CSRs are defined. Just the ones that were deemed
* necessary or potentially useful. * necessary or potentially useful.

View File

@ -2,8 +2,8 @@
PROG= orinoco PROG= orinoco
SRCS= orinoco.c hermes.c SRCS= orinoco.c hermes.c
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys -ltimers LDADD+= -lnetdriver -lsys
CPPFLAGS.orinoco.c+= -I${NETBSDSRCDIR}/minix 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_irq;
int or_hook_id; int or_hook_id;
int or_mode;
int or_flags;
char *or_model;
int or_client;
int or_link_up; int or_link_up;
int or_got_int; int or_got_int;
int or_tx_alive; int or_tx_alive;
int or_send_int; int or_send_int;
int or_clear_rx;
u32_t or_base_port;
int or_need_reset; int or_need_reset;
int or_report_link; int or_report_link;
/* Events */ /* Events */
int or_ev_rx;
int or_ev_tx;
int or_ev_info;
int or_ev_txexc;
int or_ev_alloc;
int connected; int connected;
u16_t channel_mask;
u16_t channel;
u16_t ap_density;
u16_t rts_thresh;
int bitratemode;
int last_linkstatus; int last_linkstatus;
int max_data_len;
int port_type;
/* Rx */ /* Rx */
phys_bytes or_rx_buf; phys_bytes or_rx_buf;
vir_bytes or_read_s;
u16_t rxfid[NR_RX_BUFS]; u16_t rxfid[NR_RX_BUFS];
int rx_length[NR_RX_BUFS]; int rx_length[NR_RX_BUFS];
u8_t rx_buf[NR_RX_BUFS][IEEE802_11_FRAME_LEN]; u8_t rx_buf[NR_RX_BUFS][IEEE802_11_FRAME_LEN];
u8_t rx_offset[NR_RX_BUFS];
int rx_first; int rx_first;
int rx_last; int rx_last;
int rx_current; int rx_current;
/* Tx */ /* Tx */
u16_t or_nicbuf_size; u16_t or_nicbuf_size;
vir_bytes or_transm_s;
int or_tx_head; int or_tx_head;
int or_tx_tail; int or_tx_tail;
int or_tx_busy;
struct struct
{ {
int ret_busy; int ret_busy;
u16_t or_txfid; u16_t or_txfid;
} or_tx; } 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; eth_stat_t or_stat;
message or_rx_mess; char or_name[sizeof(OR_NAME)];
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)];
hermes_t hw; hermes_t hw;
char nick[IW_ESSID_MAX_SIZE + 1];
} t_or; } t_or;

View File

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

View File

@ -1,3 +1,5 @@
/* Code left here for historical purposes only. TODO: move into libnetdriver */
#include "rtl8139.h" #include "rtl8139.h"
/* State management variables. */ /* 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/drivers.h>
#include <minix/netdriver.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 <machine/pci.h>
#include <minix/ds.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.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 #define RL_IDR 0x00 /* Ethernet address
* Note: RL_9346CR_EEM_CONFIG mode is * Note: RL_9346CR_EEM_CONFIG mode is
@ -453,18 +430,12 @@ d8 R/W Config5 Configuration register 5
d9-ff reserved d9-ff reserved
#endif #endif
#define Proc_number(p) proc_number(p)
#define debug 0
#define printW() ((void)0)
#define vm_1phys2bus(p) (p) #define vm_1phys2bus(p) (p)
#define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE #define RX_BUFSIZE RL_RCR_RBLEN_64K_SIZE
#define RX_BUFBITS RL_RCR_RBLEN_64K #define RX_BUFBITS RL_RCR_RBLEN_64K
#define N_TX_BUF RL_N_TX #define N_TX_BUF RL_N_TX
/* I/O vectors are handled IOVEC_NR entries at a time. */
#define IOVEC_NR 16
/* Configuration */ /* Configuration */
#define RL_ENVVAR "RTLETH" #define RL_ENVVAR "RTLETH"
@ -473,8 +444,6 @@ typedef struct re
port_t re_base_port; port_t re_base_port;
int re_irq; int re_irq;
int re_mode; int re_mode;
int re_flags;
int re_client;
int re_link_up; int re_link_up;
int re_got_int; int re_got_int;
int re_send_int; int re_send_int;
@ -482,12 +451,12 @@ typedef struct re
int re_clear_rx; int re_clear_rx;
int re_need_reset; int re_need_reset;
int re_tx_alive; int re_tx_alive;
char *re_model; int re_tx_busy;
const char *re_model;
/* Rx */ /* Rx */
phys_bytes re_rx_buf; phys_bytes re_rx_buf;
char *v_re_rx_buf; char *v_re_rx_buf;
vir_bytes re_read_s;
/* Tx */ /* Tx */
int re_tx_head; int re_tx_head;
@ -500,33 +469,10 @@ typedef struct re
} re_tx[N_TX_BUF]; } re_tx[N_TX_BUF];
u32_t re_ertxth; /* Early Tx Threshold */ 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 */ int re_hook_id; /* IRQ hook id at kernel */
eth_stat_t re_stat; eth_stat_t re_stat;
ether_addr_t re_address;
message re_rx_mess;
message re_tx_mess;
char re_name[sizeof("rtl8139#n")]; char re_name[sizeof("rtl8139#n")];
iovec_t re_iovec[IOVEC_NR]; } re_t;
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
/* /*
* $PchId: rtl8139.h,v 1.1 2003/09/05 10:58:50 philip Exp $ * $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) FILESNAME=$(PROG)
FILESDIR= /etc/system.conf.d FILESDIR= /etc/system.conf.d
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS} DPADD+= ${LIBNETDRIVER} ${LIBSYS}
LDADD+= -lnetdriver -lsys -ltimers LDADD+= -lnetdriver -lsys
CPPFLAGS+= -I${NETBSDSRCDIR}/minix CPPFLAGS+= -I${NETBSDSRCDIR}/minix

File diff suppressed because it is too large Load Diff

View File

@ -22,11 +22,18 @@
#include "virtio_net.h" #include "virtio_net.h"
#define VERBOSE 0
#if VERBOSE
#define dput(s) do { dprintf(s); printf("\n"); } while (0) #define dput(s) do { dprintf(s); printf("\n"); } while (0)
#define dprintf(s) do { \ #define dprintf(s) do { \
printf("%s: ", name); \ printf("%s: ", name); \
printf s; \ printf s; \
} while (0) } while (0)
#else
#define dput(s)
#define dprintf(s)
#endif
static struct virtio_device *net_dev; static struct virtio_device *net_dev;
@ -50,6 +57,7 @@ struct packet {
phys_bytes phdr; phys_bytes phdr;
char *vdata; char *vdata;
phys_bytes pdata; phys_bytes pdata;
size_t len;
STAILQ_ENTRY(packet) next; STAILQ_ENTRY(packet) next;
}; };
@ -60,7 +68,6 @@ static struct virtio_net_hdr *hdrs_vir;
static phys_bytes hdrs_phys; static phys_bytes hdrs_phys;
static struct packet *packets; static struct packet *packets;
static int in_rx; static int in_rx;
static int started;
/* Packets on this list can be given to the host */ /* Packets on this list can be given to the host */
static STAILQ_HEAD(free_list, packet) free_list; 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 */ /* Packets on this list are to be given to inet */
static STAILQ_HEAD(recv_list, packet) recv_list; 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 */ /* Various state data */
static u8_t virtio_net_mac[6];
static eth_stat_t virtio_net_stats; static eth_stat_t virtio_net_stats;
static int spurious_interrupt; static int spurious_interrupt;
/* Prototypes */ /* Prototypes */
static int virtio_net_probe(int skip); static int virtio_net_probe(unsigned int skip);
static int virtio_net_config(void); static void virtio_net_config(ether_addr_t *addr);
static int virtio_net_alloc_bufs(void); static int virtio_net_alloc_bufs(void);
static void virtio_net_init_queues(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_queues(void);
static void virtio_net_check_pending(void); static void virtio_net_check_pending(void);
static void virtio_net_fetch_iovec(iovec_s_t *iov, message *m, static int virtio_net_init(unsigned int instance, ether_addr_t *addr);
cp_grant_id_t grant, size_t count); static void virtio_net_stop(void);
static int virtio_net_cpy_to_user(message *m); static int virtio_net_send(struct netdriver_data *data, size_t len);
static int virtio_net_cpy_from_user(message *m); 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(message *m); static void virtio_net_intr(unsigned int mask);
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 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 */ /* TODO: Features are pretty much ignored */
struct virtio_feature netf[] = { static struct virtio_feature netf[] = {
{ "partial csum", VIRTIO_NET_F_CSUM, 0, 0 }, { "partial csum", VIRTIO_NET_F_CSUM, 0, 0 },
{ "given mac", VIRTIO_NET_F_MAC, 0, 1 }, { "given mac", VIRTIO_NET_F_MAC, 0, 1 },
{ "status ", VIRTIO_NET_F_STATUS, 0, 0 }, { "status ", VIRTIO_NET_F_STATUS, 0, 0 },
@ -120,7 +115,7 @@ struct virtio_feature netf[] = {
}; };
static int static int
virtio_net_probe(int skip) virtio_net_probe(unsigned int skip)
{ {
/* virtio-net has at least 2 queues */ /* virtio-net has at least 2 queues */
int queues = 2; int queues = 2;
@ -142,8 +137,8 @@ virtio_net_probe(int skip)
return OK; return OK;
} }
static int static void
virtio_net_config(void) virtio_net_config(ether_addr_t * addr)
{ {
u32_t mac14; u32_t mac14;
u32_t mac56; u32_t mac56;
@ -153,12 +148,12 @@ virtio_net_config(void)
dprintf(("Mac set by host: ")); dprintf(("Mac set by host: "));
mac14 = virtio_sread32(net_dev, 0); mac14 = virtio_sread32(net_dev, 0);
mac56 = virtio_sread32(net_dev, 4); mac56 = virtio_sread32(net_dev, 4);
*(u32_t*)virtio_net_mac = mac14; memcpy(&addr->ea_addr[0], &mac14, 4);
*(u16_t*)(virtio_net_mac + 4) = mac56; memcpy(&addr->ea_addr[4], &mac56, 2);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printf("%02x%s", virtio_net_mac[i], dprintf(("%02x%s", addr->ea_addr[i],
i == 5 ? "\n" : ":"); i == 5 ? "\n" : ":"));
} else { } else {
dput(("No mac")); dput(("No mac"));
} }
@ -174,8 +169,6 @@ virtio_net_config(void)
if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_RX)) if (virtio_host_supports(net_dev, VIRTIO_NET_F_CTRL_RX))
dput(("Host supports control channel for RX")); dput(("Host supports control channel for RX"));
return OK;
} }
static int static int
@ -233,7 +226,6 @@ virtio_net_refill_rx_queue(void)
struct packet *p; struct packet *p;
while ((in_rx < BUF_PACKETS / 2) && !STAILQ_EMPTY(&free_list)) { while ((in_rx < BUF_PACKETS / 2) && !STAILQ_EMPTY(&free_list)) {
/* peek */ /* peek */
p = STAILQ_FIRST(&free_list); p = STAILQ_FIRST(&free_list);
/* remove */ /* remove */
@ -253,7 +245,6 @@ virtio_net_refill_rx_queue(void)
virtio_to_queue(net_dev, RX_Q, phys, 2, p); virtio_to_queue(net_dev, RX_Q, phys, 2, p);
in_rx++; in_rx++;
} }
if (in_rx == 0 && STAILQ_EMPTY(&free_list)) { if (in_rx == 0 && STAILQ_EMPTY(&free_list)) {
@ -266,18 +257,21 @@ static void
virtio_net_check_queues(void) virtio_net_check_queues(void)
{ {
struct packet *p; struct packet *p;
size_t len;
/* Put the received packets into the recv list */ /* 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); STAILQ_INSERT_TAIL(&recv_list, p, next);
in_rx--; in_rx--;
virtio_net_stats.ets_packetR++; 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. * 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->vhdr, 0, sizeof(*p->vhdr));
memset(p->vdata, 0, MAX_PACK_SIZE); memset(p->vdata, 0, MAX_PACK_SIZE);
STAILQ_INSERT_HEAD(&free_list, p, next); STAILQ_INSERT_HEAD(&free_list, p, next);
@ -288,173 +282,19 @@ virtio_net_check_queues(void)
static void static void
virtio_net_check_pending(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? */ /* Pending read and something in recv_list? */
if (!STAILQ_EMPTY(&recv_list) && rx_pending) { if (!STAILQ_EMPTY(&recv_list))
dst = pending_rx_msg.m_source; netdriver_recv();
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(&free_list) && tx_pending) { if (!STAILQ_EMPTY(&free_list))
dst = pending_tx_msg.m_source; netdriver_send();
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);
} }
static void 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 */ /* Check and clear interrupt flag */
if (virtio_had_irq(net_dev)) { if (virtio_had_irq(net_dev)) {
virtio_net_check_queues(); virtio_net_check_queues();
@ -468,202 +308,131 @@ virtio_net_intr(message *m)
virtio_net_check_pending(); virtio_net_check_pending();
virtio_irq_enable(net_dev); 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) * 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.
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) { static int
started = 1; virtio_net_send(struct netdriver_data * data, size_t len)
virtio_device_ready(net_dev); {
virtio_irq_enable(net_dev); struct vumap_phys phys[2];
} struct packet *p;
/* Prepare reply */ if (STAILQ_EMPTY(&free_list))
memcpy(reply.m_netdrv_net_dl_conf.hw_addr, virtio_net_mac, return SUSPEND;
sizeof(reply.m_netdrv_net_dl_conf.hw_addr));
reply.m_type = DL_CONF_REPLY; p = STAILQ_FIRST(&free_list);
reply.m_netdrv_net_dl_conf.stat = OK; STAILQ_REMOVE_HEAD(&free_list, next);
if ((r = ipc_send(m->m_source, &reply)) != OK) if (len > MAX_PACK_SIZE)
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r); 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;
} }
static void /*
virtio_net_getstat(message *m) * 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)
{ {
int r; struct packet *p;
message reply; ssize_t len;
reply.m_type = DL_STAT_REPLY; /* Get the first received packet, if any. */
if (STAILQ_EMPTY(&recv_list))
return SUSPEND;
r = sys_safecopyto(m->m_source, m->m_net_netdrv_dl_getstat_s.grant, 0, p = STAILQ_FIRST(&recv_list);
(vir_bytes)&virtio_net_stats, STAILQ_REMOVE_HEAD(&recv_list, next);
sizeof(virtio_net_stats));
if (r != OK) /* Copy out the packet contents. */
panic("%s: copy to %d failed (%d)", name, m->m_source, r); len = p->len - sizeof(struct virtio_net_hdr);
if (len > max)
len = max;
if ((r = ipc_send(m->m_source, &reply)) != OK) /*
panic("%s: ipc_send to %d failed (%d)", name, m->m_source, r); * 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;
static void netdriver_copyout(data, 0, p->vdata, len);
virtio_net_notify(message *m)
{
if (_ENDPOINT_P(m->m_source) == HARDWARE)
virtio_net_intr(m);
}
static void /* Clean the packet. */
virtio_net_msg(message *m) memset(p->vhdr, 0, sizeof(*p->vhdr));
{ memset(p->vdata, 0, MAX_PACK_SIZE);
switch (m->m_type) { STAILQ_INSERT_HEAD(&free_list, p, next);
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) {
/* Readd packets to the receive queue as necessary. */
virtio_net_refill_rx_queue(); virtio_net_refill_rx_queue();
if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) return len;
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();
} }
/*
* Return statistics.
*/
static void static void
sef_local_startup() virtio_net_stat(eth_stat_t *stat)
{ {
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); memcpy(stat, &virtio_net_stats, sizeof(*stat));
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
sef_setcb_signal_handler(sef_cb_signal_handler);
sef_startup();
} }
/*
* Initialize the driver and the virtual hardware.
*/
static int static int
sef_cb_init_fresh(int type, sef_init_info_t *info) virtio_net_init(unsigned int instance, ether_addr_t *addr)
{ {
long instance = 0; int r;
env_parse("instance", "d", 0, &instance, 0, 255);
if (virtio_net_probe((int)instance) != OK) if ((r = virtio_net_probe(instance)) != OK)
panic("%s: No device found", name); return r;
if (virtio_net_config() != OK) virtio_net_config(addr);
panic("%s: No device found", name);
if (virtio_net_alloc_bufs() != OK) if (virtio_net_alloc_bufs() != OK)
panic("%s: Buffer allocation failed", name); panic("%s: Buffer allocation failed", name);
virtio_net_init_queues(); 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); return(OK);
} }
/*
* The driver is terminating. Clean up.
*/
static void static void
sef_cb_signal_handler(int signo) virtio_net_stop(void)
{ {
if (signo != SIGTERM)
return;
dput(("Terminating")); dput(("Terminating"));
@ -675,6 +444,18 @@ sef_cb_signal_handler(int signo)
virtio_free_queues(net_dev); virtio_free_queues(net_dev);
virtio_free_device(net_dev); virtio_free_device(net_dev);
net_dev = NULL; 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} CPPFLAGS+= -I${NETBSDSRCDIR}
NOCLANGERROR=yes
.include <minix.service.mk> .include <minix.service.mk>

View File

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

View File

@ -439,7 +439,7 @@ virtio_blk_device_intr(void)
thread_id_t *tid; thread_id_t *tid;
/* Multiple requests might have finished */ /* 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); 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"); "for 'hub port LS attach' event");
USB_MSG("Low speed device connected at " 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); hcd_add_child(device, val, HCD_SPEED_LOW);
break; break;
@ -138,7 +138,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
"for 'hub port FS attach' event"); "for 'hub port FS attach' event");
USB_MSG("Full speed device connected at " 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); hcd_add_child(device, val, HCD_SPEED_FULL);
break; break;
@ -149,7 +149,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
"for 'hub port HS attach' event"); "for 'hub port HS attach' event");
USB_MSG("High speed device connected at " 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); hcd_add_child(device, val, HCD_SPEED_HIGH);
break; break;
@ -162,7 +162,7 @@ hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val)
hcd_delete_child(device, val); hcd_delete_child(device, val);
USB_MSG("Device disconnected from " USB_MSG("Device disconnected from "
"hub 0x%08X, port %u", device, val); "hub 0x%p, port %u", device, val);
break; break;
@ -456,7 +456,7 @@ hcd_dump_tree(hcd_device_state * device, hcd_reg1 level)
/* DEBUG_DUMP; */ /* Let's keep tree output cleaner */ /* 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 */ /* Traverse device tree recursively */
for (child_num = 0; child_num < HCD_CHILDREN; child_num++) { 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; connect_cb = drv->connect;
disconnect_cb = drv->disconnect; disconnect_cb = drv->disconnect;
*_m = malloc; *_m = (ddekit_usb_malloc_fn) malloc;
*_f = free; *_f = (ddekit_usb_free_fn) free;
return EXIT_SUCCESS; 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 */ /* For now we only allow to play with the yoffset setting */
if (fbvsp->yoffset != omap_fbvs[minor].yoffset) { 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; return EINVAL;
} }

View File

@ -6,39 +6,154 @@
#include "rs/const.h" #include "rs/const.h"
#include "rs/type.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 rprocpub rprocpub[NR_SYS_PROCS];
static struct rproc rproc[NR_SYS_PROCS]; static struct rproc rproc[NR_SYS_PROCS];
static struct policies policies[NR_SYS_PROCS];
static struct inode *service_node; static struct inode *service_node;
/* /* Updates the policies state from RS. Always returns an ASCIIZ string. */
* Initialize the service directory. static const char *
*/ service_get_policies(struct policies * pol, index_t slot)
void
service_init(void)
{ {
struct inode *root, *node; #if 1 /* The following should be retrieved from RS and formated instead. */
struct inode_stat stat; 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)); memset(pol[slot].formatted, 0, MAX_POL_FORMAT_SZ);
stat.mode = DIR_ALL_MODE; for(pos = 0; pos < (sizeof(def_pol) / sizeof(def_pol[0])); pos++) {
stat.uid = SUPER_USER; if (0 == strcmp(ref_label, def_pol[pos].label)) {
stat.gid = SUPER_USER; (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, return pol[slot].formatted;
NR_SYS_PROCS, NULL);
if (service_node == NULL)
panic("unable to create service node");
} }
/* /*
* Update the contents of the service directory, by first updating the RS * Update the contents of the service directory, by first updating the RS
* tables and then updating the directory contents. * tables and then updating the directory contents.
*/ */
void static void
service_update(void) service_update(void)
{ {
struct inode *node; 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, * A lookup request is being performed. If it is in the service directory,
* update the tables. We do this lazily, to reduce overhead. * update the tables. We do this lazily, to reduce overhead.
@ -141,5 +279,8 @@ service_read(struct inode * node)
rp = &rproc[slot]; rp = &rproc[slot];
/* TODO: add a large number of other fields! */ /* 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/endpoint.h>
#include <minix/ipc.h> #include <minix/ipc.h>
#include <minix/com.h>
/* Functions defined by netdriver.c: */ /* The flags that make up the requested receive mode. */
void netdriver_announce(void); #define NDEV_NOMODE DL_NOMODE /* targeted packets only */
int netdriver_receive(endpoint_t src, message *m_ptr, int *status_ptr); #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 */ #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); struct vumap_phys *bufs, size_t num, void *data);
/* /*
* If the host used a chain of descriptors, return 0 and set data * If the host used a chain of descriptors, return 0, set data as was given to
* as was given to virtio_to_queue(). If the host has not processed * virtio_to_queue(), and if len is not NULL, set it to the resulting length.
* any element returns -1. * 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 */ /* IRQ related functions */
void virtio_irq_enable(struct virtio_device *dev); void virtio_irq_enable(struct virtio_device *dev);

View File

@ -5,6 +5,11 @@ PROG= kernel
BINDIR= /usr/sbin BINDIR= /usr/sbin
MAN= 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" .include "arch/${MACHINE_ARCH}/Makefile.inc"
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \ 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 \ MINC_OBJS_UNPAGED= atoi.o \
printf.o subr_prf.o \ printf.o subr_prf.o \
strcmp.o strcpy.o strlen.o strncmp.o \ strcmp.o strcpy.o strlen.o strncmp.o \
memcpy.o memmove.o memset.o \ memcpy.o memmove.o memset.o
udivdi3.o umoddi3.o qdivrem.o MINC_OBJS_UNPAGED+= divsi3.o udivsi3.o umodsi3.o \
MINC_OBJS_UNPAGED+= __aeabi_ldiv0.o __aeabi_idiv0.o __aeabi_uldivmod.o divide.o divsi3.o udivsi3.o umoddi3.o udivmoddi4.o aeabi_uidivmod.o \
udivmodsi4.o aeabi_uldivmod.o
atoi.o: ${NETBSDSRCDIR}/minix/lib/libminc/atoi.c atoi.o: ${NETBSDSRCDIR}/minix/lib/libminc/atoi.c
printf.o: ${NETBSDSRCDIR}/sys/lib/libsa/printf.c printf.o: ${NETBSDSRCDIR}/sys/lib/libsa/printf.c
subr_prf.o: ${NETBSDSRCDIR}/sys/lib/libsa/subr_prf.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 strcpy.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcpy.S
strcmp.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcmp.S strcmp.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/string/strcmp.S
#strcat.o: ${NETBSDSRCDIR}/common/lib/libc/string/strcat.c divsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/divsi3.c
__aeabi_idiv0.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/__aeabi_idiv0.c udivsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/udivsi3.c
__aeabi_ldiv0.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/__aeabi_ldiv0.c umodsi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/umodsi3.c
__aeabi_uldivmod.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/quad/__aeabi_uldivmod.S umoddi3.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/umoddi3.c
divide.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/divide.S udivmoddi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/udivmoddi4.c
divsi3.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/divsi3.S udivmodsi4.o: ${NETBSDSRCDIR}/sys/external/bsd/compiler_rt/dist/lib/arm/udivmodsi4.S
udivsi3.o: ${NETBSDSRCDIR}/common/lib/libc/arch/arm/gen/udivsi3.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 # the following is required by pre_init.c
strncmp.o: ${NETBSDSRCDIR}/common/lib/libc/string/strncmp.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. # LSC: putchar and kputc have the same signature. A bit hackish.
CPPFLAGS.subr_prf.c+= -Dputchar=kputc CPPFLAGS.subr_prf.c+= -Dputchar=kputc

View File

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

View File

@ -5,11 +5,11 @@
#include "kernel/kernel.h" #include "kernel/kernel.h"
void irq_handle(int irq); void irq_handle(int irq);
int hw_intr_mask(int irq); void hw_intr_mask(int irq);
int hw_intr_unmask(int irq); void hw_intr_unmask(int irq);
int hw_intr_ack(int irq); void hw_intr_ack(int irq);
int hw_intr_used(int irq); void hw_intr_used(int irq);
int hw_intr_not_used(int irq); void hw_intr_not_used(int irq);
int hw_intr_disable_all(); void hw_intr_disable_all();
#endif /* __HW_INTR_ARM_H__ */ #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. * Copyright 2003 Wasabi Systems, Inc.
@ -68,6 +68,27 @@
#include <machine/asm.h> #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 * memset: Sets a block of memory to the specified value
* *
@ -107,7 +128,7 @@ ENTRY(memset)
#ifndef _BZERO #ifndef _BZERO
orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */ orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */
#endif #endif
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
tst ip, #0x04 /* Quad-align for Xscale */ tst ip, #0x04 /* Quad-align for Xscale */
#else #else
cmp r1, #0x10 cmp r1, #0x10
@ -115,7 +136,7 @@ ENTRY(memset)
#ifndef _BZERO #ifndef _BZERO
orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */ orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */
#endif #endif
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
subne r1, r1, #0x04 /* Quad-align if necessary */ subne r1, r1, #0x04 /* Quad-align if necessary */
strne r3, [ip], #0x04 strne r3, [ip], #0x04
cmp r1, #0x10 cmp r1, #0x10
@ -128,40 +149,40 @@ ENTRY(memset)
/* Do 128 bytes at a time */ /* Do 128 bytes at a time */
.Lmemset_loop128: .Lmemset_loop128:
subs r1, r1, #0x80 subs r1, r1, #0x80
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
#else #else
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
#endif #endif
bgt .Lmemset_loop128 bgt .Lmemset_loop128
#if defined(__minix) #if defined(__minix)
@ -174,16 +195,16 @@ ENTRY(memset)
/* Do 32 bytes at a time */ /* Do 32 bytes at a time */
.Lmemset_loop32: .Lmemset_loop32:
subs r1, r1, #0x20 subs r1, r1, #0x20
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
#else #else
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
#endif #endif
bgt .Lmemset_loop32 bgt .Lmemset_loop32
#if defined(__minix) #if defined(__minix)
@ -194,12 +215,12 @@ ENTRY(memset)
adds r1, r1, #0x10 /* Partially adjust for extra sub */ adds r1, r1, #0x10 /* Partially adjust for extra sub */
/* Deal with 16 bytes or more */ /* Deal with 16 bytes or more */
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
strged r2, [ip], #0x08 strdge r2, r3, [ip], #0x08
#else #else
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
stmgeia ip!, {r2-r3} stmiage ip!, {r2-r3}
#endif #endif
#if defined(__minix) #if defined(__minix)
moveq r0, #0 moveq r0, #0
@ -218,7 +239,7 @@ ENTRY(memset)
#endif #endif
RETc(eq) /* Zero length so just exit */ RETc(eq) /* Zero length so just exit */
#ifdef __XSCALE__ #ifdef _ARM_ARCH_DWORD_OK
/* Compensate for 64-bit alignment check */ /* Compensate for 64-bit alignment check */
adds r1, r1, #0x04 adds r1, r1, #0x04
#if defined(__minix) #if defined(__minix)
@ -231,8 +252,8 @@ ENTRY(memset)
#endif #endif
strb r3, [ip], #0x01 /* Set 1 byte */ strb r3, [ip], #0x01 /* Set 1 byte */
strgeb r3, [ip], #0x01 /* Set another byte */ strbge r3, [ip], #0x01 /* Set another byte */
strgtb r3, [ip] /* and a third */ strbgt r3, [ip] /* and a third */
#if defined(__minix) #if defined(__minix)
mov r0, #0 mov r0, #0
#endif #endif
@ -242,9 +263,9 @@ ENTRY(memset)
rsb r2, r2, #0x004 rsb r2, r2, #0x004
strb r3, [ip], #0x01 /* Set 1 byte */ strb r3, [ip], #0x01 /* Set 1 byte */
cmp r2, #0x02 cmp r2, #0x02
strgeb r3, [ip], #0x01 /* Set another byte */ strbge r3, [ip], #0x01 /* Set another byte */
sub r1, r1, r2 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? */ cmp r1, #0x04 /* More than 4 bytes left? */
bge .Lmemset_wordaligned /* Yup */ bge .Lmemset_wordaligned /* Yup */
@ -256,12 +277,21 @@ ENTRY(memset)
RETc(eq) /* Zero length so exit */ RETc(eq) /* Zero length so exit */
strb r3, [ip], #0x01 /* Set 1 byte */ strb r3, [ip], #0x01 /* Set 1 byte */
cmp r1, #0x02 cmp r1, #0x02
strgeb r3, [ip], #0x01 /* Set another byte */ strbge r3, [ip], #0x01 /* Set another byte */
strgtb r3, [ip] /* and a third */ strbgt r3, [ip] /* and a third */
#if defined(__minix) #if defined(__minix)
mov r0, #0 mov r0, #0
#endif #endif
RET /* Exit */ RET /* Exit */
#ifdef _BZERO
END(bzero)
#else
#if !defined(__minix)
END(memset)
#else
END(phys_memset)
#endif
#endif
#if defined(__minix) #if defined(__minix)
LABEL(memset_fault) /* kernel can send us here */ 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) { } void busy_delay_ms(int x) { }
int raise(int n) { panic("raise(%d)\n", n); } 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, 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 */ 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. * enabling interrupts, and of course sysret instead of sysexit.
*/ */
mov 4(%esp), %ebp /* retrieve proc ptr arg */ 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 PCREG(%ebp), %ecx /* sysret restores EIP using ECX */
mov SPREG(%ebp), %esp /* restore ESP directly */ mov SPREG(%ebp), %esp /* restore ESP directly */
mov AXREG(%ebp), %eax /* trap return value */ mov AXREG(%ebp), %eax /* trap return value */
mov BXREG(%ebp), %ebx /* secondary return value */ mov BXREG(%ebp), %ebx /* secondary return value */
movl PSWREG(%ebp), %edi /* load desired PSW to EDI */
sysret /* jump to EIP in user */ sysret /* jump to EIP in user */
ENTRY(restore_user_context_int) ENTRY(restore_user_context_int)

View File

@ -43,8 +43,6 @@ ENTRY(usermapped_ ## name ## _sysenter) ;\
SETARGS /* call-specific register setup */ ;\ SETARGS /* call-specific register setup */ ;\
sysenter /* disappear into kernel */ ;\ sysenter /* disappear into kernel */ ;\
0: ;\ 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 */;\ mov %ebx, %ecx /* return w. state mangled; save %ebx */;\
pop %edi ;\ pop %edi ;\
pop %esi ;\ pop %esi ;\
@ -69,8 +67,6 @@ ENTRY(usermapped_ ## name ## _syscall) ;\
SETARGS /* call-specific register setup */ ;\ SETARGS /* call-specific register setup */ ;\
movl %ecx, %edx /* %ecx is clobbered by SYSCALL */ ;\ movl %ecx, %edx /* %ecx is clobbered by SYSCALL */ ;\
syscall /* disappear into kernel */ ;\ 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 */;\ mov %ebx, %ecx /* return w. state mangled; save %ebx */;\
pop %edi ;\ pop %edi ;\
pop %esi ;\ pop %esi ;\

View File

@ -1095,7 +1095,7 @@ int mini_notify(
#define ASCOMPLAIN(caller, entry, field) \ #define ASCOMPLAIN(caller, entry, field) \
printf("kernel:%s:%d: asyn failed for %s in %s " \ 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) field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
#define A_RETR_FLD(entry, field) \ #define A_RETR_FLD(entry, field) \

View File

@ -127,12 +127,22 @@ CPPFLAGS.sha2.c+= -D_STANDALONE
CPPFLAGS.sha2.c+= -I${NETBSDSRCDIR}/sys CPPFLAGS.sha2.c+= -I${NETBSDSRCDIR}/sys
.for f in \ .for f in \
ashrdi3.o divdi3.o lshldi3.o lshrdi3.o moddi3.o \ ashrdi3.o divdi3.o lshrdi3.o moddi3.o \
udivdi3.o umoddi3.o qdivrem.o udivdi3.o umoddi3.o umodsi3.o udivsi3.o \
${f} ${f:C/\.o/.bc/}: ${LIBCOMMONCDIR}/quad/${f:C/\.o/.c/} 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} OBJS+= ${f}
CLEANFILES+= ${f} CLEANFILES+= ${f}
COPTS+= -Wno-missing-prototypes \
-Wno-old-style-definition \
-Wno-strict-prototypes \
-Wno-uninitialized \
-Wno-cast-qual
.if ${USE_BITCODE:Uno} == "yes" .if ${USE_BITCODE:Uno} == "yes"
OBJS+= ${f:C/\.o/.bc/} OBJS+= ${f:C/\.o/.bc/}
CLEANFILES+= ${f:C/\.o/.bc/} CLEANFILES+= ${f:C/\.o/.bc/}

View File

@ -11,7 +11,7 @@ CLEANFILES+= ${f}
.endfor .endfor
.for f in \ .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/} ${f}: ${LIBCOMMONCARCHDIR}/gen/${f:C/\.o/.S/}
OBJS+= ${f} OBJS+= ${f}
CLEANFILES+= ${f} CLEANFILES+= ${f}
@ -29,12 +29,12 @@ CLEANFILES+= ${f}
CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE CPPFLAGS.__aeabi_idiv0.c+= -D_STANDALONE
CPPFLAGS.__aeabi_ldiv0.c+= -D_STANDALONE CPPFLAGS.__aeabi_ldiv0.c+= -D_STANDALONE
.for f in \ #.for f in \
__aeabi_ldivmod.o __aeabi_uldivmod.o # __aeabi_ldivmod.o __aeabi_uldivmod.o
${f}: ${LIBCOMMONCARCHDIR}/quad/${f:C/\.o/.S/} #${f}: ${LIBCOMMONCARCHDIR}/quad/${f:C/\.o/.S/}
OBJS+= ${f} #OBJS+= ${f}
CLEANFILES+= ${f} #CLEANFILES+= ${f}
.endfor #.endfor
.for f in \ .for f in \
memcmp.o memcpy.o memmove.o memset.o \ memcmp.o memcpy.o memmove.o memset.o \
@ -72,6 +72,13 @@ OBJS+= ${f}
CLEANFILES+= ${f} CLEANFILES+= ${f}
.endfor .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 \ .for f in \
fpgetround.o fpsetround.o fpgetmask.o fpsetmask.o \ fpgetround.o fpsetround.o fpgetmask.o fpsetmask.o \
fpgetsticky.o fpsetsticky.o fpgetsticky.o fpsetsticky.o

View File

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

View File

@ -1,82 +1,620 @@
/* This file contains device independent network device driver interface. /* The device-independent network driver framework. */
*
* 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
*/
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/netdriver.h> #include <minix/netdriver.h>
#include <minix/ds.h> #include <minix/ds.h>
#include <assert.h>
static int conf_expected = TRUE; #include "netdriver.h"
/*===========================================================================* static const struct netdriver *netdriver_table = NULL;
* netdriver_announce *
*===========================================================================*/ static int running;
void netdriver_announce()
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. */ /* Publish a driver up event. */
r = ds_retrieve_label_name(label, sef_self()); if ((r = ds_retrieve_label_name(label, sef_self())) != OK)
if (r != OK) { panic("netdriver: unable to get own label: %d", r);
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);
}
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 * * 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
int netdriver_receive(src, m_ptr, status_ptr) * entirely within the vector.
endpoint_t src; */
message *m_ptr; size_t
int *status_ptr; netdriver_prepare_copy(struct netdriver_data * data, size_t off, size_t size,
unsigned int * indexp)
{ {
/* receive() interface for drivers. */ unsigned int i;
int r;
while (TRUE) { assert(data->size > 0);
/* Wait for a request. */
r = sef_receive_status(src, m_ptr, status_ptr);
if (r != OK) {
return r;
}
/* Let non-datalink requests through regardless. */ /*
if (!IS_DL_RQ(m_ptr->m_type)) { * In theory we could truncate when copying out, but this creates a
return r; * 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");
/* See if only DL_CONF is to be expected. */ /*
if(conf_expected) { * Find the starting offset in the vector. If this turns out to be
if(m_ptr->m_type == DL_CONF) { * expensive, this can be adapted to store the last <element,offset>
conf_expected = FALSE; * pair in the "data" structure (this is the reason it is not 'const').
} */
else { for (i = 0; i < data->count; i++) {
continue; assert(data->iovec[i].iov_size > 0);
}
}
if (off >= data->iovec[i].iov_size)
off -= data->iovec[i].iov_size;
else
break; break;
} }
assert(i < data->count);
*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; 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 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 virtio_queue *q;
struct vring *vring; struct vring *vring;
@ -718,6 +719,9 @@ virtio_from_queue(struct virtio_device *dev, int qidx, void **data)
*data = q->data[uel->id]; *data = q->data[uel->id];
q->data[uel->id] = NULL; q->data[uel->id] = NULL;
if (len != NULL)
*len = uel->len;
return 0; return 0;
} }

View File

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

View File

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

View File

@ -1149,7 +1149,7 @@ acc_t *acc;
} }
if (acc->acc_offset + acc->acc_length > buffer->buf_size) 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, acc->acc_offset, acc->acc_length,
buffer->buf_size, buffer, acc); buffer->buf_size, buffer, acc);
return 0; return 0;

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