[comp.protocols.tcp-ip.ibmpc] WD8003 driver bug and possible bug in other drivers for 8390 chip

beame@maccs.dcss.mcmaster.ca (Carl Beame) (04/09/90)

Due to overwhelming response, here is the fix to the Clarkson packet driver 
(Version 6.0) beta. The added lines begin with ">". My original changes were
to the Beame & Whiteside Software ETHDEV.WD driver for BWNFS, I have tried to
convert them to packet driver syntax and hope this is the correct code.


- Carl Beame
Beame@McMaster.CA

==========================================================================

recv_overrun:
	setport	EN_CCMD		; Stop the card
	mov al,	ENC_STOP+ENC_NODMA
	out dx,	al		; Write "stop" to command register

>	mov al, ENC_NODMA+ENC_PAGE1	; Could be in previous out, but
>	out dx,al		; was only tested this way 
>	setport EN1_CURPAG	; Get current page
>	in al,dx
>	mov bl,al		; save it
>	setport	EN_CCMD		; 
>	mov al, ENC_NODMA+ENC_PAGE0	
>	out dx,al		; Back to page 0

; Remove one frame from the ring
	setport	EN0_BOUNDARY	; Find end of this frame
	in al,	dx		; Get memory page number
	inc	al		; Page plus 1
	cmp al,	sm_rstop_pg	; Wrapped around ring?
	jnz	rcv_ovr_nwrap	; Go if not
	mov al,	SM_RSTART_PG	; Yes, wrap the page pointer
rcv_ovr_nwrap:

>	cmp	al,bl		; Check if buffer emptry
>	je	rcv_ovr_empty	; Yes ? Don't receive anything

	xor ah,	ah		; Convert page to segment
	mov cl,	4
	mov bl,	al		; Page number as arg to rcv_frm
	shl ax,	cl		; ..
	add ax,	mem_base	; Page in this memory
	mov es,	ax		; Segment pointer to the frame header
	push	es		; Hold this frame pointer for later
	mov ax,	es:[EN_RBUF_STAT]	; Get the buffer status byte
	test al,ENPS_RXOK	; Is this frame any good?
	jz	rcv_ovr_ng	; Skip if not
 	call	rcv_frm		; Yes, go accept it
rcv_ovr_ng:
	pop	es		; Back to start of this frame
	mov ax,	es:[EN_RBUF_NXT_PG and 0fffeh] ; Get pointer to next frame
	mov	al,ah
	dec	al		; Back up one page
	cmp al,	SM_RSTART_PG	; Did it wrap?
	jae	rcv_ovr_nwr2
	mov al,	sm_rstop_pg	; Yes, back to end of ring
	dec	al
rcv_ovr_nwr2:
	loadport		; Point at boundary reg
	setport	EN0_BOUNDARY	; ..
	out dx,	al		; Set the boundary

>rcv_ovr_empty:

	setport	EN0_RCNTLO	; Point at byte count regs
	xor al,	al		; Clear them
	out dx,	al		; ..