# KEYBOARD = -DKBD_SG_LATIN1 -DKBDFLAGS=0x9F
# KEYBOARD = -DKDB_NO
+#
+# comment this line to turn off keyboard NUM LOCK
+#
+
+NUM_LOCK = -DKBD_NUMERIC_LOCK
+
#
# comment this line if you don't want the emulation-code
#
AS =as
LD =ld
HOSTCC =gcc -static
-CC =gcc -nostdinc -I$(KERNELHDRS) $(PROFILING)
+CC =gcc -DKERNEL
MAKE =make
CPP =$(CC) -E
AR =ar
Version:
@./makever.sh
- @echo \#define UTS_RELEASE \"0.97.pl4-`cat .version`\" > tools/version.h
+ @echo \#define UTS_RELEASE \"0.97.pl5-`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
+ [ NOTE! As of linux-0.97.pl5, the linux kernel include-files have
+ finally been totally integrated with the normal headers. That means
+ no more "-nostdinc -I$(KERNELHDRS)" in the Makefiles etc, but it
+ also means that you /have/ to have the correct /usr/include/linux
+ and ../asm symlinks. See "Basic configuration 2" ]
+
VERY QUICK AND DIRTY README
by Lars Wirzenius
will be slightly bigger. It is probably not worth it to recompile the
kernel just to get rid of the emulation.
-[ Linus' note1: if you have a correctly installed gcc-2.2.2d, you can
- also remove the "-nostdinc -I$(KERNELHDRS)" thing from the main
- Makefile CC definition. But it doesn't hurt to have it, as long as
- KERNELHDRS is correctly defined ]
-
-2. Create a symlink:
+2. Create the symlinks:
- ln -s /usr/src/linux/include/linux /usr/include/linux
+ ln -fs /usr/src/linux/include/linux /usr/include/linux
+ ln -fs /usr/src/linux/include/asm /usr/include/asm
-This is required so that tools/build.c will compile and link (it
-requires the standard versions of headers instead of the kernel specific
-headers, as it is a normal application, not kernel code).
+This is required so that the linux sources will correctly find their
+header files - it is also used by the normal user-level header files to
+get some system-specific information.
-[ Linus' note2: This is automatically done by the gcc-2.2.2d
+[ Linus' note2: This is automatically done by the gcc-2.2.2d and newer
installation script, so if you have the new compiler, you should
- already have this link ]
+ already have these links ]
* Things you may want to get rid of
mov ax,#0xc000
mov es,ax
lea si,msg1
- call prtstr
#ifndef SVGA_MODE
+ call prtstr
flush: in al,#0x60 ! Flush the keyboard buffer
cmp al,#0x82
jb nokey
lea cx,selmod
jmp cx
nogen: cld
+ lea si,idoakvga
+ mov di,#0x08
+ mov cx,#0x08
+ repe
+ cmpsb
+ jne nooak
+ lea si,dscoakvga
+ lea di,mooakvga
+ lea cx,selmod
+ jmp cx
+nooak: cld
lea si,idparadise ! Check Paradise 'clues'
mov di,#0x7d
mov cx,#0x04
idcandt: .byte 0xa5
idgenoa: .byte 0x77, 0x00, 0x66, 0x99
idparadise: .ascii "VGA="
+idoakvga: .ascii "OAK VGA "
! Manufacturer: Numofmodes: Mode:
motrident: .byte 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
motseng: .byte 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22
movideo7: .byte 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
+mooakvga: .byte 0x05, 0x00, 0x07, 0x4f, 0x50, 0x51
! msb = Cols lsb = Rows:
dsctrident: .word 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
dsctseng: .word 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
dscvideo7: .word 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
+dscoakvga: .word 0x2819, 0x5019, 0x843c, 0x8419, 0x842C
.text
endtext:
depend dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+ $(CPP) -M *.c >> tmp_make
cp tmp_make Makefile
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
#include <asm/system.h>
#include <asm/io.h>
+#ifdef CONFIG_BLK_DEV_SR
+extern int check_cdrom_media_change(int, int);
+#endif
+
static struct buffer_head * hash_table[NR_HASH];
static struct buffer_head * free_list = NULL;
static struct buffer_head * unused_list = NULL;
int i;
struct buffer_head * bh;
- if (MAJOR(dev) != 2)
- return;
- if (!(bh = getblk(dev,0,1024)))
- return;
- i = floppy_change(bh);
- brelse(bh);
- if (!i)
+ switch(MAJOR(dev)){
+ case 2: /* floppy disc */
+ if (!(bh = getblk(dev,0,1024)))
+ return;
+ i = floppy_change(bh);
+ brelse(bh);
+ break;
+
+#ifdef CONFIG_BLK_DEV_SR
+ case 11: /* CDROM */
+ i = check_cdrom_media_change(dev, 0);
+ if (i) printk("Flushing buffers and inodes for CDROM\n");
+ break;
+#endif
+
+ default:
return;
+ };
+
+ if (!i) return;
+
for (i=0 ; i<NR_SUPER ; i++)
if (super_block[i].s_dev == dev)
put_super(super_block[i].s_dev);
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
- ext_bmap, /* bmap */
- ext_truncate /* truncate */
+ NULL, /* bmap */
+ NULL /* truncate */
};
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
- ext_bmap, /* bmap */
- ext_truncate /* truncate */
+ NULL, /* bmap */
+ NULL /* truncate */
};
ext_rename, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
- ext_bmap, /* bmap */
+ NULL, /* bmap */
ext_truncate /* truncate */
};
static int ext_readdir(struct inode * inode, struct file * filp,
struct dirent * dirent, int count)
{
- unsigned int block,offset,i;
+ unsigned int offset,i;
char c;
struct buffer_head * bh;
struct ext_dir_entry * de;
return -EBADF;
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023;
- block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
- if (!block || !(bh = bread(inode->i_dev, block, BLOCK_SIZE))) {
+ bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
+ if (!bh) {
filp->f_pos += 1024-offset;
continue;
}
#include <linux/fs.h>
#include <linux/ext_fs.h>
+static inline void wait_on_buffer(struct buffer_head * bh)
+{
+ cli();
+ while (bh->b_lock)
+ sleep_on(&bh->b_wait);
+ sti();
+}
+
static int ext_file_read(struct inode *, struct file *, char *, int);
static int ext_file_write(struct inode *, struct file *, char *, int);
ext_truncate /* truncate */
};
-static inline void wait_on_buffer(struct buffer_head * bh)
-{
- cli();
- while (bh->b_lock)
- sleep_on(&bh->b_wait);
- sti();
-}
-
static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
- int read,left,chars,nr;
+ int read,left,chars;
int block, blocks, offset;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * buflist[NBUF];
do {
if (blocks) {
--blocks;
- if (nr = ext_bmap(inode,block++)) {
- *bhb = getblk(inode->i_dev, nr, BLOCK_SIZE);
- if (!(*bhb)->b_uptodate)
- ll_rw_block(READ,*bhb);
- } else
- *bhb = NULL;
+ *bhb = ext_getblk(inode,block++,0);
+ if (*bhb && !(*bhb)->b_uptodate)
+ ll_rw_block(READ,*bhb);
if (++bhb == &buflist[NBUF])
bhb = buflist;
static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count)
{
off_t pos;
- int written,block,c;
+ int written,c;
struct buffer_head * bh;
char * p;
pos = filp->f_pos;
written = 0;
while (written<count) {
- if (!(block = ext_create_block(inode,pos/BLOCK_SIZE))) {
+ bh = ext_getblk(inode,pos/BLOCK_SIZE,1);
+ if (!bh) {
if (!written)
written = -ENOSPC;
break;
c = BLOCK_SIZE - (pos % BLOCK_SIZE);
if (c > count-written)
c = count-written;
- if (c == BLOCK_SIZE)
- bh = getblk(inode->i_dev, block, BLOCK_SIZE);
- else
- bh = bread(inode->i_dev, block, BLOCK_SIZE);
- if (!bh) {
- if (!written)
- written = -EIO;
- break;
+ if (c != BLOCK_SIZE && !bh->b_uptodate) {
+ ll_rw_block(READ,bh);
+ wait_on_buffer(bh);
+ if (!bh->b_uptodate) {
+ brelse(bh);
+ if (!written)
+ written = -EIO;
+ break;
+ }
}
p = (pos % BLOCK_SIZE) + bh->b_data;
pos += c;
"stosl" \
::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
-int ext_free_block(int dev, int block)
+void ext_free_block(int dev, int block)
{
struct super_block * sb;
struct buffer_head * bh;
if (!(sb = get_super(dev)))
panic("trying to free block on nonexistent device");
lock_super (sb);
- if (block < sb->u.ext_sb.s_firstdatazone
- || block >= sb->u.ext_sb.s_nzones)
- panic("trying to free block not in datazone");
+ if (block < sb->u.ext_sb.s_firstdatazone ||
+ block >= sb->u.ext_sb.s_nzones) {
+ printk("trying to free block not in datazone\n");
+ return;
+ }
bh = get_hash_table(dev, block, sb->s_blocksize);
- if (bh) {
- if (bh->b_count > 1) {
- brelse(bh);
- free_super (sb);
- return 0;
- }
+ if (bh)
bh->b_dirt=0;
- bh->b_uptodate=0;
- if (bh->b_count)
- brelse(bh);
- }
+ brelse(bh);
if (sb->u.ext_sb.s_firstfreeblock)
efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
if (!sb->u.ext_sb.s_firstfreeblock || efb->count == 254) {
sb->s_dirt = 1;
sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
free_super (sb);
- return 1;
+ return;
}
int ext_new_block(int dev)
int sync_dev(int dev);
+static inline void wait_on_buffer(struct buffer_head * bh)
+{
+ cli();
+ while (bh->b_lock)
+ sleep_on(&bh->b_wait);
+ sti();
+}
+
void ext_put_inode(struct inode *inode)
{
inode->i_size = 0;
/* Don't know what value to put in buf->f_fsid */
}
-static int _ext_bmap(struct inode * inode,int block,int create)
+#define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
+
+static int block_bmap(struct buffer_head * bh, int nr)
+{
+ int tmp;
+
+ if (!bh)
+ return 0;
+ tmp = ((unsigned long *) bh->b_data)[nr];
+ brelse(bh);
+ return tmp;
+}
+
+int ext_bmap(struct inode * inode,int block)
{
- struct buffer_head * bh;
int i;
if (block<0) {
- printk("_ext_bmap: block<0");
+ printk("ext_bmap: block<0");
return 0;
}
if (block >= 9+256+256*256+256*256*256) {
- printk("_ext_bmap: block>big");
+ printk("ext_bmap: block>big");
return 0;
}
- if (block<9) {
- if (create && !inode->i_data[block])
- if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
- inode->i_ctime=CURRENT_TIME;
- inode->i_dirt=1;
- }
- return inode->i_data[block];
- }
+ if (block<9)
+ return inode_bmap(inode,block);
block -= 9;
if (block<256) {
- if (create && !inode->i_data[9])
- if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
- inode->i_dirt=1;
- inode->i_ctime=CURRENT_TIME;
- }
- if (!inode->i_data[9])
- return 0;
- if (!(bh = bread(inode->i_dev, inode->i_data[9], BLOCK_SIZE)))
+ i = inode_bmap(inode,9);
+ if (!i)
return 0;
- i = ((unsigned long *) (bh->b_data))[block];
- if (create && !i)
- if (i=ext_new_block(inode->i_dev)) {
- ((unsigned long *) (bh->b_data))[block]=i;
- bh->b_dirt=1;
- }
- brelse(bh);
- return i;
+ return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
}
block -= 256;
if (block<256*256) {
- if (create && !inode->i_data[10])
- if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
- inode->i_dirt=1;
- inode->i_ctime=CURRENT_TIME;
- }
- if (!inode->i_data[10])
- return 0;
- if (!(bh=bread(inode->i_dev, inode->i_data[10], BLOCK_SIZE)))
- return 0;
- i = ((unsigned long *)bh->b_data)[block>>8];
- if (create && !i)
- if (i=ext_new_block(inode->i_dev)) {
- ((unsigned long *) (bh->b_data))[block>>8]=i;
- bh->b_dirt=1;
- }
- brelse(bh);
+ i = inode_bmap(inode,10);
if (!i)
return 0;
- if (!(bh=bread(inode->i_dev, i, BLOCK_SIZE)))
+ i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
+ if (!i)
return 0;
- i = ((unsigned long *)bh->b_data)[block&255];
- if (create && !i)
- if (i=ext_new_block(inode->i_dev)) {
- ((unsigned long *) (bh->b_data))[block&255]=i;
- bh->b_dirt=1;
- }
- brelse(bh);
- return i;
+ return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
}
- if (create && !inode->i_data[11])
- if (inode->i_data[11] = ext_new_block(inode->i_dev)) {
- inode->i_dirt = 1;
- inode->i_ctime = CURRENT_TIME;
- }
- if (!inode->i_data[11])
- return 0;
- if (!(bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE)))
- return 0;
- i = ((unsigned long *) bh->b_data)[block >> 16];
- if (create && !i)
- if (i = ext_new_block(inode->i_dev)) {
- ((unsigned long *) bh->b_data)[block >> 16] = i;
- bh->b_dirt = 1;
- }
- brelse (bh);
+ block -= 256*256;
+ i = inode_bmap(inode,11);
if (!i)
return 0;
- if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
- return 0;
- i = ((unsigned long *) bh->b_data)[(block >> 8) & 255];
- if (create && !i)
- if (i = ext_new_block(inode->i_dev)) {
- ((unsigned long *) bh->b_data)[(block >> 8) & 255] = i;
- bh->b_dirt = 1;
- }
- brelse (bh);
+ i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
if (!i)
return 0;
- if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
+ i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
+ if (!i)
return 0;
- i = ((unsigned long *) bh->b_data)[block & 255];
- if (create && !i)
- if (i = ext_new_block(inode->i_dev)) {
- ((unsigned long *) bh->b_data)[block & 255] = i;
- bh->b_dirt = 1;
+ return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
+}
+
+static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
+{
+ int tmp;
+ unsigned long * p;
+ struct buffer_head * result;
+
+ p = inode->u.ext_i.i_data + nr;
+repeat:
+ tmp = *p;
+ if (tmp) {
+ result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
+ if (tmp == *p)
+ return result;
+ brelse(result);
+ goto repeat;
+ }
+ if (!create)
+ return NULL;
+ tmp = ext_new_block(inode->i_dev);
+ if (!tmp)
+ return NULL;
+ result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
+ if (*p) {
+ ext_free_block(inode->i_dev,tmp);
+ brelse(result);
+ goto repeat;
+ }
+ *p = tmp;
+ inode->i_ctime = CURRENT_TIME;
+ inode->i_dirt = 1;
+ return result;
+}
+
+static struct buffer_head * block_getblk(struct buffer_head * bh, int nr, int create)
+{
+ int tmp;
+ unsigned long * p;
+ struct buffer_head * result;
+
+ if (!bh)
+ return NULL;
+ if (!bh->b_uptodate) {
+ ll_rw_block(READ,bh);
+ wait_on_buffer(bh);
+ if (!bh->b_uptodate) {
+ brelse(bh);
+ return NULL;
}
- brelse (bh);
- return i;
-
- printk("ext_bmap: triple indirection not yet implemented\n");
- return 0;
+ }
+ p = nr + (unsigned long *) bh->b_data;
+repeat:
+ tmp = *p;
+ if (tmp) {
+ result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
+ if (tmp == *p) {
+ brelse(bh);
+ return result;
+ }
+ brelse(result);
+ goto repeat;
+ }
+ if (!create) {
+ brelse(bh);
+ return NULL;
+ }
+ tmp = ext_new_block(bh->b_dev);
+ if (!tmp) {
+ brelse(bh);
+ return NULL;
+ }
+ result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
+ if (*p) {
+ ext_free_block(bh->b_dev,tmp);
+ brelse(result);
+ goto repeat;
+ }
+ *p = tmp;
+ bh->b_dirt = 1;
+ brelse(bh);
+ return result;
}
-int ext_bmap(struct inode * inode,int block)
+struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
{
- return _ext_bmap(inode,block,0);
+ struct buffer_head * bh;
+
+ if (block<0) {
+ printk("ext_getblk: block<0\n");
+ return NULL;
+ }
+ if (block >= 9+256+256*256+256*256*256) {
+ printk("ext_getblk: block>big\n");
+ return NULL;
+ }
+ if (block<9)
+ return inode_getblk(inode,block,create);
+ block -= 9;
+ if (block<256) {
+ bh = inode_getblk(inode,9,create);
+ return block_getblk(bh,block,create);
+ }
+ block -= 256;
+ if (block<256*256) {
+ bh = inode_getblk(inode,10,create);
+ bh = block_getblk(bh,block>>8,create);
+ return block_getblk(bh,block & 255,create);
+ }
+ block -= 256*256;
+ bh = inode_getblk(inode,11,create);
+ bh = block_getblk(bh,block>>16,create);
+ bh = block_getblk(bh,(block>>8) & 255,create);
+ return block_getblk(bh,block & 255,create);
}
-int ext_create_block(struct inode * inode, int block)
+struct buffer_head * ext_bread(struct inode * inode, int block, int create)
{
- return _ext_bmap(inode,block,1);
+ struct buffer_head * bh;
+
+ bh = ext_getblk(inode,block,create);
+ if (!bh || bh->b_uptodate)
+ return bh;
+ ll_rw_block(READ,bh);
+ wait_on_buffer(bh);
+ if (bh->b_uptodate)
+ return bh;
+ brelse(bh);
+ return NULL;
}
void ext_read_inode(struct inode * inode)
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = raw_inode->i_zone[0];
else for (block = 0; block < 12; block++)
- inode->i_data[block] = raw_inode->i_zone[block];
+ inode->u.ext_i.i_data[block] = raw_inode->i_zone[block];
brelse(bh);
inode->i_op = NULL;
if (S_ISREG(inode->i_mode))
inode->i_op = &ext_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &ext_fifo_inode_operations;
- inode->i_size = 0;
inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_zone[0] = inode->i_rdev;
else for (block = 0; block < 12; block++)
- raw_inode->i_zone[block] = inode->i_data[block];
+ raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
bh->b_dirt=1;
inode->i_dirt=0;
brelse(bh);
#include <asm/segment.h>
-#include <const.h>
-
/*
* comment out this line if you want names > EXT_NAME_LEN chars to be
* truncated. Else they will be disallowed.
const char * name, int namelen, struct ext_dir_entry ** res_dir,
struct ext_dir_entry ** prev_dir, struct ext_dir_entry ** next_dir)
{
- int block;
long offset;
struct buffer_head * bh;
struct ext_dir_entry * de;
if (namelen > EXT_NAME_LEN)
namelen = EXT_NAME_LEN;
#endif
- if (!(block = dir->i_data[0]))
- return NULL;
- if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+ bh = ext_bread(dir,0,0);
+ if (!bh)
return NULL;
if (prev_dir)
*prev_dir = NULL;
if ((char *)de >= BLOCK_SIZE+bh->b_data) {
brelse(bh);
bh = NULL;
- if (!(block = ext_bmap(dir,offset>>BLOCK_SIZE_BITS)) ||
- !(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
+ bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,0);
+ if (!bh)
continue;
- }
de = (struct ext_dir_entry *) bh->b_data;
if (prev_dir)
*prev_dir = NULL;
static struct buffer_head * ext_add_entry(struct inode * dir,
const char * name, int namelen, struct ext_dir_entry ** res_dir)
{
- int block,i;
+ int i;
long offset;
unsigned short rec_len;
struct buffer_head * bh;
#endif
if (!namelen)
return NULL;
- if (!(block = dir->i_data[0]))
- return NULL;
- if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+ bh = ext_bread(dir,0,0);
+ if (!bh)
return NULL;
rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD;
offset = 0;
#endif
brelse(bh);
bh = NULL;
- block = ext_create_block(dir,offset>>BLOCK_SIZE_BITS);
- if (!block)
+ bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,1);
+ if (!bh)
return NULL;
- if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
- offset += BLOCK_SIZE;
- continue;
- }
de = (struct ext_dir_entry *) bh->b_data;
}
if (offset >= dir->i_size) {
}
brelse (bh);
bh = NULL;
- block = ext_create_block (dir,offset>>BLOCK_SIZE_BITS);
#ifdef EXTFS_DEBUG
printk ("ext_add_entry : creating next block\n");
#endif
- if (!block)
- return NULL;
- if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+ bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,1);
+ if (!bh)
return NULL; /* Other thing to do ??? */
de = (struct ext_dir_entry *) bh->b_data;
}
inode->i_op = &ext_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &ext_fifo_inode_operations;
- inode->i_size = 0;
inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
- 2 bytes for the name length
- 8 bytes for the name */
inode->i_mtime = inode->i_atime = CURRENT_TIME;
- if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+ dir_block = ext_bread(inode,0,1);
+ if (!dir_block) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
iput(inode);
return -ENOSPC;
}
- inode->i_dirt = 1;
- if (!(dir_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
- iput(dir);
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- return -EIO;
- }
de = (struct ext_dir_entry *) dir_block->b_data;
de->inode=inode->i_ino;
de->rec_len=16;
inode->i_nlink = 2;
dir_block->b_dirt = 1;
brelse(dir_block);
- inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
inode->i_dirt = 1;
bh = ext_add_entry(dir,name,len,&de);
if (!bh) {
*/
static int empty_dir(struct inode * inode)
{
- int block;
unsigned long offset;
struct buffer_head * bh;
struct ext_dir_entry * de, * de1;
- if (inode->i_size < 2 * 12 || !inode->i_data[0] ||
- !(bh=bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
+ if (inode->i_size < 2 * 12 || !(bh = ext_bread(inode,0,0))) {
printk("warning - bad directory on dev %04x\n",inode->i_dev);
return 1;
}
while (offset < inode->i_size ) {
if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
brelse(bh);
- block = ext_bmap(inode, offset >> BLOCK_SIZE_BITS);
- if (!block) {
+ bh = ext_bread(inode, offset >> BLOCK_SIZE_BITS,1);
+ if (!bh) {
offset += BLOCK_SIZE;
continue;
}
- if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
- return 0;
de = (struct ext_dir_entry *) bh->b_data;
}
if (de->inode) {
}
inode->i_mode = S_IFLNK | 0777;
inode->i_op = &ext_symlink_inode_operations;
- if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+ name_block = ext_bread(inode,0,1);
+ if (!name_block) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
iput(inode);
return -ENOSPC;
}
- inode->i_dirt = 1;
- if (!(name_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
- iput(dir);
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- return -EIO;
- }
i = 0;
while (i < 1023 && (c=get_fs_byte(symname++)))
name_block->b_data[i++] = c;
if (subdir(new_dir, old_inode))
goto end_rename;
retval = -EIO;
- if (!old_inode->i_data[0])
- goto end_rename;
- if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0], BLOCK_SIZE)))
+ dir_bh = ext_bread(old_inode,0,0);
+ if (!dir_bh)
goto end_rename;
if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
goto end_rename;
unsigned short fs;
struct buffer_head * bh;
+ *res_inode = NULL;
if (!dir) {
dir = current->root;
dir->i_count++;
}
if (!inode) {
iput(dir);
- *res_inode = NULL;
return -ENOENT;
}
if (!S_ISLNK(inode->i_mode)) {
*res_inode = inode;
return 0;
}
- __asm__("mov %%fs,%0":"=r" (fs));
- if ((current->link_count > 5) || !inode->i_data[0] ||
- !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
+ if (current->link_count > 5) {
iput(dir);
iput(inode);
- *res_inode = NULL;
return -ELOOP;
}
+ if (!(bh = ext_bread(inode, 0, 0))) {
+ iput(inode);
+ iput(dir);
+ return -EIO;
+ }
iput(inode);
+ __asm__("mov %%fs,%0":"=r" (fs));
__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
current->link_count++;
error = open_namei(bh->b_data,flag,mode,res_inode,dir);
}
if (buflen > 1023)
buflen = 1023;
- if (inode->i_data[0])
- bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
- else
- bh = NULL;
+ bh = ext_bread(inode, 0, 0);
iput(inode);
if (!bh)
return 0;
static int trunc_direct(struct inode * inode)
{
- int i;
- int result = 0;
+ int i, tmp;
+ unsigned long * p;
+ struct buffer_head * bh;
+ int retry = 0;
#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
repeat:
for (i = DIRECT_BLOCK ; i < 9 ; i++) {
- if (i < DIRECT_BLOCK)
+ p = inode->u.ext_i.i_data+i;
+ if (!(tmp = *p))
+ continue;
+ bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
+ if (i < DIRECT_BLOCK) {
+ brelse(bh);
goto repeat;
- if (!inode->i_data[i])
+ }
+ if ((bh && bh->b_count != 1) || tmp != *p) {
+ retry = 1;
+ brelse(bh);
continue;
- result = 1;
- if (ext_free_block(inode->i_dev,inode->i_data[i]))
- inode->i_data[i] = 0;
+ }
+ *p = 0;
+ inode->i_dirt = 1;
+ brelse(bh);
+ ext_free_block(inode->i_dev,tmp);
}
- return result;
+ return retry;
}
static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
{
- int i;
- struct buffer_head * bh = NULL;
+ int i, tmp;
+ struct buffer_head * bh;
+ struct buffer_head * ind_bh;
unsigned long * ind;
- int result = 0;
+ int retry = 0;
#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
- if (*p)
- bh = bread(inode->i_dev, *p, BLOCK_SIZE);
- if (!bh)
+ tmp = *p;
+ if (!tmp)
+ return 0;
+ ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+ if (tmp != *p) {
+ brelse(ind_bh);
+ return 1;
+ }
+ if (!ind_bh) {
+ *p = 0;
return 0;
+ }
repeat:
for (i = INDIRECT_BLOCK ; i < 256 ; i++) {
if (i < 0)
i = 0;
if (i < INDIRECT_BLOCK)
goto repeat;
- ind = i+(unsigned long *) bh->b_data;
- if (!*ind)
+ ind = i+(unsigned long *) ind_bh->b_data;
+ tmp = *ind;
+ if (!tmp)
+ continue;
+ bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
+ if (i < INDIRECT_BLOCK) {
+ brelse(bh);
+ goto repeat;
+ }
+ if ((bh && bh->b_count != 1) || tmp != *ind) {
+ retry = 1;
+ brelse(bh);
continue;
- result = 1;
- if (ext_free_block(inode->i_dev,*ind))
- *ind = 0;
+ }
+ *ind = 0;
+ ind_bh->b_dirt = 1;
+ brelse(bh);
+ ext_free_block(inode->i_dev,tmp);
}
- ind = (unsigned long *) bh->b_data;
+ ind = (unsigned long *) ind_bh->b_data;
for (i = 0; i < 256; i++)
if (*(ind++))
break;
- brelse(bh);
- if (i >= 256) {
- result = 1;
- if (ext_free_block(inode->i_dev,*p))
+ if (i >= 256)
+ if (ind_bh->b_count != 1)
+ retry = 1;
+ else {
+ tmp = *p;
*p = 0;
- }
- return result;
+ inode->i_dirt = 1;
+ ext_free_block(inode->i_dev,tmp);
+ }
+ brelse(ind_bh);
+ return retry;
}
-
+
static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
{
- int i;
- struct buffer_head * bh = NULL;
+ int i,tmp;
+ struct buffer_head * dind_bh;
unsigned long * dind;
- int result = 0;
+ int retry = 0;
#define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8)
- if (*p)
- bh = bread(inode->i_dev, *p, BLOCK_SIZE);
- if (!bh)
+ tmp = *p;
+ if (!tmp)
+ return 0;
+ dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+ if (tmp != *p) {
+ brelse(dind_bh);
+ return 1;
+ }
+ if (!dind_bh) {
+ *p = 0;
return 0;
+ }
repeat:
for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) {
if (i < 0)
i = 0;
if (i < DINDIRECT_BLOCK)
goto repeat;
- dind = i+(unsigned long *) bh->b_data;
- if (!*dind)
+ dind = i+(unsigned long *) dind_bh->b_data;
+ tmp = *dind;
+ if (!tmp)
continue;
- result |= trunc_indirect(inode,offset+(i<<8),dind);
+ retry |= trunc_indirect(inode,offset+(i<<8),dind);
+ dind_bh->b_dirt = 1;
}
- dind = (unsigned long *) bh->b_data;
+ dind = (unsigned long *) dind_bh->b_data;
for (i = 0; i < 256; i++)
if (*(dind++))
break;
- brelse(bh);
- if (i >= 256) {
- result = 1;
- if (ext_free_block(inode->i_dev,*p))
+ if (i >= 256)
+ if (dind_bh->b_count != 1)
+ retry = 1;
+ else {
+ tmp = *p;
*p = 0;
- }
- return result;
+ inode->i_dirt = 1;
+ ext_free_block(inode->i_dev,tmp);
+ }
+ brelse(dind_bh);
+ return retry;
}
static int trunc_tindirect(struct inode * inode)
{
- int i;
- struct buffer_head * bh = NULL;
- unsigned long * tind;
- int result = 0;
+ int i,tmp;
+ struct buffer_head * tind_bh;
+ unsigned long * tind, * p;
+ int retry = 0;
#define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16)
- if (inode->i_data[11])
- bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE);
- if (!bh)
+ p = inode->u.ext_i.i_data+11;
+ if (!(tmp = *p))
return 0;
+ tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+ if (tmp != *p) {
+ brelse(tind_bh);
+ return 1;
+ }
+ if (!tind_bh) {
+ *p = 0;
+ return 0;
+ }
repeat:
for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) {
if (i < 0)
i = 0;
if (i < TINDIRECT_BLOCK)
goto repeat;
- tind = i+(unsigned long *) bh->b_data;
- if (!*tind)
- continue;
- result |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
+ tind = i+(unsigned long *) tind_bh->b_data;
+ retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
+ tind_bh->b_dirt = 1;
}
- tind = (unsigned long *) bh->b_data;
+ tind = (unsigned long *) tind_bh->b_data;
for (i = 0; i < 256; i++)
if (*(tind++))
break;
- brelse(bh);
- if (i >= 256) {
- result = 1;
- if (ext_free_block(inode->i_dev,inode->i_data[11]))
- inode->i_data[11] = 0;
- }
- return result;
+ if (i >= 256)
+ if (tind_bh->b_count != 1)
+ retry = 1;
+ else {
+ tmp = *p;
+ *p = 0;
+ inode->i_dirt = 1;
+ ext_free_block(inode->i_dev,tmp);
+ }
+ brelse(tind_bh);
+ return retry;
}
-
+
void ext_truncate(struct inode * inode)
{
- int flag;
+ int retry;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
while (1) {
- flag = trunc_direct(inode);
- flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
- flag |= trunc_dindirect(inode,9+256,(unsigned long *)&inode->i_data[10]);
- flag |= trunc_tindirect(inode);
- if (!flag)
+ retry = trunc_direct(inode);
+ retry |= trunc_indirect(inode,9,inode->u.ext_i.i_data+9);
+ retry |= trunc_dindirect(inode,9+256,inode->u.ext_i.i_data+10);
+ retry |= trunc_tindirect(inode);
+ if (!retry)
break;
current->counter = 0;
schedule();
wake_up(&PIPE_READ_WAIT(*inode));
if (PIPE_READERS(*inode))
wake_up(&PIPE_WRITE_WAIT(*inode));
- if (retval || inode->i_size)
+ if (retval || PIPE_BASE(*inode))
return retval;
page = get_free_page(GFP_KERNEL);
- if (inode->i_size) {
+ if (PIPE_BASE(*inode)) {
free_page(page);
return 0;
}
if (!page)
return -ENOMEM;
- inode->i_size = page;
+ PIPE_BASE(*inode) = (char *) page;
return 0;
}
return;
}
if (inode->i_pipe) {
- wake_up(&inode->i_wait);
- wake_up(&inode->i_wait2);
+ wake_up(&PIPE_READ_WAIT(*inode));
+ wake_up(&PIPE_WRITE_WAIT(*inode));
}
repeat:
if (inode->i_count>1) {
return;
}
if (inode->i_pipe) {
- free_page(inode->i_size);
- inode->i_size = 0;
+ unsigned long page = (unsigned long) PIPE_BASE(*inode);
+ PIPE_BASE(*inode) = NULL;
+ free_page(page);
}
if (!inode->i_dev) {
inode->i_count--;
if (!(inode = get_empty_inode()))
return NULL;
- if (!(inode->i_size = get_free_page(GFP_USER))) {
+ if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
inode->i_count = 0;
return NULL;
}
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
+#include <linux/termios.h>
static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
switch (cmd) {
case FIBMAP:
- if (filp->f_inode->i_op == NULL) return -EBADF;
- if (filp->f_inode->i_op->bmap == NULL) return -EINVAL;
+ if (filp->f_inode->i_op == NULL)
+ return -EBADF;
+ if (filp->f_inode->i_op->bmap == NULL)
+ return -EINVAL;
+ verify_area((void *) arg,4);
block = get_fs_long((long *) arg);
block = filp->f_inode->i_op->bmap(filp->f_inode,block);
put_fs_long(block,(long *) arg);
return 0;
case FIGETBSZ:
- if (filp->f_inode->i_sb == NULL) return -EBADF;
+ if (filp->f_inode->i_sb == NULL)
+ return -EBADF;
+ verify_area((void *) arg,4);
put_fs_long(filp->f_inode->i_sb->s_blocksize,
(long *) arg);
return 0;
+ case FIONREAD:
+ verify_area((void *) arg,4);
+ put_fs_long(filp->f_inode->i_size - filp->f_pos,
+ (long *) arg);
+ return 0;
default:
return -EINVAL;
}
/* Don't know what value to put in buf->f_fsid */
}
-#define inode_bmap(inode,nr) ((inode)->i_data[(nr)])
+#define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
static int block_bmap(struct buffer_head * bh, int nr)
{
static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
{
int tmp;
+ unsigned short *p;
struct buffer_head * result;
+ p = inode->u.minix_i.i_data + nr;
repeat:
- tmp = inode->i_data[nr];
+ tmp = *p;
if (tmp) {
result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp == inode->i_data[nr])
+ if (tmp == *p)
return result;
brelse(result);
goto repeat;
if (!tmp)
return NULL;
result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (inode->i_data[nr]) {
+ if (*p) {
minix_free_block(inode->i_dev,tmp);
brelse(result);
goto repeat;
}
- inode->i_data[nr] = tmp;
+ *p = tmp;
inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
return result;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = raw_inode->i_zone[0];
else for (block = 0; block < 9; block++)
- inode->i_data[block] = raw_inode->i_zone[block];
+ inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
brelse(bh);
inode->i_op = NULL;
if (S_ISREG(inode->i_mode))
inode->i_op = &minix_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
- inode->i_size = 0;
inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_zone[0] = inode->i_rdev;
else for (block = 0; block < 9; block++)
- raw_inode->i_zone[block] = inode->i_data[block];
+ raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
bh->b_dirt=1;
inode->i_dirt=0;
brelse(bh);
#include <asm/segment.h>
-#include <const.h>
-
/*
* comment out this line if you want names > MINIX_NAME_LEN chars to be
* truncated. Else they will be disallowed.
inode->i_op = &minix_blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode)) {
inode->i_op = &minix_fifo_inode_operations;
- inode->i_size = 0;
inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
inode->i_nlink = 2;
dir_block->b_dirt = 1;
brelse(dir_block);
- inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
+ inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
inode->i_dirt = 1;
bh = minix_add_entry(dir,name,len,&de);
if (!bh) {
static int trunc_direct(struct inode * inode)
{
+ unsigned short * p;
struct buffer_head * bh;
int i, tmp;
int retry = 0;
repeat:
for (i = DIRECT_BLOCK ; i < 7 ; i++) {
- tmp = inode->i_data[i];
- if (!tmp)
+ p = i + inode->u.minix_i.i_data;
+ if (!(tmp = *p))
continue;
bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
if (i < DIRECT_BLOCK) {
brelse(bh);
goto repeat;
}
- if ((bh && bh->b_count != 1) || tmp != inode->i_data[i]) {
+ if ((bh && bh->b_count != 1) || tmp != *p) {
retry = 1;
brelse(bh);
continue;
}
- inode->i_data[i] = 0;
+ *p = 0;
inode->i_dirt = 1;
brelse(bh);
minix_free_block(inode->i_dev,tmp);
{
int i, tmp;
struct buffer_head * dind_bh;
- unsigned short * dind;
+ unsigned short * dind, * p;
int retry = 0;
#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
- tmp = inode->i_data[8];
- if (!tmp)
+ p = 8 + inode->u.minix_i.i_data;
+ if (!(tmp = *p))
return 0;
dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != inode->i_data[8]) {
+ if (tmp != *p) {
brelse(dind_bh);
return 1;
}
if (!dind_bh) {
- inode->i_data[8] = 0;
+ *p = 0;
return 0;
}
repeat:
if (dind_bh->b_count != 1)
retry = 1;
else {
- tmp = inode->i_data[8];
- inode->i_data[8] = 0;
+ tmp = *p;
+ *p = 0;
inode->i_dirt = 1;
minix_free_block(inode->i_dev,tmp);
}
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return;
- if (inode->i_data[7] & 0xffff0000) {
- printk("BAD! minix inode has 16 high bits set\n");
- inode->i_data[7] = 0;
- }
while (1) {
retry = trunc_direct(inode);
- retry |= trunc_indirect(inode,7,(unsigned short *)&inode->i_data[7]);
+ retry |= trunc_indirect(inode,7,inode->u.minix_i.i_data+7);
retry |= trunc_dindirect(inode);
if (!retry)
break;
if ((this = fat_access(inode->i_sb,this,-1)) == -1) return 0;
if (!this) return 0;
}
- if (!(MSDOS_I(inode)->i_busy || inode->i_nlink))
+ if (!(MSDOS_I(inode)->i_busy && inode->i_nlink))
cache_add(inode,cluster,this);
/* don't add clusters of moved files, because we can't invalidate them
when this inode is returned. */
* Some corrections by tytso.
*/
-#include <const.h>
-
#include <asm/segment.h>
#include <linux/errno.h>
struct task_struct ** p;
mode &= 07777 & ~current->umask;
- mode |= I_REGULAR;
+ mode |= S_IFREG;
error = dir_namei(pathname,&namelen,&basename,base,&dir);
if (error)
return error;
chars = count;
if (chars > size)
chars = size;
- memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
+ memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars );
read += chars;
PIPE_TAIL(*inode) += chars;
PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
chars = count;
if (chars > size)
chars = size;
- memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
+ memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars );
written += chars;
PIPE_HEAD(*inode) += chars;
PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
#include <asm/segment.h>
#include <asm/system.h>
-#include <const.h>
-
/*
* Ok, Peter made a complicated, but straightforward multiple_wait() function.
* I have rewritten this, taking some shortcuts: This code may not be easy to
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
- if( S_ISFIFO(inode->i_mode) )
- tmp.st_size = 0;
- else
- tmp.st_size = inode->i_size;
+ tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
- if( S_ISFIFO(inode->i_mode) )
- tmp.st_size = 0;
- else
- tmp.st_size = inode->i_size;
+ tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
}
blocks += indirect;
}
- tmp.st_blksize = 512;
tmp.st_blocks = blocks;
- } else {
- tmp.st_blksize = inode->i_blksize;
- tmp.st_blocks = inode->i_blocks;
- }
+ } else
+ tmp.st_blocks = (inode->i_blocks * inode->i_blksize) / 512;
+ tmp.st_blksize = 512;
memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe abou using 0x80.
+ *
* Linus
*/
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("inb $0x80,%%al":::"ax")
+#endif
+
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
extern void inline outb(char value, unsigned short port)
{
-__asm__ __volatile__ ("outb %0,%1"
+__asm__ __volatile__ ("outb %%al,%%dx"
::"a" ((char) value),"d" ((unsigned short) port));
}
-extern void inline outb_p(char value, unsigned short port)
+extern unsigned int inline inb(unsigned short port)
{
-__asm__ __volatile__ ("outb %0,%1\n\t"
-#ifdef REALLY_SLOW_IO
- "outb %0,$0x80\n\t"
- "outb %0,$0x80\n\t"
- "outb %0,$0x80\n\t"
-#endif
- "outb %0,$0x80"
- ::"a" ((char) value),"d" ((unsigned short) port));
+ unsigned int _v;
+__asm__ __volatile__ ("inb %%dx,%%al"
+ :"=a" (_v):"d" ((unsigned short) port),"0" (0));
+ return _v;
}
-extern unsigned char inline inb(unsigned short port)
+extern void inline outb_p(char value, unsigned short port)
{
- unsigned char _v;
-__asm__ __volatile__ ("inb %1,%0"
- :"=a" (_v):"d" ((unsigned short) port));
- return _v;
+__asm__ __volatile__ ("outb %%al,%%dx"
+ ::"a" ((char) value),"d" ((unsigned short) port));
+ SLOW_DOWN_IO;
}
-extern unsigned char inline inb_p(unsigned short port)
+extern unsigned int inline inb_p(unsigned short port)
{
- unsigned char _v;
-__asm__ __volatile__ ("inb %1,%0\n\t"
-#ifdef REALLY_SLOW_IO
- "outb %0,$0x80\n\t"
- "outb %0,$0x80\n\t"
- "outb %0,$0x80\n\t"
-#endif
- "outb %0,$0x80"
- :"=a" (_v):"d" ((unsigned short) port));
+ unsigned int _v;
+__asm__ __volatile__ ("inb %%dx,%%al"
+ :"=a" (_v):"d" ((unsigned short) port),"0" (0));
+ SLOW_DOWN_IO;
return _v;
}
* Minor modifications for Linux 0.96c-pl1 by Nathan Laredo
* gt7080a@prism.gatech.edu (13JUL92)
*
+ * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+ *
+ * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+ * 8/28/92
+ *
+ * Microsoft Bus Mouse support folded into 0.97pl4 code
+ * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ * Changes: Logitech and Microsoft support in the same kernel.
+ * Defined new constants in busmouse.h for MS mice.
+ * Added int mse_busmouse_type to distinguish busmouse types
+ * Added a couple of new functions to handle differences in using
+ * MS vs. Logitech (where the int variable wasn't appropriate).
+ *
*/
#define MOUSE_IRQ 5
+#define LOGITECH_BUSMOUSE 0 /* Minor device # for Logitech */
+#define MICROSOFT_BUSMOUSE 2 /* Minor device # for Microsoft */
+
+/*--------- LOGITECH BUSMOUSE ITEMS -------------*/
#define MSE_DATA_PORT 0x23c
#define MSE_SIGNATURE_PORT 0x23d
#define MSE_DEFAULT_MODE 0x90
#define MSE_SIGNATURE_BYTE 0xa5
-/* useful macros */
+/* useful Logitech Mouse macros */
#define MSE_INT_OFF() outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT)
#define MSE_INT_ON() outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT)
+
+/*--------- MICROSOFT BUSMOUSE ITEMS -------------*/
+
+#define MS_MSE_DATA_PORT 0x23d
+#define MS_MSE_SIGNATURE_PORT 0x23d
+#define MS_MSE_CONTROL_PORT 0x23c
+#define MS_MSE_CONFIG_PORT 0x23f
+
+#define MS_MSE_ENABLE_INTERRUPTS 0x11
+#define MS_MSE_DISABLE_INTERRUPTS 0x10
+
+#define MS_MSE_READ_BUTTONS 0x00
+#define MS_MSE_READ_X 0x01
+#define MS_MSE_READ_Y 0x02
+
+#define MS_MSE_START 0x80
+#define MS_MSE_COMMAND_MODE 0x07
+
+/* useful microsoft busmouse macros */
+
+#define MS_MSE_INT_OFF() {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); \
+ outb(MS_MSE_DISABLE_INTERRUPTS, MS_MSE_DATA_PORT);}
+#define MS_MSE_INT_ON() {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); \
+ outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT);}
+
struct mouse_status
{
struct inode *inode;
};
+/* Variable Definitions */
+extern int mse_busmouse_type; /* to distinguish what type mouse we're working with */
+
+
/* Function Prototypes */
extern long mouse_init(long);
+
#endif
--- /dev/null
+/****************************************************************************************
+ * *
+ * SCSI header library for linux *
+ * (C) 1992 David Giller rafetmad@oxy.edu *
+ * *
+ * <linux/cdrom.h> -- CD-ROM IOCTLs and structs *
+ * *
+ ****************************************************************************************/
+
+#ifndef _LINUX_CDROM_H
+#define _LINUX_CDROM_H
+
+/*
+ *
+ * For IOCTL calls, we will commandeer byte 0x53, or 'S'.
+ *
+ */
+
+/*
+ * These are flags for the SCMD_DOORLOCK command. They really should be defined
+ * somewhere more standard.
+ */
+
+#define SR_REMOVAL_PREVENT 1
+#define SR_REMOVAL_ALLOW 0
+
+/*
+ * CD-ROM-specific SCSI command opcodes
+ */
+
+/*
+ * Group 2 (10-byte). All of these are called 'optional' by SCSI-II.
+ */
+
+#define SCMD_READ_TOC 0x43 /* read table of contents */
+#define SCMD_PLAYAUDIO_MSF 0x47 /* play data at time offset */
+#define SCMD_PLAYAUDIO_TI 0x48 /* play data at track/index */
+#define SCMD_PAUSE_RESUME 0x4B /* pause/resume audio */
+#define SCMD_READ_SUBCHANNEL 0x42 /* read SC info on playing disc */
+#define SCMD_PLAYAUDIO10 0x45 /* play data at logical block */
+#define SCMD_READ_HEADER 0x44 /* read TOC header */
+
+/*
+ * Group 5
+ */
+
+#define SCMD_PLAYAUDIO12 0xA5 /* play data at logical block */
+#define SCMD_PLAYTRACK_REL12 0xA9 /* play track at relative offset*/
+
+/*
+ * Group 6 Commands
+ */
+
+#define SCMD_CD_PLAYBACK_CONTROL 0xC9 /* Sony vendor-specific audio */
+#define SCMD_CD_PLAYBACK_STATUS 0xC4 /* control opcodes. info please!*/
+
+/*
+ * CD-ROM capacity structure.
+ */
+
+struct scsi_capacity
+ {
+ u_long capacity;
+ u_long lbasize;
+ };
+
+/*
+ * CD-ROM MODE_SENSE/MODE_SELECT parameters
+ */
+
+#define ERR_RECOVERY_PARMS 0x01
+#define DISCO_RECO_PARMS 0x02
+#define FORMAT_PARMS 0x03
+#define GEOMETRY_PARMS 0x04
+#define CERTIFICATION_PARMS 0x06
+#define CACHE_PARMS 0x38
+
+/*
+ * standard mode-select header prepended to all mode-select commands
+ */
+
+struct ccs_modesel_head
+ {
+ u_char _r1; /* reserved */
+ u_char medium; /* device-specific medium type */
+ u_char _r2; /* reserved */
+ u_char block_desc_length; /* block descriptor length */
+ u_char density; /* device-specific density code */
+ u_char number_blocks_hi; /* number of blocks in this block desc */
+ u_char number_blocks_med;
+ u_char number_blocks_lo;
+ u_char _r3;
+ u_char block_length_hi; /* block length for blocks in this desc */
+ u_short block_length;
+ };
+
+/*
+ * error recovery parameters
+ */
+
+struct ccs_err_recovery
+ {
+ u_char _r1 : 2; /* reserved */
+ u_char page_code : 6; /* page code */
+ u_char page_length; /* page length */
+ u_char awre : 1; /* auto write realloc enabled */
+ u_char arre : 1; /* auto read realloc enabled */
+ u_char tb : 1; /* transfer block */
+ u_char rc : 1; /* read continuous */
+ u_char eec : 1; /* enable early correction */
+ u_char per : 1; /* post error */
+ u_char dte : 1; /* disable transfer on error */
+ u_char dcr : 1; /* disable correction */
+ u_char retry_count; /* error retry count */
+ u_char correction_span; /* largest recov. to be attempted, bits */
+ u_char head_offset_count; /* head offset (2's C) for each retry */
+ u_char strobe_offset_count; /* data strobe " */
+ u_char recovery_time_limit; /* time limit on recovery attempts */
+};
+
+/*
+ * disco/reco parameters
+ */
+
+struct ccs_disco_reco
+ {
+ u_char _r1 : 2; /* reserved */
+ u_char page_code : 6; /* page code */
+ u_char page_length; /* page length */
+ u_char buffer_full_ratio; /* write buffer reconnect threshold */
+ u_char buffer_empty_ratio; /* read " */
+ u_short bus_inactivity_limit; /* limit on bus inactivity time */
+ u_short disconnect_time_limit; /* minimum disconnect time */
+ u_short connect_time_limit; /* minimum connect time */
+ u_short _r2; /* reserved */
+};
+
+/*
+ * drive geometry parameters
+ */
+
+struct ccs_geometry
+ {
+ u_char _r1 : 2; /* reserved */
+ u_char page_code : 6; /* page code */
+ u_char page_length; /* page length */
+ u_char cyl_ub; /* #cyls */
+ u_char cyl_mb;
+ u_char cyl_lb;
+ u_char heads; /* #heads */
+ u_char precomp_cyl_ub; /* precomp start */
+ u_char precomp_cyl_mb;
+ u_char precomp_cyl_lb;
+ u_char current_cyl_ub; /* reduced current start */
+ u_char current_cyl_mb;
+ u_char current_cyl_lb;
+ u_short step_rate; /* stepping motor rate */
+ u_char landing_cyl_ub; /* landing zone */
+ u_char landing_cyl_mb;
+ u_char landing_cyl_lb;
+ u_char _r2;
+ u_char _r3;
+ u_char _r4;
+ };
+
+/*
+ * cache parameters
+ */
+
+struct ccs_cache
+ {
+ u_char _r1 : 2; /* reserved */
+ u_char page_code : 6; /* page code */
+ u_char page_length; /* page length */
+ u_char mode; /* cache control byte */
+ u_char threshold; /* prefetch threshold */
+ u_char max_prefetch; /* maximum prefetch size */
+ u_char max_multiplier; /* maximum prefetch multiplier */
+ u_char min_prefetch; /* minimum prefetch size */
+ u_char min_multiplier; /* minimum prefetch multiplier */
+ u_char _r2[8];
+ };
+
+/*
+ * CDROM IOCTL structures
+ */
+
+struct cdrom_msf
+ {
+ u_char cdmsf_min0; /* start minute */
+ u_char cdmsf_sec0; /* start second */
+ u_char cdmsf_frame0; /* start frame */
+ u_char cdmsf_min1; /* end minute */
+ u_char cdmsf_sec1; /* end second */
+ u_char cdmsf_frame1; /* end frame */
+ };
+
+struct cdrom_ti
+ {
+ u_char cdti_trk0; /* start track */
+ u_char cdti_ind0; /* start index */
+ u_char cdti_trk1; /* end track */
+ u_char cdti_ind1; /* end index */
+ };
+
+struct cdrom_tochdr
+ {
+ u_char cdth_trk0; /* start track */
+ u_char cdth_trk1; /* end track */
+ };
+
+struct cdrom_tocentry
+ {
+ u_char cdte_track;
+ u_char cdte_adr :4;
+ u_char cdte_ctrl :4;
+ u_char cdte_format;
+ union
+ {
+ struct
+ {
+ u_char minute;
+ u_char second;
+ u_char frame;
+ } msf;
+ int lba;
+ } cdte_addr;
+ u_char cdte_datamode;
+ };
+
+/*
+ * CD-ROM address types (cdrom_tocentry.cdte_format)
+ */
+
+#define CDROM_LBA 0x01
+#define CDROM_MSF 0x02
+
+/*
+ * bit to tell whether track is data or audio
+ */
+
+#define CDROM_DATA_TRACK 0x04
+
+/*
+ * The leadout track is always 0xAA, regardless of # of tracks on disc
+ */
+
+#define CDROM_LEADOUT 0xAA
+
+struct cdrom_subchnl
+ {
+ u_char cdsc_format;
+ u_char cdsc_audiostatus;
+ u_char cdsc_adr: 4;
+ u_char cdsc_ctrl: 4;
+ u_char cdsc_trk;
+ u_char cdsc_ind;
+ union
+ {
+ struct
+ {
+ u_char minute;
+ u_char second;
+ u_char frame;
+ } msf;
+ int lba;
+ } cdsc_absaddr;
+ union
+ {
+ struct
+ {
+ u_char minute;
+ u_char second;
+ u_char frame;
+ } msf;
+ int lba;
+ } cdsc_reladdr;
+ };
+
+/*
+ * return value from READ SUBCHANNEL DATA
+ */
+
+#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */
+#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */
+#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */
+#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */
+#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */
+#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */
+
+struct cdrom_volctrl
+ {
+ u_char channel0;
+ u_char channel1;
+ u_char channel2;
+ u_char channel3;
+ };
+
+struct cdrom_read
+ {
+ int cdread_lba;
+ caddr_t cdread_bufaddr;
+ int cdread_buflen;
+ };
+
+#ifdef FIVETWELVE
+#define CDROM_MODE1_SIZE 512
+#else
+#define CDROM_MODE1_SIZE 2048
+#endif FIVETWELVE
+#define CDROM_MODE2_SIZE 2336
+
+/*
+ * CD-ROM IOCTL commands
+ */
+
+#define CDROMPAUSE 0x5301 /* pause */
+#define CDROMRESUME 0x5302 /* resume */
+
+#define CDROMPLAYMSF 0x5303 /* (stuct cdrom_msf) */
+ /* SCMD_PLAY_AUDIO_MSF */
+
+#define CDROMPLAYTRKIND 0x5304 /* (struct cdrom_ti) */
+ /* SCMD_PLAY_AUDIO_TI */
+
+#define CDROMREADTOCHDR 0x5305 /* (struct cdrom_tochdr) */
+ /* read the TOC header */
+#define CDROMREADTOCENTRY 0x5306 /* (struct cdrom_tocentry) */
+ /* read a TOC entry */
+
+#define CDROMSTOP 0x5307 /* stop the drive motor */
+#define CDROMSTART 0x5308 /* turn the motor on */
+
+#define CDROMEJECT 0x5309 /* eject CD-ROM media */
+
+#define CDROMVOLCTRL 0x530a /* (struct cdrom_volctrl) */
+ /* vlume control */
+
+#define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */
+ /* read sub-channel data */
+
+#define CDROMREADMODE2 0x530c /* (struct cdrom_read) */
+ /* read type-2 data (not suppt) */
+
+#define CDROMREADMODE1 0x530d /* (struct cdrom_read) */
+ /* read type-1 data */
+
+/*
+ * Linux-specific CD-ROM ioctls for convenience and ISO-9660 support
+ */
+
+#define CDROMDOORLOCK 0x5380 /* lock the eject mechanism */
+#define CDROMDOORUNLOCK 0x5381 /* unlock the mechanism */
+
+#endif _LINUX_CDROM_H
#define CONFIG_BLK_DEV_HD
#undef CONFIG_BLK_DEV_SD
#define CONFIG_BLK_DEV_SD
+#undef CONFIG_BLK_DEV_SR
+#define CONFIG_BLK_DEV_SR
#undef CONFIG_BLK_DEV_ST
#define CONFIG_BLK_DEV_ST
#define CONFIG_BLK_DEV_HD
#undef CONFIG_BLK_DEV_SD
#undef CONFIG_BLK_DEV_ST
+#undef CONFIG_BLK_DEV_SR
/*
#undef CONFIG_SCSI_ULTRASTOR
#undef CONFIG_SCSI_7000FASST
-#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_CD) || \
+#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_SR) || \
defined(CONFIG_CHR_DEV_ST)
#ifndef CONFIG_SCSI
#define CONFIG_SCSI
extern void ext_free_inode(struct inode * inode);
extern unsigned long ext_count_free_inodes(struct super_block *sb);
extern int ext_new_block(int dev);
-extern int ext_free_block(int dev, int block);
+extern void ext_free_block(int dev, int block);
extern unsigned long ext_count_free_blocks(struct super_block *sb);
-extern int ext_create_block(struct inode *, int);
extern int ext_bmap(struct inode *,int);
+extern struct buffer_head * ext_getblk(struct inode *, int, int);
+extern struct buffer_head * ext_bread(struct inode *, int, int);
+
extern void ext_truncate(struct inode *);
extern void ext_put_super(struct super_block *);
extern void ext_write_super(struct super_block *);
* extended file system inode data in memory
*/
struct ext_inode_info {
+ unsigned long i_data[16];
};
#endif
/* devices are as follows: (same as minix, so we can use the minix
* file system. These are major numbers.)
*
- * 0 - unused (nodev)
- * 1 - /dev/mem
- * 2 - /dev/fd
- * 3 - /dev/hd
- * 4 - /dev/ttyx
- * 5 - /dev/tty
- * 6 - /dev/lp
- * 7 - unnamed pipes
- * 8 - /dev/sd
- * 9 - /dev/st
+ * 0 - unused (nodev)
+ * 1 - /dev/mem
+ * 2 - /dev/fd
+ * 3 - /dev/hd
+ * 4 - /dev/ttyx
+ * 5 - /dev/tty
+ * 6 - /dev/lp
+ * 7 -
+ * 8 - /dev/sd
+ * 9 - /dev/st
+ * 10 - mice
+ * 11 - scsi cdrom
*/
-#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3 || (x)==8)
-
#define MAY_EXEC 1
#define MAY_WRITE 2
#define MAY_READ 4
#define NULL ((void *) 0)
#endif
-#define PIPE_READ_WAIT(inode) ((inode).i_wait)
-#define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)
-#define PIPE_HEAD(inode) ((inode).i_data[0])
-#define PIPE_TAIL(inode) ((inode).i_data[1])
-#define PIPE_READERS(inode) ((inode).i_data[2])
-#define PIPE_WRITERS(inode) ((inode).i_data[3])
-#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
-#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))
-#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
-
#define NIL_FILP ((struct file *)0)
#define SEL_IN 1
#define SEL_OUT 2
struct buffer_head * b_reqnext; /* request queue */
};
+#include <linux/pipe_fs_i.h>
#include <linux/minix_fs_i.h>
#include <linux/ext_fs_i.h>
#include <linux/msdos_fs_i.h>
time_t i_ctime;
unsigned long i_blksize;
unsigned long i_blocks;
- unsigned long i_data[16];
struct inode_operations * i_op;
struct super_block * i_sb;
struct wait_queue * i_wait;
- struct wait_queue * i_wait2; /* for pipes */
struct file_lock *i_flock;
unsigned short i_count;
unsigned short i_flags;
unsigned char i_seek;
unsigned char i_update;
union {
+ struct pipe_inode_info pipe_i;
struct minix_inode_info minix_i;
struct ext_inode_info ext_i;
struct msdos_inode_info msdos_i;
--- /dev/null
+#ifndef _LINUX_KD_H
+#define _LINUX_KD_H
+
+/* 0x4B is 'K', to avoid collision with termios and vt */
+
+#define SWAPMONO 0x4B00 /* use mca as output device */
+#define SWAPCGA 0x4B01 /* use cga as output device */
+#define SWAPEGA 0x4B02 /* use ega as output device */
+#define SWAPVGA 0x4B03 /* use vga as output device */
+#define CONS_CURRENT 0x4B04 /* return current output device */
+#define MONO 0x01
+#define CGA 0x02
+#define EGA 0x03
+
+#define SW_B40x25 0x4B05 /* 40x25 mono text (cga/ega) */
+#define SW_C40x25 0x4B06 /* 40x24 color text (cga/ega) */
+#define SW_B80x25 0x4B07 /* 80x25 mono text (cga/ega) */
+#define SW_C80x25 0x4B08 /* 80x25 color text (cga/ega) */
+#define SW_BG320 0x4B09 /* 320x200 mono graphics (cga/ega) */
+#define SW_CG320 0x4B0A /* 320x200 color graphics (cga/ega) */
+#define SW_BG640 0x4B0B /* 640x200 mono graphics (cga/ega) */
+#define SW_CG320_D 0x4B0C /* 320x200 graphics (ega mode d) */
+#define SW_CG640_E 0x4B0D /* 640x200 graphics (ega mode e) */
+#define SW_EGAMONOAPA 0x4B0E /* 640x350 graphics (ega mode f) */
+#define SW_ENH_MONOAPA2 0x4B0F /* 640x350 graphics extd mem (ega mode f*) */
+#define SW_CG640x350 0x4B10 /* 640x350 graphics (ega mode 10) */
+#define SW_ENH_CG640 0x4B11 /* 640x350 graphics extd mem (ega mode 10*) */
+#define SW_EGAMONO80x25 0x4B12 /* 80x25 mono text (ega mode 7) */
+#define SW_ENHB40x25 0x4B13 /* enhanced 40x25 mono text (ega) */
+#define SW_ENHC40x25 0x4B14 /* enhanced 40x25 color text (ega) */
+#define SW_ENHB80x25 0x4B15 /* enhanced 80x25 mono text (ega) */
+#define SW_ENHC80x25 0x4B16 /* enhanced 80x25 color text (ega) */
+#define SW_ENHB80x43 0x4B17 /* enhanced 80x43 mono text (ega) */
+#define SW_ENHC80x43 0x4B18 /* enhanced 80x43 color text (ega) */
+#define SW_MCAMODE 0x4B19 /* reinit mca */
+#define SW_ATT640 0x4B1A /* 640x400 16color */
+/* should add more vga modes, etc */
+
+#define CONS_GET 0x4B1B /* get current display mode */
+#define M_B40x25 0 /* 40x25 mono (cga/ega) */
+#define M_C40x25 1 /* 40x25 color (cga/ega) */
+#define M_B80x25 2 /* 80x25 mono (cga/ega) */
+#define M_C80x25 3 /* 80x25 color (cga/ega) */
+#define M_BG320 4 /* 320x200 mono (cga/ega) */
+#define M_CG320 5 /* 320x200 color (cga/ega) */
+#define M_BG640 6 /* 640x200 mono (cga/ega) */
+#define M_EGAMONO80x25 7 /* 80x25 mono (ega) */
+#define M_CG320_D 13 /* ega mode d */
+#define M_CG640_E 14 /* ega mode e */
+#define M_EFAMONOAPA 15 /* ega mode f */
+#define M_CG640x350 16 /* ega mode 10 */
+#define M_ENHMONOAPA2 17 /* ega mode f with ext mem */
+#define M_ENH_CG640 18 /* ega mode 10* */
+#define M_ENH_B40x25 19 /* ega enh 40x25 mono */
+#define M_ENH_C40x25 20 /* ega enh 40x25 color */
+#define M_ENH_B80x25 21 /* ega enh 80x25 mono */
+#define M_ENH_C80x25 22 /* ega enh 80x25 color */
+#define M_ENH_B80x43 0x70 /* ega enh 80x43 mono */
+#define M_ENH_C80x43 0x71 /* ega enh 80x43 color */
+#define M_MCA_MODE 0xff /* monochrome adapter mode */
+#define MCA_GET 0x4B1C /* get mca display mode */
+#define CGA_GET 0x4B1D /* get cga display mode */
+#define EGA_GET 0x4B1E /* get ega display mode */
+
+#define MAPCONS 0x4B1F /* map current video mem into address space */
+#define MAPMONO 0x4B20 /* map mca video mem into address space */
+#define MAPCGA 0x4B21 /* map cga video mem into address space */
+#define MAPEGA 0x4B22 /* map ega video mem into address space */
+#define MAPVGA 0x4B23 /* map vga video mem into address space */
+
+struct port_io_struc {
+ char dir; /* direction in vs out */
+ unsigned short port;
+ char data;
+};
+#define IN_ON_PORT 0x00
+#define OUT_ON_PORT 0x01
+struct port_io_arg {
+ struct port_io_struc args[4];
+};
+#define MCAIO 0x4B24 /* i/o to mca video board */
+#define CGAIO 0x4B25 /* i/o to cga video board */
+#define EGAIO 0x4B26 /* i/o to ega video board */
+#define VGAIO 0x4B27 /* i/o to vga video board */
+
+#define GIO_FONT8x8 0x4B28 /* gets current 8x8 font used */
+#define PIO_FONT8x8 0x4B29 /* use supplied 8x8 font */
+#define GIO_FONT8x14 0x4B2A /* gets current 8x14 font used */
+#define PIO_FONT8x14 0x4B2B /* use supplied 8x14 font */
+#define GIO_FONT8x16 0x4B2C /* gets current 8x16 font used */
+#define PIO_FONT8x16 0x4B2D /* use supplied 8x16 font */
+
+#define MKDIOADDR 32 /* io bitmap size from <linux/sched.h> */
+struct kd_disparam {
+ long type; /* type of display */
+ char *addr; /* display mem address */
+ ushort ioaddr[MKDIOADDR]; /* valid i/o addresses */
+};
+#define KDDISPTYPE 0x4B2E /* gets display info */
+#define KD_MONO 0x01
+#define KD_HERCULES 0x02
+#define KD_CGA 0x03
+#define KD_EGA 0x04
+
+#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
+#define KDMKTONE 0x4B30 /* generate tone */
+
+#define KDGETLED 0x4B31 /* return current led flags */
+#define KDSETLED 0x4B32 /* set current led flags */
+#define LED_SCR 0x01 /* scroll lock */
+#define LED_CAP 0x04 /* caps lock */
+#define LED_NUM 0x02 /* num lock */
+
+#define KDGKBTYPE 0x4B33 /* get keyboard type */
+#define KB_84 0x01
+#define KB_101 0x02
+#define KB_OTHER 0x03
+
+#define KDADDIO 0x4B34 /* add i/o port as valid */
+#define KDDELIO 0x4B35 /* del i/o port as valid */
+#define KDENABIO 0x4B36 /* enable i/o to video board */
+#define KDDISABIO 0x4B37 /* disable i/o to video board */
+
+struct kd_quemode {
+ int qsize; /* desired # elem in queue */
+ int signo; /* signal to send when queue not empty */
+ char *qaddr; /* user virt addr of queue */
+};
+#define KDQUEMODE 0x4B38 /* enable/disable special queue mode */
+
+#define KDSBORDER 0x4B39 /* set screen boarder in ega text mode */
+
+#define KDSETMODE 0x4B3A /* set text/grahics mode */
+#define KD_TEXT 0x00
+#define KD_GRAPHICS 0x01
+#define KD_TEXT0 0x02 /* ? */
+#define KD_TEXT1 0x03 /* ? */
+#define KDGETMODE 0x4B3B /* get current mode */
+
+struct kd_memloc {
+ char *vaddr; /* virt addr to map to */
+ char *physaddr; /* phys addr to map from */
+ long length; /* number of bytes */
+ long ioflg; /* enable i/o if set */
+};
+#define KDMAPDISP 0x4B3C /* map display into address space */
+#define KDUNMAPDISP 0x4B3D /* unmap display from address space */
+
+#define KDVDCTYPE 0x4B3E /* return vdc controller/display info */
+
+#define KIOCINFO 0x4B3F /* tell what the device is */
+
+typedef char scrnmap_t;
+#define E_TABSZ 256
+#define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */
+#define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */
+
+#define GIO_ATTR 0x4B42 /* get screen attributes */
+#define GIO_COLOR 0x4B43 /* return nonzero if display is color */
+
+#define K_RAW 0x00
+#define K_XLATE 0x01
+#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+struct kbentry {
+ u_char kb_table;
+ u_char kb_index;
+ u_char kb_value;
+};
+#define K_NORMTAB 0x00
+#define K_SHIFTTAB 0x01
+#define K_ALTTAB 0x02
+#define K_ALTSHIFTTAB 0x03
+#define K_SRQTAB 0x04
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
+#define KDSKBENT 0x4B47 /* sets one entry in translation table */
+
+#endif /* _LINUX_KD_H */
* minix fs inode data in memory
*/
struct minix_inode_info {
+ unsigned short i_data[16];
};
#endif
--- /dev/null
+#ifndef _LINUX_MKTIME_H
+#define _LINUX_MKTIME_H
+
+struct mktime {
+ int sec;
+ int min;
+ int hour;
+ int day;
+ int mon;
+ int year;
+};
+
+#endif
--- /dev/null
+#ifndef _LINUX_MMAN_H
+#define _LINUX_MMAN_H
+
+#define PROT_READ 0x1 /* page can be read */
+#define PROT_WRITE 0x2 /* page can be written */
+#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_NONE 0x0 /* page can not be accessed */
+
+#define MAP_SHARED 1 /* Share changes */
+#define MAP_PRIVATE 2 /* Changes are private */
+#define MAP_TYPE 0xf /* Mask for type of mapping */
+#define MAP_FIXED 0x10 /* Interpret addr exactly */
+
+#endif /* _LINUX_MMAN_H */
#define BUSMOUSE_MINOR 0
#define PSMOUSE_MINOR 1
+#define MS_BUSMOUSE_MINOR 2
long mouse_init(long);
--- /dev/null
+#ifndef _LINUX_PIPE_FS_I_H
+#define _LINUX_PIPE_FS_I_H
+
+struct pipe_inode_info {
+ struct wait_queue * read_wait;
+ struct wait_queue * write_wait;
+ char * base;
+ unsigned int head;
+ unsigned int tail;
+ unsigned int readers;
+ unsigned int writers;
+};
+
+#define PIPE_READ_WAIT(inode) ((inode).u.pipe_i.read_wait)
+#define PIPE_WRITE_WAIT(inode) ((inode).u.pipe_i.write_wait)
+#define PIPE_BASE(inode) ((inode).u.pipe_i.base)
+#define PIPE_HEAD(inode) ((inode).u.pipe_i.head)
+#define PIPE_TAIL(inode) ((inode).u.pipe_i.tail)
+#define PIPE_READERS(inode) ((inode).u.pipe_i.readers)
+#define PIPE_WRITERS(inode) ((inode).u.pipe_i.writers)
+#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
+#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))
+#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
+
+#endif
unsigned short rss; /* number of resident pages */
char comm[8];
struct vm86_struct * vm86_info;
+ unsigned long screen_bitmap;
/* file system info */
int link_count;
int tty; /* -1 if no tty, so it must be signed */
/* math */ 0, \
/* rss */ 2, \
/* comm */ "swapper", \
-/* vm86_info */ NULL, \
+/* vm86_info */ NULL, 0, \
/* fs info */ 0,-1,0022,NULL,NULL,NULL, \
/* libraries */ { { NULL, 0, 0}, }, 0, \
/* filp */ {NULL,}, 0, \
extern void send_break(unsigned int line);
extern int get_serial_info(unsigned int, struct serial_struct *);
extern int set_serial_info(unsigned int, struct serial_struct *);
+extern int get_modem_info(unsigned int, unsigned int *);
+extern int set_modem_info(unsigned int, unsigned int, unsigned int *);
/* pty.c */
long gs;
};
-/*
- * flags isn't even used yet: it's just there as an example of
- * what kind of information we might want to give sys_vm86() (or
- * want it to return to us).
- */
struct vm86_struct {
struct vm86_regs regs;
unsigned long flags;
+ unsigned long screen_bitmap;
};
+/*
+ * flags masks
+ */
+#define VM86_SCREEN_BITMAP 1
+
#endif
--- /dev/null
+#ifndef _LINUX_VT_H
+#define _LINUX_VT_H
+
+/* 0x56 is 'V', to avoid collision with termios and kd */
+
+#define VT_OPENQRY 0x5600 /* find available vt */
+
+struct vt_mode {
+ char mode; /* vt mode */
+ char waitv; /* if set, hang on writes if not active */
+ short relsig; /* signal to raise on release req */
+ short acqsig; /* signal to raise on acquisition */
+ short frsig; /* unused (set to 0) */
+};
+#define VT_GETMODE 0x5601 /* get mode of active vt */
+#define VT_SETMODE 0x5602 /* set mode of active vt */
+#define VT_AUTO 0x00 /* auto vt switching */
+#define VT_PROCESS 0x01 /* process controls switching */
+
+struct vt_stat {
+ ushort v_active; /* active vt */
+ ushort v_signal; /* signal to send */
+ ushort v_state; /* vt bitmask */
+};
+#define VT_GETSTATE 0x5603 /* get global vt state info */
+#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
+
+#define VT_RELDISP 0x5605 /* release display */
+
+#define VT_ACTIVATE 0x5606 /* make vt active */
+
+#endif /* _LINUX_VT_H */
*/
#include <stdarg.h>
-#include <time.h>
#include <asm/system.h>
#include <asm/io.h>
+#include <linux/mktime.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/config.h>
extern void floppy_init(void);
extern void sock_init(void);
extern long rd_init(long mem_start, int length);
-extern long kernel_mktime(struct tm * tm);
-extern void malloc_grab_pages(void);
+extern long kernel_mktime(struct mktime * time);
#ifdef CONFIG_SCSI
extern void scsi_dev_init(void);
static void time_init(void)
{
- struct tm time;
+ struct mktime time;
do {
- time.tm_sec = CMOS_READ(0);
- time.tm_min = CMOS_READ(2);
- time.tm_hour = CMOS_READ(4);
- time.tm_mday = CMOS_READ(7);
- time.tm_mon = CMOS_READ(8);
- time.tm_year = CMOS_READ(9);
- } while (time.tm_sec != CMOS_READ(0));
- BCD_TO_BIN(time.tm_sec);
- BCD_TO_BIN(time.tm_min);
- BCD_TO_BIN(time.tm_hour);
- BCD_TO_BIN(time.tm_mday);
- BCD_TO_BIN(time.tm_mon);
- BCD_TO_BIN(time.tm_year);
- time.tm_mon--;
+ time.sec = CMOS_READ(0);
+ time.min = CMOS_READ(2);
+ time.hour = CMOS_READ(4);
+ time.day = CMOS_READ(7);
+ time.mon = CMOS_READ(8);
+ time.year = CMOS_READ(9);
+ } while (time.sec != CMOS_READ(0));
+ BCD_TO_BIN(time.sec);
+ BCD_TO_BIN(time.min);
+ BCD_TO_BIN(time.hour);
+ BCD_TO_BIN(time.day);
+ BCD_TO_BIN(time.mon);
+ BCD_TO_BIN(time.year);
+ time.mon--;
startup_time = kernel_mktime(&time);
}
buffer_init();
time_init();
floppy_init();
- malloc_grab_pages();
sock_init();
sti();
#ifdef CONFIG_SCSI
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+ $(CPP) -M *.c >> tmp_make
cp tmp_make Makefile
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+ $(CPP) -M *.c >> tmp_make
cp tmp_make Makefile
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep); done
#ifndef _BLK_H
#define _BLK_H
-#define NR_BLK_DEV 10
+#define NR_BLK_DEV 12
/*
* NR_REQUEST is the number of entries in the request-queue.
* NOTE that writes may use only the low 2/3 of these: reads
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
-#elif
+#elif (MAJOR_NR == 11)
+/* scsi CD-ROM */
+#define DEVICE_NAME "CD-ROM"
+#define DEVICE_INTR do_sr
+#define DEVICE_REQUEST do_sr_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+
+#else
/* unknown blk device */
#error "unknown blk device"
extern unsigned char current_DOR;
-#define immoutb_p(val,port) \
-__asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port))
-
#define TYPE(x) ((x)>>2)
#define DRIVE(x) ((x)&0x03)
static void setup_DMA(void)
{
unsigned long addr,count;
+ unsigned char dma_code;
+ dma_code = DMA_WRITE;
+ if (command == FD_READ)
+ dma_code = DMA_READ;
if (command == FD_FORMAT) {
addr = (long) tmp_floppy_area;
count = floppy->sect*4;
- }
- else {
+ } else {
addr = (long) CURRENT->buffer;
count = 1024;
}
if (command == FD_WRITE)
copy_buffer(CURRENT->buffer,tmp_floppy_area);
}
-/* mask DMA 2 */
cli();
#ifndef HHB_SYSMACROS
- immoutb_p(4|2,10);
+/* mask DMA 2 */
+ outb_p(4|2,10);
/* output command byte. I don't know why, but everyone (minix, */
/* sanches & canton) output this twice, first to 12 then to 11 */
- __asm__("outb %%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t"
- "outb %%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:"::
- "a" ((char) ((command == FD_READ)?DMA_READ:DMA_WRITE)));
+ outb_p(dma_code,12);
+ outb_p(dma_code,11);
/* 8 low bits of addr */
- immoutb_p(addr,4);
+ outb_p(addr,4);
addr >>= 8;
/* bits 8-15 of addr */
- immoutb_p(addr,4);
+ outb_p(addr,4);
addr >>= 8;
/* bits 16-19 of addr */
- immoutb_p(addr,0x81);
+ outb_p(addr,0x81);
/* low 8 bits of count-1 */
count--;
- immoutb_p(count,5);
+ outb_p(count,5);
count >>= 8;
/* high 8 bits of count-1 */
- immoutb_p(count,5);
+ outb_p(count,5);
/* activate DMA 2 */
- immoutb_p(0|2,10);
+ outb_p(0|2,10);
#else /* just to show off my macros -- hhb */
DISABLE_DMA(DMA2);
CLEAR_DMA_FF(DMA2);
}
repeat:
cli();
- if ((major == 3 || major == 8 )&& (req = blk_dev[major].current_request)) {
+ if ((major == 3 || major == 8 || major == 11)&& (req = blk_dev[major].current_request)) {
while (req = req->next) {
if (req->dev == bh->b_dev &&
!req->waiting &&
LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c
LOWLEVELHSRC = aha1542.h fdomain.h seagate.h ultrastor.h 7000fasst.o
-CSRC = hosts.c sd.c sd_ioctl.c st.c st_ioctl.c scsi.c scsi_ioctl.c $(LOWLEVELCSRC)
-HSRC = hosts.h sd.h st.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC)
+CSRC = hosts.c sd.c sd_ioctl.c st.c st_ioctl.c sr.c sr_ioctl.c scsi.c scsi_ioctl.c $(LOWLEVELCSRC)
+HSRC = hosts.h sd.h st.h sr.h sr_ioctl.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC)
OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \
+ sr.o sr_ioctl.o \
aha1542.o fdomain.o seagate.o seagate2.o ultrastor.o 7000fasst.o
all: scsi.a
/* What's this little function for? */
char *aha1542_info(void)
{
- static char buffer[] = "Adaptec 1542";
+ static char buffer[] = ""; /* looks nicer without anything here */
return buffer;
}
do_done = NULL;
#ifdef DEBUG
+ {
+ int flag = inb(INTRFLAGS);
printk("aha1542_intr_handle: ");
if (!(flag&ANYINTR)) printk("no interrupt?");
if (flag&MBIF) printk("MBIF ");
printk("status %02x\n", inb(STATUS));
if (ccb.tarstat|ccb.hastat)
printk("aha1542_command: returning %x (status %d)\n", ccb.tarstat + ((int) ccb.hastat << 16), mb[1].status);
+ };
#endif
aha1542_intr_reset();
if (!my_done) {
if (ccb.tarstat == 2) {
int i;
DEB(printk("aha1542_intr_handle: sense:"));
+#ifdef DEBUG
for (i = 0; i < 12; i++)
printk("%02x ", ccb.cdb[ccb.cdblen+i]);
printk("\n");
+#endif
/*
DEB(printk("aha1542_intr_handle: buf:"));
for (i = 0; i < bufflen; i++)
DEB(if (target > 1) {done(aha1542_host, DID_TIME_OUT << 16); return 0;});
+ if(*cmd == REQUEST_SENSE){
+ memcpy(buff, &ccb.cdb[ccb.cdblen], bufflen);
+ done(aha1542_host, 0);
+ return 0;
+ };
+
#ifdef DEBUG
if (*cmd == READ_10 || *cmd == WRITE_10)
i = xscsi2int(cmd+2);
aha1542_intr_reset();
}
- aha1542_stat();
+ DEB(aha1542_stat());
setup_mailboxes();
- aha1542_stat();
+ DEB(aha1542_stat());
DEB(printk("aha1542_detect: enable interrupt channel %d\n", intr_chan));
call_buh();
#include "st.h"
#endif
+#ifdef CONFIG_BLK_DEV_SR
+#include "sr.h"
+#endif
+
/*
static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
*/
-#define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic(""))
+#define INTERNAL_ERROR (printk ("Internal error in file %s, line %d.\n", __FILE__, __LINE__), panic(""))
static void scsi_done (int host, int result);
static void update_timeout (void);
+static void print_inquiry(unsigned char *data);
static int time_start;
static int time_elapsed;
scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES];
#endif
break;
+ case TYPE_ROM:
+ printk("Detected scsi CD-ROM at host %d, ID %d, lun %d \n", host_nr, dev, lun);
+#ifdef CONFIG_BLK_DEV_SR
+ if (!(maxed = (NR_SR >= MAX_SR)))
+ scsi_CDs[NR_SR].device = &scsi_devices[NR_SCSI_DEVICES];
+#endif
+ break;
default :
#ifdef DEBUG
printk("Detected scsi disk at host %d, ID %d, lun %d \n", host_nr, dev, lun);
#endif
}
+ print_inquiry(scsi_result);
+
if (maxed)
{
- printk ("scsi : already have detected maximum number of SCSI %ss Unable to \n"
- "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ?
- "tape" : "disk", scsi_hosts[host_nr].name,
+ printk ("Already have detected "
+ "maximum number of SCSI "
+ "%ss Unable to \n"
+ "add drive at SCSI host "
+ "%s, ID %d, LUN %d\n\r",
+ (type == TYPE_TAPE) ?
+ "tape" :
+ (type == TYPE_DISK) ?
+ "disk" : "CD-ROM",
+ scsi_hosts[host_nr].name,
dev, lun);
type = -1;
break;
*p = 0;
printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
- (type == TYPE_TAPE) ? 't' : 'd',
+ (type == TYPE_TAPE) ? 't' : ((type == TYPE_ROM) ? 'r' : 'd'),
(type == TYPE_TAPE) ?
#ifdef CONFIG_BLK_DEV_ST
NR_ST
-1
#endif
:
+ (type == TYPE_ROM ?
+#ifdef CONFIG_BLK_DEV_SR
+ NR_SR
+#else
+ -1
+#endif
+ :
#ifdef CONFIG_BLK_DEV_SD
NR_SD
#else
-1
#endif
+ )
+
,host_nr , dev, lun, p);
if (type == TYPE_TAPE)
#ifdef CONFIG_BLK_DEV_ST
;
#endif
- else
+ else if (type == TYPE_DISK)
#ifdef CONFIG_BLK_DEV_SD
++NR_SD;
#else
;
+#endif
+ else
+#ifdef CONFIG_BLK_DEV_SR
+ ++NR_SR;
+#else
+;
#endif
}
++slave;
"%d tape%s "
#endif
- "total.\n",
+#ifdef CONFIG_BLK_DEV_SR
+"%d CD-ROM drive%s "
+#endif
+
+ "total.\n"
#ifdef CONFIG_BLK_DEV_SD
- NR_SD, (NR_SD != 1) ? "s" : ""
-#ifdef CONFIG_BLK_DEV_ST
- ,
-#endif
+ , NR_SD, (NR_SD != 1) ? "s" : ""
#endif
#ifdef CONFIG_BLK_DEV_ST
- NR_ST, (NR_ST != 1) ? "s" : ""
+ , NR_ST, (NR_ST != 1) ? "s" : ""
+#endif
+
+#ifdef CONFIG_BLK_DEV_SR
+ , NR_SR, (NR_SR != 1) ? "s" : ""
#endif
);
in_scan = 0;
"bufflen = %d, done = %08x)\n", host, target, cmnd, buffer, bufflen, done);
#endif
-
if (scsi_hosts[host].can_queue)
{
#ifdef DEBUG
static int check_sense (int host)
{
- if (((sense_buffer[0] & 0x70) >> 4) == 7)
- switch (sense_buffer[2] & 0xf)
+ if (((last_cmnd[host].sense_buffer[0] & 0x70) >> 4) == 7)
+ switch (last_cmnd[host].sense_buffer[2] & 0xf)
{
case NO_SENSE:
case RECOVERED_ERROR:
#define FINISHED 0
#define MAYREDO 1
#define REDO 3
+#define PENDING 4
#ifdef DEBUG
printk("In scsi_done(host = %d, result = %06x)\n", host, result);
#endif
scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun);
+ status = PENDING;
break;
case CONDITION_GOOD:
switch (status)
{
case FINISHED:
+ case PENDING:
break;
case MAYREDO:
#undef FINISHED
#undef REDO
#undef MAYREDO
-
+#undef PENDING
}
/*
#ifdef CONFIG_BLK_DEV_ST
st_init(); /* init scsi tapes */
#endif
+
+#ifdef CONFIG_BLK_DEV_SR
+ sr_init();
+#endif
}
#endif
+
+static void print_inquiry(unsigned char *data)
+{
+ int i;
+
+ printk(" Vendor:");
+ for (i = 8; i < 15; i++)
+ {
+ if (data[i] >= 20)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk(" Model:");
+ for (i = 16; i < 31; i++)
+ {
+ if (data[i] >= 20)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk(" Rev:");
+ for (i = 32; i < 35; i++)
+ {
+ if (data[i] >= 20)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk("\n");
+
+ i = data[0] & 0x1f;
+
+ printk(" Type: %s ", i == 0x00 ? "Direct-Access " :
+ i == 0x01 ? "Sequential-Access" :
+ i == 0x02 ? "Printer " :
+ i == 0x03 ? "Processor " :
+ i == 0x04 ? "WORM " :
+ i == 0x05 ? "CD-ROM " :
+ i == 0x06 ? "Scanner " :
+ i == 0x07 ? "Optical Device " :
+ i == 0x08 ? "Medium Changer " :
+ i == 0x09 ? "Communications " :
+ "Unknown " );
+ printk("ANSI SCSI revision: %02x\n", data[2] & 0x07);
+}
+
/*
You guesed it. This sends a command to the selected SCSI host
+
+extern void print_inquiry(unsigned char *data);
+
*/
int NR_SD=0;
Scsi_Disk rscsi_disks[MAX_SD];
-static int sd_sizes[MAX_SD << 4];
+static int sd_sizes[MAX_SD << 4] = {0, };
static int this_count;
static int the_result;
static void sd_geninit (void) {
int i;
for (i = 0; i < NR_SD; ++i)
- sd_sizes[i << 4] =
- (sd[i << 4].nr_sects = rscsi_disks[i].capacity) >>
- (BLOCK_SIZE_BITS - 9);
+ sd[i << 4].nr_sects = rscsi_disks[i].capacity;
sd_gendisk.nr_real = NR_SD;
}
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
- blk_size[MAJOR_NR] = sd_sizes;
- blkdev_fops[MAJOR_NR] = &sd_fops;
+ blkdev_fops[MAJOR_NR] = &sd_fops;
sd_gendisk.next = gendisk_head;
gendisk_head = &sd_gendisk;
-}
+}
#endif
--- /dev/null
+/*
+ * sr.c by David Giller
+ *
+ * adapted from:
+ * sd.c Copyright (C) 1992 Drew Eckhardt
+ * Linux scsi disk driver by
+ * Drew Eckhardt
+ *
+ * <drew@colorado.edu>
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_BLK_DEV_SR
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include "scsi.h"
+#include "sr.h"
+
+#define MAJOR_NR 11
+
+#include "../blk.h"
+
+#define MAX_RETRIES 0
+#define SR_TIMEOUT 200
+
+int NR_SR=0;
+Scsi_CD scsi_CDs[MAX_SR];
+static int sr_sizes[MAX_SR << 4];
+static unsigned long int this_count;
+
+struct block_buffer
+ {
+ unsigned block;
+ unsigned start;
+ unsigned use:1;
+ unsigned char buffer[2048];
+ };
+
+static struct block_buffer bb[MAX_SR];
+
+static int sr_result;
+
+static int sr_open(struct inode *, struct file *);
+
+extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
+
+static void sr_release(struct inode * inode, struct file * file)
+{
+ sync_dev(inode->i_rdev);
+}
+
+static struct file_operations sr_fops =
+{
+ NULL, /* lseek - default */
+ block_read, /* read - general block-dev read */
+ block_write, /* write - general block-dev write */
+ NULL, /* readdir - bad */
+ NULL, /* select */
+ sr_ioctl, /* ioctl */
+ sr_open, /* no special open code */
+ sr_release /* release */
+};
+
+/*
+ * The sense_buffer is where we put data for all mode sense commands performed.
+ */
+
+static unsigned char sense_buffer[255];
+
+/*
+ * rw_intr is the interrupt routine for the device driver. It will be notified on the
+ * end of a SCSI read / write, and will take on of several actions based on success or failure.
+ */
+
+static void rw_intr (int host, int result)
+{
+ if (SR_HOST != host)
+ {
+ panic ("sr.o : rw_intr() recieving interrupt for different host.");
+ }
+
+ if (!result)
+ { /* No error */
+ if (bb[DEVICE_NR(CURRENT->dev)].use)
+ {
+ memcpy((char *)CURRENT->buffer,
+ bb[DEVICE_NR(CURRENT->dev)].buffer +
+ (bb[DEVICE_NR(CURRENT->dev)].start << 9),
+ this_count << 9);
+ }
+
+ CURRENT->nr_sectors -= this_count;
+
+#ifdef DEBUG
+ printk("(%x %x %x) ",CURRENT->bh, CURRENT->nr_sectors,
+ this_count);
+#endif
+ if (CURRENT->nr_sectors)
+ {
+ CURRENT->sector += this_count;
+ CURRENT->errors = 0;
+ if (!CURRENT->bh)
+ {
+ (char *) CURRENT->buffer += this_count << 9;
+ } else {
+ end_request(1);
+ do_sr_request();
+ }
+ }
+ else
+ {
+ end_request(1); /* All done */
+ do_sr_request();
+ }
+ }
+
+ /* We only come through here if we have an error of some kind */
+
+ if (driver_byte(result) != 0) {
+ bb[DEVICE_NR(CURRENT->dev)].block = -1;
+
+ if ((sense_buffer[0] & 0x7f) == 0x70) {
+ if ((sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
+ /* detected disc change. set a bit and quietly refuse */
+ /* further access. */
+
+ scsi_CDs[DEVICE_NR(CURRENT->dev)].changed = 1;
+ end_request(0);
+ return;
+ }
+ }
+
+ if (sense_buffer[2] == ILLEGAL_REQUEST) {
+ printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
+ if (scsi_CDs[DEVICE_NR(CURRENT->dev)].ten) {
+ scsi_CDs[DEVICE_NR(CURRENT->dev)].ten = 0;
+ do_sr_request();
+ result = 0;
+ return;
+ } else {
+ end_request(0);
+ do_sr_request(); /* Do next request */
+ return;
+ }
+
+ }
+
+ if (sense_buffer[2] == NOT_READY) {
+ printk("CDROM not ready. Make sure you have a disc in the drive.\n");
+ end_request(0);
+ do_sr_request(); /* Do next request */
+ return;
+ };
+ }
+
+ /* We only get this far if we have an error we have not recognized */
+ if(result) {
+ printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
+ scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no,
+ scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id,
+ scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun,
+ result);
+
+ if (status_byte(result) == CHECK_CONDITION)
+ printk("\tSense class %x, sense error %x, extended sense %x\n",
+ sense_class(sense_buffer[0]),
+ sense_error(sense_buffer[0]),
+ sense_buffer[2] & 0xf);
+
+ end_request(0);
+ do_sr_request();
+ }
+}
+
+static int sr_open(struct inode * inode, struct file * filp)
+{
+ if (filp->f_mode)
+ check_disk_change(inode->i_rdev);
+ return 0;
+}
+
+/*
+ * do_sr_request() is the request handler function for the sr driver. Its function in life
+ * is to take block device requests, and translate them to SCSI commands.
+ */
+
+void do_sr_request (void)
+{
+ unsigned int dev, block, realcount;
+ unsigned char cmd[10], *buffer, tries;
+
+ tries = 2;
+
+ repeat:
+ INIT_REQUEST;
+ dev = MINOR(CURRENT->dev);
+ block = CURRENT->sector;
+
+ bb[dev].start = block % 4;
+ block = block / 4;
+
+ if (dev >= NR_SR)
+ {
+ /* printk("CD-ROM request error: invalid device.\n"); */
+ end_request(0);
+ tries = 2;
+ goto repeat;
+ }
+
+ if (!scsi_CDs[dev].use)
+ {
+ /* printk("CD-ROM request error: device marked not in use.\n"); */
+ end_request(0);
+ tries = 2;
+ goto repeat;
+ }
+
+ if (scsi_CDs[dev].changed)
+ {
+/*
+ * quietly refuse to do anything to a changed disc until the changed bit has been reset
+ */
+ /* printk("CD-ROM has been changed. Prohibiting further I/O.\n"); */
+ end_request(0);
+ tries = 2;
+ goto repeat;
+ }
+
+ if (!CURRENT->bh)
+ this_count = CURRENT->nr_sectors;
+ else
+ this_count = (CURRENT->bh->b_size / 512);
+
+ if (bb[dev].start)
+ {
+ bb[dev].use = 1;
+
+ this_count = ((this_count > 4 - bb[dev].start) ?
+ (4 - bb[dev].start) : (this_count));
+
+ if (bb[dev].block == block)
+ {
+ rw_intr(SR_HOST, 0);
+ return;
+ }
+
+ buffer = bb[dev].buffer;
+ bb[dev].block = block;
+ }
+ else if (this_count < 4)
+ {
+ bb[dev].use = 1;
+
+ if (bb[dev].block == block)
+ {
+ rw_intr(SR_HOST, 0);
+ return;
+ }
+
+ buffer = bb[dev].buffer;
+ bb[dev].block = block;
+ }
+ else
+ {
+ this_count -= this_count % 4;
+ buffer = CURRENT->buffer;
+ bb[dev].use = 0;
+ }
+
+ realcount = (this_count + 3) / 4;
+
+ switch (CURRENT->cmd)
+ {
+ case WRITE:
+ end_request(0);
+ goto repeat;
+ break;
+ case READ :
+ cmd[0] = READ_6;
+ break;
+ default :
+ printk ("Unknown sr command %d\r\n", CURRENT->cmd);
+ panic("");
+ }
+
+ cmd[1] = (SR_LUN << 5) & 0xe0;
+
+ if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
+ {
+ if (realcount > 0xffff)
+ {
+ realcount = 0xffff;
+ this_count = realcount * 4;
+ }
+
+ cmd[0] += READ_10 - READ_6 ;
+ cmd[2] = (unsigned char) (block >> 24) & 0xff;
+ cmd[3] = (unsigned char) (block >> 16) & 0xff;
+ cmd[4] = (unsigned char) (block >> 8) & 0xff;
+ cmd[5] = (unsigned char) block & 0xff;
+ cmd[6] = cmd[9] = 0;
+ cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
+ cmd[8] = (unsigned char) realcount & 0xff;
+ }
+ else
+ {
+ if (realcount > 0xff)
+ {
+ realcount = 0xff;
+ this_count = realcount * 4;
+ }
+
+ cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
+ cmd[2] = (unsigned char) ((block >> 8) & 0xff);
+ cmd[3] = (unsigned char) block & 0xff;
+ cmd[4] = (unsigned char) realcount;
+ cmd[5] = 0;
+ }
+
+ scsi_do_cmd (SR_HOST, SR_ID, (void *) cmd, buffer, realcount << 11,
+ rw_intr, SR_TIMEOUT, sense_buffer, MAX_RETRIES);
+}
+
+void sr_init(void)
+{
+ int i;
+
+ for (i = 0; i < NR_SR; ++i)
+ {
+ scsi_CDs[i].capacity = 0x1fffff;
+ scsi_CDs[i].sector_size = 2048;
+ scsi_CDs[i].use = 1;
+ scsi_CDs[i].ten = 1;
+ scsi_CDs[i].remap = 1;
+ scsi_CDs[i].changed = 0;
+ sr_sizes[i] = scsi_CDs[i].capacity;
+
+ bb[i].block = -1;
+ }
+
+ blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blk_size[MAJOR_NR] = sr_sizes;
+ blkdev_fops[MAJOR_NR] = &sr_fops;
+}
+#endif
+
+
+
+
+
--- /dev/null
+/*
+ * sr.h by David Giller
+ * CD-ROM disk driver header file
+ *
+ * adapted from:
+ * sd.h Copyright (C) 1992 Drew Eckhardt
+ * SCSI disk driver header file by
+ * Drew Eckhardt
+ *
+ * <drew@colorado.edu>
+ */
+
+#ifndef _SR_H
+#define _SR_H
+
+#include "scsi.h"
+
+#define MAX_SR 2
+extern int NR_SR;
+
+typedef struct
+ {
+ unsigned capacity; /* size in blocks */
+ unsigned sector_size; /* size in bytes */
+ Scsi_Device *device;
+ unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */
+ unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift*/
+ unsigned ten:1; /* support ten byte commands */
+ unsigned remap:1; /* support remapping */
+ unsigned use:1; /* is this device still supportable */
+ unsigned changed:1; /* disk changed flag */
+ } Scsi_CD;
+
+extern Scsi_CD scsi_CDs[MAX_SR];
+
+void sr_init(void);
+
+#define SR_HOST (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no)
+#define SR_ID (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id)
+#define SR_LUN (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun)
+#endif
--- /dev/null
+#include <linux/config.h>
+#ifdef CONFIG_BLK_DEV_SR
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <asm/segment.h>
+#include <linux/errno.h>
+
+#include "../blk.h"
+#include "scsi.h"
+#include "sr.h"
+
+#include <linux/cdrom.h>
+
+#define IOCTL_RETRIES 3
+/* The CDROM is fairly slow, so we need a little extra time */
+#define IOCTL_TIMEOUT 200
+
+static u_char sr_cmd[10];
+static u_char data_buffer[255];
+static u_char sense_buffer[255];
+static int the_result;
+
+static struct wait_queue *sr_cmd_wait = NULL; /* For waiting until cmd done*/
+static u_char sr_lock = 0; /* To make sure that only one person is doing
+ an ioctl at one time */
+static int target;
+
+extern int scsi_ioctl (int dev, int cmd, void *arg);
+
+static void lock_sr_ioctl( void )
+{
+ /* We do not use wakeup here because there could conceivably be three
+ processes trying to get at the drive simultaneously, and we would
+ be screwed if that happened.
+ */
+
+ while (sr_lock);
+ sr_lock = 1;
+}
+
+static void unlock_sr_ioctl( void )
+{
+ sr_lock = 0;
+}
+
+static void sr_ioctl_done( int host, int result )
+{
+ the_result = result;
+ wake_up(&sr_cmd_wait);
+}
+
+/* We do our own retries because we want to know what the specific
+ error code is. Normally the UNIT_ATTENTION code will automatically
+ clear after one error */
+
+static int do_ioctl( void )
+{
+ int retries = IOCTL_RETRIES;
+retry:
+
+ the_result = -1;
+
+ scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
+ (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done,
+ IOCTL_TIMEOUT, (void *) sense_buffer, 0);
+
+ while (the_result < 0) sleep_on(&sr_cmd_wait);
+
+ if(driver_byte(the_result) != 0 &&
+ (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
+ scsi_CDs[target].changed = 1;
+ printk("Disc change detected.\n");
+ };
+
+ if (the_result && retries)
+ {
+ retries--;
+ goto retry;
+ }
+
+/* Minimal error checking. Ignore cases we know about, and report the rest. */
+ if(driver_byte(the_result) != 0)
+ switch(sense_buffer[2] & 0xf) {
+ case UNIT_ATTENTION:
+ scsi_CDs[target].changed = 1;
+ printk("Disc change detected.\n");
+ break;
+ case NOT_READY: /* This happens if there is no disc in drive */
+ printk("CDROM not ready. Make sure there is a disc in the drive.\n");
+ break;
+ case ILLEGAL_REQUEST:
+ printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
+ break;
+ default:
+ printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
+ scsi_CDs[target].device->host_no,
+ scsi_CDs[target].device->id,
+ scsi_CDs[target].device->lun,
+ the_result);
+ printk("\tSense class %x, sense error %x, extended sense %x\n",
+ sense_class(sense_buffer[0]),
+ sense_error(sense_buffer[0]),
+ sense_buffer[2] & 0xf);
+
+ };
+ return the_result;
+}
+
+/*
+ * This function checks to see if the media has been changed in the
+ * CDROM drive. It is possible that we have already sensed a change,
+ * or the drive may have sensed one and not yet reported it. We must
+ * be ready for either case. This function always reports the current
+ * value of the changed bit. If flag is 0, then the changed bit is reset.
+ * This function could be done as an ioctl, but we would need to have
+ * an inode for that to work, and we do not always have one.
+ */
+
+int check_cdrom_media_change(int full_dev, int flag){
+ int retval;
+
+ lock_sr_ioctl();
+
+ target = MINOR(full_dev);
+
+ if (target >= NR_SR) {
+ printk("CD-ROM request error: invalid device.\n");
+ unlock_sr_ioctl();
+ return 0;
+ };
+
+ sr_cmd[0] = TEST_UNIT_READY;
+ sr_cmd[1] = (scsi_CDs[target].device->lun << 5) & 0xe0;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
+
+ retval = do_ioctl();
+
+ if(retval){ /* Unable to test, unit probably not ready. This usually
+ means there is no disc in the drive. Mark as changed,
+ and we will figure it out later once the drive is
+ available again. */
+
+ scsi_CDs[target].changed = 1;
+ unlock_sr_ioctl();
+ return 1; /* This will force a flush, if called from
+ check_disk_change */
+ };
+
+ retval = scsi_CDs[target].changed;
+ if(!flag) scsi_CDs[target].changed = 0;
+ unlock_sr_ioctl();
+
+ return retval;
+}
+
+int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
+{
+ int dev = inode->i_rdev;
+ int result;
+
+ target = MINOR(dev);
+
+ switch (cmd)
+ {
+ /* linux-specific */
+ case CDROMDOORUNLOCK:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+ sr_cmd[4] = SR_REMOVAL_ALLOW;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMDOORLOCK:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+ sr_cmd[4] = SR_REMOVAL_PREVENT;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ /* Sun-compatible */
+ case CDROMPAUSE:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = SCMD_PAUSE_RESUME;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
+ sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
+ sr_cmd[8] = 1;
+ sr_cmd[9] = 0;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMRESUME:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = SCMD_PAUSE_RESUME;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
+ sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
+ sr_cmd[8] = 0;
+ sr_cmd[9] = 0;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMPLAYMSF:
+ {
+ struct cdrom_msf msf;
+ lock_sr_ioctl();
+
+ memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
+
+ sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = 0;
+ sr_cmd[3] = msf.cdmsf_min0;
+ sr_cmd[4] = msf.cdmsf_sec0;
+ sr_cmd[5] = msf.cdmsf_frame0;
+ sr_cmd[6] = msf.cdmsf_min1;
+ sr_cmd[7] = msf.cdmsf_sec1;
+ sr_cmd[8] = msf.cdmsf_frame1;
+ sr_cmd[9] = 0;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+ }
+
+ case CDROMPLAYTRKIND:
+ {
+ struct cdrom_ti ti;
+ lock_sr_ioctl();
+
+ memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
+
+ sr_cmd[0] = SCMD_PLAYAUDIO_TI;
+ sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+ sr_cmd[2] = 0;
+ sr_cmd[3] = 0;
+ sr_cmd[4] = ti.cdti_trk0;
+ sr_cmd[5] = ti.cdti_ind0;
+ sr_cmd[6] = 0;
+ sr_cmd[7] = ti.cdti_trk1;
+ sr_cmd[8] = ti.cdti_ind1;
+ sr_cmd[9] = 0;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+ }
+
+ case CDROMREADTOCHDR:
+ return -EINVAL;
+ case CDROMREADTOCENTRY:
+ return -EINVAL;
+
+ case CDROMSTOP:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = START_STOP;
+ sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+ sr_cmd[4] = 0;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMSTART:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = START_STOP;
+ sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+ sr_cmd[4] = 1;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMEJECT:
+ lock_sr_ioctl();
+
+ sr_cmd[0] = START_STOP;
+ sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+ sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+ sr_cmd[4] = 0x02;
+
+ result = do_ioctl();
+
+ unlock_sr_ioctl();
+ return result;
+
+ case CDROMVOLCTRL:
+ return -EINVAL;
+ case CDROMSUBCHNL:
+ return -EINVAL;
+ case CDROMREADMODE2:
+ return -EINVAL;
+ case CDROMREADMODE1:
+ return -EINVAL;
+
+ RO_IOCTLS(dev,arg);
+ default:
+ return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
+ }
+}
+
+#endif
$(AR) rcs chr_drv.a $(OBJS)
sync
+console.o: console.c
+ $(CC) $(CFLAGS) $(NUM_LOCK) -c -o console.o console.c
+
keyboard.o: keyboard.c
- $(CC) $(CFLAGS) $(KEYBOARD) -c -o keyboard.o keyboard.c
+ $(CC) $(CFLAGS) $(KEYBOARD) $(NUM_LOCK) -c -o keyboard.o keyboard.c
clean:
rm -f core *.o *.a tmp_make keyboard.s
* removed assignment chr_fops[10] = &mouse_fops; see mouse.c
* renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
* renamed this file mouse.c => busmouse.c
- *
- * version 0.1
+ *
+ * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+ *
+ * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+ * 8/28/92
+ *
+ * Microsoft Bus Mouse support folded into 0.97pl4 code
+ * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ * Changes: Logitech and Microsoft support in the same kernel.
+ * Defined new constants in busmouse.h for MS mice.
+ * Added int mse_busmouse_type to distinguish busmouse types
+ * Added a couple of new functions to handle differences in using
+ * MS vs. Logitech (where the int variable wasn't appropriate).
+ *
+ * version 0.2
*/
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/irq.h>
+
static struct mouse_status mouse;
static void mouse_interrupt(int unused)
wake_up(&mouse.inode->i_wait);
MSE_INT_ON();
+
+}
+
+/* Use separate function for MS mice - keep both short & fast */
+static void ms_mouse_interrupt(int unused)
+{
+ char dx, dy, buttons;
+
+ outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
+ outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
+
+ outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
+ dx = inb(MS_MSE_DATA_PORT);
+
+ outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
+ dy = inb(MS_MSE_DATA_PORT);
+
+ outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
+ buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
+
+ outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
+ outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
+
+ mouse.buttons = buttons;
+ mouse.latch_buttons |= buttons;
+ mouse.dx += dx;
+ mouse.dy += dy;
+ mouse.ready = 1;
+ if (mouse.inode && mouse.inode->i_wait)
+ wake_up(&mouse.inode->i_wait);
+
}
static void release_mouse(struct inode * inode, struct file * file)
{
- MSE_INT_OFF();
+ if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+ MSE_INT_OFF();
+ } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) {
+ MS_MSE_INT_OFF();
+ } /* else if next mouse type, etc. */
+
mouse.active = 0;
mouse.ready = 0;
mouse.inode = NULL;
mouse.dx = 0;
mouse.dy = 0;
mouse.buttons = mouse.latch_buttons = 0x80;
- if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
- /* once we get to here mouse is unused, IRQ is busy */
- mouse.active = 0; /* it's not active, fix it */
- return -EBUSY; /* IRQ is busy, so we're BUSY */
- } /* if we can't get the IRQ and mouse not active */
- MSE_INT_ON();
+
+ if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+ if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
+ /* once we get to here mouse is unused, IRQ is busy */
+ mouse.active = 0; /* it's not active, fix it */
+ return -EBUSY; /* IRQ is busy, so we're BUSY */
+ } /* if we can't get the IRQ and mouse not active */
+ MSE_INT_ON();
+
+ } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) {
+
+ if (request_irq(MOUSE_IRQ, ms_mouse_interrupt)) {
+ /* once we get to here mouse is unused, IRQ is busy */
+ mouse.active = 0; /* it's not active, fix it */
+ return -EBUSY; /* IRQ is busy, so we're BUSY */
+ } /* if we can't get the IRQ and mouse not active */
+ outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
+ MS_MSE_INT_ON();
+
+ }
+
return 0;
}
+
static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
{
return -EINVAL;
if (count < 3) return -EINVAL;
if (!mouse.ready) return -EAGAIN;
-
- MSE_INT_OFF();
+
+ if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+ MSE_INT_OFF();
+ }
put_fs_byte(mouse.latch_buttons | 0x80, buffer);
mouse.latch_buttons = mouse.buttons;
mouse.ready = 0;
- MSE_INT_ON();
+ if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+ MSE_INT_ON();
+ }
+
return i;
}
for (i = 0; i < 100000; i++); /* busy loop */
if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
- printk("No bus mouse detected.\n");
+ printk("No Logitech bus mouse detected.\n");
mouse.present = 0;
return kmem_start;
}
mouse.buttons = mouse.latch_buttons = 0x80;
mouse.dx = 0;
mouse.dy = 0;
- printk("Bus mouse detected and installed.\n");
+ printk("Logitech Bus mouse detected and installed.\n");
+ return kmem_start;
+}
+
+long ms_bus_mouse_init(long kmem_start)
+{
+
+ MS_MSE_INT_OFF();
+
+ mouse.present = 1;
+ mouse.active = mouse.ready = 0;
+ mouse.buttons = mouse.latch_buttons = 0x80;
+ mouse.dx = mouse.dy = 0;
+ printk("Microsoft Bus mouse detected and installed.\n");
return kmem_start;
}
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/kd.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/segment.h>
-#include <sys/kd.h>
#include "vt_kern.h"
#define NPAR 16
#define kbdleds (vt_cons[currcons].vc_kbdleds)
#define vtmode (vt_cons[currcons].vt_mode)
+#if defined KBD_NUMERIC_LOCK
+#define NUMLED_DEFAULT 0x02
+
+#else
+#define NUMLED_DEFAULT 0
+#endif
+
#define SET(mode,fg,v) \
(mode) = (v); \
if (currcons == fg_console) \
ckmode = 0;
kapplic = 0;
lfnlmode = 0;
- kleds = 2;
+ kleds = NUMLED_DEFAULT;
kmode = 0;
set_leds();
} else {
decckm = 0;
kbdapplic = 0;
lnm = 0;
- kbdleds = 2;
+ kbdleds = NUMLED_DEFAULT;
kbdmode = 0;
}
#define NUMLED 0x02
#define CAPSLED 0x04
+#if defined KBD_NUMERIC_LOCK
+#define NUMLED_DEFAULT NUMLED
+
+#else
+#define NUMLED_DEFAULT 0
+#endif
+
#define NO_META_BIT 0x80
unsigned char kapplic = 0;
unsigned char ckmode = 0;
unsigned char krepeat = 1;
unsigned char kmode = 0;
-unsigned char kleds = NUMLED;
+unsigned char kleds = NUMLED_DEFAULT;
unsigned char ke0 = 0;
unsigned char kraw = 0;
unsigned char kbd_flags = KBDFLAGS;
typedef void (*fptr)(int);
-static unsigned char old_leds = 2;
+static unsigned char old_leds = NUMLED;
static int diacr = -1;
static int npadch = 0;
fptr key_table[];
* Generic mouse open routine by Johan Myreen
*
* Based on code from Linus
+ *
+ * Teemu Rantanen's Microsoft Busmouse support and Derrick Cole's
+ * changes incorporated into 0.97pl4
+ * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ * See busmouse.c for particulars.
*/
#include <linux/fs.h>
extern struct file_operations psaux_fops;
extern long bus_mouse_init(long);
extern long psaux_init(long);
+extern long ms_bus_mouse_init(long);
+
+int mse_busmouse_type;
static int mouse_open(struct inode * inode, struct file * file)
{
file->f_op = &bus_mouse_fops;
else if (MINOR(inode->i_rdev) == PSMOUSE_MINOR)
file->f_op = &psaux_fops;
+ else if (MINOR(inode->i_rdev) == MS_BUSMOUSE_MINOR)
+ file->f_op = &bus_mouse_fops;
else
return -ENODEV;
+ mse_busmouse_type = (int) MINOR(inode->i_rdev);
return file->f_op->open(inode,file);
}
{
kmem_start = bus_mouse_init(kmem_start);
kmem_start = psaux_init(kmem_start);
+ kmem_start = ms_bus_mouse_init(kmem_start);
+ mse_busmouse_type = -1;
chrdev_fops[10] = &mouse_fops;
return kmem_start;
}
return 0;
}
+int get_modem_info(unsigned int line, unsigned int *value)
+{
+ unsigned port = (serial_table + line)->port;
+ unsigned char control = inb(port+4);
+ unsigned char status = inb(port+6);
+ unsigned int result;
+
+ result = ((control & 0x02) ? TIOCM_RTS : 0)
+ | ((control & 0x01) ? TIOCM_DTR : 0)
+ | ((status & 0x80) ? TIOCM_CAR : 0)
+ | ((status & 0x40) ? TIOCM_RNG : 0)
+ | ((status & 0x20) ? TIOCM_DSR : 0)
+ | ((status & 0x10) ? TIOCM_CTS : 0);
+ put_fs_long(result,(unsigned long *) value);
+ return 0;
+}
+
+int set_modem_info(unsigned int line, unsigned int cmd, unsigned int *value)
+{
+ unsigned port = (serial_table + line)->port;
+ unsigned char control = inb(port+4);
+ unsigned int arg = get_fs_long((unsigned long *) value);
+
+ switch (cmd) {
+ case TIOCMBIS:
+ if (arg & TIOCM_RTS)
+ control |= 0x02;
+ if (arg & TIOCM_DTR)
+ control |= 0x01;
+ break;
+ case TIOCMBIC:
+ if (arg & TIOCM_RTS)
+ control &= ~0x02;
+ if (arg & TIOCM_DTR)
+ control &= ~0x01;
+ break;
+ case TIOCMSET:
+ control = (control & ~0x03)
+ | ((arg & TIOCM_RTS) ? 0x02 : 0)
+ | ((arg & TIOCM_DTR) ? 0x01 : 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ outb(port,control);
+ return 0;
+}
+
long rs_init(long kmem_start)
{
int i;
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/ctype.h>
+#include <linux/kd.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <sys/kd.h>
#include "vt_kern.h"
#define QUEUES (3*(NR_CONSOLES+NR_SERIALS+2*NR_PTYS))
set_window_size(other_tty,(struct winsize *) arg);
return set_window_size(tty,(struct winsize *) arg);
case TIOCMGET:
- return -EINVAL; /* not implemented */
+ if (!IS_A_SERIAL(dev))
+ return -EINVAL;
+ verify_area((void *) arg,sizeof(unsigned int *));
+ return get_modem_info(dev-64,(unsigned int *) arg);
case TIOCMBIS:
- return -EINVAL; /* not implemented */
case TIOCMBIC:
- return -EINVAL; /* not implemented */
case TIOCMSET:
- return -EINVAL; /* not implemented */
+ if (!IS_A_SERIAL(dev))
+ return -EINVAL;
+ return set_modem_info(dev-64,cmd,(unsigned int *) arg);
case TIOCGSOFTCAR:
return -EINVAL; /* not implemented */
case TIOCSSOFTCAR:
#include <linux/tty.h>
#include <linux/timer.h>
#include <linux/kernel.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
#include <asm/io.h>
#include <asm/segment.h>
#include "vt_kern.h"
-#include <sys/kd.h>
-#include <sys/vt.h>
/*
* console (vt and kd) routines, as defined by usl svr4 manual
* Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <time.h>
+#include <linux/mktime.h>
/*
* This isn't the library routine, it is only used in the kernel.
DAY*(31+29+31+30+31+30+31+31+30+31+30)
};
-long kernel_mktime(struct tm * tm)
+long kernel_mktime(struct mktime * time)
{
long res;
int year;
- year = tm->tm_year - 70;
+ year = time->year - 70;
/* magic offsets (y+1) needed to get leapyears right.*/
res = YEAR*year + DAY*((year+1)/4);
- res += month[tm->tm_mon];
+ res += month[time->mon];
/* and (y+2) here. If it wasn't a leap-year, we have to adjust */
- if (tm->tm_mon>1 && ((year+2)%4))
+ if (time->mon>1 && ((year+2)%4))
res -= DAY;
- res += DAY*(tm->tm_mday-1);
- res += HOUR*tm->tm_hour;
- res += MINUTE*tm->tm_min;
- res += tm->tm_sec;
+ res += DAY*(time->day-1);
+ res += HOUR*time->hour;
+ res += MINUTE*time->min;
+ res += time->sec;
return res;
}
do_exit(SIGSEGV);
}
memcpy_tofs(&(current->vm86_info->regs),regs,sizeof(*regs));
+ put_fs_long(current->screen_bitmap,&(current->vm86_info->screen_bitmap));
stack = current->tss.esp0;
current->tss.esp0 = current->saved_kernel_stack;
current->saved_kernel_stack = 0;
return stack;
}
+static void mark_screen_rdonly(struct task_struct * tsk)
+{
+ unsigned long tmp;
+ unsigned long *pg_table;
+
+ if (tmp = tsk->tss.cr3) {
+ tmp = *(unsigned long *) tmp;
+ if (tmp & PAGE_PRESENT) {
+ tmp &= 0xfffff000;
+ pg_table = (0xA00000 >> PAGE_SHIFT) + (unsigned long *) tmp;
+ tmp = 32;
+ while (tmp--) {
+ if (PAGE_PRESENT & *pg_table)
+ *pg_table &= ~PAGE_RW;
+ pg_table++;
+ }
+ }
+ }
+}
+
int sys_vm86(struct vm86_struct * v86)
{
struct vm86_struct info;
current->saved_kernel_stack = current->tss.esp0;
current->tss.esp0 = (unsigned long) pt_regs;
current->vm86_info = v86;
+ current->screen_bitmap = info.screen_bitmap;
+ if (info.flags & VM86_SCREEN_BITMAP)
+ mark_screen_rdonly(current);
__asm__ __volatile__("movl %0,%%esp\n\t"
"pushl $ret_from_sys_call\n\t"
"ret"::"g" ((long) &(info.regs)),"a" (info.regs.eax));
movl %eax,EAX(%esp) # save the return value
.align 4,0x90
ret_from_sys_call:
- movl EFLAGS(%esp),%eax
- testl $VM_MASK,%eax
- jne 1f
+ movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
+ testl $VM_MASK,%eax # different then
+ jne 4f
cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
jne 2f
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
jne 2f
-1: orl $IF_MASK,%eax # these just try to make sure
+4: orl $IF_MASK,%eax # these just try to make sure
andl $~NT_MASK,%eax # the program doesn't do anything
movl %eax,EFLAGS(%esp) # stupid
- cmpl $0,_need_resched
+1: cmpl $0,_need_resched
jne reschedule
movl _current,%eax
cmpl _task,%eax # task[0] cannot have signals
big buffers around for itself.) I guess I'll have return from
syscall fill up the free page descriptors. -RAB */
+/* since the advent of GFP_ATOMIC, I've changed the malloc code to
+ use it and return NULL if it can't get a page. -RAB */
+
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
{ 4096, (struct bucket_desc *) 0},
{ 0, (struct bucket_desc *) 0}}; /* End of list marker */
-/* Where to keep the extra pages, and how many. */
-#define FREE_PAGES 20
-static volatile unsigned long free_pages[FREE_PAGES]={0,};
-volatile short free_page_ptr=0; /* this -1 is next free page. */
-
-/* malloc_free_page makes sure that we have all the free pages we
- want around before actually freeing the page. */
-
-/* called with interrupts off. */
-void
-malloc_free_page (unsigned long addr)
-{
- if (free_page_ptr < FREE_PAGES)
- free_pages[free_page_ptr++] = addr;
- else
- free_page (addr);
-}
-
-/* Fill up the extra page buffer. Should be called quite often to make
- sure we have some floating around. */
-
-void
-malloc_grab_pages(void)
-{
- while (free_page_ptr < FREE_PAGES)
- {
- unsigned long page;
-
- page = get_free_page (GFP_KERNEL);
- if (page == 0)
- {
- printk ("malloc_grab_pages: Can't happen. no memory.\n");
- continue;
- }
- /* see if we still need the page. This can only happen if
- we get interrupted while we are trying to get some pages,
- and we are out of pages. It shouldn't happen, but it
- could and we had better check for it. */
- cli();
- if (free_page_ptr < FREE_PAGES)
- {
- free_pages[free_page_ptr] = page;
- free_page_ptr++;
- }
- else
- {
- free_page(page);
- }
- sti();
- }
-}
-
-/* called with interrupts off. */
-static inline unsigned long
-malloc_get_free_page (void)
-{
- unsigned long page;
- int page_ptr;
-
- if (free_page_ptr > 0)
- {
- page_ptr = --free_page_ptr;
- page = free_pages[page_ptr];
- free_pages[page_ptr] = 0;
- return (page);
- }
-
- printk ("malloc_get_free_page: Calling malloc_grab_pages\n");
- /* this routine turns on interrupts. Maybe we should do a pushflags
- pop flags around it. */
- malloc_grab_pages();
- cli();
- page_ptr = --free_page_ptr;
- page = free_pages[page_ptr];
- free_pages[page_ptr] = 0;
- return (page);
-}
-
/*
* This contains a linked list of free bucket descriptor blocks
*/
/*
* This routine initializes a bucket description page.
*/
-static inline void init_bucket_desc()
+static inline int init_bucket_desc()
{
struct bucket_desc *bdesc, *first;
- int i;
+ int i;
/* this turns interrupt on, so we should be carefull. */
- first = bdesc = (struct bucket_desc *) malloc_get_free_page();
+ first = bdesc = (struct bucket_desc *) get_free_page(GFP_ATOMIC);
if (!bdesc)
- panic("Out of memory in init_bucket_desc()");
+ return 1;
for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {
bdesc->next = bdesc+1;
bdesc++;
}
/*
- * This is done last, to avoid race conditions in case
+ * This is done last, to avoid race conditions in case
* get_free_page() sleeps and this routine gets called again....
*/
+ /* Get free page will not sleep because of the GFP_ATOMIC */
bdesc->next = free_bucket_desc;
free_bucket_desc = first;
+ return (0);
}
void *malloc(unsigned int len)
for (bdir = bucket_dir; bdir->size; bdir++)
if (bdir->size >= len)
break;
+
if (!bdir->size) {
- printk("malloc called with impossibly large argument (%d)\n",
- len);
- panic("malloc: bad arg");
+ printk("malloc called with impossibly large argument (%d)\n", len);
+ return NULL;
}
/*
* Now we search for a bucket descriptor which has free space
*/
cli(); /* Avoid race conditions */
- for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
+ for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
if (bdesc->freeptr)
break;
/*
- * If we didn't find a bucket with free space, then we'll
+ * If we didn't find a bucket with free space, then we'll
* allocate a new one.
*/
if (!bdesc) {
- char *cp;
- int i;
-
- if (!free_bucket_desc)
- init_bucket_desc();
+ char *cp;
+ int i;
+
+ if (!free_bucket_desc)
+ if (init_bucket_desc()) {
+ sti();
+ return NULL;
+ }
bdesc = free_bucket_desc;
free_bucket_desc = bdesc->next;
bdesc->refcnt = 0;
bdesc->bucket_size = bdir->size;
bdesc->page = bdesc->freeptr =
- (void *) cp = malloc_get_free_page();
- if (!cp)
- panic("Out of memory in kernel malloc()");
+ (void *) cp = get_free_page(GFP_ATOMIC);
+ if (!cp) {
+ sti();
+ return NULL;
+ }
/* Set up the chain of free objects */
for (i=PAGE_SIZE/bdir->size; i > 1; i--) {
*((char **) cp) = cp + bdir->size;
bdesc->freeptr = *((void **) retval);
bdesc->refcnt++;
sti(); /* OK, we're safe again */
- return(retval);
+ return retval;
}
/*
* Here is the free routine. If you know the size of the object that you
* are freeing, then free_s() will use that information to speed up the
* search for the bucket descriptor.
- *
+ *
* We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"
*/
void free_s(void *obj, int size)
if (bdir->size < size)
continue;
for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) {
- if (bdesc->page == page)
+ if (bdesc->page == page)
goto found;
prev = bdesc;
}
panic("malloc bucket chains corrupted");
bdir->chain = bdesc->next;
}
- malloc_free_page((unsigned long) bdesc->page);
+ free_page((unsigned long) bdesc->page);
bdesc->next = free_bucket_desc;
free_bucket_desc = bdesc;
}
sti();
return;
}
-
* when the page is referenced. current assumptions
* cause it to be treated as demand allocation.
*/
- if (mask == 4 || to >= high_memory)
+ if (mask == 4 || to >= high_memory || !mem_map[MAP_NR(to)])
*page_table++ = 0; /* not present */
else {
++current->rss;
void do_page_fault(unsigned long *esp, unsigned long error_code)
{
unsigned long address;
- unsigned long user_esp;
+ unsigned long user_esp = 0;
- if ((0xffff & esp[1]) == 0xf)
- user_esp = esp[3];
- else
- user_esp = 0;
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
+ if (esp[2] & VM_MASK) {
+ unsigned int bit;
+
+ bit = (address - 0xA0000) >> PAGE_SHIFT;
+ if (bit < 32)
+ current->screen_bitmap |= 1 << bit;
+ } else
+ if ((0xffff & esp[1]) == 0xf)
+ user_esp = esp[3];
if (!(error_code & 1))
do_no_page(error_code, address, current, user_esp);
else
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/errno.h>
+#include <linux/mman.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <sys/mman.h>
-
/*
* description of effects of mapping type and prot in current implementation.
* this is due to the current handling of page faults in memory.c. the expected
*table_ptr = 0;
invalidate();
free_page(page);
- return !mem_map[MAP_NR(page)];
+ return 1 + mem_map[MAP_NR(page)];
}
/*
swap_table++;
goto check_dir;
}
- if (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
- p->rss--;
- return 1;
+ switch (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
+ case 0: break;
+ case 1: p->rss--; return 1;
+ default: p->rss--;
}
swap_page++;
goto check_table;
read_swap_page(page>>1, (char *) tmp);
if (*ppage == page) {
*ppage = tmp | (PAGE_DIRTY | 7);
+ ++p->rss;
swap_free(page>>1);
tmp = 0;
}
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+ $(CPP) -M *.c >> tmp_make
cp tmp_make Makefile
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE) dep) || exit; done