add directory Linux-0.97
This commit is contained in:
67
Linux-0.97/binaries/usr.bin/diffs/stuff
Normal file
67
Linux-0.97/binaries/usr.bin/diffs/stuff
Normal file
@@ -0,0 +1,67 @@
|
||||
*** linux/kernel/sys_call.S Fri May 15 08:56:45 1992
|
||||
--- linux/kernel/sys_call.S.~1~ Sun May 10 13:59:58 1992
|
||||
***************
|
||||
*** 87,97 ****
|
||||
.globl _double_fault,_coprocessor_segment_overrun
|
||||
.globl _invalid_TSS,_segment_not_present,_stack_segment
|
||||
.globl _general_protection,_irq13,_reserved
|
||||
.globl _alignment_check,_page_fault
|
||||
.globl _keyboard_interrupt,_hd_interrupt
|
||||
! .globl _IRQ3_interrupt,_IRQ4_interrupt,_irq5_interrupt
|
||||
|
||||
#define SAVE_ALL \
|
||||
cld; \
|
||||
push %gs; \
|
||||
push %fs; \
|
||||
--- 87,97 ----
|
||||
.globl _double_fault,_coprocessor_segment_overrun
|
||||
.globl _invalid_TSS,_segment_not_present,_stack_segment
|
||||
.globl _general_protection,_irq13,_reserved
|
||||
.globl _alignment_check,_page_fault
|
||||
.globl _keyboard_interrupt,_hd_interrupt
|
||||
! .globl _IRQ3_interrupt,_IRQ4_interrupt
|
||||
|
||||
#define SAVE_ALL \
|
||||
cld; \
|
||||
push %gs; \
|
||||
push %fs; \
|
||||
***************
|
||||
*** 265,285 ****
|
||||
pushl $-1
|
||||
SAVE_ALL
|
||||
ACK_FIRST(0x10)
|
||||
sti
|
||||
call _do_IRQ4
|
||||
- cli
|
||||
- UNBLK_FIRST(0x10)
|
||||
- jmp ret_from_sys_call
|
||||
-
|
||||
- .align 2
|
||||
- _irq5_interrupt:
|
||||
- pushl $-1
|
||||
- SAVE_ALL
|
||||
- ACK_FIRST(0x10)
|
||||
- sti
|
||||
- call _wd8003_interrupt
|
||||
cli
|
||||
UNBLK_FIRST(0x10)
|
||||
jmp ret_from_sys_call
|
||||
|
||||
.align 2
|
||||
--- 265,274 ----
|
||||
*** linux/init/main.c Fri May 15 09:01:02 1992
|
||||
--- linux/init/main.c.~1~ Sat May 2 19:29:31 1992
|
||||
***************
|
||||
*** 173,183 ****
|
||||
sched_init();
|
||||
buffer_init(buffer_memory_end);
|
||||
hd_init();
|
||||
floppy_init();
|
||||
sock_init();
|
||||
- wd8003_init();
|
||||
sti();
|
||||
#ifdef CONFIG_SCSI
|
||||
scsi_dev_init();
|
||||
#endif
|
||||
move_to_user_mode();
|
||||
--- 173,182 ----
|
||||
BIN
Linux-0.97/binaries/usr.bin/gmake-3.62.1.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.bin/gmake-3.62.1.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.bin/ka9q.4.bin.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.bin/ka9q.4.bin.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.bin/ka9qbin.7.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.bin/ka9qbin.7.tar.Z
Normal file
Binary file not shown.
25
Linux-0.97/binaries/usr.bin/linux/include/linux/eth.h
Normal file
25
Linux-0.97/binaries/usr.bin/linux/include/linux/eth.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#define ETHERMTU 2048
|
||||
#define ETHER_MIN_LEN 64
|
||||
#define ETHER_ADDR_LEN 6
|
||||
/* this must be a power of 2 */
|
||||
#define ETH_BUFF_SIZE 0x2000
|
||||
|
||||
/* some ioctls. */
|
||||
#define ETH_START 0
|
||||
#define ETH_STOP 1
|
||||
|
||||
typedef void * (*callback)(void *);
|
||||
|
||||
#define ETHERTYPE_ARP 0x806
|
||||
#define ETHERTYPE_IP 0x800
|
||||
|
||||
#define NET16(x) (((x)<<8)|(x)&0xff)
|
||||
|
||||
struct enet_header
|
||||
{
|
||||
unsigned char saddr[ETHER_ADDR_LEN];
|
||||
unsigned char daddr[ETHER_ADDR_LEN];
|
||||
unsigned short type;
|
||||
};
|
||||
|
||||
#define ETHER_HEADER sizeof(enet_header)
|
||||
789
Linux-0.97/binaries/usr.bin/linux/kernel/chr_drv/we.c
Normal file
789
Linux-0.97/binaries/usr.bin/linux/kernel/chr_drv/we.c
Normal file
@@ -0,0 +1,789 @@
|
||||
/* we.c an wd8003 ethernet driver for linux. */
|
||||
/*
|
||||
Copyright (C) 1992 Ross Biro
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
The Author may be reached as bir7@leland.stanford.edu or
|
||||
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
|
||||
*/
|
||||
/* The bsd386 version was used as an example in order to write this
|
||||
code */
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/tty.h>
|
||||
#include <sys/types.h>
|
||||
/* #include <linux/driver.h>*/
|
||||
#include <linux/eth.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/memory.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "wereg.h"
|
||||
|
||||
static unsigned char interrupt_mask;
|
||||
/* format of status byte.
|
||||
bit
|
||||
0 start
|
||||
1 open
|
||||
2 transmitter in use */
|
||||
|
||||
#define START 1
|
||||
#define OPEN 2
|
||||
#define TRS_BUSY 4
|
||||
|
||||
static unsigned int status;
|
||||
|
||||
struct driver {
|
||||
struct task_struct **d_rwait;
|
||||
struct task_struct **d_wwait;
|
||||
} builtin_dev;
|
||||
|
||||
|
||||
static unsigned char we_addr[ETHER_ADDR_LEN];
|
||||
static struct driver *mdev;
|
||||
static int recv_errors=0;
|
||||
static int trans_errors=0;
|
||||
static int spackets=0;
|
||||
static int collisions=0;
|
||||
static struct task_struct *wwait_ptr=NULL;
|
||||
static struct task_struct *rwait_ptr=NULL;
|
||||
extern void irq5_interrupt(void);
|
||||
|
||||
static inline int
|
||||
min(int a, int b)
|
||||
{
|
||||
if (a<b) return (a);
|
||||
return (b);
|
||||
}
|
||||
|
||||
static inline int
|
||||
max(int a, int b)
|
||||
{
|
||||
if (a>b) return (a);
|
||||
return (b);
|
||||
}
|
||||
|
||||
struct bufhead
|
||||
{
|
||||
long len;
|
||||
};
|
||||
|
||||
struct buf
|
||||
{
|
||||
short head, tail;
|
||||
unsigned char *memory;
|
||||
};
|
||||
|
||||
static unsigned char rbuf_c[ETH_BUFF_SIZE];
|
||||
static unsigned char wbuf_c[ETH_BUFF_SIZE];
|
||||
static struct buf Buf[]=
|
||||
{
|
||||
{0,0,rbuf_c},
|
||||
{0,0,wbuf_c}
|
||||
};
|
||||
|
||||
static struct buf *rbuf = Buf;
|
||||
static struct buf *wbuf = Buf+1;
|
||||
|
||||
static inline int
|
||||
buf_free(struct buf *b)
|
||||
{
|
||||
if (b->head >= b->tail)
|
||||
return(ETH_BUFF_SIZE-b->head +b->tail);
|
||||
else
|
||||
return (b->tail-b->head);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_buf(struct buf *b)
|
||||
{
|
||||
b->head=0;
|
||||
b->tail=0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
copy_to_buf(struct buf *b, void *vptr, long len,
|
||||
void *end_buff, callback split)
|
||||
{
|
||||
struct bufhead *head;
|
||||
long end;
|
||||
long bend;
|
||||
long total=0;
|
||||
unsigned char *ptr;
|
||||
/* check to see if there is enough space. */
|
||||
if (len+3*sizeof(*head) >=
|
||||
buf_free(b))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
head = (struct bufhead *)(b->memory + b->head);
|
||||
head->len = len;
|
||||
b->head += sizeof (*head);
|
||||
ptr = vptr;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
end = ETH_BUFF_SIZE - b->head;
|
||||
bend = (unsigned long)end_buff - (unsigned long)ptr;
|
||||
if (bend <= 0)
|
||||
{
|
||||
ptr =split(ptr);
|
||||
bend = (unsigned long)end_buff - (unsigned long)ptr;
|
||||
}
|
||||
/* copy up to the end of a buffer. */
|
||||
end = min(end,bend);
|
||||
end = min (end,len);
|
||||
if (end < 0)
|
||||
{
|
||||
printk ("copy_to_buf end=%d\n",end);
|
||||
end=0;
|
||||
}
|
||||
(void) memcpy (b->memory+b->head, ptr,end);
|
||||
ptr += end;
|
||||
len -= end;
|
||||
b->head+=end;
|
||||
total += end;
|
||||
if (b->head >= ETH_BUFF_SIZE)
|
||||
b->head = 0;
|
||||
}
|
||||
if (b->head >= ETH_BUFF_SIZE-2*sizeof(*head))
|
||||
b->head = 0;
|
||||
return (total);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
copy_to_buf_fs(struct buf *b, void *vptr, unsigned long len)
|
||||
{
|
||||
struct bufhead *head;
|
||||
unsigned long end;
|
||||
unsigned char *ptr;
|
||||
|
||||
/* check to see if there is enough space. */
|
||||
if (len+3*sizeof(*head) >=
|
||||
buf_free(b))
|
||||
{
|
||||
printk ("copy_to_buf_fs failed %d\n",len);
|
||||
return(0);
|
||||
}
|
||||
|
||||
head = (struct bufhead *)(b->memory + b->head);
|
||||
head->len = len;
|
||||
b->head += sizeof (*head);
|
||||
|
||||
end = ETH_BUFF_SIZE - b->head;
|
||||
ptr = vptr;
|
||||
/* copy up to the end of the buffer. */
|
||||
end = min(end,len);
|
||||
memcpy_fromfs (b->memory+b->head, ptr,end);
|
||||
ptr += end;
|
||||
len -= end;
|
||||
b->head+=end;
|
||||
if (b->head >= ETH_BUFF_SIZE)
|
||||
b->head = 0;
|
||||
/* now copy the rest. */
|
||||
memcpy_fromfs (b->memory+b->head, ptr, len);
|
||||
b->head += len;
|
||||
if (b->head >= ETH_BUFF_SIZE-2*sizeof(*head))
|
||||
b->head = 0;
|
||||
return (end + len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
copy_from_buf(struct buf *b, void *vptr, long len)
|
||||
{
|
||||
struct bufhead *head;
|
||||
long end;
|
||||
unsigned char *ptr;
|
||||
|
||||
/* check to see if there is anything in the buffer. */
|
||||
if (b->head == b->tail)
|
||||
return(0);
|
||||
|
||||
head = (struct bufhead *)(b->memory + b->tail);
|
||||
b->tail += sizeof (*head);
|
||||
len = min (head->len,len);
|
||||
|
||||
end = ETH_BUFF_SIZE - b->tail;
|
||||
ptr = vptr;
|
||||
/* copy up to the end of the buffer. */
|
||||
end = min(end,len);
|
||||
if (end < 0)
|
||||
{
|
||||
printk ("copy from buf end = %d\n",end);
|
||||
end = 0;
|
||||
}
|
||||
(void) memcpy (ptr, b->memory+b->tail, end);
|
||||
ptr += end;
|
||||
len -= end;
|
||||
b->tail+=end;
|
||||
if (b->tail >= ETH_BUFF_SIZE)
|
||||
b->tail = 0;
|
||||
/* now copy the rest. */
|
||||
(void )memcpy (ptr, b->memory+b->tail, len);
|
||||
/* now forget about any leftover stuff. */
|
||||
b->tail += head->len - end;
|
||||
if (b->tail >= ETH_BUFF_SIZE)
|
||||
b->tail-=ETH_BUFF_SIZE;
|
||||
if (b->tail >= ETH_BUFF_SIZE-2*sizeof(*head))
|
||||
b->tail = 0;
|
||||
return (end + len);
|
||||
}
|
||||
|
||||
static inline int
|
||||
copy_from_buf_fs(struct buf *b, void *vptr, unsigned long len)
|
||||
{
|
||||
struct bufhead *head;
|
||||
unsigned long end;
|
||||
unsigned char *ptr;
|
||||
|
||||
/* check to see if there is anything in the buffer. */
|
||||
if (b->head == b->tail)
|
||||
return(0);
|
||||
|
||||
head = (struct bufhead *)(b->memory + b->tail);
|
||||
b->tail += sizeof (*head);
|
||||
len = min (head->len,len);
|
||||
|
||||
end = ETH_BUFF_SIZE - b->tail;
|
||||
ptr = vptr;
|
||||
/* copy up to the end of the buffer. */
|
||||
end = min(end,len);
|
||||
memcpy_tofs (ptr, b->memory+b->tail, end);
|
||||
ptr += end;
|
||||
len -= end;
|
||||
b->tail+=end;
|
||||
if (b->tail >= ETH_BUFF_SIZE)
|
||||
b->tail = 0;
|
||||
/* now copy the rest. */
|
||||
if (len != 0)
|
||||
{
|
||||
memcpy_tofs (ptr,b->memory+b->tail, len);
|
||||
}
|
||||
/* now forget about any leftover stuff. */
|
||||
b->tail += head->len - end;
|
||||
if (b->tail >= ETH_BUFF_SIZE)
|
||||
b->tail-=ETH_BUFF_SIZE;
|
||||
if (b->tail >= ETH_BUFF_SIZE-2*sizeof(*head))
|
||||
b->tail = 0;
|
||||
return (end + len);
|
||||
}
|
||||
|
||||
void
|
||||
wd_stop(void)
|
||||
{
|
||||
unsigned char cmd;
|
||||
cli();
|
||||
cmd = inb_p(WD_COMM);
|
||||
cmd |= CSTOP;
|
||||
cmd &= ~(CSTART|CPAGE);
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb(0,WD_IMR);
|
||||
sti();
|
||||
interrupt_mask = 0;
|
||||
status &= ~START;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wd_start(void)
|
||||
{
|
||||
unsigned char cmd;
|
||||
interrupt_mask=RECV_MASK;
|
||||
cli();
|
||||
cmd = inb_p(WD_COMM);
|
||||
cmd &= ~(CSTOP|CPAGE);
|
||||
cmd |= CSTART;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb(interrupt_mask,WD_IMR);
|
||||
sti();
|
||||
status |= START;
|
||||
}
|
||||
|
||||
int wd8003_close(struct inode *inode, struct file *filep)
|
||||
{
|
||||
int minor;
|
||||
minor = MINOR(inode->i_rdev);
|
||||
if (minor != 0) return (-ENODEV);
|
||||
wd_stop();
|
||||
status = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
wd8003_open(struct inode *inode, struct file *filep)
|
||||
{
|
||||
unsigned char cmd;
|
||||
int i;
|
||||
int minor;
|
||||
|
||||
minor = MINOR(inode->i_rdev);
|
||||
if (minor != 0) return (-ENODEV);
|
||||
if (status & OPEN) return (-EBUSY);
|
||||
|
||||
/* clear the buffs. */
|
||||
clear_buf(rbuf);
|
||||
clear_buf(wbuf);
|
||||
|
||||
/* we probably don't want to be interrupted here. */
|
||||
cli();
|
||||
/* This section of code is mostly copied from the bsd driver which is
|
||||
mostly copied from somewhere else. */
|
||||
cmd=inb_p(WD_COMM);
|
||||
cmd|=CSTOP;
|
||||
cmd &= ~(CSTART|CPAGE);
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(0, WD_IMR);
|
||||
sti();
|
||||
outb_p(WD_DCONFIG,WD_DCR);
|
||||
/*Zero the remote byte count. */
|
||||
outb_p(0, WD_RBY0);
|
||||
outb_p(0, WD_RBY1);
|
||||
outb_p(WD_MCONFIG,WD_RCC);
|
||||
outb_p(WD_TCONFIG,WD_TRC);
|
||||
/* Set the transmit page */
|
||||
outb_p(0,WD_TRPG);
|
||||
outb_p(WD_TXBS,WD_PSTRT);
|
||||
outb_p(WD_MAX_PAGES,WD_PSTOP);
|
||||
outb_p(WD_TXBS,WD_BNDR);
|
||||
/* clear interrupt status. */
|
||||
outb_p(0xff,WD_ISR);
|
||||
/* we don't want no stinking interrupts. */
|
||||
outb_p(0 ,WD_IMR);
|
||||
cmd|=1<<CPAGE_SHIFT;
|
||||
outb_p(cmd,WD_COMM);
|
||||
/* set the either address. */
|
||||
for (i=0; i < ETHER_ADDR_LEN; i++)
|
||||
{
|
||||
outb_p(we_addr[i],WD_PAR0+i);
|
||||
}
|
||||
/* set the multicast address. */
|
||||
for (i=0; i < ETHER_ADDR_LEN; i++)
|
||||
{
|
||||
outb_p(0xff,WD_MAR0+i);
|
||||
}
|
||||
outb_p(WD_TXBS,WD_CUR);
|
||||
cmd&=~(CPAGE|CRDMA);
|
||||
cmd|= 4<<CRDMA_SHIFT;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(WD_RCONFIG,WD_RCC);
|
||||
status = OPEN;
|
||||
wd_start();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *
|
||||
wd_callback(void *ptr)
|
||||
{
|
||||
if (ptr >= (void *)WD_BUFFEND)
|
||||
return ((void *)(WD_MEM + (WD_TXBS<<8)));
|
||||
return (ptr);
|
||||
}
|
||||
/*This routine just copies the stuff from the ring into the
|
||||
buffer. It remove the ring headers, and makes sure that
|
||||
everything fits. */
|
||||
|
||||
static inline int
|
||||
wdget(struct wd_ring *ring)
|
||||
{
|
||||
unsigned char *fptr;
|
||||
unsigned long len;
|
||||
int i;
|
||||
fptr = (unsigned char *)(ring +1);
|
||||
len = ring->count-4;
|
||||
for (i =0; i < ETHER_ADDR_LEN; i++)
|
||||
if (fptr[i] != we_addr[i])
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
if (copy_to_buf (rbuf, fptr, len,(void *) WD_BUFFEND, wd_callback)
|
||||
!= len) return (1);
|
||||
return (0);
|
||||
}
|
||||
/* wd_strans attempts to start a transmission. It is
|
||||
only called when the transmit buffer is free. */
|
||||
static inline void
|
||||
wd_strans(void)
|
||||
{
|
||||
unsigned long len;
|
||||
unsigned char cmd;
|
||||
|
||||
len = copy_from_buf(wbuf,(void *)WD_MEM,WD_TXBS<<8);
|
||||
/* see if there is anything to send. */
|
||||
if (len == 0)
|
||||
{
|
||||
interrupt_mask &= ~TRANS_MASK;
|
||||
status &= ~(TRS_BUSY);
|
||||
return;
|
||||
}
|
||||
status |= TRS_BUSY;
|
||||
/* now we need to set up the card info. */
|
||||
len=max(len, ETHER_MIN_LEN);
|
||||
cmd=inb_p(WD_COMM);
|
||||
outb_p(len&0xff,WD_TB0);
|
||||
outb_p(len>>8,WD_TB1);
|
||||
cmd |= CTRANS;
|
||||
outb(cmd,WD_COMM);
|
||||
interrupt_mask |= TRANS_MASK;
|
||||
}
|
||||
|
||||
int
|
||||
rw_wd8003(int rw, unsigned minor, char *buf, int count, unsigned short flags )
|
||||
{
|
||||
unsigned long len=0;
|
||||
unsigned char cmd;
|
||||
if (minor != 0) return (-ENODEV);
|
||||
|
||||
if (rw == READ)
|
||||
{
|
||||
while (len == 0)
|
||||
{
|
||||
verify_area(buf, count);
|
||||
len = copy_from_buf_fs(rbuf,buf, count);
|
||||
if (len == 0)
|
||||
{
|
||||
clear_buf(rbuf);
|
||||
if ( flags & O_NONBLOCK)
|
||||
{
|
||||
return (-EAGAIN);
|
||||
}
|
||||
interruptible_sleep_on(mdev->d_rwait);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len == 0)
|
||||
{
|
||||
verify_area(buf, count);
|
||||
len = copy_to_buf_fs(wbuf,buf, count);
|
||||
if (len == 0)
|
||||
{
|
||||
clear_buf(wbuf);
|
||||
if ( flags & O_NONBLOCK)
|
||||
{
|
||||
return (-EAGAIN);
|
||||
}
|
||||
interruptible_sleep_on(mdev->d_wwait);
|
||||
}
|
||||
}
|
||||
/* see if we need to start the transmission. */
|
||||
if (!(status & TRS_BUSY))
|
||||
{
|
||||
cli();
|
||||
cmd = inb_p(WD_COMM);
|
||||
cmd &= ~(CPAGE);
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(0, WD_IMR);
|
||||
sti();
|
||||
wd_strans();
|
||||
outb_p(interrupt_mask,WD_IMR);
|
||||
}
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static int
|
||||
wd8003_read (struct inode *inode, struct file *file, char *buf, int count)
|
||||
{
|
||||
return (rw_wd8003(READ, MINOR(inode->i_rdev), buf, count, file->f_flags));
|
||||
}
|
||||
|
||||
static int
|
||||
wd8003_write (struct inode *inode, struct file *file, char *buf, int count)
|
||||
{
|
||||
return (rw_wd8003(WRITE, MINOR(inode->i_rdev), buf, count, file->f_flags));
|
||||
}
|
||||
|
||||
/* This routine handles the packet recieved interrupt. */
|
||||
/* It is called with interrupts enabled, but with
|
||||
the wd card configured not to return interrupts. */
|
||||
/* It is enterred with page one selected, and it must
|
||||
leave that way. */
|
||||
/* I think there might be an infinite loop here, so I'm putting
|
||||
in a maximum number of packets we can look at at once.
|
||||
Someone with good docs can try to fix this one. */
|
||||
|
||||
static inline void
|
||||
wd_rcv(void)
|
||||
{
|
||||
unsigned char bnd;
|
||||
unsigned char cur;
|
||||
unsigned char cmd;
|
||||
struct wd_ring *ring;
|
||||
int count = 0;
|
||||
|
||||
cmd=inb_p(WD_COMM);
|
||||
bnd=inb_p(WD_BNDR);
|
||||
cmd |= 1<< CPAGE_SHIFT;
|
||||
outb_p (cmd, WD_COMM);
|
||||
cur=inb(WD_CUR);
|
||||
while (bnd != cur)
|
||||
{
|
||||
count++;
|
||||
if (count > 10)
|
||||
{
|
||||
bnd=cur;
|
||||
break;
|
||||
}
|
||||
ring = (struct wd_ring *)(WD_MEM + (bnd << 8));
|
||||
if (ring->count > 34 && ring->count <= ETHERMTU+104)
|
||||
{
|
||||
if (wdget(ring))
|
||||
{
|
||||
/* we have a buffer overflow. */
|
||||
/* reset the bndry and the current. */
|
||||
cmd |= CSTOP;
|
||||
outb_p(cmd,WD_COMM);
|
||||
outb_p(WD_MCONFIG,WD_RCC);
|
||||
outb_p(WD_TXBS,WD_BNDR);
|
||||
cmd |= 1 <<CPAGE_SHIFT;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(WD_TXBS,WD_CUR);
|
||||
cmd &= ~(CSTOP|CPAGE);
|
||||
cmd |= CSTART;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(WD_RCONFIG,WD_RCC);
|
||||
return;
|
||||
}
|
||||
wake_up(mdev->d_rwait);
|
||||
}
|
||||
else
|
||||
{
|
||||
bnd=cur;
|
||||
break;
|
||||
}
|
||||
/* compute a new boundary. */
|
||||
if (ring->next >= WD_MAX_PAGES)
|
||||
{
|
||||
bnd= ring->next - WD_MAX_PAGES + WD_TXBS;
|
||||
}
|
||||
else
|
||||
{
|
||||
bnd=ring->next;
|
||||
if (bnd <= WD_TXBS)
|
||||
{
|
||||
bnd += WD_TXBS;
|
||||
}
|
||||
}
|
||||
/* tell the card about the new boundary. */
|
||||
cmd &=~(CPAGE);
|
||||
outb_p(cmd,WD_COMM);
|
||||
if (bnd != WD_TXBS)
|
||||
outb_p(bnd-1,WD_BNDR);
|
||||
else
|
||||
outb_p(WD_MAX_PAGES-1,WD_BNDR);
|
||||
cmd |= 1<< CPAGE_SHIFT;
|
||||
outb_p(cmd,WD_COMM);
|
||||
/* update our copy of cur. */
|
||||
cur = inb_p(WD_CUR);
|
||||
}
|
||||
/* we have to make sure we reset the i/o page. */
|
||||
cmd &= ~(CPAGE);
|
||||
outb_p(cmd,WD_COMM);
|
||||
if (bnd != WD_TXBS)
|
||||
outb_p(bnd-1, WD_BNDR);
|
||||
else
|
||||
outb_p(WD_MAX_PAGES-1, WD_BNDR);
|
||||
}
|
||||
|
||||
/* This get's the transmit interrupts.
|
||||
It assume command page 0 is set, and
|
||||
returns with command page 0 set. */
|
||||
|
||||
static inline void
|
||||
wd_trs(void)
|
||||
{
|
||||
/*update the stats. */
|
||||
spackets++;
|
||||
collisions += inb(WD_TB0);
|
||||
/* attempt to start a transmission. */
|
||||
wd_strans();
|
||||
/* wakeup anything that was sleeping on writes. */
|
||||
if (*(mdev->d_wwait)) wake_up(mdev->d_wwait);
|
||||
}
|
||||
/* Currently this routine sometimes gets stuck in an infinite
|
||||
loop. So I'm putting in a counter. When the routine
|
||||
has looped 10 times, I'm just resetting everything,
|
||||
then leaving. Someone who has real docs can fix this. */
|
||||
|
||||
void
|
||||
wd8003_interrupt(void)
|
||||
{
|
||||
unsigned char cmd;
|
||||
unsigned char isr;
|
||||
int count=0;
|
||||
/* Acknowledge the interrupt. */
|
||||
outb_p(0x20,0x20);
|
||||
/* now we can be interrupted, but since we have
|
||||
done nothing yet it doesn't matter. */
|
||||
/*we don't want to be interrupted after we
|
||||
read the command byte. */
|
||||
cli();
|
||||
cmd=inb_p(WD_COMM);
|
||||
cmd&=~(CPAGE);
|
||||
outb_p(cmd,WD_COMM);
|
||||
isr=inb(WD_ISR);
|
||||
do {
|
||||
outb_p(0,WD_IMR);
|
||||
/* we have turned the wd8003 interrupts off, so we can reenable
|
||||
them at the processor level. */
|
||||
sti();
|
||||
/* From now on other devices will be able to interrupt us, so
|
||||
some care is probably required. */
|
||||
count++;
|
||||
if (count > 10)
|
||||
{
|
||||
printk ("wd8003:Warning loop broken\n");
|
||||
/* we are caught in a loop, reset everything that we can think
|
||||
of and return. This needs to be fixed. */
|
||||
cmd |= CSTOP;
|
||||
outb_p(cmd,WD_COMM);
|
||||
outb_p(WD_IMEM|0x80,WD_CTL);
|
||||
outb_p(WD_IMEM,WD_CTL);
|
||||
outb_p(WD_MCONFIG,WD_RCC);
|
||||
outb_p(WD_TXBS,WD_BNDR);
|
||||
cmd |= 1 <<CPAGE_SHIFT;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(WD_TXBS,WD_CUR);
|
||||
cmd &= ~(CSTOP|CPAGE);
|
||||
cmd |= CSTART;
|
||||
outb_p(cmd, WD_COMM);
|
||||
outb_p(WD_RCONFIG,WD_RCC);
|
||||
outb_p (0,WD_ISR);
|
||||
outb_p(interrupt_mask,WD_IMR);
|
||||
return;
|
||||
}
|
||||
/* see what to do about the interrupt. */
|
||||
if (isr & IRCV) /* got a packet. */
|
||||
wd_rcv();
|
||||
if (isr & ITRS) /* finished sending a packet. */
|
||||
wd_trs();
|
||||
|
||||
if (isr & IRCE) /* recieve error */
|
||||
{
|
||||
/* reading these registers might clear the error condition. */
|
||||
collisions += inb(WD_TB0);
|
||||
(void) inb(WD_RCC);
|
||||
(void) inb(WD_DCR);
|
||||
recv_errors++;
|
||||
}
|
||||
if (isr & ITRE) /* transmit error. */
|
||||
{
|
||||
collisions += inb(WD_TB0);
|
||||
trans_errors++;
|
||||
}
|
||||
|
||||
/* acknowledge the intterupt. */
|
||||
outb_p(isr, WD_ISR);
|
||||
|
||||
/* Now we will try to reenable onboard interrupts. */
|
||||
cli();
|
||||
outb_p(interrupt_mask,WD_IMR);
|
||||
isr=inb_p(WD_ISR)&interrupt_mask;
|
||||
} while (isr != 0);
|
||||
sti();
|
||||
}
|
||||
|
||||
int
|
||||
wd8003_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned int arg)
|
||||
{
|
||||
int dev;
|
||||
dev=MINOR(inode->i_rdev);
|
||||
if (dev != 0) return (-ENODEV);
|
||||
switch (cmd)
|
||||
{
|
||||
case ETH_START:
|
||||
wd_start();
|
||||
return (0);
|
||||
|
||||
case ETH_STOP:
|
||||
wd_stop();
|
||||
return(0);
|
||||
|
||||
default:
|
||||
return (-EINVAL);
|
||||
|
||||
}
|
||||
}
|
||||
static struct file_operations wd_fops =
|
||||
{
|
||||
NULL,
|
||||
wd8003_read,
|
||||
wd8003_write,
|
||||
NULL,
|
||||
NULL,
|
||||
wd8003_ioctl,
|
||||
wd8003_open,
|
||||
wd8003_close
|
||||
};
|
||||
|
||||
void
|
||||
wd8003_init(struct driver *dev)
|
||||
{
|
||||
unsigned char csum;
|
||||
int i;
|
||||
chrdev_fops[10]=&wd_fops;
|
||||
mdev = &builtin_dev;
|
||||
mdev->d_rwait = &rwait_ptr;
|
||||
mdev->d_wwait = &wwait_ptr;
|
||||
csum = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
csum += inb_p(WD_ROM+i);
|
||||
}
|
||||
if (csum != WD_CHECK)
|
||||
{
|
||||
printk ("Warning no WD8003 board installed.\n");
|
||||
/* make sure no one can attempt to open the device. */
|
||||
status = OPEN;
|
||||
return;
|
||||
}
|
||||
|
||||
/* mapin the interface memory. */
|
||||
outb(WD_IMEM,WD_CTL);
|
||||
|
||||
/* clear the interface memory */
|
||||
for (i = 0; i < WD_MEMSIZE; i++)
|
||||
{
|
||||
((unsigned char *)WD_MEM)[i] = 0;
|
||||
if (((unsigned char *)WD_MEM)[i] != 0)
|
||||
{
|
||||
printk ("WD Memory error.\n");
|
||||
status = OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* print the initialization message, and the
|
||||
ethernet address. */
|
||||
printk ("WD8003 ethernet Address ");
|
||||
for (i = 0; i <ETHER_ADDR_LEN; i++)
|
||||
{
|
||||
we_addr[i]=inb_p(WD_ROM+i);
|
||||
printk ("%2.2X ",we_addr[i]);
|
||||
}
|
||||
printk ("\n");
|
||||
status = 0;
|
||||
set_trap_gate (0x25, irq5_interrupt);
|
||||
outb(inb_p(0x21)&0xDF, 0x21);
|
||||
}
|
||||
131
Linux-0.97/binaries/usr.bin/linux/kernel/chr_drv/wereg.h
Normal file
131
Linux-0.97/binaries/usr.bin/linux/kernel/chr_drv/wereg.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/* wereg.h */
|
||||
/*
|
||||
Copyright (C) 1992 Ross Biro
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
The Author may be reached as bir7@leland.stanford.edu or
|
||||
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
|
||||
*/
|
||||
/* This is based on if_wereg.h from bsd386 */
|
||||
|
||||
struct wd_ring
|
||||
{
|
||||
unsigned char status; /* status */
|
||||
/* format of status
|
||||
bit
|
||||
0 packet ok
|
||||
1 crc error
|
||||
2 frame alignment error
|
||||
3 fifo overrun
|
||||
*/
|
||||
#define STRECVD 0xf1
|
||||
unsigned char next; /* pointer to next packet. */
|
||||
unsigned short count; /*packet lenght in bytes + 4 */
|
||||
};
|
||||
|
||||
/* Format of command register.
|
||||
bits
|
||||
0 stop
|
||||
1 start
|
||||
2 transmit packet
|
||||
3-5 Remote DMA command
|
||||
6-7 Page Select */
|
||||
|
||||
#define CSTOP 0x1
|
||||
#define CSTART 0x2
|
||||
#define CTRANS 0x4
|
||||
#define CRDMA 0x38
|
||||
#define CRDMA_SHIFT 3
|
||||
#define CPAGE 0xc0
|
||||
#define CPAGE_SHIFT 6
|
||||
/* interrupt status defenitions
|
||||
bits
|
||||
0 Recv.
|
||||
1 Transmit
|
||||
2 RcvErr
|
||||
3 Transmit Err
|
||||
4 Overwrite warning
|
||||
5 Counter overflow
|
||||
6 Remote DMA complete
|
||||
7 Reset Status */
|
||||
|
||||
#define IRCV 0x1
|
||||
#define ITRS 0x2
|
||||
#define IRCE 0x4
|
||||
#define ITRE 0x8
|
||||
|
||||
/* transmit status format
|
||||
bits
|
||||
0 Packet transmitted ok.
|
||||
1 Non Deferred transmition
|
||||
2 Transmit collied
|
||||
3 Transmit aborted
|
||||
4 Carrier Sense Lost
|
||||
5 Fifo Underrun
|
||||
6 CD Heartbeat
|
||||
7 Out of Window Collision */
|
||||
|
||||
#define TROK 0x1
|
||||
#define TRAB 0x4
|
||||
|
||||
/* Some ID stuff */
|
||||
#define WD_ID1 0x03
|
||||
#define WD_ID2 0x05
|
||||
#define WD_CHECK 0xff
|
||||
#define WD_PAGE 256 /* page size in bytes. */
|
||||
#define WD_TXBS 6 /* size of transmit buffer in pages. */
|
||||
#define WD_MAX_PAGES 32 /* Number of pages off ram on card (8k) */
|
||||
#define WD_NIC 16 /* i/o base offset to NIC */
|
||||
|
||||
/* Some configuration stuff. */
|
||||
/* where the memory is mapped in. */
|
||||
#define WD_MEM 0xd0000
|
||||
#define WD_BUFFEND 0xd4000
|
||||
#define WD_MEMSIZE (WD_BUFFEND-WD_MEM)
|
||||
#define WD_BASE 0x280
|
||||
|
||||
#define TRANS_MASK 0xa
|
||||
#define RECV_MASK 0x5
|
||||
#define WD_DCONFIG 0x48
|
||||
#define WD_RCONFIG 0x4
|
||||
#define WD_MCONFIG 0x20
|
||||
#define WD_TCONFIG 0x0
|
||||
#define WD_IMEM (((WD_MEM>>13) & 0x3f)|0x40)
|
||||
|
||||
/* WD registers. */
|
||||
#define WD_ROM (WD_BASE+8)
|
||||
#define WD_CTL (WD_BASE+0)
|
||||
|
||||
/* WD NIC register offsets */
|
||||
#define WD_COMM (WD_BASE+WD_NIC+0x00) /* command register */
|
||||
#define WD_PSTRT (WD_BASE+WD_NIC+0x01) /* page start register */
|
||||
#define WD_PSTOP (WD_BASE+WD_NIC+0x02) /* page stop register */
|
||||
#define WD_BNDR (WD_BASE+WD_NIC+0x03) /* Boundary Pointer */
|
||||
#define WD_TRST (WD_BASE+WD_NIC+0x04) /* Transmit Status */
|
||||
#define WD_TRPG (WD_BASE+WD_NIC+0x04) /* Transmit Page */
|
||||
#define WD_TB0 (WD_BASE+WD_NIC+0x05) /* Transmit byte count, low */
|
||||
#define WD_TB1 (WD_BASE+WD_NIC+0x06) /* Transmit byte count, high */
|
||||
#define WD_ISR (WD_BASE+WD_NIC+0x07) /* Interrupt status register */
|
||||
#define WD_RBY0 (WD_BASE+WD_NIC+0x0a) /* remote byte count low. */
|
||||
#define WD_RBY1 (WD_BASE+WD_NIC+0x0b) /* remote byte count high. */
|
||||
#define WD_RCC (WD_BASE+WD_NIC+0x0c) /* receive configuration */
|
||||
#define WD_TRC (WD_BASE+WD_NIC+0x0d) /* transmit configuration */
|
||||
#define WD_DCR (WD_BASE+WD_NIC+0x0e) /* data configuration */
|
||||
#define WD_IMR (WD_BASE+WD_NIC+0x0f) /* Interrupt Mask register. */
|
||||
#define WD_PAR0 (WD_BASE+WD_NIC+0x01)
|
||||
#define WD_CUR (WD_BASE+WD_NIC+0x07)
|
||||
#define WD_MAR0 (WD_BASE+WD_NIC+0x08)
|
||||
|
||||
BIN
Linux-0.97/binaries/usr.bin/minicom.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.bin/minicom.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.bin/tkppp-1.0.tar.gz
Normal file
BIN
Linux-0.97/binaries/usr.bin/tkppp-1.0.tar.gz
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.bin/utree.bin.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.bin/utree.bin.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.bin/wd8003.tar
Normal file
BIN
Linux-0.97/binaries/usr.bin/wd8003.tar
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/banner.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/banner.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/dkbtrace.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/dkbtrace.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/dungeon.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/dungeon.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/gnuchess-3.1.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/gnuchess-3.1.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/mille.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/mille.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/neko-bin.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/neko-bin.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/omega-0.78-bin.tar.gz
Normal file
BIN
Linux-0.97/binaries/usr.games/omega-0.78-bin.tar.gz
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/plumbing.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/plumbing.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/spider.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/spider.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/tetris-bin.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/tetris-bin.tar.Z
Normal file
Binary file not shown.
BIN
Linux-0.97/binaries/usr.games/xgames.tar.Z
Normal file
BIN
Linux-0.97/binaries/usr.games/xgames.tar.Z
Normal file
Binary file not shown.
Reference in New Issue
Block a user