+
+all: Version Image
+
#
# Make "config" the default target if there is no configuration file or
# "depend" the target if there is no top-level dependency information.
.c.o:
$(CC) $(CFLAGS) -c -o $*.o $<
-all: Version Image
-
Version: dummy
- rm tools/version.h
+ rm -f tools/version.h
lilo: $(CONFIGURE) Image
if [ -f /vmlinux ]; then mv /vmlinux /vmlinux.old; fi
linuxsubdirs: dummy
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
+tools/./version.h: tools/version.h
+
tools/version.h: $(CONFIGURE) Makefile
@./makever.sh
- @echo \#define UTS_RELEASE \"0.99.pl3-`cat .version`\" > tools/version.h
+ @echo \#define UTS_RELEASE \"0.99.pl4-`cat .version`\" > tools/version.h
@echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
boot/head.o: $(CONFIGURE) boot/head.s
-boot/head.s: $(CONFIGURE) boot/head.S
+boot/head.s: $(CONFIGURE) boot/head.S include/linux/tasks.h
$(CPP) -traditional boot/head.S -o boot/head.s
tools/version.o: tools/version.c tools/version.h
.globl _empty_bad_page_table
.globl _tmp_floppy_area,_floppy_track_buffer
+#include <linux/tasks.h>
+
/*
* swapper_pg_dir is the main page directory, address 0x00001000
*/
.align 4
.word 0
gdt_descr:
- .word 256*8-1
+ .word (4+2*NR_TASKS)*8-1
.long 0xc0000000+_gdt
/*
.quad 0xc0c39a000000ffff /* 1GB at 0xC0000000 */
.quad 0xc0c392000000ffff /* 1GB */
.quad 0x0000000000000000 /* TEMPORARY - don't use */
- .fill 252,8,0 /* space for LDT's and TSS's etc */
+ .fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */
! things as simple as possible, we do no register set-up or anything,
! we let the gnu-compiled 32-bit programs do that. We just jump to
! absolute address 0x00000, in 32-bit protected mode.
-
+!
+! Note that the short jump isn't strictly needed, althought there are
+! reasons why it might be a good idea. It won't hurt in any case.
+!
mov ax,#0x0001 ! protected mode (PE) bit
lmsw ax ! This is it!
+ jmp flush_instr
+flush_instr:
jmpi 0,8 ! jmp offset 0 of segment 8 (cs)
! This routine checks that the keyboard command queue is empty
!
! Flush the keyboard buffer
!
-flush: in al,#0x60
- .word 0x00eb,0x00eb
+flush: call getkey
cmp al,#0x82
jae flush
ret
jne nf1280
lea si,dscf1280
lea di,mof1280
- lea cx,selmod
- jmp cx
+ br selmod
nf1280: cld
lea si,idati ! Check ATI 'clues'
mov di,#0x31
jne noati
lea si,dscati
lea di,moati
- lea cx,selmod
- jmp cx
+ br selmod
noati: mov ax,#0x200f ! Check Ahead 'clues'
mov dx,#0x3ce
out dx,ax
jne noahed
isahed: lea si,dscahead
lea di,moahead
- lea cx,selmod
- jmp cx
+ br selmod
noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
in al,dx
or al,#0x10
jne nocant
lea si,dsccandt
lea di,mocandt
- lea cx,selmod
- jmp cx
+ br selmod
nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
mov al,#0x0c
out dx,al
call rst3d4
lea si,dsccirrus
lea di,mocirrus
- lea cx,selmod
- jmp cx
+ br selmod
rst3d4: mov dx,#0x3d4
mov al,bl
xor ah,ah
je istrid
lea si,dsceverex
lea di,moeverex
- lea cx,selmod
- jmp cx
+ br selmod
istrid: lea cx,ev2tri
jmp cx
noevrx: lea si,idgenoa ! Check Genoa 'clues'
jne nogen
lea si,dscgenoa
lea di,mogenoa
- lea cx,selmod
- jmp cx
+ br selmod
nogen: cld
lea si,idoakvga
mov di,#0x08
jne nooak
lea si,dscoakvga
lea di,mooakvga
- lea cx,selmod
- jmp cx
+ br selmod
nooak: cld
lea si,idparadise ! Check Paradise 'clues'
mov di,#0x7d
jne nopara
lea si,dscparadise
lea di,moparadise
- lea cx,selmod
- jmp cx
+ br selmod
nopara: mov dx,#0x3c4 ! Check Trident 'clues'
mov al,#0x0e
out dx,al
jne notrid
ev2tri: lea si,dsctrident
lea di,motrident
- lea cx,selmod
- jmp cx
+ jmp selmod
notrid: mov dx,#0x3cd ! Check Tseng 'clues'
in al,dx ! Could things be this simple ! :-)
mov bl,al
jne notsen
lea si,dsctseng
lea di,motseng
- lea cx,selmod
- jmp cx
+ jmp selmod
notsen: mov dx,#0x3cc ! Check Video7 'clues'
in al,dx
mov dx,#0x3b4
if (!(filp->f_mode & 2))
return -EBADF;
break;
+ case F_SHLCK :
+ if (!(filp->f_mode & 3))
+ return -EBADF;
+ file_lock.fl_type = F_RDLCK;
+ break;
+ case F_EXLCK :
+ if (!(filp->f_mode & 3))
+ return -EBADF;
+ file_lock.fl_type = F_WRLCK;
+ break;
case F_UNLCK :
break;
}
#include <linux/kernel.h>
#include <linux/string.h>
+#include <asm/bitops.h>
+
#define clear_block(addr) \
__asm__("cld\n\t" \
"rep\n\t" \
"stosl" \
::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
-#define set_bit(nr,addr) ({\
-char res; \
-__asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
-"=q" (res):"r" (nr),"m" (*(addr))); \
-res;})
-
-#define clear_bit(nr,addr) ({\
-char res; \
-__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
-"=q" (res):"r" (nr),"m" (*(addr))); \
-res;})
-
#define find_first_zero(addr) ({ \
int __res; \
__asm__("cld\n" \
buf += chars;
}
wake_up(& PIPE_WRITE_WAIT(*inode));
- return read?read:-EAGAIN;
+ if (read)
+ return read;
+ if (PIPE_WRITERS(*inode))
+ return -EAGAIN;
+ return 0;
}
static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
i.totalswap, i.totalswap-i.freeswap, i.freeswap);
}
+static int get_version(char * buffer)
+{
+ extern char *linux_banner;
+
+ strcpy(buffer, linux_banner);
+ return strlen(buffer);
+}
+
static struct task_struct ** get_task(pid_t pid)
{
struct task_struct ** p;
case 4:
length = get_meminfo(page);
break;
+ case 6:
+ length = get_version(page);
+ break;
case 9:
length = get_env(pid, page);
break;
{ 3,6,"uptime" },
{ 4,7,"meminfo" },
{ 5,4,"kmsg" },
- { 6,4,"self" } /* will change inode # */
+ { 6,7,"version" },
+ { 7,4,"self" } /* will change inode # */
};
#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
*result = dir;
return 0;
}
- if (ino == 6) /* self modifying inode ... */
+ if (ino == 7) /* self modifying inode ... */
ino = (current->pid << 16) + 2;
} else {
pid = 0;
return 0; /* we don't iput(dir_i) - see umount */
}
+
+/*
+ * Alters the mount flags of a mounted file system. Only the mount point
+ * is used as a reference - file system type and the device are ignored.
+ * FS-specific mount options can't be altered by remounting.
+ */
+
+static int do_remount(const char *dir,int flags)
+{
+ struct inode *dir_i;
+ int retval;
+
+ retval = namei(dir,&dir_i);
+ if (retval)
+ return retval;
+ if (dir_i != dir_i->i_sb->s_mounted) {
+ iput(dir_i);
+ return -EINVAL;
+ }
+ dir_i->i_sb->s_flags = (dir_i->i_sb->s_flags & ~MS_RMT_MASK) |
+ (flags & MS_RMT_MASK);
+ iput(dir_i);
+ return 0;
+}
+
+
/*
* Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
* be given to the mount() call (ie: read-only, no-dev, no-suid etc).
if (!suser())
return -EPERM;
+ if ((new_flags & (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL |
+ MS_REMOUNT))
+ return do_remount(dir_name,new_flags & ~MS_MGC_MSK &
+ ~MS_REMOUNT);
if (type) {
for (i = 0 ; i < 100 ; i++)
if (!(tmp[i] = get_fs_byte(type++)))
return retval;
}
}
- if ((new_flags & 0xffff0000) == 0xC0ED0000) {
- flags = new_flags & 0xffff;
+ if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
+ flags = new_flags & ~MS_MGC_MSK;
if (data) {
if ((unsigned long) data >= TASK_SIZE) {
iput(inode);
*
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
-extern inline int set_bit(int nr,int * addr)
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy { unsigned long a[100]; };
+#define ADDR (*(struct __dummy *) addr)
+
+extern inline int set_bit(int nr, void * addr)
{
char ok;
- __asm__ __volatile__("btsl %1,%2\n\tsetb %0":
- "=q" (ok):"r" (nr),"m" (*(addr)));
+ __asm__ __volatile__("btsl %2,%1\n\tsetb %0"
+ :"=q" (ok),"=m" (ADDR)
+ :"r" (nr));
return ok;
}
-extern inline int clear_bit(int nr, int * addr)
+extern inline int clear_bit(int nr, void * addr)
{
char ok;
- __asm__ __volatile__("btrl %1,%2\n\tsetnb %0":
- "=q" (ok):"r" (nr),"m" (*(addr)));
+ __asm__ __volatile__("btrl %2,%1\n\tsetnb %0"
+ :"=q" (ok),"=m" (ADDR)
+ :"r" (nr));
return ok;
}
* This routine doesn't need to be atomic, but it's faster to code it
* this way.
*/
-extern inline int test_bit(int nr, int * addr)
+extern inline int test_bit(int nr, void * addr)
{
char ok;
- __asm__ __volatile__("btl %1,%2\n\tsetb %0":
- "=q" (ok):"r" (nr),"m" (*(addr)));
+ __asm__ __volatile__("btl %2,%1\n\tsetb %0"
+ :"=q" (ok)
+ :"m" (ADDR),"r" (nr));
return ok;
}
"pop %es\n\t" \
"iret"
+/*
+ * The "inb" instructions are not needed, but seem to change the timings
+ * a bit - without them it seems that the harddisk driver won't work on
+ * all hardware. Arghh.
+ */
#define ACK_FIRST(mask) \
- "orb $" #mask ",_cache_21\n\t" \
+ "inb $0x21,%al\n\t" \
+ "jmp 1f\n" \
+ "1:\tjmp 1f\n" \
+ "1:\torb $" #mask ",_cache_21\n\t" \
"movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t" \
"jmp 1f\n" \
"outb %al,$0x20\n\t"
#define ACK_SECOND(mask) \
- "orb $" #mask ",_cache_A1\n\t" \
+ "inb $0xA1,%al\n\t" \
+ "jmp 1f\n" \
+ "1:\tjmp 1f\n" \
+ "1:\torb $" #mask ",_cache_A1\n\t" \
"movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t" \
"jmp 1f\n" \
"1:\toutb %al,$0x20\n\t"
#define UNBLK_FIRST(mask) \
- "andb $~(" #mask "),_cache_21\n\t" \
+ "inb $0x21,%al\n\t" \
+ "jmp 1f\n" \
+ "1:\tjmp 1f\n" \
+ "1:\tandb $~(" #mask "),_cache_21\n\t" \
"movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t"
#define UNBLK_SECOND(mask) \
- "andb $~(" #mask "),_cache_A1\n\t" \
+ "inb $0xA1,%al\n\t" \
+ "jmp 1f\n" \
+ "1:\tjmp 1f\n" \
+ "1:\tandb $~(" #mask "),_cache_A1\n\t" \
"movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t"
RESTORE_MOST \
"\n\n.align 4\n" \
"_bad_IRQ" #nr "_interrupt:\n\t" \
- "pushl %eax\n\t" \
+ SAVE_MOST \
ACK_##chip(mask) \
- "popl %eax\n\t" \
- "iret");
+ RESTORE_MOST);
#endif
#define F_WRLCK 1
#define F_UNLCK 2
+/* For bsd flock () */
+#define F_EXLCK 4 /* or 3 */
+#define F_SHLCK 8 /* or 4 */
+
/* Once again - not implemented, but ... */
struct flock {
short l_type;
#define MS_NODEV 4 /* disallow access to device special files */
#define MS_NOEXEC 8 /* disallow program execution */
#define MS_SYNC 16 /* writes are synced at once */
+#define MS_REMOUNT 32 /* alter flags of a mounted FS */
+
+/*
+ * Flags that can be altered by MS_REMOUNT
+ */
+#define MS_RMT_MASK (MS_RDONLY)
+
+/*
+ * Magic mount flag number. Has to be or-ed to the flag values.
+ */
+#define MS_MGC_VAL 0xC0ED0000 /* magic flag number to indicate "new" flags */
+#define MS_MGC_MSK 0xffff0000 /* magic flag number mask */
/*
* Note that read-only etc flags are inode-specific: setting some file-system
* flags just means all the inodes inherit those flags by default. It might be
* possible to overrride it sevelctively if you really wanted to with some
* ioctl() that is not currently implemented.
+ *
+ * Exception: MS_RDONLY is always applied to the entire file system.
*/
-#define IS_RDONLY(inode) ((inode)->i_flags & MS_RDONLY)
+#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
#define HZ 100
-/*
- * This is the maximum nr of tasks - change it if you need to
- */
-#define NR_TASKS 64
+#include <linux/tasks.h>
/*
* User space process size: 3GB. This is hardcoded into a few places,
--- /dev/null
+#ifndef _LINUX_TASKS_H
+#define _LINUX_TASKS_H
+
+/*
+ * This is the maximum nr of tasks - change it if you need to
+ */
+#define NR_TASKS 64
+
+#endif
static int blacklisted(char * response_data){
int i = 0;
+ char * pnt;
for(i=0; 1; i++){
if(blacklist[i].vendor == NULL) return 0;
- if(strncmp(blacklist[i].vendor, &response_data[8],
+ pnt = &response_data[8];
+ while(*pnt && *pnt == ' ') pnt++;
+ if(strncmp(blacklist[i].vendor, pnt,
strlen(blacklist[i].vendor))) continue;
- if(strncmp(blacklist[i].model, &response_data[16],
+ pnt = &response_data[16];
+ while(*pnt && *pnt == ' ') pnt++;
+ if(strncmp(blacklist[i].model, pnt,
strlen(blacklist[i].model))) continue;
return 1;
};
I believe it.
*/
-{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 5, 46, FD},
+{"FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88",5,48, FD},
+{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
{"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
{"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
+{"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
#endif
}
;
static void seagate_reconnect_intr (int unused)
{
int temp;
+ Scsi_Cmnd * SCtmp;
/* enable all other interrupts. */
sti();
hostno, temp);
#endif
if(!SCint) panic("SCint == NULL in seagate");
- SCint->result = temp;
- done_fn (SCint);
+ SCtmp = SCint;
SCint = NULL;
+ SCtmp->result = temp;
+ done_fn (SCtmp);
}
else
printk("done_fn() not defined.\n");
* The seagate_st0x_queue_command() function provides a queued interface
* to the seagate SCSI driver. Basically, it just passes control onto the
* seagate_command() function, after fixing it so that the done_fn()
- * is set to the one passed to the function.
+ * is set to the one passed to the function. We have to be very careful,
+ * because there are some commands on some devices that do not disconnect,
+ * and if we simply call the done_fn when the command is done then another
+ * command is started and queue_command is called again... We end up
+ * overflowing the kernel stack, and this tends not to be such a good idea.
*/
+static int recursion_depth = 0;
+
int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
int result;
+ Scsi_Cmnd * SCtmp;
done_fn = done;
current_target = SCpnt->target;
current_data = SCpnt->request_buffer;
current_bufflen = SCpnt->request_bufflen;
SCint = SCpnt;
-
- result = internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
- SCpnt->request_bufflen,
- CAN_RECONNECT);
- if (msg_byte(result) == DISCONNECT)
- return 0;
- else
- {
- SCpnt->result = result;
- done_fn (SCpnt);
- SCint = NULL;
- return 1;
- }
- }
+ if(recursion_depth) {
+ return 0;
+ };
+ recursion_depth++;
+ do{
+
+ result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
+ SCint->request_bufflen,
+ CAN_RECONNECT);
+ if (msg_byte(result) == DISCONNECT) break;
+ SCtmp = SCint;
+ SCint = NULL;
+ SCtmp->result = result;
+ done_fn (SCtmp);
+ } while(SCint);
+ recursion_depth--;
+ return 0;
+ }
int seagate_st0x_command (Scsi_Cmnd * SCpnt)
{
return mem_start;
}
+void sound_mem_init(void)
+{
+}
+
#ifdef CONFIG_SOUND
#error The Sound Driver not installed.
#endif
tty_termios[dev] = NULL;
kfree_s(tp, sizeof(struct termios));
}
+ if (tty == redirect || o_tty == redirect)
+ redirect = NULL;
free_page((unsigned long) tty);
if (o_tty)
free_page((unsigned long) o_tty);
child->signal = 0;
return 0;
}
- if (!(child->flags & PF_PTRACED) || child->state != TASK_STOPPED)
+ if (!(child->flags & PF_PTRACED))
+ return -ESRCH;
+ if (child->state != TASK_STOPPED && request != PTRACE_DETACH)
return -ESRCH;
if (child->p_pptr != current)
return -ESRCH;
unsigned long high_memory = 0;
+extern void sound_mem_init(void);
+
int nr_free_pages = 0;
unsigned long free_page_list = 0;
/*
mem_map[MAP_NR(start_mem)] = 0;
start_mem += 4096;
}
+ sound_mem_init();
free_page_list = 0;
nr_free_pages = 0;
for (tmp = 0 ; tmp < end_mem ; tmp += 4096) {
*/
-static struct sk_buff *backlog = NULL;
+static volatile struct sk_buff * volatile backlog = NULL;
int
dev_rint(unsigned char *buff, long len, int flags,
struct device * dev)
{
- struct sk_buff *skb=NULL;
+ volatile struct sk_buff *skb=NULL;
unsigned char *to;
int amount;
}
skb->lock = 0;
skb->mem_len = sizeof (*skb) + len;
- skb->mem_addr = skb;
+ skb->mem_addr = (struct sk_buff *)skb;
/* first we copy the packet into a buffer, and save it for later. */
to = (unsigned char *)(skb+1);
cli();
if (backlog == NULL)
{
- skb->prev = skb;
- skb->next = skb;
+ skb->prev = (struct sk_buff *)skb;
+ skb->next = (struct sk_buff *)skb;
backlog = skb;
}
else
{
- skb ->prev = backlog->prev;
- skb->next = backlog;
- skb->next->prev = skb;
- skb->prev->next = skb;
+ skb->prev = backlog->prev;
+ skb->next = (struct sk_buff *)backlog;
+ skb->next->prev = (struct sk_buff *)skb;
+ skb->prev->next = (struct sk_buff *)skb;
}
sti();
void
inet_bh(void *tmp)
{
- struct sk_buff *skb;
+ volatile struct sk_buff *skb;
struct packet_type *ptype;
unsigned short type;
unsigned char flag =0;
- static int in_bh=0;
+ static volatile int in_bh=0;
cli();
if (in_bh != 0)
skb->len -= skb->dev->hard_header_len;
/* convert the type to an ethernet type. */
- type = skb->dev->type_trans (skb, skb->dev);
+ type = skb->dev->type_trans ((struct sk_buff *)skb, skb->dev);
/* if there get to be a lot of types we should changes this to
a bunch of linked lists like we do for ip protocols. */
}
else
{
- skb2 = skb;
+ skb2 = (struct sk_buff *)skb;
flag = 1;
}
if (!flag)
{
PRINTK (("discarding packet type = %X\n", type));
- kfree_skb (skb, FREE_READ);
+ kfree_skb ((struct sk_buff *)skb, FREE_READ);
}
}
in_bh = 0;
{
sk->err = ECONNRESET;
sk->state = TCP_CLOSE;
- sk->state = SHUTDOWN_MASK;
+ sk->shutdown = SHUTDOWN_MASK;
tcp_reset (daddr, saddr, th, sk->prot, opt,dev);
if (!sk->dead)
{
{
sk->err = ECONNREFUSED ;
sk->state = TCP_CLOSE;
- sk->state = SHUTDOWN_MASK;
+ sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead)
{
wake_up (sk->sleep);