Commit 20f1405b authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14b

parent 6da98bdd
VERSION = 0.99 VERSION = 0.99
PATCHLEVEL = 14 PATCHLEVEL = 14
ALPHA = a ALPHA = b
all: Version zImage all: Version zImage
...@@ -149,12 +149,14 @@ init/main.o: $(CONFIGURE) init/main.c ...@@ -149,12 +149,14 @@ init/main.o: $(CONFIGURE) init/main.c
$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $< $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -T 1000 -M boot/head.o init/main.o tools/version.o \ $(LD) $(LDFLAGS) -T 1000 boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \ $(ARCHIVES) \
$(FILESYSTEMS) \ $(FILESYSTEMS) \
$(DRIVERS) \ $(DRIVERS) \
$(LIBS) \ $(LIBS) \
-o tools/system > System.map -o tools/system
nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
sort > System.map
boot/setup: boot/setup.s boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s $(AS86) -o boot/setup.o boot/setup.s
...@@ -187,12 +189,14 @@ zlilo: $(CONFIGURE) zImage ...@@ -187,12 +189,14 @@ zlilo: $(CONFIGURE) zImage
tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -T 100000 -M boot/head.o init/main.o tools/version.o \ $(LD) $(LDFLAGS) -T 100000 boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \ $(ARCHIVES) \
$(FILESYSTEMS) \ $(FILESYSTEMS) \
$(DRIVERS) \ $(DRIVERS) \
$(LIBS) \ $(LIBS) \
-o tools/zSystem > zSystem.map -o tools/zSystem
nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
sort > zSystem.map
fs: dummy fs: dummy
$(MAKE) linuxsubdirs SUBDIRS=fs $(MAKE) linuxsubdirs SUBDIRS=fs
......
Linux kernel release 0.99 patchlevel 13 Linux kernel release 0.99 patchlevel 14
[ Just to show everybody that I have no personal integrity at all, this These are the release notes for linux version 0.99.14. Read them
release is dedicated to Martin Mueller and Sebastian Hetze just because
they wrote the German Linux Anwenderhandbuch. The fact that they sent
me some of the money they made on selling it has nothing at all to do
with the dedication. Oh, no. That would be crass. ]
These are the release notes for linux version 0.99.13. Read them
carefully, as they tell you what's new, explain how to install the carefully, as they tell you what's new, explain how to install the
kernel, and what to do if something goes wrong. kernel, and what to do if something goes wrong.
NOTE! There has been some indication that gcc versions older than 2.4.5
result in bad kernels being built: 2.3.3 will fail even to build the
kernel, and I have at least one report of trouble with a 2.4.3-built
kernel that went away when the kernel was recompiled with 2.4.5.
INSTALLING the kernel: INSTALLING the kernel:
- if you install by patching, you need a *clean* 0.99.12 source tree, - if you install by patching, you need a *clean* 0.99.13 source tree,
which presumably exists in /usr/src/linux. If so, to get the kernel which presumably exists in /usr/src/linux. If so, to get the kernel
patched, just do a patched, just do a
cd /usr/src cd /usr/src
patch -p0 < linux-0.99.patch13 patch -p0 < linux-0.99.patch14
and you should be ok. You may want to remove the backup files (xxx~ and you should be ok. You may want to remove the backup files (xxx~
or xxx.orig), and make sure that there are no failed patches (xxx# or or xxx.orig), and make sure that there are no failed patches (xxx# or
...@@ -32,7 +21,7 @@ INSTALLING the kernel: ...@@ -32,7 +21,7 @@ INSTALLING the kernel:
- If you install the full sources, do a - If you install the full sources, do a
cd /usr/src cd /usr/src
tar xvf linux-0.99.13.tar tar xvf linux-0.99.14.tar
to get it all put in place. to get it all put in place.
......
...@@ -433,12 +433,14 @@ sb_dsp_prepare_for_output (int dev, int bsize, int bcount) ...@@ -433,12 +433,14 @@ sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
dsp_cleanup (); dsp_cleanup ();
dsp_speaker (ON); dsp_speaker (ON);
#ifndef EXCLUDE_SBPRO
if (major == 3) /* SB Pro */ if (major == 3) /* SB Pro */
{ {
sb_mixer_set_stereo(dsp_stereo); sb_mixer_set_stereo(dsp_stereo);
dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
* changes */ * changes */
} }
#endif
return 0; return 0;
} }
......
...@@ -82,7 +82,7 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count) ...@@ -82,7 +82,7 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
int blocksize; int blocksize;
int blocksize_bits, i; int blocksize_bits, i;
unsigned int left; unsigned int left;
int blocks; unsigned int blocks;
int bhrequest, uptodate; int bhrequest, uptodate;
struct buffer_head ** bhb, ** bhe; struct buffer_head ** bhb, ** bhe;
struct buffer_head * buflist[NBUF]; struct buffer_head * buflist[NBUF];
......
...@@ -24,7 +24,7 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -24,7 +24,7 @@ static int fifo_open(struct inode * inode,struct file * filp)
*/ */
filp->f_op = &connecting_fifo_fops; filp->f_op = &connecting_fifo_fops;
if (!PIPE_READERS(*inode)++) if (!PIPE_READERS(*inode)++)
wake_up(&PIPE_WRITE_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) { if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
PIPE_RD_OPENERS(*inode)++; PIPE_RD_OPENERS(*inode)++;
while (!PIPE_WRITERS(*inode)) { while (!PIPE_WRITERS(*inode)) {
...@@ -32,17 +32,17 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -32,17 +32,17 @@ static int fifo_open(struct inode * inode,struct file * filp)
retval = -ERESTARTSYS; retval = -ERESTARTSYS;
break; break;
} }
interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
} }
if (!--PIPE_RD_OPENERS(*inode)) if (!--PIPE_RD_OPENERS(*inode))
wake_up(&PIPE_WRITE_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
} }
while (PIPE_WR_OPENERS(*inode)) while (PIPE_WR_OPENERS(*inode))
interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
if (PIPE_WRITERS(*inode)) if (PIPE_WRITERS(*inode))
filp->f_op = &read_fifo_fops; filp->f_op = &read_fifo_fops;
if (retval && !--PIPE_READERS(*inode)) if (retval && !--PIPE_READERS(*inode))
wake_up(&PIPE_WRITE_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
break; break;
case 2: case 2:
...@@ -57,7 +57,7 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -57,7 +57,7 @@ static int fifo_open(struct inode * inode,struct file * filp)
} }
filp->f_op = &write_fifo_fops; filp->f_op = &write_fifo_fops;
if (!PIPE_WRITERS(*inode)++) if (!PIPE_WRITERS(*inode)++)
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
if (!PIPE_READERS(*inode)) { if (!PIPE_READERS(*inode)) {
PIPE_WR_OPENERS(*inode)++; PIPE_WR_OPENERS(*inode)++;
while (!PIPE_READERS(*inode)) { while (!PIPE_READERS(*inode)) {
...@@ -65,15 +65,15 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -65,15 +65,15 @@ static int fifo_open(struct inode * inode,struct file * filp)
retval = -ERESTARTSYS; retval = -ERESTARTSYS;
break; break;
} }
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
} }
if (!--PIPE_WR_OPENERS(*inode)) if (!--PIPE_WR_OPENERS(*inode))
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
} }
while (PIPE_RD_OPENERS(*inode)) while (PIPE_RD_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
if (retval && !--PIPE_WRITERS(*inode)) if (retval && !--PIPE_WRITERS(*inode))
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
break; break;
case 3: case 3:
...@@ -85,13 +85,13 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -85,13 +85,13 @@ static int fifo_open(struct inode * inode,struct file * filp)
*/ */
filp->f_op = &rdwr_fifo_fops; filp->f_op = &rdwr_fifo_fops;
if (!PIPE_READERS(*inode)++) if (!PIPE_READERS(*inode)++)
wake_up(&PIPE_WRITE_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
while (PIPE_WR_OPENERS(*inode)) while (PIPE_WR_OPENERS(*inode))
interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
if (!PIPE_WRITERS(*inode)++) if (!PIPE_WRITERS(*inode)++)
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
while (PIPE_RD_OPENERS(*inode)) while (PIPE_RD_OPENERS(*inode))
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
break; break;
default: default:
...@@ -106,7 +106,8 @@ static int fifo_open(struct inode * inode,struct file * filp) ...@@ -106,7 +106,8 @@ static int fifo_open(struct inode * inode,struct file * filp)
} }
if (!page) if (!page)
return -ENOMEM; return -ENOMEM;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; PIPE_LOCK(*inode) = 0;
PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
PIPE_BASE(*inode) = (char *) page; PIPE_BASE(*inode) = (char *) page;
return 0; return 0;
} }
...@@ -151,9 +152,10 @@ void init_fifo(struct inode * inode) ...@@ -151,9 +152,10 @@ void init_fifo(struct inode * inode)
{ {
inode->i_op = &fifo_inode_operations; inode->i_op = &fifo_inode_operations;
inode->i_pipe = 1; inode->i_pipe = 1;
PIPE_LOCK(*inode) = 0;
PIPE_BASE(*inode) = NULL; PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL; PIPE_WAIT(*inode) = NULL;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
} }
...@@ -308,10 +308,8 @@ void iput(struct inode * inode) ...@@ -308,10 +308,8 @@ void iput(struct inode * inode)
inode->i_ino, inode->i_mode); inode->i_ino, inode->i_mode);
return; return;
} }
if (inode->i_pipe) { if (inode->i_pipe)
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
wake_up(&PIPE_WRITE_WAIT(*inode));
}
repeat: repeat:
if (inode->i_count>1) { if (inode->i_count>1) {
inode->i_count--; inode->i_count--;
...@@ -403,10 +401,11 @@ struct inode * get_pipe_inode(void) ...@@ -403,10 +401,11 @@ struct inode * get_pipe_inode(void)
} }
inode->i_op = &pipe_inode_operations; inode->i_op = &pipe_inode_operations;
inode->i_count = 2; /* sum of readers/writers */ inode->i_count = 2; /* sum of readers/writers */
PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL; PIPE_WAIT(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
PIPE_LOCK(*inode) = 0;
inode->i_pipe = 1; inode->i_pipe = 1;
inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
inode->i_uid = current->euid; inode->i_uid = current->euid;
......
...@@ -13,33 +13,54 @@ ...@@ -13,33 +13,54 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/termios.h> #include <linux/termios.h>
/* We don't use the head/tail construction any more. Now we use the start/len*/
/* contruction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */
/* Florian Coosmann (FGC) ^ current = 1 */
/* Additionally, we now use locking technique. This prevents race condition */
/* in case of paging and multiple read/write on the same pipe. (FGC) */
static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count) static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
{ {
int chars, size, read = 0; int chars = 0, size = 0, read = 0;
char *pipebuf;
if (!(filp->f_flags & O_NONBLOCK)) if (filp->f_flags & O_NONBLOCK) {
while (!PIPE_SIZE(*inode)) { if (PIPE_LOCK(*inode))
wake_up(& PIPE_WRITE_WAIT(*inode)); return -EAGAIN;
if (!PIPE_WRITERS(*inode)) /* are there any writers? */ if (PIPE_EMPTY(*inode))
if (PIPE_WRITERS(*inode))
return -EAGAIN;
else
return 0;
} else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
if (PIPE_EMPTY(*inode)) {
if (!PIPE_WRITERS(*inode))
return 0; return 0;
}
if (current->signal & ~current->blocked) if (current->signal & ~current->blocked)
return -ERESTARTSYS; return -ERESTARTSYS;
interruptible_sleep_on(& PIPE_READ_WAIT(*inode)); interruptible_sleep_on(&PIPE_WAIT(*inode));
} }
PIPE_LOCK(*inode)++;
while (count>0 && (size = PIPE_SIZE(*inode))) { while (count>0 && (size = PIPE_SIZE(*inode))) {
chars = PAGE_SIZE-PIPE_TAIL(*inode); chars = PIPE_MAX_RCHUNK(*inode);
if (chars > count) if (chars > count)
chars = count; chars = count;
if (chars > size) if (chars > size)
chars = size; chars = size;
memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars );
read += chars; read += chars;
PIPE_TAIL(*inode) += chars; pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
PIPE_TAIL(*inode) &= (PAGE_SIZE-1); PIPE_START(*inode) += chars;
PIPE_START(*inode) &= (PIPE_BUF-1);
PIPE_LEN(*inode) -= chars;
count -= chars; count -= chars;
memcpy_tofs(buf, pipebuf, chars );
buf += chars; buf += chars;
} }
wake_up(& PIPE_WRITE_WAIT(*inode)); PIPE_LOCK(*inode)--;
wake_up(&PIPE_WAIT(*inode));
if (read) if (read)
return read; return read;
if (PIPE_WRITERS(*inode)) if (PIPE_WRITERS(*inode))
...@@ -49,45 +70,47 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c ...@@ -49,45 +70,47 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count) static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
{ {
int chars, size, written = 0; int chars = 0, free = 0, written = 0;
char *pipebuf;
if (!PIPE_READERS(*inode)) { /* no readers */ if (!PIPE_READERS(*inode)) { /* no readers */
send_sig(SIGPIPE,current,0); send_sig(SIGPIPE,current,0);
return -EPIPE; return -EPIPE;
} }
/* if count < PAGE_SIZE, we have to make it atomic */ /* if count <= PIPE_BUF, we have to make it atomic */
if (count < PAGE_SIZE) if (count <= PIPE_BUF)
size = PAGE_SIZE-count; free = count;
else else
size = PAGE_SIZE-1; free = 1; /* can't do it atomically, wait for any free space */
while (count>0) { while (count>0) {
while (PIPE_SIZE(*inode) >= size) { while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
if (!PIPE_READERS(*inode)) { /* no readers */ if (!PIPE_READERS(*inode)) { /* no readers */
send_sig(SIGPIPE,current,0); send_sig(SIGPIPE,current,0);
return written?written:-EPIPE; return written? :-EPIPE;
} }
if (current->signal & ~current->blocked) if (current->signal & ~current->blocked)
return written?written:-ERESTARTSYS; return written? :-ERESTARTSYS;
if (filp->f_flags & O_NONBLOCK) if (filp->f_flags & O_NONBLOCK)
return written?written:-EAGAIN; return written? :-EAGAIN;
else interruptible_sleep_on(&PIPE_WAIT(*inode));
interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
} }
while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) { PIPE_LOCK(*inode)++;
chars = PAGE_SIZE-PIPE_HEAD(*inode); while (count>0 && (free = PIPE_FREE(*inode))) {
chars = PIPE_MAX_WCHUNK(*inode);
if (chars > count) if (chars > count)
chars = count; chars = count;
if (chars > size) if (chars > free)
chars = size; chars = free;
memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars ); pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
written += chars; written += chars;
PIPE_HEAD(*inode) += chars; PIPE_LEN(*inode) += chars;
PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
count -= chars; count -= chars;
memcpy_fromfs(pipebuf, buf, chars );
buf += chars; buf += chars;
} }
wake_up(& PIPE_READ_WAIT(*inode)); PIPE_LOCK(*inode)--;
size = PAGE_SIZE-1; wake_up(&PIPE_WAIT(*inode));
free = 1;
} }
return written; return written;
} }
...@@ -129,12 +152,12 @@ static int pipe_select(struct inode * inode, struct file * filp, int sel_type, s ...@@ -129,12 +152,12 @@ static int pipe_select(struct inode * inode, struct file * filp, int sel_type, s
case SEL_IN: case SEL_IN:
if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode)) if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
return 1; return 1;
select_wait(&PIPE_READ_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_OUT: case SEL_OUT:
if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode)) if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
return 1; return 1;
select_wait(&PIPE_WRITE_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_EX: case SEL_EX:
if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
...@@ -155,12 +178,12 @@ static int fifo_select(struct inode * inode, struct file * filp, int sel_type, s ...@@ -155,12 +178,12 @@ static int fifo_select(struct inode * inode, struct file * filp, int sel_type, s
case SEL_IN: case SEL_IN:
if (!PIPE_EMPTY(*inode)) if (!PIPE_EMPTY(*inode))
return 1; return 1;
select_wait(&PIPE_READ_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_OUT: case SEL_OUT:
if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode)) if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
return 1; return 1;
select_wait(&PIPE_WRITE_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_EX: case SEL_EX:
if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
...@@ -183,10 +206,10 @@ static int connect_read(struct inode * inode, struct file * filp, char * buf, in ...@@ -183,10 +206,10 @@ static int connect_read(struct inode * inode, struct file * filp, char * buf, in
break; break;
if (filp->f_flags & O_NONBLOCK) if (filp->f_flags & O_NONBLOCK)
return -EAGAIN; return -EAGAIN;
wake_up(& PIPE_WRITE_WAIT(*inode)); wake_up(& PIPE_WAIT(*inode));
if (current->signal & ~current->blocked) if (current->signal & ~current->blocked)
return -ERESTARTSYS; return -ERESTARTSYS;
interruptible_sleep_on(& PIPE_READ_WAIT(*inode)); interruptible_sleep_on(& PIPE_WAIT(*inode));
} }
filp->f_op = &read_fifo_fops; filp->f_op = &read_fifo_fops;
return pipe_read(inode,filp,buf,count); return pipe_read(inode,filp,buf,count);
...@@ -200,12 +223,12 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type ...@@ -200,12 +223,12 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type
filp->f_op = &read_fifo_fops; filp->f_op = &read_fifo_fops;
return 1; return 1;
} }
select_wait(&PIPE_READ_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_OUT: case SEL_OUT:
if (!PIPE_FULL(*inode)) if (!PIPE_FULL(*inode))
return 1; return 1;
select_wait(&PIPE_WRITE_WAIT(*inode), wait); select_wait(&PIPE_WAIT(*inode), wait);
return 0; return 0;
case SEL_EX: case SEL_EX:
if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
...@@ -223,21 +246,20 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type ...@@ -223,21 +246,20 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type
static void pipe_read_release(struct inode * inode, struct file * filp) static void pipe_read_release(struct inode * inode, struct file * filp)
{ {
PIPE_READERS(*inode)--; PIPE_READERS(*inode)--;
wake_up(&PIPE_WRITE_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
} }
static void pipe_write_release(struct inode * inode, struct file * filp) static void pipe_write_release(struct inode * inode, struct file * filp)
{ {
PIPE_WRITERS(*inode)--; PIPE_WRITERS(*inode)--;
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
} }
static void pipe_rdwr_release(struct inode * inode, struct file * filp) static void pipe_rdwr_release(struct inode * inode, struct file * filp)
{ {
PIPE_READERS(*inode)--; PIPE_READERS(*inode)--;
PIPE_WRITERS(*inode)--; PIPE_WRITERS(*inode)--;
wake_up(&PIPE_READ_WAIT(*inode)); wake_up(&PIPE_WAIT(*inode));
wake_up(&PIPE_WRITE_WAIT(*inode));
} }
/* /*
......
...@@ -11,7 +11,7 @@ extern unsigned long loops_per_sec; ...@@ -11,7 +11,7 @@ extern unsigned long loops_per_sec;
extern __inline__ void __delay(int loops) extern __inline__ void __delay(int loops)
{ {
__asm__("\n1:\tdecl %0\n\tjns 1b\n": :"a" (loops):"ax"); __asm__(".align 2,0x90\n1:\tdecl %0\n\tjns 1b": :"a" (loops):"ax");
} }
/* /*
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/dirent.h> #include <linux/dirent.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/net.h>
/* /*
* It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
...@@ -177,6 +178,7 @@ struct inode { ...@@ -177,6 +178,7 @@ struct inode {
struct inode * i_hash_next, * i_hash_prev; struct inode * i_hash_next, * i_hash_prev;
struct inode * i_bound_to, * i_bound_by; struct inode * i_bound_to, * i_bound_by;
struct inode * i_mount; struct inode * i_mount;
struct socket * i_socket;
unsigned short i_count; unsigned short i_count;
unsigned short i_flags; unsigned short i_flags;
unsigned char i_lock; unsigned char i_lock;
......
...@@ -124,41 +124,41 @@ extern unsigned short int htons(unsigned short int); ...@@ -124,41 +124,41 @@ extern unsigned short int htons(unsigned short int);
static __inline__ unsigned long int static __inline__ unsigned long int
__ntohl(unsigned long int x) __ntohl(unsigned long int x)
{ {
register unsigned long int tmp __asm__ ("ax") = x; __asm__("xchgb %l0,%h0\n\t" /* swap lower bytes */
__asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap lower bytes */ "rorl $16,%0\n\t" /* swap words */
"rorl $16,%%eax\n\t" /* swap words */ "xchgb %l0,%h0" /* swap higher bytes */
"xchgb %%al,%%ah\n\t" /* swap higher bytes */ :"=q" (x)
: "=a" (tmp) : "a" (tmp) ); : "0" (x));
return(tmp); return x;
} }
static __inline__ unsigned short int static __inline__ unsigned short int
__ntohs(unsigned short int x) __ntohs(unsigned short int x)
{ {
register unsigned short int tmp __asm__ ("ax") = x; __asm__("xchgb %b0,%h0" /* swap bytes */
__asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap bytes */ : "=q" (x)
: "=a" (tmp) : "a" (tmp)); : "0" (x));
return(tmp); return x;
} }
static __inline__ unsigned long int static __inline__ unsigned long int
__htonl(unsigned long int x) __htonl(unsigned long int x)
{ {
register unsigned long int tmp __asm__ ("ax") = x; __asm__("xchgb %l0,%h0\n\t" /* swap lower bytes */
__asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap lower bytes */ "rorl $16,%0\n\t" /* swap words */
"rorl $16,%%eax\n\t" /* swap words */ "xchgb %l0,%h0" /* swap higher bytes */
"xchgb %%al,%%ah\n\t" /* swap higher bytes */ :"=q" (x)
: "=a" (tmp) : "a" (tmp)); : "0" (x));
return(tmp); return x;
} }
static __inline__ unsigned short int static __inline__ unsigned short int
__htons(unsigned short int x) __htons(unsigned short int x)
{ {
register unsigned short int tmp __asm__ ("ax") = x; __asm__("xchgb %b0,%h0" /* swap bytes */
__asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap bytes */ : "=q" (x)
: "=a" (tmp) : "a" (tmp)); : "0" (x));
return(tmp); return x;
} }
#ifdef __OPTIMIZE__ #ifdef __OPTIMIZE__
......
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
#define MAX_INPUT 255 /* size of the type-ahead buffer */ #define MAX_INPUT 255 /* size of the type-ahead buffer */
#define NAME_MAX 255 /* # chars in a file name */ #define NAME_MAX 255 /* # chars in a file name */
#define PATH_MAX 1024 /* # chars in a path name */ #define PATH_MAX 1024 /* # chars in a path name */
#define PIPE_BUF 4095 /* # bytes in atomic write to a pipe */ #define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */
#endif #endif
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/socket.h>
#define NSOCKETS 128 /* should be dynamic, later... */ #define NSOCKETS 128 /* should be dynamic, later... */
...@@ -75,13 +76,10 @@ struct socket { ...@@ -75,13 +76,10 @@ struct socket {
struct socket *iconn; /* incomplete client conn.s */ struct socket *iconn; /* incomplete client conn.s */
struct socket *next; struct socket *next;
struct wait_queue **wait; /* ptr to place to wait on */ struct wait_queue **wait; /* ptr to place to wait on */
void *dummy; struct inode *inode;
}; };
#define SOCK_INODE(S) ((struct inode *)(S)->dummy) #define SOCK_INODE(S) ((S)->inode)
extern struct socket sockets[NSOCKETS];
#define last_socket (sockets + NSOCKETS - 1)
struct proto_ops { struct proto_ops {
int family; int family;
......
...@@ -2,28 +2,34 @@ ...@@ -2,28 +2,34 @@
#define _LINUX_PIPE_FS_I_H #define _LINUX_PIPE_FS_I_H
struct pipe_inode_info { struct pipe_inode_info {
struct wait_queue * read_wait; struct wait_queue * wait;
struct wait_queue * write_wait;
char * base; char * base;
unsigned int head; unsigned int start;
unsigned int tail; unsigned int len;
unsigned int lock;
unsigned int rd_openers; unsigned int rd_openers;
unsigned int wr_openers; unsigned int wr_openers;
unsigned int readers; unsigned int readers;
unsigned int writers; unsigned int writers;
}; };
#define PIPE_READ_WAIT(inode) ((inode).u.pipe_i.read_wait) #define PIPE_WAIT(inode) ((inode).u.pipe_i.wait)
#define PIPE_WRITE_WAIT(inode) ((inode).u.pipe_i.write_wait)
#define PIPE_BASE(inode) ((inode).u.pipe_i.base) #define PIPE_BASE(inode) ((inode).u.pipe_i.base)
#define PIPE_HEAD(inode) ((inode).u.pipe_i.head) #define PIPE_START(inode) ((inode).u.pipe_i.start)
#define PIPE_TAIL(inode) ((inode).u.pipe_i.tail) #define PIPE_LEN(inode) ((inode).u.pipe_i.len)
#define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers) #define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers)
#define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers) #define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers)
#define PIPE_READERS(inode) ((inode).u.pipe_i.readers) #define PIPE_READERS(inode) ((inode).u.pipe_i.readers)
#define PIPE_WRITERS(inode) ((inode).u.pipe_i.writers) #define PIPE_WRITERS(inode) ((inode).u.pipe_i.writers)
#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1)) #define PIPE_LOCK(inode) ((inode).u.pipe_i.lock)
#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode)) #define PIPE_SIZE(inode) PIPE_LEN(inode)
#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
#define PIPE_EMPTY(inode) (PIPE_SIZE(inode)==0)
#define PIPE_FULL(inode) (PIPE_SIZE(inode)==PIPE_BUF)
#define PIPE_FREE(inode) (PIPE_BUF - PIPE_LEN(inode))
#define PIPE_END(inode) ((PIPE_START(inode)+PIPE_LEN(inode))&\
(PIPE_BUF-1))
#define PIPE_MAX_RCHUNK(inode) (PIPE_BUF - PIPE_START(inode))
#define PIPE_MAX_WCHUNK(inode) (PIPE_BUF - PIPE_END(inode))
#endif #endif
...@@ -269,7 +269,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -269,7 +269,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if (!(child->flags & PF_PTRACED)) if (!(child->flags & PF_PTRACED))
return -ESRCH; return -ESRCH;
if (child->state != TASK_STOPPED) { if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL && request != PTRACE_DETACH) if (request != PTRACE_KILL)
return -ESRCH; return -ESRCH;
} }
if (child->p_pptr != current) if (child->p_pptr != current)
......
...@@ -425,19 +425,22 @@ static inline unsigned short ...@@ -425,19 +425,22 @@ static inline unsigned short
ip_fast_csum(unsigned char * buff, int wlen) ip_fast_csum(unsigned char * buff, int wlen)
{ {
unsigned long sum = 0; unsigned long sum = 0;
__asm__("\t clc\n"
"1:\n" if (wlen)
"\t lodsl\n" __asm__("clc\n"
"\t adcl %%eax, %%ebx\n" "1:\t"
"\t loop 1b\n" "lodsl\n\t"
"\t adcl $0, %%ebx\n" "adcl %%eax, %0\n\t"
"\t movl %%ebx, %%eax\n" "decl %2\n\t"
"\t shrl $16, %%eax\n" "jne 1b\n\t"
"\t addw %%ax, %%bx\n" "adcl $0, %0\n\t"
"\t adcw $0, %%bx\n" "movl %0, %%eax\n\t"
: "=b" (sum) , "=S" (buff) "shrl $16, %%eax\n\t"
: "0" (sum), "c" (wlen) ,"1" (buff) "addw %%ax, %w0\n\t"
: "ax", "cx", "si", "bx" ); "adcw $0, %w0"
: "=r" (sum), "=S" (buff), "=r" (wlen)
: "0" (sum), "1" (buff), "2" (wlen)
: "ax" );
return (~sum) & 0xffff; return (~sum) & 0xffff;
} }
...@@ -452,33 +455,33 @@ ip_compute_csum(unsigned char * buff, int len) ...@@ -452,33 +455,33 @@ ip_compute_csum(unsigned char * buff, int len)
/* Do the first multiple of 4 bytes and convert to 16 bits. */ /* Do the first multiple of 4 bytes and convert to 16 bits. */
if (len > 3) { if (len > 3) {
__asm__("\t clc\n" __asm__("clc\n"
"1:\n" "1:\t"
"\t lodsl\n" "lodsl\n\t"
"\t adcl %%eax, %%ebx\n" "adcl %%eax, %%ebx\n\t"
"\t loop 1b\n" "loop 1b\n\t"
"\t adcl $0, %%ebx\n" "adcl $0, %%ebx\n\t"
"\t movl %%ebx, %%eax\n" "movl %%ebx, %%eax\n\t"
"\t shrl $16, %%eax\n" "shrl $16, %%eax\n\t"
"\t addw %%ax, %%bx\n" "addw %%ax, %%bx\n\t"
"\t adcw $0, %%bx\n" "adcw $0, %%bx"
: "=b" (sum) , "=S" (buff) : "=b" (sum) , "=S" (buff)
: "0" (sum), "c" (len >> 2) ,"1" (buff) : "0" (sum), "c" (len >> 2) ,"1" (buff)
: "ax", "cx", "si", "bx" ); : "ax", "cx", "si", "bx" );
} }
if (len & 2) { if (len & 2) {
__asm__("\t lodsw\n" __asm__("lodsw\n\t"
"\t addw %%ax, %%bx\n" "addw %%ax, %%bx\n\t"
"\t adcw $0, %%bx\n" "adcw $0, %%bx"
: "=b" (sum), "=S" (buff) : "=b" (sum), "=S" (buff)
: "0" (sum), "1" (buff) : "0" (sum), "1" (buff)
: "bx", "ax", "si"); : "bx", "ax", "si");
} }
if (len & 1) { if (len & 1) {
__asm__("\t lodsb\n" __asm__("lodsb\n\t"
"\t movb $0, %%ah\n" "movb $0, %%ah\n\t"
"\t addw %%ax, %%bx\n" "addw %%ax, %%bx\n\t"
"\t adcw $0, %%bx\n" "adcw $0, %%bx"
: "=b" (sum), "=S" (buff) : "=b" (sum), "=S" (buff)
: "0" (sum), "1" (buff) : "0" (sum), "1" (buff)
: "bx", "ax", "si"); : "bx", "ax", "si");
......
...@@ -69,11 +69,13 @@ static struct file_operations socket_file_ops = { ...@@ -69,11 +69,13 @@ static struct file_operations socket_file_ops = {
NULL, /* no special open code... */ NULL, /* no special open code... */
sock_close sock_close
}; };
struct socket sockets[NSOCKETS];
static struct socket sockets[NSOCKETS];
static struct wait_queue *socket_wait_free = NULL; static struct wait_queue *socket_wait_free = NULL;
static struct proto_ops *pops[NPROTO]; static struct proto_ops *pops[NPROTO];
static int net_debug = 0; static int net_debug = 0;
#define last_socket (sockets + NSOCKETS - 1)
#ifdef SOCK_DEBUG #ifdef SOCK_DEBUG
/* Module debugging. */ /* Module debugging. */
...@@ -138,8 +140,16 @@ socki_lookup(struct inode *inode) ...@@ -138,8 +140,16 @@ socki_lookup(struct inode *inode)
{ {
struct socket *sock; struct socket *sock;
if ((sock = inode->i_socket) != NULL) {
if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
return sock;
printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
}
for (sock = sockets; sock <= last_socket; ++sock) for (sock = sockets; sock <= last_socket; ++sock)
if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) return(sock); if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) {
printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n");
return(sock);
}
return(NULL); return(NULL);
} }
...@@ -187,6 +197,7 @@ sock_alloc(int wait) ...@@ -187,6 +197,7 @@ sock_alloc(int wait)
SOCK_INODE(sock)->i_mode = S_IFSOCK; SOCK_INODE(sock)->i_mode = S_IFSOCK;
SOCK_INODE(sock)->i_uid = current->euid; SOCK_INODE(sock)->i_uid = current->euid;
SOCK_INODE(sock)->i_gid = current->egid; SOCK_INODE(sock)->i_gid = current->egid;
SOCK_INODE(sock)->i_socket = sock;
sock->wait = &SOCK_INODE(sock)->i_wait; sock->wait = &SOCK_INODE(sock)->i_wait;
DPRINTF((net_debug, DPRINTF((net_debug,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment