VFS gets "permission()" virtual function.
[Original announcement below]
Still no 1.0 - I have had a couple of reports of problems, so I'll make
yet another 0.99 release. The diffs (against 0.99.2) and complete
source can be found at nic.funet.fi: pub/OS/Linux/PEOPLE/Linus as usual,
and will probably show up at the other sites pretty soon.
0.99.3 contains no real new features, but the diffs are pretty big
anyway (100kB+ compressed): various things have moved around a bit and
there are a lot of minor changes. The changes include (but are not
limited to):
- the math emulator code now also understands the unofficial codes (in
case somebody followed the ML math emulator thread). I'd be
interested to hear whether ML now works with the emulator.
- various SCSI driver changes
- some re-organization of the tty open/close code to remove a few race
conditions.
- interrupt handling rewrites (two-level interrupt code cleanups)
- the serial drivers are tytso's alpha-drivers: they aren't quite
completed, but as they need the interrupt handling patches to get
ready, this is probably the least traumatic way of doing it.
- some more minor keyboard driver changes (mostly taking advantage of
the two-level interrupts)
+ a lot of other minor changes. I once more hope people will try it
out, and report any problems or successes to me.
Known problems:
- there seems to be something weird going on in the ST-0x driver with
some scsi disks.
- tcp/ip is reportedly still not quite stable, and I can't even test it
out.
NOTE! The DMA functions have changed for the high DMA channels - all DMA
functions now take their arguments as the number of bytes instead of the
old way of using bytes for ch 0-3 and words for ch 5-7. This might lead
to problems with the SoundBlaster driver, which may need editing.
Linus
#
# This script is used to configure the linux kernel.
# It's a fast hack - feel free to do something better.
-CONFIG=.config
+CONFIG=.config~
CONFIG_H=include/linux/autoconf.h
echo "#" > $CONFIG
echo "# Automatically generated make config: don't edit" >> $CONFIG
#
-# Make "config" the default target if there is no configuration file
+# Make "config" the default target if there is no configuration file or
+# "depend" the target if there is no top-level dependency information.
#
ifeq (.config,$(wildcard .config))
include .config
+ifeq (.depend,$(wildcard .depend))
+include .depend
+else
+CONFIGURATION = depend
+endif
else
CONFIGURATION = config
endif
+ifdef CONFIGURATION
+CONFIGURE = dummy
+endif
+
#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
#
# The value of KBDFLAGS should be or'ed together from the following
# bits, depending on which features you want enabled.
-# 0x80 - Off: the Alt key will set bit 7 if pressed together with
-# another key.
-# On: the Alt key will NOT set the high bit; an escape
-# character is prepended instead.
+#
# The least significant bits control if the following keys are "dead".
# The key is dead by default if the bit is on.
# 0x01 - backquote (`)
all: Version Image
-lilo: Image
+Version: dummy
+ rm tools/version.h
+
+lilo: $(CONFIGURE) Image
if [ -f /vmlinux ]; then mv /vmlinux /vmlinux.old; fi
cat Image > /vmlinux
/etc/lilo/install
config:
-ifdef CONFIGURATION
- @echo
- @echo "You have no .config: running Configure"
- @echo
-endif
sh Configure < config.in
-ifdef CONFIGURATION
- @echo
- @echo "Configure successful. Try re-making (ignore the error that follows)"
- @echo
- exit 1
-endif
+ mv .config~ .config
linuxsubdirs: dummy
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
-Version: dummy
+tools/version.h: $(CONFIGURE) Makefile
@./makever.sh
- @echo \#define UTS_RELEASE \"0.99.pl2-`cat .version`\" > tools/version.h
+ @echo \#define UTS_RELEASE \"0.99.pl3-`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
@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> tools/version.h
-Image: $(CONFIGURATION) boot/bootsect boot/setup tools/system tools/build
+Image: $(CONFIGURE) boot/bootsect boot/setup tools/system tools/build
cp tools/system system.tmp
$(STRIP) system.tmp
tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image
disk: Image
dd bs=8192 if=Image of=/dev/fd0
-tools/build: tools/build.c
+tools/build: $(CONFIGURE) tools/build.c
$(HOSTCC) $(CFLAGS) \
-o tools/build tools/build.c
-boot/head.o: boot/head.s
+boot/head.o: $(CONFIGURE) boot/head.s
-boot/head.s: boot/head.S
+boot/head.s: $(CONFIGURE) boot/head.S
$(CPP) -traditional boot/head.S -o boot/head.s
tools/version.o: tools/version.c tools/version.h
-init/main.o: init/main.c
+init/main.o: $(CONFIGURE) init/main.c
$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs
$(AS86) -o boot/setup.o boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
-boot/setup.s: boot/setup.S include/linux/config.h Makefile
+boot/setup.s: $(CONFIGURE) boot/setup.S include/linux/config.h Makefile
$(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/setup.S -o boot/setup.s
-boot/bootsect.s: boot/bootsect.S include/linux/config.h Makefile
+boot/bootsect.s: $(CONFIGURE) boot/bootsect.S include/linux/config.h Makefile
$(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/bootsect.S -o boot/bootsect.s
boot/bootsect: boot/bootsect.s
sync
depend dep:
- for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .depend
+ for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .depend~
+ for i in tools/*.c;do echo -n "tools/";$(CPP) -M $$i;done >> .depend~
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
+ mv .depend~ .depend
-dummy: $(CONFIGURATION)
+ifdef CONFIGURATION
+..$(CONFIGURATION):
+ @echo
+ @echo "You have no" .$(CONFIGURATION) ": running 'make" $(CONFIGURATION)"'"
+ @echo
+ $(MAKE) $(CONFIGURATION)
+ @echo
+ @echo "Successful. Try re-making (ignore the error that follows)"
+ @echo
+ exit 1
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
+dummy: ..$(CONFIGURATION)
+else
+
+dummy:
+
+endif
CONFIG_TCPIP y/n y
Kernel profiling support
CONFIG_PROFILE y/n n
-Limit to memory to low 16MB
+Limit memory to low 16MB
CONFIG_MAX_16M y/n y
Use -m486 flag for 486-specific optimizations
CONFIG_M486 y/n y
.
Various character device drivers..
.
+Keyboard meta-key sends ESC-prefix
+CONFIG_KBD_META y/n y
Autoconfigure serial IRQ lines at bootup
CONFIG_AUTO_IRQ y/n n
AST Fourport serial driver support
dump.u_fpvalid = 0;
}
__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+/* struct user */
DUMP_WRITE(&dump,sizeof(dump));
- DUMP_SEEK(sizeof(dump));
- /* Dump the task struct. Not be used by gdb, but could be useful */
- DUMP_WRITE(current,sizeof(*current));
+/* name of the executable */
+ DUMP_WRITE(current->comm,16);
/* Now dump all of the user data. Include malloced stuff as well */
DUMP_SEEK(PAGE_SIZE);
/* now we start writing out the user space info */
dump_size = dump.u_ssize << 12;
DUMP_WRITE(dump_start,dump_size);
};
+/* Finally dump the task struct. Not be used by gdb, but could be useful */
+ __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+ DUMP_WRITE(current,sizeof(*current));
close_coredump:
if (file.f_op->release)
file.f_op->release(inode,&file);
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- ext_truncate /* truncate */
+ ext_truncate, /* truncate */
+ NULL /* permission */
};
static int ext_readdir(struct inode * inode, struct file * filp,
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
ext_bmap, /* bmap */
- ext_truncate /* truncate */
+ ext_truncate, /* truncate */
+ NULL /* permission */
};
static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
ext_readlink, /* readlink */
ext_follow_link, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int ext_follow_link(struct inode * dir, struct inode * inode,
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
/* This is used to speed up lookup. Without this we would need to
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
/* This is a heuristic to determine if a file is text of binary. If it
isofs_readlink, /* readlink */
isofs_follow_link, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int isofs_follow_link(struct inode * dir, struct inode * inode,
}
bh->b_dirt = 1;
j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
- if (j >= sb->u.minix_sb.s_nzones)
+ if (j < sb->u.minix_sb.s_firstdatazone ||
+ j >= sb->u.minix_sb.s_nzones)
return 0;
if (!(bh = getblk(sb->s_dev,j,BLOCK_SIZE))) {
printk("new_block: cannot get block");
printk("free_inode: inode on nonexistent device\n");
return;
}
- if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
+ if (inode->i_ino < 1 || inode->i_ino >= inode->i_sb->u.minix_sb.s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
return;
}
if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL)
if ((j=find_first_zero(bh->b_data))<8192)
break;
- if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
+ if (!bh || j >= 8192) {
iput(inode);
return NULL;
}
return NULL;
}
bh->b_dirt = 1;
+ j += i*8192;
+ if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) {
+ iput(inode);
+ return NULL;
+ }
inode->i_count = 1;
inode->i_nlink = 1;
inode->i_dev = sb->s_dev;
inode->i_uid = current->euid;
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->egid;
inode->i_dirt = 1;
- inode->i_ino = j + i*8192;
+ inode->i_ino = j;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_op = NULL;
inode->i_blocks = inode->i_blksize = 0;
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- minix_truncate /* truncate */
+ minix_truncate, /* truncate */
+ NULL /* permission */
};
static int minix_readdir(struct inode * inode, struct file * filp,
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
minix_bmap, /* bmap */
- minix_truncate /* truncate */
+ minix_truncate, /* truncate */
+ NULL /* permission */
};
static int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count)
int block, ino;
ino = inode->i_ino;
+ inode->i_op = NULL;
+ inode->i_mode = 0;
+ if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
+ printk("Bad inode number on dev 0x%04x: %d is out of range\n",
+ inode->i_dev, ino);
+ return;
+ }
block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
inode->i_sb->u.minix_sb.s_zmap_blocks +
(ino-1)/MINIX_INODES_PER_BLOCK;
- if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE)))
- panic("unable to read i-node block");
+ if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
+ printk("Major problem: unable to read inode from dev 0x%04x\n",
+ inode->i_dev);
+ return;
+ }
raw_inode = ((struct minix_inode *) bh->b_data) +
(ino-1)%MINIX_INODES_PER_BLOCK;
inode->i_mode = raw_inode->i_mode;
else for (block = 0; block < 9; 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_file_inode_operations;
else if (S_ISDIR(inode->i_mode))
{
struct buffer_head * bh;
struct minix_inode * raw_inode;
- int block;
+ int ino, block;
+ ino = inode->i_ino;
+ if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
+ printk("Bad inode number on dev 0x%04x: %d is out of range\n",
+ inode->i_dev, ino);
+ inode->i_dirt = 0;
+ return;
+ }
block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
- (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
+ (ino-1)/MINIX_INODES_PER_BLOCK;
if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
panic("unable to read i-node block");
raw_inode = ((struct minix_inode *)bh->b_data) +
- (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
+ (ino-1)%MINIX_INODES_PER_BLOCK;
raw_inode->i_mode = inode->i_mode;
raw_inode->i_uid = inode->i_uid;
raw_inode->i_gid = inode->i_gid;
minix_readlink, /* readlink */
minix_follow_link, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int minix_follow_link(struct inode * dir, struct inode * inode,
NULL, /* readlink */
NULL, /* follow_link */
msdos_bmap, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int msdos_readdir(struct inode *inode,struct file *filp,
NULL, /* readlink */
NULL, /* follow_link */
msdos_bmap, /* bmap */
- msdos_truncate /* truncate */
+ msdos_truncate, /* truncate */
+ NULL /* permission */
};
/* No bmap for MS-DOS FS' that don't align data at kByte boundaries. */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- msdos_truncate /* truncate */
+ msdos_truncate, /* truncate */
+ NULL /* permission */
};
/* special case: not even root can read/write a deleted file */
if (inode->i_dev && !inode->i_nlink)
return 0;
+ else if (inode->i_op && inode->i_op->permission)
+ return inode->i_op->permission(inode, mask);
else if (current->euid == inode->i_uid)
mode >>= 6;
else if (in_group_p(inode->i_gid))
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* follow_link */
NULL, /* bmap */
NULL, /* truncate */
+ NULL /* permission */
};
static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
if (result < 0) {
c_dev = 0;
-#if 0
- printk("nfs_readdir: readdir error = %d\n", result);
-#endif
return result;
}
if (result > 0) {
* though most of them will fail.
*/
-#define NFS_LOOKUP_CACHE_SIZE 16
-
static struct nfs_lookup_cache_entry {
int dev;
int inode;
for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
entry = nfs_lookup_cache + i;
if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
- && !strcmp(filename, entry->filename))
+ && !strncmp(filename, entry->filename, NFS_MAXNAMLEN))
return entry;
}
return NULL;
struct nfs_fattr *fattr)
{
static int nfs_lookup_cache_pos = 0;
-
struct nfs_lookup_cache_entry *entry;
/* compensate for bug in SGI NFS server */
strcpy(entry->filename, filename);
entry->fhandle = *fhandle;
entry->fattr = *fattr;
- entry->expiration_date = jiffies + NFS_SERVER(dir)->acregmax;
+ entry->expiration_date = jiffies + (S_ISDIR(fattr->mode)
+ ? NFS_SERVER(dir)->acdirmax : NFS_SERVER(dir)->acregmax);
}
-static void nfs_lookup_cache_remove(struct inode *dir, char *filename)
+static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
+ char *filename)
{
struct nfs_lookup_cache_entry *entry;
+ int dev;
+ int fileid;
+ int i;
- if ((entry = nfs_lookup_cache_index(dir, filename)))
- entry->dev = 0;
+ if (inode) {
+ dev = inode->i_dev;
+ fileid = inode->i_ino;
+ }
+ else if ((entry = nfs_lookup_cache_index(dir, filename))) {
+ dev = entry->dev;
+ fileid = entry->fattr.fileid;
+ }
+ else
+ return;
+ for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
+ entry = nfs_lookup_cache + i;
+ if (entry->dev == dev && entry->fattr.fileid == fileid)
+ entry->dev = 0;
+ }
}
static void nfs_lookup_cache_refresh(struct inode *file,
struct nfs_fattr *fattr)
{
struct nfs_lookup_cache_entry *entry;
+ int dev = file->i_dev;
+ int fileid = file->i_ino;
int i;
for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
entry = nfs_lookup_cache + i;
- if (entry->dev == file->i_dev
- && entry->fattr.fileid == file->i_ino) {
+ if (entry->dev == dev && entry->fattr.fileid == fileid)
entry->fattr = *fattr;
- break;
- }
}
}
}
memcpy_fromfs(filename, (char *) name, len);
filename[len] = '\0';
-#if 0
- sattr.mode = mode & 0777;
-#else
sattr.mode = mode;
-#endif
sattr.uid = sattr.gid = sattr.size = -1;
sattr.atime.seconds = sattr.mtime.seconds = -1;
if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
}
memcpy_fromfs(filename, (char *) name, len);
filename[len] = '\0';
-#if 0
- sattr.mode = mode & 0777;
-#else
sattr.mode = mode;
-#endif
sattr.uid = sattr.gid = sattr.size = -1;
sattr.atime.seconds = sattr.mtime.seconds = -1;
error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
filename[len] = '\0';
error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), filename);
if (!error)
- nfs_lookup_cache_remove(dir, filename);
+ nfs_lookup_cache_remove(dir, NULL, filename);
iput(dir);
return error;
}
filename[len] = '\0';
error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), filename);
if (!error)
- nfs_lookup_cache_remove(dir, filename);
+ nfs_lookup_cache_remove(dir, NULL, filename);
iput(dir);
return error;
}
filename[len] = '\0';
error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
NFS_FH(dir), filename);
+ if (!error)
+ nfs_lookup_cache_remove(dir, oldinode, NULL);
iput(oldinode);
iput(dir);
return error;
NFS_FH(old_dir), old_filename,
NFS_FH(new_dir), new_filename);
if (!error)
- nfs_lookup_cache_remove(old_dir, old_filename);
+ nfs_lookup_cache_remove(old_dir, NULL, old_filename);
iput(old_dir);
iput(new_dir);
return error;
return;
}
was_empty = inode->i_mode == 0;
-#if 0
- if (!was_empty && inode->i_atime > fattr->atime.seconds)
- return;
-#endif
inode->i_mode = fattr->mode;
inode->i_nlink = fattr->nlink;
inode->i_uid = fattr->uid;
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
put_fs_long(res.blocks, &buf->f_blocks);
put_fs_long(res.bfree, &buf->f_bfree);
put_fs_long(res.bavail, &buf->f_bavail);
-#if 0
- put_fs_long(-1, &buf->f_files);
- put_fs_long(-1, &buf->f_ffree);
-#else
put_fs_long(0, &buf->f_files);
put_fs_long(0, &buf->f_ffree);
-#endif
}
/*
* filesystem and type 'ls xyzzy' to turn on debugging.
*/
+#if 0
#define NFS_PROC_DEBUG
+#endif
#include <linux/param.h>
#include <linux/sched.h>
#include <netinet/in.h>
-#ifdef NFS_PROC_DEBUG
static int proc_debug = 0;
+
+#ifdef NFS_PROC_DEBUG
#define PRINTK if (proc_debug) printk
#else
-#define PRINTK (void)
+#define PRINTK if (0) printk
#endif
static int *nfs_rpc_header(int *p, int procedure);
int n;
p++;
- if (ntohl(*p++) != RPC_REPLY) {
- printk("not an RPC reply\n");
+ if ((n = ntohl(*p++)) != RPC_REPLY) {
+ printk("nfs_rpc_verify: not an RPC reply: %d\n", n);
return 0;
}
- if (ntohl(*p++) != RPC_MSG_ACCEPTED) {
- printk("RPC call rejected\n");
+ if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
+ printk("nfs_rpc_verify: RPC call rejected: %d\n", n);
return 0;
}
if ((n = ntohl(*p++)) != RPC_AUTH_NULL && n != RPC_AUTH_UNIX) {
- printk("reply with unknown RPC authentication type\n");
+ printk("nfs_rpc_verify: bad RPC authentication type: %d\n",
+ n);
return 0;
}
n = ntohl(*p++);
p += (n + 3) >> 2;
- if (ntohl(*p++) != RPC_SUCCESS) {
- printk("RPC call failed\n");
+ if ((n = ntohl(*p++)) != RPC_SUCCESS) {
+ printk("nfs_rpc_verify: RPC call failed: %d\n", n);
return 0;
}
return p;
enum nfs_stat stat;
int errno;
} nfs_errtbl[] = {
- { NFS_OK, 0 },
- { NFSERR_PERM, EPERM },
- { NFSERR_NOENT, ENOENT },
- { NFSERR_IO, EIO },
- { NFSERR_NXIO, ENXIO },
- { NFSERR_ACCES, EACCES },
- { NFSERR_EXIST, EEXIST },
- { NFSERR_NODEV, ENODEV },
- { NFSERR_NOTDIR, ENOTDIR },
- { NFSERR_ISDIR, EISDIR },
- { NFSERR_FBIG, EFBIG },
- { NFSERR_NOSPC, ENOSPC },
- { NFSERR_ROFS, EROFS },
- { NFSERR_NAMETOOLONG, ENAMETOOLONG },
- { NFSERR_NOTEMPTY, ENOTEMPTY },
- { NFSERR_DQUOT, EDQUOT },
- { NFSERR_STALE, ESTALE },
- { NFSERR_WFLUSH, EIO },
- { -1, EIO }
+ { NFS_OK, 0 },
+ { NFSERR_PERM, EPERM },
+ { NFSERR_NOENT, ENOENT },
+ { NFSERR_IO, EIO },
+ { NFSERR_NXIO, ENXIO },
+ { NFSERR_ACCES, EACCES },
+ { NFSERR_EXIST, EEXIST },
+ { NFSERR_NODEV, ENODEV },
+ { NFSERR_NOTDIR, ENOTDIR },
+ { NFSERR_ISDIR, EISDIR },
+ { NFSERR_FBIG, EFBIG },
+ { NFSERR_NOSPC, ENOSPC },
+ { NFSERR_ROFS, EROFS },
+ { NFSERR_NAMETOOLONG, ENAMETOOLONG },
+ { NFSERR_NOTEMPTY, ENOTEMPTY },
+ { NFSERR_DQUOT, EDQUOT },
+ { NFSERR_STALE, ESTALE },
+#ifdef EWFLUSH
+ { NFSERR_WFLUSH, EWFLUSH },
+#endif
+ { -1, EIO }
};
static int nfs_stat_to_errno(int stat)
{
- int errno;
int i;
- errno = EIO;
for (i = 0; nfs_errtbl[i].stat != -1; i++) {
- if (nfs_errtbl[i].stat == stat) {
- errno = nfs_errtbl[i].errno;
- break;
- }
+ if (nfs_errtbl[i].stat == stat)
+ return nfs_errtbl[i].errno;
}
- return errno;
+ printk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
+ return nfs_errtbl[i].errno;
}
int major_timeout_seen;
char *server_name;
int n;
+ int addrlen;
xid = start[0];
len = ((char *) end) - ((char *) start);
else if (wait_table.nr)
remove_wait_queue(entry.wait_address, &entry.wait);
current->state = TASK_RUNNING;
- result = sock->ops->recv(sock, (void *) start, 4096, 1, 0);
+ addrlen = 0;
+ result = sock->ops->recvfrom(sock, (void *) start, 4096, 1, 0,
+ NULL, &addrlen);
if (result < 0) {
if (result == -EAGAIN) {
printk("nfs_rpc_call: bad select ready\n");
nfs_readlink, /* readlink */
nfs_follow_link, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int nfs_follow_link(struct inode *dir, struct inode *inode,
inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
if (!suser() && !in_group_p(inode->i_gid))
inode->i_mode &= ~S_ISGID;
+ inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
return notify_change(inode);
}
inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
if (!suser() && !in_group_p(inode->i_gid))
inode->i_mode &= ~S_ISGID;
+ inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
error = notify_change(inode);
iput(inode);
suser()) {
inode->i_uid = user;
inode->i_gid = group;
+ inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
return notify_change(inode);
}
suser()) {
inode->i_uid = user;
inode->i_gid = group;
+ inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1;
error = notify_change(inode);
iput(inode);
if (!suser())
return -EPERM;
- /* send the SIGHUP signal. */
- kill_pg(current->pgrp, SIGHUP, 0);
/* See if there is a controlling tty. */
if (current->tty < 0)
return 0;
+ /* send the SIGHUP signal. */
+ tty = TTY_TABLE(current->tty);
+ if (tty && tty->pgrp > 0)
+ kill_pg(tty->pgrp, SIGHUP, 0);
for (process = task + 0; process < task + NR_TASKS; process++) {
for (j = 0; j < NR_OPEN; j++) {
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static struct proc_dir_entry base_dir[] = {
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int proc_lookupfd(struct inode * dir,const char * name, int len,
case 5:
case 6:
inode->i_op = &proc_link_inode_operations;
- inode->i_size = 3;
+ inode->i_size = 64;
inode->i_mode = S_IFLNK | 0700;
return;
case 7:
if (ino >= NR_OPEN || !p->filp[ino])
return;
inode->i_op = &proc_link_inode_operations;
- inode->i_size = 3;
+ inode->i_size = 64;
inode->i_mode = S_IFLNK | 0700;
return;
case 2:
if (ino >= p->numlibraries)
return;
inode->i_op = &proc_link_inode_operations;
- inode->i_size = 3;
+ inode->i_size = 64;
inode->i_mode = S_IFLNK | 0700;
return;
}
#include <asm/segment.h>
#include <asm/io.h>
+extern unsigned long log_size;
+extern struct wait_queue * log_wait;
+
extern int sys_syslog(int type, char * bug, int count);
static int kmsg_open(struct inode * inode, struct file * file)
return sys_syslog(2,buf,count);
}
+static int kmsg_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
+{
+ if (sel_type != SEL_IN)
+ return 0;
+ if (log_size)
+ return 1;
+ select_wait(&log_wait, wait);
+ return 0;
+}
+
+
static struct file_operations proc_kmsg_operations = {
NULL, /* kmsg_lseek */
kmsg_read,
NULL, /* kmsg_write */
NULL, /* kmsg_readdir */
- NULL, /* kmsg_select */
+ kmsg_select, /* kmsg_select */
NULL, /* kmsg_ioctl */
NULL, /* mmap */
kmsg_open,
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
proc_readlink, /* readlink */
proc_follow_link, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static int proc_follow_link(struct inode * dir, struct inode * inode,
static int proc_readlink(struct inode * inode, char * buffer, int buflen)
{
int i;
+ unsigned int dev,ino;
+ char buf[64];
+ i = proc_follow_link(NULL, inode, 0, 0, &inode);
+ if (i)
+ return i;
+ if (!inode)
+ return -EIO;
+ dev = inode->i_dev;
+ ino = inode->i_ino;
iput(inode);
- if (buflen > 3)
- buflen = 3;
+ i = sprintf(buf,"[%04x]:%u", dev, ino);
+ if (buflen > i)
+ buflen = i;
i = 0;
- while (i++ < buflen)
- put_fs_byte('-',buffer++);
+ while (i < buflen)
+ put_fs_byte(buf[i++],buffer++);
return i;
}
#include <asm/segment.h>
#include <asm/io.h>
+/*
+ * mem_write isn't really a good idea right now. It needs
+ * to check a lot more: if the process we try to write to
+ * dies in the middle right now, mem_write will overwrite
+ * kernel memory.. This disables it altogether.
+ */
+#define mem_write NULL
+
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
{
unsigned long addr, pid, cr3;
return tmp-buf;
}
+#ifndef mem_write
+
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
{
unsigned long addr, pid, cr3;
return 0;
}
+#endif
+
static int mem_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
{
switch (orig) {
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* bmap */
- NULL /* truncate */
+ NULL, /* truncate */
+ NULL /* permission */
};
static struct proc_dir_entry root_dir[] = {
-/* $Id: dma.h,v 1.5 1992/11/18 02:37:20 root Exp root $
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
* linux/include/asm/dma.h: Defines for using and allocating dma channels.
* Written by Hennus Bergman, 1992.
* High DMA channel support & info by Hannu Savolainen
#define _ASM_DMA_H
#include <asm/io.h> /* need byte IO */
-#include <linux/kernel.h> /* need panic() [FIXME] */
#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
/* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a know state.
- * After that, keep track of it. :-) In order to do that,
- * dma_set_addr() and dma_set_count() should only be used wile
- * interrupts are disbled.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disbled! ---
*/
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
* NOTE: from a manual: "the number of transfers is one more
* than the initial word count"! This is taken into account.
* Assumes dma flip-flop is clear.
- * NOTE 2: "count" must represent _words_ for channels 5-7.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
*/
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
if (dmanr <= 3) {
outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- } else {
- outb( count & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- outb( (count>>8) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ } else {
+ outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
}
}
/* Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of bytes (or words) left to
- * transfer, minus 1, modulo 64k.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
* Assumes DMA flip-flop is clear.
*/
-static __inline__ short int get_dma_residue(unsigned int dmanr)
+static __inline__ int get_dma_residue(unsigned int dmanr)
{
- if (dmanr <= 3) {
- return 1 + inb( ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ) +
- (inb( ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ) << 8);
- } else {
- return 1 + inb( ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ) +
- (inb( ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ) << 8);
- }
+ unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+ : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+ /* using short to get 16-bit wrap around */
+ short count = 1 + inb(io_port) +
+ ( inb(io_port) << 8 );
+
+ return (dmanr<=3)? count : (count<<1);
}
+
/* These are in kernel/dma.c: */
extern int request_dma(unsigned int dmanr); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
"iret"
#define ACK_FIRST(mask) \
- "inb $0x21,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\torb $" #mask ",%al\n\t" \
+ "orb $" #mask ",_cache_21\n\t" \
+ "movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"outb %al,$0x20\n\t"
#define ACK_SECOND(mask) \
- "inb $0xA1,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\torb $" #mask ",%al\n\t" \
+ "orb $" #mask ",_cache_A1\n\t" \
+ "movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\toutb %al,$0x20\n\t"
#define UNBLK_FIRST(mask) \
- "inb $0x21,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tandb $~(" #mask "),%al\n\t" \
+ "andb $~(" #mask "),_cache_21\n\t" \
+ "movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t"
#define UNBLK_SECOND(mask) \
- "inb $0xA1,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tandb $~(" #mask "),%al\n\t" \
+ "andb $~(" #mask "),_cache_A1\n\t" \
+ "movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t"
#define IRQ_NAME2(nr) nr##_interrupt()
void FAST_IRQ_NAME(nr); \
void BAD_IRQ_NAME(nr); \
__asm__( \
-"\n.align 2\n" \
+"\n.align 4\n" \
"_IRQ" #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
UNBLK_##chip(mask) \
"decl _intr_count\n\t" \
"jne ret_from_sys_call\n\t" \
- "cmpl $0,_bh_active\n\t" \
+ "movl _bh_mask,%eax\n\t" \
+ "andl _bh_active,%eax\n\t" \
"je ret_from_sys_call\n\t" \
"incl _intr_count\n\t" \
"sti\n\t" \
+ "bsfl %eax,%eax\n\t" \
+ "btrl %eax,_bh_active\n\t" \
+ "pushl %eax\n\t" \
"call _do_bottom_half\n\t" \
+ "addl $4,%esp\n\t" \
"cli\n\t" \
"decl _intr_count\n\t" \
"jmp ret_from_sys_call\n" \
-"\n.align 2\n" \
+"\n.align 4\n" \
"_fast_IRQ" #nr "_interrupt:\n\t" \
SAVE_MOST \
ACK_##chip(mask) \
+ "incl _intr_count\n\t" \
"pushl $" #nr "\n\t" \
"call _do_fast_IRQ\n\t" \
"addl $4,%esp\n\t" \
"cli\n\t" \
UNBLK_##chip(mask) \
+ "decl _intr_count\n\t" \
+ "jne 1f\n\t" \
+ "movl _bh_mask,%eax\n\t" \
+ "andl _bh_active,%eax\n\t" \
+ "jne 2f\n" \
+ "1:\t" \
+ RESTORE_MOST \
+ "\n.align 4\n" \
+ "2:\tincl _intr_count\n\t" \
+ "sti\n\t" \
+ "bsfl %eax,%eax\n\t" \
+ "btrl %eax,_bh_active\n\t" \
+ "pushl %eax\n\t" \
+ "call _do_bottom_half\n\t" \
+ "addl $4,%esp\n\t" \
+ "cli\n\t" \
+ "decl _intr_count\n\t" \
RESTORE_MOST \
-"\n\n.align 2\n" \
+"\n\n.align 4\n" \
"_bad_IRQ" #nr "_interrupt:\n\t" \
"pushl %eax\n\t" \
ACK_##chip(mask) \
{
char res;
- __asm__("xchg %0,%1":"=q" (res),"=m" (*m):"0" (0x1));
+ __asm__("xchgb %0,%1":"=q" (res),"=m" (*m):"0" (0x1));
return res;
}
#ifndef UTS_NODENAME
#define UTS_NODENAME "(none)" /* set by sethostname() */
#endif
+
+#ifdef CONFIG_M486
+#define UTS_MACHINE "i486" /* hardware type */
+#else
#define UTS_MACHINE "i386" /* hardware type */
+#endif
+
/*
* The definitions for UTS_RELEASE and UTS_VERSION are now defined
* in linux/version.h, and should only be used by linux/version.c
int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **);
int (*bmap) (struct inode *,int);
void (*truncate) (struct inode *);
+ int (*permission) (struct inode *, int);
};
struct super_operations {
#define WIN_SPECIFY 0x91
/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark ? */
+#define MARK_ERR 0x01 /* Bad address mark */
#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define ABRT_ERR 0x04 /* ? */
-#define ID_ERR 0x10 /* ? */
-#define ECC_ERR 0x40 /* ? */
-#define BBD_ERR 0x80 /* ? */
+#define ABRT_ERR 0x04 /* Command aborted */
+#define ID_ERR 0x10 /* ID field not found */
+#define ECC_ERR 0x40 /* Uncorrectable ECC error */
+#define BBD_ERR 0x80 /* block marked bad */
/* HDIO_GETGEO is the preferred choice - HDIO_REQ will be removed at some
void *data;
};
-extern int bh_active;
+extern unsigned long bh_active;
+extern unsigned long bh_mask;
extern struct bh_struct bh_base[32];
/* Who gets which entry in bh_base. Things which will occur most often
KEYBOARD_BH
};
-void do_bottom_half();
-
extern inline void mark_bh(int nr)
{
__asm__ __volatile__("btsl %1,%0":"=m" (bh_active):"ir" (nr));
#define IOCCMD_MASK 0x0000ffff /* command code */
#define IOCCMD_SHIFT 0
-#define _IO(c,d) (IOC_VOID | (d)<<16) | c) /* param encoded */
+#define _IO(c,d) (IOC_VOID | ((d)<<16) | c) /* param encoded */
/* use _IOXX(magic, subcode, arg_t) where arg_t is the type of the
* (last) argument field in the ioctl call, if present.
*/
#define _IOR(c,d,t) (IOC_OUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \
(c<<8) | d)
/* WR rather than RW to avoid conflict with stdio.h */
-#define _IOWR(c,d,t) (IOC_INOUT | (sizeof(t)<<16) & IOCSIZE_MASK) | \
+#define _IOWR(c,d,t) (IOC_INOUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \
(c<<8) | d)
#endif /* _LINUX_IOCTL_H */
#ifndef __LINUX_KEYBOARD_H
#define __LINUX_KEYBOARD_H
+#include <linux/interrupt.h>
+#define set_leds() mark_bh(KEYBOARD_BH)
+
/*
* Global flags: things that don't change between virtual consoles.
* This includes things like "key-down" flags - if the shift key is
#define LED_MASK 7
-#ifndef KBD_DEFFLAGS
-#define KBD_DEFFLAGS ((1 << VC_NUMLOCK) | (1 << VC_REPEAT))
-#endif
-
extern unsigned long kbd_init(unsigned long);
extern inline int kbd_flag(int flag)
#ifndef _LINUX_LP_H
#define _LINUX_LP_H
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/io.h>
-#include <asm/segment.h>
-
/*
* usr/include/linux/lp.h c.1991-1992 James Wiegand
* many modifications copyright (C) 1992 Michael K. Johnson
#define LP_B(minor) lp_table[(minor)].base /* IO address */
#define LP_F(minor) lp_table[(minor)].flags /* flags for busy, etc. */
-#define LP_S(minor) inb(LP_B((minor)) + 1) /* status port */
+#define LP_S(minor) inb_p(LP_B((minor)) + 1) /* status port */
#define LP_C(minor) (lp_table[(minor)].base + 2) /* control port */
#define LP_CHAR(minor) lp_table[(minor)].chars /* busy timeout */
#define LP_TIME(minor) lp_table[(minor)].time /* wait time */
#ifndef _LINUX_NFS_H
#define _LINUX_NFS_H
-#define RPC_VERSION 2
-
#define NFS_PORT 2049
#define NFS_MAXDATA 8192
#define NFS_MAXPATHLEN 1024
#define NFSMODE_SOCK 0140000
#define NFSMODE_FIFO 0010000
+#ifdef KERNEL /* user programs should get these from the rpc header files */
+
+#define RPC_VERSION 2
+
enum rpc_auth_flavor {
RPC_AUTH_NULL = 0,
RPC_AUTH_UNIX = 1,
enum rpc_reply_stat {
RPC_MSG_ACCEPTED = 0,
- RPC_MSG_DENIED,
+ RPC_MSG_DENIED = 1,
};
enum rpc_accept_stat {
RPC_AUTH_REJECTEDVERF = 4,
RPC_AUTH_TOOWEAK = 5,
};
+
+#endif /* KERNEL */
enum nfs_stat {
NFS_OK = 0,
#define NFS_MAX_RPC_TIMEOUT 600
+/*
+ * Size of the lookup cache in units of number of entries cached.
+ * It is better not to make this too large although the optimimum
+ * depends on a usage and environment.
+ */
+
+#define NFS_LOOKUP_CACHE_SIZE 64
+
#define NFS_SUPER_MAGIC 0x6969
#define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server)
* WARNING! Do not delete or change the order of these fields. If
* a new field is required then add it to the end. The version field
* tracks which fields are present. This will ensure some measure of
- * mount-to-kernel version compatibilty. Most of these are used yet
+ * mount-to-kernel version compatibilty. Some of these aren't used yet
* but here they are anyway.
*/
* Public License (GPL)
*/
-/*
- * This our internal structure for keeping track of interrupt service
- * routines.
- */
-typedef struct struct_ISR *async_ISR;
-struct struct_ISR {
- int irq; /* The IRQ assigned for this device */
- int port; /* The base port for this device */
- /* (use is ISR specific) */
- void (*ISR_proc)(async_ISR, int);
- int line; /* The serial line (or base */
- /* serial line) */
- int refcnt; /* How many devices are depending on */
- /* this interrupt (multiport boards) */
- async_ISR next_ISR; /* For the linked list */
- async_ISR prev_ISR;
-};
-
/*
* This is our internal structure for each serial port's state.
*
struct async_struct {
int baud_base;
int port;
- async_ISR ISR;
+ int irq;
int flags;
int type;
struct tty_struct *tty;
int x_char; /* xon/xoff characater */
int event;
int line;
+ struct async_struct *next_port; /* For the linked list */
+ struct async_struct *prev_port;
+
};
/*
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
#define UART_FCR_CLEAR_CMD (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT)
-#define UART_FCR_SETUP_CMD (UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14)
+#define UART_FCR_SETUP_CMD (UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8)
/*
* These are the definitions for the Line Control Register
int flags;
int xmit_fifo_size;
int custom_divisor;
- int reserved[8];
+ int baud_base;
+ int reserved[7];
};
/*
/*
* Definitions for async_struct (and serial_struct) flags field
*/
-#define ASYNC_NOSCRATCH 0x0001 /* 16XXX UART with no scratch register */
#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */
#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */
-#define ASYNC_FLAGS 0x0037 /* Possible legal async flags */
+#define ASYNC_FLAGS 0x0036 /* Possible legal async flags */
+
+/* Internal flags used only by kernel/chr_drv/serial.c */
+#define ASYNC_NO_IRQ 0x80000000 /* No IRQ was initialized */
#define IS_A_CONSOLE(min) (((min) & 0xC0) == 0x00)
#define IS_A_SERIAL(min) (((min) & 0xC0) == 0x40)
#define TTY_CR_PENDING 2
#define TTY_SQ_THROTTLED 3
#define TTY_RQ_THROTTLED 4
+#define TTY_IO_ERROR 5
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
#define TTY_READ_FLUSH(tty) tty_read_flush((tty))
#define VT_SETMODE 0x5602 /* set mode of active vt */
#define VT_AUTO 0x00 /* auto vt switching */
#define VT_PROCESS 0x01 /* process controls switching */
+#define VT_ACKACQ 0x02 /* acknowledge switch */
struct vt_stat {
ushort v_active; /* active vt */
#define VT_RELDISP 0x5605 /* release display */
#define VT_ACTIVATE 0x5606 /* make vt active */
+#define VT_WAITACTIVE 0x5607 /* wait for vt active */
#endif /* _LINUX_VT_H */
}
+void ffreep()
+{
+ /* ffree st(i) + pop - unofficial code */
+ st(FPU_rm).tag = TW_Empty;
+ pop();
+}
+
+
void fst_i_()
{
/* fst st(i) */
#define __BAD__ Un_impl /* Not implemented */
+#define _d9_d8_ fstp_i /* unofficial code (19) */
+#define _dc_d0_ fcom_st /* unofficial code (14) */
+#define _dc_d8_ fcompst /* unofficial code (1c) */
+#define _dd_c8_ fxch_i /* unofficial code (0d) */
+#define _de_d0_ fcompst /* unofficial code (16) */
+#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
+#define _df_c8_ fxch_i /* unofficial code (0f) */
+#define _df_d0_ fstp_i /* unofficial code (17) */
+#define _df_d8_ fstp_i /* unofficial code (1f) */
+
static FUNC st_instr_table[64] = {
- fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
- fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
- fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
- fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
+ fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
+ fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
fsub__, fp_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
fdiv__, trig_a, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
#define _null_ 4 /* Function illegal or not implemented */
static unsigned char type_table[64] = {
- _REGI_, _NONE_, _null_, _null_, _REGI_, _REGi_, _REGI_, _null_,
- _REGI_, _REGI_, _null_, _null_, _REGI_, _null_, _REGI_, _null_,
- _REGI_, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
- _REGI_, _null_, _null_, _null_, _null_, _REG0_, _REGI_, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGI_, _REGi_, _REGI_, _REGi_,
+ _REGI_, _REGI_, _null_, _null_, _REGI_, _REGI_, _REGI_, _REGI_,
+ _REGI_, _NONE_, _null_, _null_, _REGI_, _REG0_, _REGI_, _REG0_,
+ _REGI_, _REG0_, _null_, _null_, _REGI_, _REG0_, _REGI_, _REG0_,
_REGI_, _NONE_, _null_, _NONE_, _REGI_, _REGI_, _REGI_, _NONE_,
_REGI_, _NONE_, _REGI_, _null_, _REGI_, _REGI_, _REGI_, _null_,
_REGI_, _NONE_, _null_, _null_, _REGI_, _null_, _REGI_, _null_,
extern void fld_i_(void);
extern void fxch_i(void);
extern void ffree_(void);
+extern void ffreep(void);
extern void fst_i_(void);
extern void fstp_i(void);
/* fpu_entry.c */
_null_, _null_, _null_, _null_,
_REG0_, _REG0_, _REG0_, _REG0_,
_REG0_, _REG0_, _REG0_, _REG0_,
- _null_, _null_, _NONE_, _PUSH_,
+ _NONE_, _null_, _NONE_, _PUSH_,
_NONE_, _PUSH_, _null_, _PUSH_,
- _null_, _null_, _NONE_, _REG0_,
+ _NONE_, _null_, _NONE_, _REG0_,
_NONE_, _REG0_, _NONE_, _REG0_
};
/* fdomain.c -- Future Domain TMC-1660/TMC-1680 driver
* Created: Sun May 3 18:53:19 1992 by faith
- * Revised: Wed Dec 9 21:34:53 1992 by root
+ * Revised: Sun Jan 10 01:23:29 1993 by root
* Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992 Rickard E. Faith
+ * Copyright 1992, 1993 Rickard E. Faith
*
* $Log$
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
- * WARNING: THIS IS A BETA VERSION!
- * USE AT YOUR OWN RISK!
- * BACKUP YOUR SYSTEM BEFORE USING!
-
- * I would like to thank Maxtor, whose *free* 206 page manual on the LXT
- * drives was very helpful: "LXT SCSI Products: Specifications and OEM
- * Technical Manual (Revision B/September 1991)"
-
- * I wish that I could thank Future Domain for the necessary documentation,
- * but I can't. I used the $25 "TMC-1800 SCSI Chip Specification" document
- * (FDC-1800T), which documents the *chip* and not the board. Without it,
- * I would have been totally lost, but it would have been nice to have some
- * example source. (The DOS BIOS source cost $250 and the UN*X driver
- * source was $750 [both required a non-disclosure agreement]. Ever wonder
- * why there are no freely available Future Domain drivers?)
-
- * Thanks to: Todd Carrico (todd@wutc.wustl.edu), Dan Poirier
- * (poirier@cs.unc.edu ), Ken Corey (kenc@sol.acs.unt.edu), C. de Bruin
- * (bruin@dutiba.tudelft.nl) and Sakari Aaltonen (sakaria@vipunen.hit.fi)
- * for alpha testing. Also thanks to Drew Eckhardt (drew@cs.colorado.edu)
- * and Eric Youngdale (eric@tantalus.nrl.navy.mil) for answering questions,
- * and to Doug Hoffman (hoffman@cs.unc.edu) for lending me SCSI devices to
- * make the driver more robust. */
+ **************************************************************************
+
+
+ DESCRIPTION:
+
+ This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
+ and TMC-1670 SCSI host adapters.
+
+
+ REFERENCES USED:
+
+ "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
+ 1990.
+
+ "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
+ B/September 1991)", Maxtor Corporation, 1991.
+
+ "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
+
+ Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
+ Youngdale (eric@tantalus.nrl.navy.mil), 1992.
+
+
+ NOTES ON REFERENCES:
+
+ The Maxtor manuals were free. Maxtor telephone technical support is
+ great!
+
+ The Future Domain manual is $25. It documents the chip, not the TMC-16x0
+ boards, so some information I had to guess at. Future Domain sells DOS
+ BIOS source for $250 and the UN*X driver source was $750, but these
+ require a non-disclosure agreement, so even if I could afford them, they
+ would *not* have been useful for writing this publically distributable
+ driver. Future Domain technical support has provided some information on
+ the phone, and this has been somewhat helpful.
+
+
+ ALPHA TESTERS:
+
+ Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
+ Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@dutiba.tudelft.nl),
+ Sakari Aaltonen (sakaria@vipunen.hit.fi), John Rice
+ (rice@xanth.cs.odu.edu), and Brad Yearwood (brad@optilink.com).
+
+
+ NOTES ON USER DEFINABLE OPTIONS:
+
+ DEBUG: This turns on the printing of various debug informaiton.
+
+ ENABLE_PARITY: This turns on SCSI parity checking. With the current
+ driver, all attached devices must support SCSI parity. If none of your
+ devices support parity, then you can probably get the driver to work by
+ turning this option off. I have no way of testing this, however.
+
+ QUEUE: Enable "command queueing." This is supported by the higher level
+ SCSI code, and allows the kernel to continue to schedule tasks while the
+ SCSI request is pending. If this option is turned off, then everything
+ will "freeze" during SCSI requests, and system performance will become
+ unbearable. Later, this will allow multiple outstanding SCSI requests. I
+ have received reports that if this option is turned off, the driver will
+ no longer function correctly. I have not had time to track down this bug,
+ since I hope to make the driver work for everyone with QUEUE on.
+
+ FIFO_COUNT: The host adapter has an 8K cache. When this many 512 byte
+ blocks are filled by the SCSI device, an interrupt will be raised.
+ Therefore, this could be as low as 0, or as high as 16. Note, however,
+ that values which are too high or too low seem to prevent any interrupts
+ from occuring, and thereby lock up the machine. I have found that 2 is a
+ good number, but throughput may be increased by changing this value to
+ values which are close to 2. Please let me know if you try any different
+ values.
+
+ DO_DETECT: This activates some old scan code which was needed before the
+ high level drivers got fixed. If you are having toruble with the driver,
+ turning this on should not hurt, and might help. Please let me know if
+ this is the case, since this code will be removed from future drivers.
+
+ RESELECTION: DO *NOT* USE THIS OPTION! This turns on SCSI device
+ disconnect and reselection, which does not work at this time. When I get
+ this working, it will support multiple outstanding SCSI commands.
+
+ **************************************************************************/
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/system.h>
#include <linux/errno.h>
-#define VERSION "3.2" /* Change with each revision */
+#define VERSION "3.3" /* Change with each revision */
/* START OF USER DEFINABLE OPTIONS */
#define DEBUG 1 /* Enable debugging output */
#define ENABLE_PARITY 1 /* Enable SCSI Parity */
#define QUEUE 1 /* Enable command queueing */
-#define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */
+#define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */
#define DO_DETECT 0 /* Do device detection here (see scsi.c) */
#define RESELECTION 0 /* Support RESELECTION PHASE (NOT stable) */
#define EVERY_ACCESS 0 /* Write a line on every scsi access */
#define ERRORS_ONLY 1 /* Only write a line if there is an error */
#define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
-#define DEBUG_MESSAGES 0 /* Debug MESSAGE IN PHASE */
-#define DEBUG_ABORT 1 /* Debug abort() routine */
+#define DEBUG_MESSAGES 0 /* Debug MESSAGE IN PHASE */
+#define DEBUG_ABORT 1 /* Debug abort() routine */
#else
#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
#define ERRORS_ONLY 0
READ EVERY WORD, ESPECIALLY THE WORD *NOT*
- This driver works *ONLY* for Future Domain cards using the
- TMC-1800 chip. This includes models TMC-1660 and TMC-1680
- *ONLY*.
+ This driver works *ONLY* for Future Domain cards using the TMC-1800 chip.
+ This includes models TMC-1660, 1670, and 1680 *ONLY*.
The following BIOS signatures have been tried with this driver. These
signatures are for boards which do *NOT* work with this driver (but the
first one should work with the Seagate driver):
- FUTURE DOMAIN COPR. (C) 1986-1989 V6.0A7/28/90
-
- FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
-
- FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
+ FUTURE DOMAIN COPR. (C) 1986-1989 V6.0A7/28/90
+ FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
+ FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
*/
int sig_offset;
int sig_length;
} signatures[] = {
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0 7/28/89", 5, 50 },
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800", 5, 37 },
+ /* 1 2 3 4 5 6 */
+ /* 123456789012345678901234567890123456789012345678901234567890 */
+ { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50 },
+ { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44 },
/* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE */
};
const char *fdomain_16x0_info(void)
{
static char buffer[] =
- "Future Domain TMC-1660/TMC-1680 SCSI driver version "
+ "Future Domain TMC-16x0 SCSI driver version "
VERSION
"\n";
return buffer;
/* fdomain.h -- Header for Future Domain TMC-1660/TMC-1680 driver
* Created: Sun May 3 18:47:33 1992
- * Revised: Fri Nov 27 22:12:55 1992 by root
+ * Revised: Sun Jan 10 00:54:29 1993 by root
* Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992 Rickard E. Faith
+ * Copyright 1992, 1993 Rickard E. Faith
* This program comes with ABSOLUTELY NO WARRANTY.
*
* $Log$
int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
int fdomain_16x0_biosparam( int, int, int * );
-#define FDOMAIN_16X0 { "Future Domain TMC-1660/TMC-1680", \
+#define FDOMAIN_16X0 { "Future Domain TMC-16x0", \
fdomain_16x0_detect, \
fdomain_16x0_info, \
fdomain_16x0_command, \
static struct blist blacklist[] =
{{"TANDBERG","TDC 3600","U07"}, /* Locks up if polled for lun != 0 */
{"SEAGATE","ST296","921"}, /* Responds to all lun */
+ {"SONY","CD-ROM CDU-541","4.3d"},
+ {"DENON","DRD-25X","V"}, /* A cdrom that locks up when probed at lun != 0 */
{NULL, NULL, NULL}};
static int blacklisted(char * response_data){
if (req) {
memcpy(&SCpnt->request, req, sizeof(struct request));
req->dev = -1;
- } else
+ } else {
SCpnt->request.dev = 0xffff; /* Busy, but no request */
+ SCpnt->request.waiting = NULL; /* And no one is waiting for the device either */
+ };
SCpnt->use_sg = 0; /* Reset the scatter-gather flag */
return SCpnt;
*reqp = req->next;
} else {
SCpnt->request.dev = 0xffff; /* Busy */
+ SCpnt->request.waiting = NULL; /* And no one is waiting for this to complete */
};
sti();
break;
base_address = NULL;
#ifdef OVERRIDE
- base_address = (void *) OVERRIDE;
+ base_address = (void *) OVERRIDE;
+
+/* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
+#ifdef CONTROLLER
+ controller_type = CONTROLLER;
+#else
+#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
+#endif
#ifdef DEBUG
- printk("Base address overridden to %x\n", base_address);
+ printk("Base address overridden to %x, controller type is %s\n",
+ base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
#endif
#else
/*
printk("scsi%d : done_fn(%d,%08x)", hostno,
hostno, temp);
#endif
+ if(!SCint) panic("SCint == NULL in seagate");
SCint->result = temp;
done_fn (SCint);
+ SCint = NULL;
}
else
printk("done_fn() not defined.\n");
{
SCpnt->result = result;
done_fn (SCpnt);
+ SCint = NULL;
return 1;
}
}
Kai Makisara, Nov 9, 1992 email makisara@vtinsx.ins.vtt.fi or
Kai.Makisara@vtt.fi
- Last changes Dec 19, 1992.
+ Last changes Jan 3, 1993.
*/
#include <linux/fs.h>
dev = dev & 127;
- SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
-
memset(cmd, 0, 10);
switch (cmd_in) {
case MTFSF:
cmd[2] = (ltmp >> 16);
cmd[3] = (ltmp >> 8);
cmd[4] = ltmp;
- SCpnt->result = -1;
#ifdef DEBUG
if (cmd[2] & 0x80)
ltmp = 0xff000000;
break;
default:
printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
- SCpnt->request.dev = -1; /* Mark as not busy */
return (-ENOSYS);
}
+ SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
SCpnt->sense_buffer[0] = 0;
SCpnt->request.dev = dev;
scsi_do_cmd(SCpnt,
#define NPAR 16
extern void vt_init(void);
-extern void set_leds(void);
unsigned long video_num_columns; /* Number of text columns */
unsigned long video_num_lines; /* Number of test lines */
#include <linux/ptrace.h>
#include <linux/keyboard.h>
#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#ifndef KBD_DEFFLAGS
+#ifdef CONFIG_KBD_META
+#define KBD_DEFFLAGS ((1 << VC_NUMLOCK) | (1 << VC_REPEAT) | (1 << VC_META))
+#else
+#define KBD_DEFFLAGS ((1 << VC_NUMLOCK) | (1 << VC_REPEAT))
+#endif
+#endif
/*
* The default IO slowdown is doing 'inb()'s from 0x61, which should be
unsigned long kbd_dead_keys = 0;
unsigned long kbd_prev_dead_keys = 0;
+static int want_console = -1;
struct kbd_struct kbd_table[NR_CONSOLES];
static struct kbd_struct * kbd = kbd_table;
static struct tty_struct * tty = NULL;
fptr key_table[];
static void put_queue(int);
-void set_leds(void);
static void applkey(int);
static void cur(int);
static unsigned int handle_diacr(unsigned int);
key_table[scancode](scancode);
rep = scancode;
end_kbd_intr:
- do_keyboard_interrupt();
send_cmd(0xAE);
+ mark_bh(KEYBOARD_BH);
}
static void put_queue(int ch)
return; /* key already pressed: defeat repeat */
set_kbd_flag(KG_CAPSLOCK);
chg_vc_kbd_flag(kbd,VC_CAPSLOCK);
- set_leds();
}
static void uncaps(int sc)
show_ptregs();
else if (kbd_flag(KG_LCTRL) || kbd_flag(KG_RCTRL))
show_state();
- else {
+ else
chg_vc_kbd_flag(kbd,VC_SCROLLOCK);
- set_leds();
- }
}
static void num(int sc)
{
if (vc_kbd_flag(kbd,VC_APPLIC))
applkey(0x50);
- else {
+ else
chg_vc_kbd_flag(kbd,VC_NUMLOCK);
- set_leds();
- }
}
static void applkey(int key)
return;
}
if (kbd_flag(KG_ALT))
- change_console(sc);
+ want_console = sc;
else
if (kbd_flag(KG_LSHIFT) || kbd_flag(KG_RSHIFT)) /* DEC F11 - F20 */
puts_queue(func_table[1][sc]);
return 0;
}
+/*
+ * This routine is the bottom half of the keyboard interrupt
+ * routine, and runs with all interrupts enabled. It does
+ * console changing, led setting and copy_to_cooked, which can
+ * take a reasonably long time.
+ *
+ * Aside from timing (which isn't really that important for
+ * keyboard interrupts as they happen often), using the software
+ * interrupt routines for this thing allows us to easily mask
+ * this when we don't want any of the above to happen. Not yet
+ * used, but this allows for easy and efficient race-condition
+ * prevention later on.
+ */
static void kbd_bh(void * unused)
{
static unsigned char old_leds = -1;
unsigned char leds = kbd_table[fg_console].flags & LED_MASK;
- if (leds == old_leds)
- return;
- old_leds = leds;
- if (!send_data(0xed) || !send_data(leds))
- send_data(0xf4); /* re-enable kbd if any errors */
-}
-
-void set_leds(void)
-{
- mark_bh(KEYBOARD_BH);
+ if (leds != old_leds) {
+ old_leds = leds;
+ if (!send_data(0xed) || !send_data(leds))
+ send_data(0xf4); /* re-enable kbd if any errors */
+ }
+ if (want_console >= 0) {
+ change_console(want_console);
+ want_console = -1;
+ }
+ do_keyboard_interrupt();
}
long no_idt[2] = {0, 0};
int i, j;
extern unsigned long pg0[1024];
- cli();
+ sti();
/* rebooting needs to touch the page at absolute addr 0 */
pg0[0] = 7;
*((unsigned short *)0x472) = 0x1234;
/* Copyright (C) 1992 by Jim Weigand, Linus Torvalds, and Michael K. Johnson
*/
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/lp.h>
-/* sched.h is included from lp.h */
+
+#include <asm/io.h>
+#include <asm/segment.h>
/*
* All my debugging code assumes that you debug with only one printer at
int testvalue;
/* reset value */
- outb(0, LP_C(minor));
+ outb_p(0, LP_C(minor));
for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
;
- outb(LP_PSELECP | LP_PINITP, LP_C(minor));
+ outb_p(LP_PSELECP | LP_PINITP, LP_C(minor));
return LP_S(minor);
}
int retval = 0, wait = 0;
unsigned long count = 0;
- outb(lpchar, LP_B(minor));
+ outb_p(lpchar, LP_B(minor));
do {
retval = LP_S(minor);
count ++;
low, according spec. Some printers need it, others don't. */
while(wait != LP_WAIT(minor)) wait++;
/* control port takes strobe high */
- outb(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor )));
+ outb_p(( LP_PSELECP | LP_PINITP | LP_PSTROBE ), ( LP_C( minor )));
while(wait) wait--;
/* take strobe low */
- outb(( LP_PSELECP | LP_PINITP ), ( LP_C( minor )));
+ outb_p(( LP_PSELECP | LP_PINITP ), ( LP_C( minor )));
/* get something meaningful for return value */
return LP_S(minor);
}
static int lp_lseek(struct inode * inode, struct file * file,
off_t offset, int origin)
{
- return -EINVAL;
+ return -ESPIPE;
}
static int lp_open(struct inode * inode, struct file * file)
/* take on all known port values */
for (offset = 0; offset < LP_NO; offset++) {
/* write to port & read back to check */
- outb( LP_DUMMY, LP_B(offset));
+ outb_p( LP_DUMMY, LP_B(offset));
for (testvalue = 0 ; testvalue < LP_DELAY ; testvalue++)
;
- testvalue = inb(LP_B(offset));
+ testvalue = inb_p(LP_B(offset));
if (testvalue != 255) {
LP_F(offset) |= LP_EXIST;
lp_reset(offset);
* Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now
* much more extensible to support other serial cards based on the
* 16450/16550A UART's. Added support for the AST FourPort and the
- * Accent Async board. We use the async_ISR structure to allow
- * multiple ports (or boards, if the hardware permits) to share a
- * single IRQ channel.
+ * Accent Async board.
*
* set_serial_info fixed to set the flags, custom divisor, and uart
* type fields. Fix suggested by Michael K. Johnson 12/12/92.
* cleanly than it used to in 0.98pl2-6. It should be
* much less vulnerable to false IRQ's now.
*
- * NEW_INTERRUPT_ROUTINE
- * Enables the new interrupt routine, which is faster
- * (which is better on slow CPU's), and handles parity
- * errors, break conditions, and hardware handshaking.
- * People were having problems with it earlier, but I
- * believe they have been fixed now, so there should
- * hopefully be no reason to #undef this option.
- *
* CONFIG_AST_FOURPORT
* Enables support for the AST Fourport serial port.
*
* Enables support for the Accent Async 4 port serial
* port.
*
+ * SOFT_IRQ
+ * Not yet ready; requires changes in the rest of the
+ * Linux kernel
+ *
*/
-#undef NEW_INTERRUPT_ROUTINE
-
+#define NEW_INTERRUPT_ROUTINE
+#undef SOFT_IRQ
+#undef FAKE_SOFT_IRQ
+
+#ifdef FAKE_SOFT_IRQ
+#define SOFT_IRQ
+#endif
+
#define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
/*
* transmitting (and therefore have a
* write timeout pending, in case the
* THRE interrupt gets lost.)
- * IRQ_ISR[] - Array to store the head of the ISR linked list
- * for each IRQ.
*/
-static unsigned long rs_event = 0;
+static volatile unsigned long rs_event = 0;
static unsigned long rs_write_active = 0;
-static async_ISR IRQ_ISR[16];
-
-static void UART_ISR_proc(async_ISR ISR, int line);
-
-struct struct_ISR COM1_ISR = { 4, 0x3f8, UART_ISR_proc, 0, };
-struct struct_ISR COM2_ISR = { 3, 0x2f8, UART_ISR_proc, 0, };
-struct struct_ISR COM3_ISR = { 4, 0x3e8, UART_ISR_proc, 0, };
-struct struct_ISR COM4_ISR = { 3, 0x2e8, UART_ISR_proc, 0, };
-
-#ifdef CONFIG_AST_FOURPORT
-static void FourPort_ISR_proc(async_ISR ISR, int line);
-
-struct struct_ISR FourPort1_ISR = { 2, 0x1bf, FourPort_ISR_proc, 0, };
-struct struct_ISR FourPort2_ISR = { 5, 0x2bf, FourPort_ISR_proc, 0, };
-#endif
+static int doing_softint = 0;
-#ifdef CONFIG_ACCENT_ASYNC
-struct struct_ISR Accent3_ISR = { 4, 0x330, UART_ISR_proc, 0, };
-struct struct_ISR Accent4_ISR = { 4, 0x338, UART_ISR_proc, 0, };
-#endif
+static struct async_struct *IRQ_ports[16];
/*
* This assumes you have a 1.8432 MHz clock for your UART.
#define BASE_BAUD ( 1843200 / 16 )
struct async_struct rs_table[] = {
- { BASE_BAUD, 0x3F8, &COM1_ISR, 0, },
- { BASE_BAUD, 0x2F8, &COM2_ISR, 0, },
- { BASE_BAUD, 0x3E8, &COM3_ISR, 0, },
- { BASE_BAUD, 0x2E8, &COM4_ISR, 0, },
+ { BASE_BAUD, 0x3F8, 4, 0, },
+ { BASE_BAUD, 0x2F8, 3, 0, },
+ { BASE_BAUD, 0x3E8, 4, 0, },
+ { BASE_BAUD, 0x2E8, 3, 0, },
#ifdef CONFIG_AST_FOURPORT
- { BASE_BAUD, 0x1A0, &FourPort1_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x1A8, &FourPort1_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x1B0, &FourPort1_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x1B8, &FourPort1_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
-
- { BASE_BAUD, 0x2A0, &FourPort2_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x2A8, &FourPort2_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x2B0, &FourPort2_ISR, ASYNC_FOURPORT },
- { BASE_BAUD, 0x2B8, &FourPort2_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
+ { BASE_BAUD, 0x1A0, 2, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x1A8, 2, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x1B0, 2, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x1B8, 2, ASYNC_FOURPORT },
+
+ { BASE_BAUD, 0x2A0, 5, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x2A8, 5, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x2B0, 5, ASYNC_FOURPORT },
+ { BASE_BAUD, 0x2B8, 5, ASYNC_FOURPORT },
#else /* CONFIG_AST_FOURPORT */
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
-
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
#endif /* CONFIG_AST_FOURPORT */
#ifdef CONFIG_ACCENT_ASYNC
- { BASE_BAUD, 0x330, &Accent3_ISR, 0 },
- { BASE_BAUD, 0x338, &Accent4_ISR, 0 },
+ { BASE_BAUD, 0x330, 4, 0 },
+ { BASE_BAUD, 0x338, 4, 0 },
#else /* CONFIG_ACCENT_ASYNC */
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
#endif /* CONFIG_ACCENT_ASYNC */
- { BASE_BAUD, 0x000 },
- { BASE_BAUD, 0x000 },
-
+ { BASE_BAUD, 0x000, 0 },
+ { BASE_BAUD, 0x000, 0 },
+
+ { BASE_BAUD, 0x100, 4, 0 },
+ { BASE_BAUD, 0x108, 4, 0 },
+ { BASE_BAUD, 0x110, 4, 0 },
+ { BASE_BAUD, 0x118, 4, 0 },
+ { BASE_BAUD, 0x120, 4, 0 },
+ { BASE_BAUD, 0x128, 4, 0 },
+ { BASE_BAUD, 0x130, 4, 0 },
+ { BASE_BAUD, 0x138, 4, 0 },
+ { BASE_BAUD, 0x140, 4, 0 },
+ { BASE_BAUD, 0x148, 4, 0 },
+ { BASE_BAUD, 0x150, 4, 0 },
+ { BASE_BAUD, 0x158, 4, 0 },
+ { BASE_BAUD, 0x160, 4, 0 },
+ { BASE_BAUD, 0x168, 4, 0 },
+ { BASE_BAUD, 0x170, 4, 0 },
+ { BASE_BAUD, 0x178, 4, 0 },
};
#define NR_PORTS (sizeof(rs_table)/sizeof(struct async_struct))
*/
static int baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 56000, 115200, 0 };
+ 9600, 19200, 38400, 56700, 115200, 0 };
static void startup(struct async_struct * info);
static void shutdown(struct async_struct * info);
static void rs_throttle(struct tty_struct * tty, int status);
+static void restart_port(struct async_struct *info);
+#ifdef FAKE_SOFT_IRQ
+static void do_softint();
+#endif
-static void send_break( struct async_struct * info)
+static inline unsigned int serial_in(struct async_struct *info, int offset)
{
- unsigned short port;
+ return inb(info->port + offset);
+}
- if (!(port = info->port))
+static inline unsigned int serial_inp(struct async_struct *info, int offset)
+{
+ return inb_p(info->port + offset);
+}
+
+static inline void serial_out(struct async_struct *info, int offset, int value)
+{
+ outb(value, info->port+offset);
+}
+
+static inline void serial_outp(struct async_struct *info, int offset,
+ int value)
+{
+ outb_p(value, info->port+offset);
+}
+
+static void send_break( struct async_struct * info)
+{
+ if (!info->port)
return;
- port += UART_LCR;
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + 25;
- outb_p(inb_p(port) | UART_LCR_SBC, port);
+ serial_out(info, UART_LCR, serial_inp(info, UART_LCR) | UART_LCR_SBC);
schedule();
- outb(inb_p(port) & ~UART_LCR_SBC, port);
+ serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
}
-static inline void rs_sched_event(int line,
- struct async_struct *info,
+static inline void rs_sched_event(struct async_struct *info,
int event)
{
info->event |= 1 << event;
- rs_event |= 1 << line;
+ rs_event |= 1 << info->line;
+
+#ifndef SOFT_IRQ
timer_table[RS_TIMER].expires = 0;
timer_active |= 1 << RS_TIMER;
+#endif
}
-#ifdef NEW_INTERRUPT_ROUTINE
+
/*
- * This ISR handles the COM1-4 8250, 16450, and 16550A UART's. It is
- * also called by the FourPort ISR, since the FourPort also uses the
- * same National Semiconduct UART's, with some interrupt multiplexing
- * thrown in.
- *
- * This routine assumes nobody else will be mucking with the tty
- * queues its working on. It should be called with the interrupts
- * disabled, since it is not reentrant, and it assumes it doesn't need
- * to worry about other routines mucking about its data structures
- * while it keeps copies of critical pointers in registers.
+ * This is the serial driver's generic interrupt routine
*/
-static void UART_ISR_proc(async_ISR ISR, int line)
+static void rs_interrupt(int irq)
{
unsigned char status;
- struct async_struct * info = rs_table + line;
+ struct async_struct * info;
struct tty_queue * queue;
int head, tail, count, ch;
- int cflag, iflag;
+ int done;
/*
* Just like the LEFT(x) macro, except it uses the loal tail
* and head variables.
*/
#define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
-
- if (!info || !info->tty || !info->port)
- return;
- cflag = info->tty->termios->c_cflag;
- iflag = info->tty->termios->c_iflag;
-
- do {
- restart:
- status = inb_p(UART_LSR + info->port);
+#define IFLAG (info->tty->termios->c_iflag)
+#define CFLAG (info->tty->termios->c_cflag)
+
+ info = IRQ_ports[irq];
+ done = 1;
+ while (info) {
+#ifdef SERIAL_INT_DEBUG
+ printk("rsint(%d)...", info->line);
+#endif
+ if (serial_inp(info, UART_IIR) & UART_IIR_NO_INT)
+ goto next_loop;
+ done = 0;
+
+ status = serial_inp(info, UART_LSR);
if (status & UART_LSR_DR) {
+#ifdef SERIAL_INT_DEBUG
+ printk("DR...");
+#endif
queue = &info->tty->read_q;
head = queue->head;
tail = queue->tail;
do {
- ch = inb(UART_RX + info->port);
+ ch = serial_in(info, UART_RX);
/*
* There must be at least 3 characters
* free in the queue; otherwise we punt.
UART_LSR_PE)) {
if (status & (UART_LSR_BI)) {
if (info->flags & ASYNC_SAK)
- rs_sched_event(line, info, RS_EVENT_DO_SAK);
- else if (iflag & IGNBRK)
+ rs_sched_event(info, RS_EVENT_DO_SAK);
+ else if (IFLAG & IGNBRK)
continue;
- else if (iflag & BRKINT)
- rs_sched_event(line, info, RS_EVENT_BREAK_INT);
+ else if (IFLAG & BRKINT)
+ rs_sched_event(info, RS_EVENT_BREAK_INT);
else
ch = 0;
- } else if (iflag & IGNPAR)
+ } else if (IFLAG & IGNPAR)
continue;
- if (iflag & PARMRK) {
+ if (IFLAG & PARMRK) {
queue->buf[head++] = 0xff;
head &= TTY_BUF_SIZE-1;
queue->buf[head++] = 0;
head &= TTY_BUF_SIZE-1;
} else
ch = 0;
- } else if ((iflag & PARMRK) && (ch == 0xff)) {
+ } else if ((IFLAG & PARMRK) && (ch == 0xff)) {
queue->buf[head++] = 0xff;
head &= TTY_BUF_SIZE-1;
}
queue->buf[head++] = ch;
head &= TTY_BUF_SIZE-1;
- } while ((status = inb_p(UART_LSR + info->port)) &
+ } while ((status = serial_inp(info, UART_LSR)) &
UART_LSR_DR);
queue->head = head;
if ((VLEFT < RQ_THRESHOLD_LW)
&& !set_bit(TTY_RQ_THROTTLED, &info->tty->flags))
rs_throttle(info->tty, TTY_THROTTLE_RQ_FULL);
- rs_sched_event(line, info, RS_EVENT_READ_PROCESS);
+ rs_sched_event(info, RS_EVENT_READ_PROCESS);
}
if ((status & UART_LSR_THRE) &&
!info->tty->stopped) {
if (head==tail && !info->x_char)
goto no_xmit;
if (info->x_char) {
- outb_p(info->x_char, UART_TX + info->port);
+ serial_outp(info, UART_TX, info->x_char);
info->x_char = 0;
} else {
count = info->xmit_fifo_size;
while (count--) {
if (tail == head)
break;
- outb_p(queue->buf[tail++],
- UART_TX + info->port);
+ serial_outp(info, UART_TX,
+ queue->buf[tail++]);
tail &= TTY_BUF_SIZE-1;
}
}
queue->tail = tail;
if (VLEFT > WAKEUP_CHARS)
- rs_sched_event(line, info,
- RS_EVENT_WRITE_WAKEUP);
+ rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
info->timer = jiffies + info->timeout;
if (info->timer < timer_table[RS_TIMER].expires)
timer_table[RS_TIMER].expires = info->timer;
#ifdef i386
- rs_write_active |= 1 << line;
+ rs_write_active |= 1 << info->line;
#else
- set_bit(line, &rs_write_active);
+ set_bit(info->line, &rs_write_active);
#endif
timer_active |= 1 << RS_TIMER;
+#ifdef SERIAL_INT_DEBUG
+ printk("THRE...");
+#endif
}
no_xmit:
- status = inb(UART_MSR + info->port);
+ status = serial_in(info, UART_MSR);
- if (!(cflag & CLOCAL) && (status & UART_MSR_DDCD)) {
+ if (!(CFLAG & CLOCAL) && (status & UART_MSR_DDCD)) {
if (!(status & UART_MSR_DCD))
- rs_sched_event(line, info, RS_EVENT_HUP_PGRP);
+ rs_sched_event(info, RS_EVENT_HUP_PGRP);
}
- /*
- * Because of the goto statement, this block must be
- * last. We have to skip the do/while test condition
- * because the THRE interrupt has probably been lost.
- */
- if (cflag & CRTSCTS) {
+ if (CFLAG & CRTSCTS) {
if (info->tty->stopped) {
if (status & UART_MSR_CTS) {
info->tty->stopped = 0;
- goto restart;
+ restart_port(info);
}
} else
info->tty->stopped = !(status & UART_MSR_CTS);
}
- } while (!(inb_p(UART_IIR + info->port) & UART_IIR_NO_INT));
-}
-#else /* NEW_INTERRUPT_ROUTINE */
-/*
- * There are several races here: we avoid most of them by disabling
- * timer_active for the crucial part of the process.. That's a good
- * idea anyway.
- *
- * The problem is that we have to output characters /both/ from interrupts
- * and from the normal write: the latter to be sure the interrupts start up
- * again. With serial lines, the interrupts can happen so often that the
- * races actually are noticeable.
- */
-static void send_intr(struct async_struct * info)
-{
- unsigned short port = info->port;
- int line = info->line;
- struct tty_queue * queue = &info->tty->write_q;
- int c, count = 0;
-
- if (info->tty->stopped)
- return;
-
- if (info->type == PORT_16550A)
- count = 16;
- else
- count = 1;
-
- rs_write_active &= ~(1 << line);
-
- if (inb_p(UART_LSR + info->port) & UART_LSR_THRE) {
- while (count-- && !info->tty->stopped) {
- if (queue->tail == queue->head)
- goto end_send;
- c = queue->buf[queue->tail];
- queue->tail++;
- queue->tail &= TTY_BUF_SIZE-1;
- outb(c, UART_TX + port);
+ next_loop:
+ info = info->next_port;
+ if (!info && !done) {
+#ifdef SERIAL_INT_DEBUG
+ printk("repeating...");
+#endif
+ info = IRQ_ports[irq];
+ done = 1;
}
}
- info->timer = jiffies + info->timeout;
- if (info->timer < timer_table[RS_TIMER].expires)
- timer_table[RS_TIMER].expires = info->timer;
- rs_write_active |= 1 << line;
- timer_active |= 1 << RS_TIMER;
-end_send:
- if (LEFT(queue) > WAKEUP_CHARS)
- wake_up(&queue->proc_list);
-}
-
-static void receive_intr(struct async_struct * info)
-{
- unsigned short port = info->port;
- struct tty_queue * queue = &info->tty->read_q;
- int head = queue->head;
- int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1);
- int count = 0;
-
- do {
- count++;
- queue->buf[head] = inb(UART_TX + port);
- if (head != maxhead) {
- head++;
- head &= TTY_BUF_SIZE-1;
- }
- } while (inb(UART_LSR + port) & UART_LSR_DR);
- queue->head = head;
- rs_sched_event(info->line, info, RS_EVENT_READ_PROCESS);
-}
-
-static void line_status_intr(struct async_struct * info)
-{
- unsigned char status = inb(UART_LSR + info->port);
-
-/* printk("line status: %02x\n",status); */
-}
-
-static void modem_status_intr(struct async_struct * info)
-{
- unsigned char status = inb(UART_MSR + info->port);
-
- if (!(info->tty->termios->c_cflag & CLOCAL)) {
- if ((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
- tty_hangup(info->tty);
-
- if (info->tty->termios->c_cflag & CRTSCTS)
- info->tty->stopped = !(status & UART_MSR_CTS);
-
- if (!info->tty->stopped)
- send_intr(info);
- }
-}
-
-static void (*jmp_table[4])(struct async_struct *) = {
- modem_status_intr,
- send_intr,
- receive_intr,
- line_status_intr
-};
-
-/*
- * This ISR handles the COM1-4 8250, 16450, and 16550A UART's. It is
- * also called by the FourPort ISR, since the FourPort also uses the
- * same National Semiconduct UART's, with some interrupt multiplexing
- * thrown in.
- */
-static void UART_ISR_proc(async_ISR ISR, int line)
-{
- unsigned char ident;
- struct async_struct * info = rs_table + line;
-
- if (!info || !info->tty || !info->port)
- return;
- while (1) {
- ident = inb(UART_IIR + info->port) & 7;
- if (ident & 1)
- return;
- ident = ident >> 1;
- jmp_table[ident](info);
- }
-}
-#endif /* NEW_INTERRUPT_ROUTINE */
-
-#ifdef CONFIG_AST_FOURPORT
-/*
- * Here is the fourport ISR
- */
-static void FourPort_ISR_proc(async_ISR ISR, int line)
-{
- int i;
- unsigned char ivec;
-
- ivec = ~inb(ISR->port) & 0x0F;
- do {
- for (i = line; ivec; i++) {
- if (ivec & 1)
- UART_ISR_proc(ISR, i);
- ivec = ivec >> 1;
- }
- ivec = ~inb(ISR->port) & 0x0F;
- } while (ivec);
-}
-#endif /* CONFIG_AST_FOURPORT */
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-static void rs_interrupt(int irq)
-{
- async_ISR p = IRQ_ISR[irq];
-
- while (p) {
- (p->ISR_proc)(p, p->line);
- p = p->next_ISR;
+#ifdef FAKE_SOFT_IRQ
+ if (rs_event && !doing_softint) {
+ doing_softint = 1;
+ sti(); /* Turn on interrupts! */
+ do_softint();
}
+#endif
}
#ifdef CONFIG_AUTO_IRQ
}
#endif
+#ifdef SOFT_IRQ
+static void do_softint()
+{
+ unsigned long mask;
+ struct async_struct *info;
+
+ while (rs_event) {
+ info = rs_table;
+ for (mask = 1 ; mask ; info++, mask <<= 1) {
+ if (mask > rs_event)
+ break;
+ if (!info->tty) /* check that we haven't closed it.. */
+ continue;
+ if (mask & rs_event) {
+ rs_event &= ~mask;
+ if (!clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
+ TTY_READ_FLUSH(info->tty);
+ }
+ if (!clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+ wake_up_interruptible(&info->tty->write_q.proc_list);
+ }
+ if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event))
+ tty_hangup(info->tty);
+ if (!clear_bit(RS_EVENT_BREAK_INT, &info->event)) {
+ flush_input(info->tty);
+ flush_output(info->tty);
+ if (info->tty->pgrp > 0)
+ kill_pg(info->tty->pgrp,SIGINT,1);
+ }
+ if (!clear_bit(RS_EVENT_DO_SAK, &info->event)) {
+ do_SAK(info->tty);
+ }
+ }
+ }
+ }
+#ifdef FAKE_SOFT_IRQ
+ doing_softint = 0;
+#endif
+}
+#endif
+
/*
* This subroutine handles all of the timer functionality required for
* the serial ports.
struct async_struct *info;
unsigned long next_timeout;
+#ifdef FAKE_SOFT_IRQ
+ cli();
+ if (rs_event && !doing_softint) {
+ doing_softint = 1;
+ sti(); /* Turn on interrupts! */
+ do_softint();
+ }
+ sti();
+#endif
info = rs_table;
next_timeout = END_OF_TIME;
for (mask = 1 ; mask ; info++, mask <<= 1) {
- if ((mask > rs_event) &&
+ if (
+#ifndef SOFT_IRQ
+ (mask > rs_event) &&
+#endif
(mask > rs_write_active))
break;
if (!info->tty) { /* check that we haven't closed it.. */
rs_write_active &= ~mask;
continue;
}
+#ifndef SOFT_IRQ
if (mask & rs_event) {
if (!clear_bit(RS_EVENT_READ_PROCESS, &info->event)) {
TTY_READ_FLUSH(info->tty);
rs_event &= ~mask;
sti();
}
+#endif
if (mask & rs_write_active) {
if (info->timer <= jiffies) {
#ifdef i386
}
}
+/*
+ * Note: this subroutine must be called with the interrupts *off*
+ */
+static void restart_port(struct async_struct *info)
+{
+ struct tty_queue * queue;
+ int head, tail, count;
+
+ if (serial_inp(info, UART_LSR) & UART_LSR_THRE) {
+ if (info->x_char) {
+ serial_outp(info, UART_TX, info->x_char);
+ info->x_char = 0;
+ } else {
+ queue = &info->tty->write_q;
+ head = queue->head;
+ tail = queue->tail;
+ count = info->xmit_fifo_size;
+ while (count--) {
+ if (tail == head)
+ break;
+ serial_outp(info, UART_TX, queue->buf[tail++]);
+ tail &= TTY_BUF_SIZE-1;
+ }
+ queue->tail = tail;
+ }
+ }
+}
+
/*
* This routine gets called when tty_write has put something into
- * the write_queue. It calls UART_ISR_proc to simulate an interrupt,
- * which gets things going.
+ * the write_queue.
*/
void rs_write(struct tty_struct * tty)
{
struct async_struct *info;
- if (!tty || tty->stopped || EMPTY(&tty->write_q))
+ if (!tty || tty->stopped)
return;
info = rs_table + DEV_TO_SL(tty->line);
- if (!test_bit(info->line, &rs_write_active)) {
- cli();
-#ifdef NEW_INTERRUPT_ROUTINE
- UART_ISR_proc(info->ISR, info->line);
-#else
- send_intr(info);
-#endif
- sti();
- }
-
+ cli();
+ restart_port(info);
+ sti();
}
static void rs_throttle(struct tty_struct * tty, int status)
if (tty->termios->c_iflag & IXOFF) {
info->x_char = STOP_CHAR(tty);
} else {
- mcr = inb_p(UART_MCR + info->port);
+ mcr = serial_inp(info, UART_MCR);
mcr &= ~UART_MCR_RTS;
- outb(mcr, UART_MCR + info->port);
+ serial_out(info, UART_MCR, mcr);
}
break;
case TTY_THROTTLE_RQ_AVAIL:
info->x_char = START_CHAR(tty);
sti();
} else {
- mcr = inb(UART_MCR + info->port);
+ mcr = serial_in(info, UART_MCR);
mcr |= UART_MCR_RTS;
- outb_p(mcr, UART_MCR + info->port);
+ serial_out(info, UART_MCR, mcr);
}
break;
}
/*
* This routine is called when the serial port gets closed. First, we
* wait for the last remaining data to be sent. Then, we unlink its
- * ISR from the interrupt chain if necessary, and we free that IRQ if
- * nothing is left in the chain.
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
*/
static void rs_close(struct tty_struct *tty, struct file * filp)
{
struct async_struct * info;
- async_ISR ISR;
int irq, line;
line = DEV_TO_SL(tty->line);
#endif
info->event = 0;
info->tty = 0;
- ISR = info->ISR;
- irq = ISR->irq;
- if (irq == 2)
- irq = 9;
- if (--ISR->refcnt == 0) {
- if (ISR->next_ISR)
- ISR->next_ISR->prev_ISR = ISR->prev_ISR;
- if (ISR->prev_ISR)
- ISR->prev_ISR->next_ISR = ISR->next_ISR;
+ if (info->flags & ASYNC_NO_IRQ)
+ info->flags &= ~ASYNC_NO_IRQ;
+ else {
+ irq = info->irq;
+ if (irq == 2)
+ irq = 9;
+ if (info->next_port)
+ info->next_port->prev_port = info->prev_port;
+ if (info->prev_port)
+ info->prev_port->next_port = info->next_port;
else
- IRQ_ISR[irq] = ISR->next_ISR;
- if (!IRQ_ISR[irq])
+ IRQ_ports[irq] = info->next_port;
+ if (!IRQ_ports[irq])
free_irq(irq);
}
}
static void startup(struct async_struct * info)
{
- unsigned short port = info->port;
unsigned short ICP;
/*
* First, clear the FIFO buffers and disable them
*/
if (info->type == PORT_16550A)
- outb_p(UART_FCR_CLEAR_CMD, UART_FCR + port);
+ serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD);
/*
* Next, clear the interrupt registers.
*/
- (void)inb_p(UART_LSR + port);
- (void)inb_p(UART_RX + port);
- (void)inb_p(UART_IIR + port);
- (void)inb_p(UART_MSR + port);
+ (void)serial_inp(info, UART_LSR);
+ (void)serial_inp(info, UART_RX);
+ (void)serial_inp(info, UART_IIR);
+ (void)serial_inp(info, UART_MSR);
/*
* Now, initialize the UART
*/
- outb_p(UART_LCR_WLEN8, UART_LCR + port); /* reset DLAB */
+ serial_outp(info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
if (info->flags & ASYNC_FOURPORT)
- outb_p(UART_MCR_DTR | UART_MCR_RTS,
- UART_MCR + port);
+ serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
else
- outb_p(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
- UART_MCR + port);
+ serial_outp(info, UART_MCR,
+ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
/*
* Enable FIFO's if necessary
*/
if (info->type == PORT_16550A) {
- outb_p(UART_FCR_SETUP_CMD, UART_FCR + port);
+ serial_outp(info, UART_FCR, UART_FCR_SETUP_CMD);
info->xmit_fifo_size = 16;
} else {
info->xmit_fifo_size = 1;
/*
* Finally, enable interrupts
*/
- outb_p(0x0f,UART_IER + port); /* enable all intrs */
+ serial_outp(info, UART_IER, 0x0f); /* enable all intrs */
if (info->flags & ASYNC_FOURPORT) {
/* Enable interrupts on the AST Fourport board */
- ICP = (port & 0xFE0) | 0x01F;
+ ICP = (info->port & 0xFE0) | 0x01F;
outb_p(0x80, ICP);
- (void) inb(ICP);
+ (void) inb_p(ICP);
}
/*
* And clear the interrupt registers again for luck.
*/
- (void)inb_p(UART_LSR + port);
- (void)inb_p(UART_RX + port);
- (void)inb_p(UART_IIR + port);
- (void)inb_p(UART_MSR + port);
+ (void)serial_inp(info, UART_LSR);
+ (void)serial_inp(info, UART_RX);
+ (void)serial_inp(info, UART_IIR);
+ (void)serial_inp(info, UART_MSR);
}
static void shutdown(struct async_struct * info)
{
- unsigned short port = info->port;
-
- outb_p(0x00, UART_IER + port); /* disable all intrs */
+ serial_outp(info, UART_IER, 0x00); /* disable all intrs */
if (info->tty && !(info->tty->termios->c_cflag & HUPCL))
- outb_p(UART_MCR_DTR, UART_MCR + port);
+ serial_outp(info, UART_MCR, UART_MCR_DTR);
else
/* reset DTR,RTS,OUT_2 */
- outb_p(0x00, UART_MCR + port);
- outb_p(UART_FCR_CLEAR_CMD, UART_FCR + info->port); /* disable FIFO's */
- (void)inb(UART_RX + port); /* read data port to reset things */
+ serial_outp(info, UART_MCR, 0x00);
+ serial_outp(info, UART_FCR, UART_FCR_CLEAR_CMD); /* disable FIFO's */
+ (void)serial_in(info, UART_RX); /* read data port to reset things */
}
void change_speed(unsigned int line)
quot = 0;
info->timeout = 0;
}
- mcr = inb(UART_MCR + port);
+ mcr = serial_in(info, UART_MCR);
if (quot)
- outb(mcr | UART_MCR_DTR, UART_MCR + port);
+ serial_out(info, UART_MCR, mcr | UART_MCR_DTR);
else {
- outb(mcr & ~UART_MCR_DTR, UART_MCR + port);
+ serial_out(info, UART_MCR, mcr & ~UART_MCR_DTR);
return;
}
/* byte size and parity */
if (!(cflag & PARODD))
cval |= 16;
cli();
- outb_p(cval | UART_LCR_DLAB, UART_LCR + port); /* set DLAB */
- outb_p(quot & 0xff, UART_DLL + port); /* LS of divisor */
- outb_p(quot >> 8, UART_DLM + port); /* MS of divisor */
- outb(cval, UART_LCR + port); /* reset DLAB */
+ serial_outp(info, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
+ serial_outp(info, UART_DLL, quot & 0xff); /* LS of divisor */
+ serial_outp(info, UART_DLM, quot >> 8); /* MS of divisor */
+ serial_outp(info, UART_LCR, cval); /* reset DLAB */
sti();
}
tmp.type = info->type;
tmp.line = info->line;
tmp.port = info->port;
- tmp.irq = info->ISR->irq;
-/* tmp.flags = info->flags; */
+ tmp.irq = info->irq;
+ tmp.flags = info->flags;
+ tmp.baud_base = info->baud_base;
memcpy_tofs(retinfo,&tmp,sizeof(*retinfo));
return 0;
}
struct serial_struct * new_info)
{
struct serial_struct tmp;
- async_ISR ISR;
unsigned int new_port;
unsigned int irq,new_irq;
int retval;
struct sigaction sa;
+ struct async_struct old_info;
if (!suser())
return -EPERM;
return -EFAULT;
memcpy_fromfs(&tmp,new_info,sizeof(tmp));
+ old_info = *info;
+ info->baud_base = tmp.baud_base;
info->flags = tmp.flags & ASYNC_FLAGS;
-
- if ( (tmp.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
- info->custom_divisor = tmp.custom_divisor;
-
+ info->custom_divisor = tmp.custom_divisor;
+
if ((tmp.type >= PORT_UNKNOWN) && (tmp.type <= PORT_MAX))
info->type = tmp.type;
new_port = tmp.port;
new_irq = tmp.irq;
- if (new_irq > 15 || new_port > 0xffff)
+ if (new_irq > 15 || new_port > 0xffff) {
+ *info = old_info;
return -EINVAL;
+ }
if (new_irq == 2)
new_irq = 9;
- ISR = info->ISR;
- irq = ISR->irq;
+ irq = info->irq;
if (irq == 2)
irq = 9;
if (irq != new_irq) {
* necessary, first we try to grab the new IRQ for
* serial interrupts.
*/
- if (!IRQ_ISR[new_irq]) {
+ if (!IRQ_ports[new_irq]) {
sa.sa_handler = rs_interrupt;
sa.sa_flags = (SA_INTERRUPT);
sa.sa_mask = 0;
sa.sa_restorer = NULL;
retval = irqaction(new_irq,&sa);
- if (retval)
+ if (retval) {
+ *info = old_info;
return retval;
+ }
}
/*
- * If the new IRQ is OK, now we unlink the ISR from
+ * If the new IRQ is OK, now we unlink the async structure from
* the existing interrupt chain.
*/
- if (ISR->next_ISR)
- ISR->next_ISR->prev_ISR = ISR->prev_ISR;
- if (ISR->prev_ISR)
- ISR->prev_ISR->next_ISR = ISR->next_ISR;
+ if (info->next_port)
+ info->next_port->prev_port = info->prev_port;
+ if (info->prev_port)
+ info->prev_port->next_port = info->next_port;
else
- IRQ_ISR[irq] = ISR->next_ISR;
- if (!IRQ_ISR[irq])
+ IRQ_ports[irq] = info->next_port;
+ if (!IRQ_ports[irq])
free_irq(irq);
/*
* Now link in the interrupt to the new interrupt chain.
*/
- ISR->prev_ISR = 0;
- ISR->next_ISR = IRQ_ISR[new_irq];
- if (ISR->next_ISR)
- ISR->next_ISR->prev_ISR = ISR;
- IRQ_ISR[new_irq] = ISR;
- ISR->irq = new_irq;
+ info->prev_port = 0;
+ info->next_port = IRQ_ports[new_irq];
+ if (info->next_port)
+ info->next_port->prev_port = info;
+ IRQ_ports[new_irq] = info;
+ info->irq = new_irq;
}
cli();
if (new_port != info->port) {
info->port = new_port;
startup(info);
change_speed(info->line);
+ old_info = *info; /* To avoid second change_speed */
}
sti();
+
+ if (((old_info.flags & ASYNC_SPD_MASK) != (info->flags & ASYNC_SPD_MASK)) ||
+ (old_info.custom_divisor != info->custom_divisor))
+ change_speed(info->line);
return 0;
}
static int get_modem_info(struct async_struct * info, unsigned int *value)
{
- unsigned port;
unsigned char control, status;
unsigned int result;
- port = info->port;
- control = inb(UART_MCR + port);
- status = inb(UART_MSR + port);
+ control = serial_in(info, UART_MCR);
+ status = serial_in(info, UART_MSR);
result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
| ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
static int set_modem_info(struct async_struct * info, unsigned int cmd,
unsigned int *value)
{
- unsigned port;
unsigned char control;
unsigned int arg = get_fs_long((unsigned long *) value);
- port = info->port;
- control = inb(UART_MCR + port);
+ control = serial_in(info, UART_MCR);
switch (cmd) {
case TIOCMBIS:
default:
return -EINVAL;
}
- outb(control, UART_MCR + port);
+ serial_out(info, UART_MCR, control);
return 0;
}
/*
* This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its interrupt into
- * the ISR chain. It also performs the serial-speicific
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain. It also performs the serial-speicific
* initalization for the tty structure.
*/
int rs_open(struct tty_struct *tty, struct file * filp)
{
struct async_struct *info;
- async_ISR ISR;
int irq, retval, line;
struct sigaction sa;
if ((line < 0) || (line >= NR_PORTS))
return -ENODEV;
info = rs_table + line;
- if (!info->port || !info->ISR->irq)
+ if (!info->port || !info->irq || !info->type) {
+#ifdef TTY_IO_ERROR
+ set_bit(TTY_IO_ERROR, &tty->flags);
+ info->flags |= ASYNC_NO_IRQ;
+ info->tty = tty;
+ tty->close = rs_close;
+ tty->ioctl = rs_ioctl;
+ return 0;
+#else
return -ENODEV;
+#endif
+ } else
+ info->flags &= ~ASYNC_NO_IRQ;
info->tty = tty;
tty->write = rs_write;
tty->close = rs_close;
tty->ioctl = rs_ioctl;
tty->throttle = rs_throttle;
- ISR = info->ISR;
- irq = ISR->irq;
+ irq = info->irq;
if (irq == 2)
irq = 9;
- if (!IRQ_ISR[irq]) {
+ if (!IRQ_ports[irq]) {
sa.sa_handler = rs_interrupt;
sa.sa_flags = (SA_INTERRUPT);
sa.sa_mask = 0;
if (retval)
return retval;
}
- if (!ISR->refcnt++) {
- /*
- * If this is the first time we're using this ISR,
- * link it in.
- */
- ISR->prev_ISR = 0;
- ISR->next_ISR = IRQ_ISR[irq];
- if (ISR->next_ISR)
- ISR->next_ISR->prev_ISR = ISR;
- IRQ_ISR[irq] = ISR;
- }
+ /*
+ * Link in port to IRQ chain
+ */
+ info->prev_port = 0;
+ info->next_port = IRQ_ports[irq];
+ if (info->next_port)
+ info->next_port->prev_port = info;
+ IRQ_ports[irq] = info;
startup(info);
change_speed(info->line);
return 0;
static void show_serial_version()
{
- printk("Serial driver version 3.1 with");
+ printk("Serial driver version 3.8 with");
#ifdef CONFIG_AST_FOURPORT
printk(" AST_FOURPORT");
#define SERIAL_OPT
printk (" AUTO_IRQ");
#define SERIAL_OPT
#endif
-#ifdef NEW_INTERRUPT_ROUTINE
- printk(" NEW_INTERRUPT_ROUTINE");
-#define SERIAL_OPT
-#endif
#ifdef SERIAL_OPT
printk(" enabled\n");
#else
* Enable interrupts and see who answers
*/
rs_irq_triggered = 0;
- scratch = inb_p(UART_IER + port);
- status1 = inb_p(UART_MCR + port);
+ scratch = serial_inp(info, UART_IER);
+ status1 = serial_inp(info, UART_MCR);
if (info->flags & ASYNC_FOURPORT) {
- outb_p(UART_MCR_DTR | UART_MCR_RTS, UART_MCR + port);
- outb_p(0x0f,UART_IER + port); /* enable all intrs */
+ serial_outp(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+ serial_outp(info, UART_IER, 0x0f); /* enable all intrs */
ICP = (port & 0xFE0) | 0x01F;
save_ICP = inb_p(ICP);
outb_p(0x80, ICP);
(void) inb(ICP);
} else {
- outb_p(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2,
- UART_MCR + port);
- outb_p(0x0f,UART_IER + port); /* enable all intrs */
+ serial_outp(info, UART_MCR,
+ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+ serial_outp(info, UART_IER, 0x0f); /* enable all intrs */
}
/*
* Next, clear the interrupt registers.
*/
- (void)inb_p(UART_LSR + port);
- (void)inb_p(UART_RX + port);
- (void)inb_p(UART_IIR + port);
- (void)inb_p(UART_MSR + port);
+ (void)serial_inp(info, UART_LSR);
+ (void)serial_inp(info, UART_RX);
+ (void)serial_inp(info, UART_IIR);
+ (void)serial_inp(info, UART_MSR);
+
timeout = jiffies+2;
while (timeout >= jiffies) {
if (rs_irq_triggered)
* Now check to see if we got any business, and clean up.
*/
if (rs_irq_triggered) {
- outb_p(0, UART_IER + port);
- info->ISR->irq = rs_irq_triggered;
+ serial_outp(info, UART_IER, 0);
+ info->irq = rs_irq_triggered;
} else {
- outb_p(scratch, UART_IER + port);
- outb_p(status1, UART_MCR + port);
+ serial_outp(info, UART_IER, scratch);
+ serial_outp(info, UART_MCR, status1);
if (info->flags & ASYNC_FOURPORT)
outb_p(save_ICP, ICP);
info->type = PORT_UNKNOWN;
/*
* Check to see if a UART is really there.
*/
- scratch = inb_p(UART_MCR + port);
- outb_p(UART_MCR_LOOP | scratch, UART_MCR + port);
- scratch2 = inb_p(UART_MSR + port);
- outb_p(UART_MCR_LOOP | 0x0A, UART_MCR + port);
- status1 = inb_p(UART_MSR + port) & 0xF0;
- outb_p(scratch, UART_MCR + port);
- outb_p(scratch2, UART_MSR + port);
+ scratch = serial_inp(info, UART_MCR);
+ serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
+ scratch2 = serial_inp(info, UART_MSR);
+ serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
+ status1 = serial_inp(info, UART_MSR) & 0xF0;
+ serial_outp(info, UART_MCR, scratch);
+ serial_outp(info, UART_MSR, scratch2);
if (status1 != 0x90) {
info->type = PORT_UNKNOWN;
return;
}
#endif /* CONFIG_AUTO_IRQ */
- if (!(info->flags & ASYNC_NOSCRATCH)) {
+ outb_p(UART_FCR_ENABLE_FIFO, UART_FCR + port);
+ scratch = inb(UART_IIR + port) >> 6;
+ info->xmit_fifo_size = 1;
+ switch (scratch) {
+ case 0:
+ info->type = PORT_16450;
+ break;
+ case 1:
+ info->type = PORT_UNKNOWN;
+ break;
+ case 2:
+ info->type = PORT_16550;
+ break;
+ case 3:
+ info->type = PORT_16550A;
+ info->xmit_fifo_size = 16;
+ break;
+ }
+ if (info->type == PORT_16450) {
scratch = inb(UART_SCR + port);
outb_p(0xa5, UART_SCR + port);
status1 = inb(UART_SCR + port);
outb_p(0x5a, UART_SCR + port);
status2 = inb(UART_SCR + port);
outb_p(scratch, UART_SCR + port);
- } else {
- status1 = 0xa5;
- status2 = 0x5a;
+ if ((status1 != 0xa5) || (status2 != 0x5a))
+ info->type = PORT_8250;
}
- if (status1 == 0xa5 && status2 == 0x5a) {
- outb_p(UART_FCR_ENABLE_FIFO, UART_FCR + port);
- scratch = inb(UART_IIR + port) >> 6;
- info->xmit_fifo_size = 1;
- switch (scratch) {
- case 0:
- info->type = PORT_16450;
- break;
- case 1:
- info->type = PORT_UNKNOWN;
- break;
- case 2:
- info->type = PORT_16550;
- break;
- case 3:
- info->type = PORT_16550A;
- info->xmit_fifo_size = 16;
- break;
- }
- } else
- info->type = PORT_8250;
shutdown(info);
}
timer_table[RS_TIMER].expires = 0;
for (i = 0; i < 16; i++) {
- IRQ_ISR[i] = 0;
+ IRQ_ports[i] = 0;
#ifdef CONFIG_AUTO_IRQ
if (!irqaction(i, &sa))
irq_lines |= 1 << i;
info->custom_divisor = 0;
info->x_char = 0;
info->event = 0;
- if (!info->ISR->line) {
- info->ISR->line = i;
- info->ISR->refcnt = 0;
- info->ISR->next_ISR = 0;
- info->ISR->prev_ISR = 0;
- }
+ info->next_port = 0;
+ info->prev_port = 0;
init(info);
if (info->type == PORT_UNKNOWN)
continue;
printk("ttys%d%s at 0x%04x (irq = %d)", info->line,
(info->flags & ASYNC_FOURPORT) ? " FourPort" : "",
- info->port, info->ISR->irq);
+ info->port, info->irq);
switch (info->type) {
case PORT_8250:
printk(" is a 8250\n");
struct tty_struct * redirect = NULL;
struct wait_queue * keypress_wait = NULL;
-static int initialize_tty_struct(struct tty_struct *tty, int line);
+static void initialize_tty_struct(int line, struct tty_struct *tty);
+static void initialize_termios(int line, struct termios *tp);
+
static int tty_read(struct inode *, struct file *, char *, int);
static int tty_write(struct inode *, struct file *, char *, int);
static int tty_select(struct inode *, struct file *, int, select_table *);
static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
{
- return -EBADF;
+ return -ESPIPE;
}
static struct file_operations tty_fops = {
return filp->f_op == &hung_up_tty_fops;
}
+/*
+ * Sometimes we want to wait until a particular VT has been activated. We
+ * do it in a very simple manner. Everybody waits on a single queue and
+ * get woken up at once. Those that are satisfied go on with their business,
+ * while those not ready go back to sleep. Seems overkill to add a wait
+ * to each vt just for this - usually this does nothing!
+ */
+static struct wait_queue *vt_activate_queue = NULL;
+
+/*
+ * Sleeps until a vt is activated, or the task is interrupted. Returns
+ * 0 if activation, -1 if interrupted.
+ */
+int vt_waitactive(void)
+{
+ interruptible_sleep_on(&vt_activate_queue);
+ return (current->signal & ~current->blocked) ? -1 : 0;
+}
+
+#define vt_wake_waitactive() wake_up(&vt_activate_queue)
+
extern int kill_proc(int pid, int sig, int priv);
/*
}
}
+ /*
+ * Wake anyone waiting for their VT to activate
+ */
+ vt_wake_waitactive();
return;
}
}
dev = MINOR(dev);
tty = TTY_TABLE(dev);
- if (!tty)
+ if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
return -EIO;
if (MINOR(inode->i_rdev) && (tty->pgrp > 0) &&
(current->tty == dev) &&
tty = redirect;
else
tty = TTY_TABLE(dev);
- if (!tty || !tty->write)
+ if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
return -EIO;
if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
(current->tty == dev) && (tty->pgrp != current->pgrp)) {
return i;
}
+/*
+ * This is so ripe with races that you should *really* not touch this
+ * unless you know exactly what you are doing. All the changes have to be
+ * made atomically, or there may be incorrect pointers all over the place.
+ */
+static int init_dev(int dev)
+{
+ struct tty_struct *tty, *o_tty;
+ struct termios *tp, *o_tp;
+ int retval;
+ int o_dev;
+
+ o_dev = PTY_OTHER(dev);
+ tty = o_tty = NULL;
+ tp = o_tp = NULL;
+repeat:
+ retval = -EAGAIN;
+ if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
+ goto end_init;
+ retval = -ENOMEM;
+ if (!tty_table[dev] && !tty) {
+ tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
+ if (!tty)
+ goto end_init;
+ initialize_tty_struct(dev, tty);
+ goto repeat;
+ }
+ if (!tty_termios[dev] && !tp) {
+ tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
+ if (!tp)
+ goto end_init;
+ initialize_termios(dev, tp);
+ goto repeat;
+ }
+ if (IS_A_PTY(dev)) {
+ if (!tty_table[o_dev] && !o_tty) {
+ o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
+ if (!o_tty)
+ goto end_init;
+ initialize_tty_struct(o_dev, o_tty);
+ goto repeat;
+ }
+ if (!tty_termios[o_dev] && !o_tp) {
+ o_tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
+ if (!o_tp)
+ goto end_init;
+ initialize_termios(o_dev, o_tp);
+ goto repeat;
+ }
+ }
+ /* Now we have allocated all the structures: update all the pointers.. */
+ if (!tty_termios[dev]) {
+ tty_termios[dev] = tp;
+ tp = NULL;
+ }
+ if (!tty_table[dev]) {
+ tty->termios = tty_termios[dev];
+ tty_table[dev] = tty;
+ tty = NULL;
+ }
+ if (IS_A_PTY(dev)) {
+ if (!tty_termios[o_dev]) {
+ tty_termios[o_dev] = o_tp;
+ o_tp = NULL;
+ }
+ if (!tty_table[o_dev]) {
+ o_tty->termios = tty_termios[o_dev];
+ tty_table[o_dev] = o_tty;
+ o_tty = NULL;
+ }
+ tty_table[dev]->link = tty_table[o_dev];
+ tty_table[o_dev]->link = tty_table[dev];
+ }
+ tty_table[dev]->count++;
+ if (IS_A_PTY_MASTER(dev))
+ tty_table[o_dev]->count++;
+ retval = 0;
+end_init:
+ if (tty)
+ free_page((unsigned long) tty);
+ if (o_tty)
+ free_page((unsigned long) tty);
+ if (tp)
+ kfree_s(tp, sizeof(struct termios));
+ if (o_tp)
+ kfree_s(o_tp, sizeof(struct termios));
+ return retval;
+}
+
+/*
+ * Even releasing the tty structures is a tricky business.. We have
+ * to be very careful that the structures are all released at the
+ * same time, as interrupts might otherwise get the wrong pointers.
+ */
+static void release_dev(int dev, struct file * filp)
+{
+ struct tty_struct *tty, *o_tty;
+ struct termios *tp, *o_tp;
+
+ tty = tty_table[dev];
+ tp = tty_termios[dev];
+ o_tty = NULL;
+ o_tp = NULL;
+ if (!tty) {
+ printk("release_dev: tty_table[%d] was NULL\n", dev);
+ return;
+ }
+ if (!tp) {
+ printk("release_dev: tty_termios[%d] was NULL\n", dev);
+ return;
+ }
+ if (IS_A_PTY(dev)) {
+ o_tty = tty_table[PTY_OTHER(dev)];
+ o_tp = tty_termios[PTY_OTHER(dev)];
+ if (!o_tty) {
+ printk("release_dev: pty pair(%d) was NULL\n", dev);
+ return;
+ }
+ if (!o_tp) {
+ printk("release_dev: pty pair(%d) termios was NULL\n", dev);
+ return;
+ }
+ if (tty->link != o_tty || o_tty->link != tty) {
+ printk("release_dev: bad pty pointers\n");
+ return;
+ }
+ }
+ if (tty->count < 2 && tty->close)
+ tty->close(tty, filp);
+ if (IS_A_PTY_MASTER(dev)) {
+ if (--tty->link->count < 0) {
+ printk("release_dev: bad tty slave count (dev = %d): %d\n",
+ dev, tty->count);
+ tty->link->count = 0;
+ }
+ }
+ if (--tty->count < 0) {
+ printk("release_dev: bad tty_table[%d]->count: %d\n",
+ dev, tty->count);
+ tty->count = 0;
+ }
+ if (tty->count)
+ return;
+ if (o_tty) {
+ if (o_tty->count)
+ return;
+ else {
+ tty_table[PTY_OTHER(dev)] = NULL;
+ tty_termios[PTY_OTHER(dev)] = NULL;
+ }
+ }
+ tty_table[dev] = NULL;
+ if (IS_A_PTY(dev)) {
+ tty_termios[dev] = NULL;
+ kfree_s(tp, sizeof(struct termios));
+ }
+ free_page((unsigned long) tty);
+ if (o_tty)
+ free_page((unsigned long) o_tty);
+ if (o_tp)
+ kfree_s(o_tp, sizeof(struct termios));
+}
+
/*
* tty_open and tty_release keep up the tty count that contains the
* number of opens done on a tty. We cannot use the inode-count, as
*/
static int tty_open(struct inode * inode, struct file * filp)
{
- struct tty_struct *tty, *o_tty;
+ struct tty_struct *tty;
int dev, retval;
dev = inode->i_rdev;
if (!dev)
dev = fg_console + 1;
filp->f_rdev = 0x0400 | dev;
-/*
- * There be race-conditions here... Lots of them. Careful now.
- */
- tty = o_tty = NULL;
+ retval = init_dev(dev);
+ if (retval)
+ return retval;
tty = tty_table[dev];
- if (!tty) {
- tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
- if (tty_table[dev]) {
- /*
- * Stop our allocation of tty if race
- * condition detected.
- */
- if (tty)
- free_page((unsigned long) tty);
- tty = tty_table[dev];
- } else {
- if (!tty)
- return -ENOMEM;
- retval = initialize_tty_struct(tty, dev);
- if (retval) {
- free_page((unsigned long) tty);
- return retval;
- }
- tty_table[dev] = tty;
- }
- }
- tty->count++; /* bump count to preserve tty */
- if (IS_A_PTY(dev)) {
- o_tty = tty_table[PTY_OTHER(dev)];
- if (!o_tty) {
- o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
- if (tty_table[PTY_OTHER(dev)]) {
- /*
- * Stop our allocation of o_tty if race
- * condition detected.
- */
- free_page((unsigned long) o_tty);
- o_tty = tty_table[PTY_OTHER(dev)];
- } else {
- if (!o_tty) {
- tty->count--;
- return -ENOMEM;
- }
- retval = initialize_tty_struct(o_tty, PTY_OTHER(dev));
- if (retval) {
- tty->count--;
- free_page((unsigned long) o_tty);
- return retval;
- }
- tty_table[PTY_OTHER(dev)] = o_tty;
- }
- }
- tty->link = o_tty;
- o_tty->link = tty;
- }
- if (IS_A_PTY_MASTER(dev)) {
- if (tty->count > 1) {
- tty->count--;
- return -EAGAIN;
- }
- if (tty->link)
- tty->link->count++;
- }
- retval = 0;
-
/* clean up the packet stuff. */
tty->status_changed = 0;
tty->ctrl_status = 0;
tty->packet = 0;
+ if (tty->open) {
+ retval = tty->open(tty, filp);
+ } else {
+ retval = -ENODEV;
+ }
+ if (retval) {
+ release_dev(dev, filp);
+ return retval;
+ }
if (!(filp->f_flags & O_NOCTTY) &&
current->leader &&
current->tty<0 &&
tty->session = current->session;
tty->pgrp = current->pgrp;
}
- if (tty->open)
- retval = tty->open(tty, filp);
- else
- retval = -ENODEV;
- if (retval) {
- tty->count--;
- if (IS_A_PTY_MASTER(dev) && tty->link)
- tty->link->count--;
- }
- return retval;
+ return 0;
}
/*
static void tty_release(struct inode * inode, struct file * filp)
{
int dev;
- struct tty_struct * tty;
- unsigned long free_tty_struct;
- struct termios *free_termios;
dev = filp->f_rdev;
if (MAJOR(dev) != 4) {
return;
}
dev = MINOR(filp->f_rdev);
- if (!dev)
- dev = fg_console+1;
- tty = tty_table[dev];
- if (!tty) {
- printk("tty_release: tty_table[%d] was NULL\n", dev);
+ if (!dev) {
+ printk("tty_release: bad f_rdev\n");
return;
}
- if (IS_A_PTY_MASTER(dev) && tty->link) {
- if (--tty->link->count < 0) {
- printk("tty_release: bad tty slave count (dev = %d): %d\n",
- dev, tty->count);
- tty->link->count = 0;
- }
- }
- if (--tty->count < 0) {
- printk("tty_release: bad tty_table[%d]->count: %d\n",
- dev, tty->count);
- tty->count = 0;
- }
- if (tty->count)
- return;
- if (tty->close)
- tty->close(tty, filp);
- if (tty == redirect)
- redirect = NULL;
- if (tty->link && !tty->link->count && (tty->link == redirect))
- redirect = NULL;
- if (tty->link) {
- if (tty->link->count)
- return;
- /*
- * Free the tty structure, being careful to avoid race conditions
- */
- free_tty_struct = (unsigned long) tty_table[PTY_OTHER(dev)];
- tty_table[PTY_OTHER(dev)] = 0;
- free_page(free_tty_struct);
- /*
- * If this is a PTY, free the termios structure, being
- * careful to avoid race conditions
- */
- if (IS_A_PTY(dev)) {
- free_termios = tty_termios[PTY_OTHER(dev)];
- tty_termios[PTY_OTHER(dev)] = 0;
- kfree_s(free_termios, sizeof(struct termios));
- }
- }
- /*
- * Free the tty structure, being careful to avoid race conditions
- */
- free_tty_struct = (unsigned long) tty_table[dev];
- tty_table[dev] = 0;
- free_page(free_tty_struct);
- /*
- * If this is a PTY, free the termios structure, being careful
- * to avoid race conditions
- */
- if (IS_A_PTY(dev)) {
- free_termios = tty_termios[dev];
- tty_termios[dev] = 0;
- kfree_s(free_termios, sizeof(struct termios));
- }
+ release_dev(dev, filp);
}
static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
* This subroutine initializes a tty structure. We have to set up
* things correctly for each different type of tty.
*/
-static int initialize_tty_struct(struct tty_struct *tty, int line)
+static void initialize_tty_struct(int line, struct tty_struct *tty)
{
- struct termios *tp = tty_termios[line];
-
memset(tty, 0, sizeof(struct tty_struct));
tty->line = line;
tty->pgrp = -1;
tty->winsize.ws_row = 24;
tty->winsize.ws_col = 80;
- if (!tty_termios[line]) {
- tp = kmalloc(sizeof(struct termios), GFP_KERNEL);
- if (!tty_termios[line]) {
- if (!tp)
- return -ENOMEM;
- memset(tp, 0, sizeof(struct termios));
- memcpy(tp->c_cc, INIT_C_CC, NCCS);
- if (IS_A_CONSOLE(line)) {
- tp->c_iflag = ICRNL | IXON;
- tp->c_oflag = OPOST | ONLCR;
- tp->c_cflag = B38400 | CS8 | CREAD;
- tp->c_lflag = ISIG | ICANON | ECHO |
- ECHOCTL | ECHOKE;
- } else if (IS_A_SERIAL(line)) {
- tp->c_cflag = B2400 | CS8 | CREAD | HUPCL;
- } else if (IS_A_PTY_MASTER(line)) {
- tp->c_cflag = B9600 | CS8 | CREAD;
- } else if (IS_A_PTY_SLAVE(line)) {
- tp->c_iflag = ICRNL | IXON;
- tp->c_oflag = OPOST | ONLCR;
- tp->c_cflag = B38400 | CS8 | CREAD;
- tp->c_lflag = ISIG | ICANON | ECHO |
- ECHOCTL | ECHOKE;
- }
- tty_termios[line] = tp;
- }
- }
- tty->termios = tty_termios[line];
-
if (IS_A_CONSOLE(line)) {
tty->open = con_open;
tty->winsize.ws_row = video_num_lines;
} else if IS_A_PTY(line) {
tty->open = pty_open;
}
- return 0;
}
+static void initialize_termios(int line, struct termios * tp)
+{
+ memset(tp, 0, sizeof(struct termios));
+ memcpy(tp->c_cc, INIT_C_CC, NCCS);
+ if (IS_A_CONSOLE(line)) {
+ tp->c_iflag = ICRNL | IXON;
+ tp->c_oflag = OPOST | ONLCR;
+ tp->c_cflag = B38400 | CS8 | CREAD;
+ tp->c_lflag = ISIG | ICANON | ECHO |
+ ECHOCTL | ECHOKE;
+ } else if (IS_A_SERIAL(line)) {
+ tp->c_cflag = B2400 | CS8 | CREAD | HUPCL;
+ } else if (IS_A_PTY_MASTER(line)) {
+ tp->c_cflag = B9600 | CS8 | CREAD;
+ } else if (IS_A_PTY_SLAVE(line)) {
+ tp->c_iflag = ICRNL | IXON;
+ tp->c_oflag = OPOST | ONLCR;
+ tp->c_cflag = B38400 | CS8 | CREAD;
+ tp->c_lflag = ISIG | ICANON | ECHO |
+ ECHOCTL | ECHOKE;
+ }
+}
+
long tty_init(long kmem_start)
{
int i;
#include "vt_kern.h"
/*
- * Console (vt and kd) routines, as defined by USL SVR4 manual
+ * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
+ * experimentation and study of X386 SYSV handling.
*
* One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
* /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
* and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
* always treat our set of vt as numbered 1..NR_CONSOLES (corresponding to
- * ttys 0..NR_CONSOLES-1).
- *
- * Mostly done for X386, but with some slight differences and omissions.
- * Should be useable by other SYSV programs in the future.
+ * ttys 0..NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
+ * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
+ * to the current console is done by the main ioctl code.
*/
struct vt_cons vt_cons[NR_CONSOLES];
extern int sys_ioperm(unsigned long from, unsigned long num, int on);
-extern void set_leds(void);
extern void change_console(unsigned int new_console);
extern void complete_change_console(unsigned int new_console);
+extern int vt_waitactive(void);
/*
* these are the valid i/o ports we're allowed to change. they map all the
return 0;
}
+ /*
+ * Returns global vt state. Note that VT 0 is always open, since
+ * it's an alias for the current VT, and people can't use it here.
+ */
+ case VT_GETSTATE:
+ {
+ struct vt_stat *vtstat = (struct vt_stat *)arg;
+ unsigned short state, mask;
+
+ verify_area((void *)vtstat, sizeof(struct vt_stat));
+ put_fs_word(fg_console + 1, &vtstat->v_active);
+ state = 1; /* /dev/tty0 is always open */
+ for (i = 1, mask = 2; i <= NR_CONSOLES; ++i, mask <<= 1)
+ if (tty_table[i] && tty_table[i]->count > 0)
+ state |= mask;
+ put_fs_word(state, &vtstat->v_state);
+ return 0;
+ }
+
/*
* Returns the first available (non-opened) console.
*/
change_console(arg - 1);
return 0;
+ /*
+ * wait until the specified VT has been activated
+ */
+ case VT_WAITACTIVE:
+ if (arg == 0 || arg > NR_CONSOLES)
+ return -ENXIO;
+ while (fg_console != arg - 1)
+ {
+ if (vt_waitactive() < 0)
+ return -EINTR;
+ }
+ return 0;
+
/*
* If a vt is under process control, the kernel will not switch to it
* immediately, but postpone the operation until the process calls this
* ioctl, allowing the switch to complete.
*
- * XXX Under X, the switching code calls VT_RELDISP with an arg of 2
- * when it has switched back to it's vt. That's not kosher according
- * to my documentation, which says this is only called when releasing
- * the vt under your control.
+ * According to the X sources this is the behavior:
+ * 0: pending switch-from not OK
+ * 1: pending switch-from OK
+ * 2: completed switch-to OK
*/
case VT_RELDISP:
- if (vt_cons[console].vt_mode.mode != VT_PROCESS ||
- vt_cons[console].vt_newvt < 0)
+ if (vt_cons[console].vt_mode.mode != VT_PROCESS)
return -EINVAL;
- if (arg != 0)
+ /*
+ * Switching-from response
+ */
+ if (vt_cons[console].vt_newvt >= 0)
{
- /*
- * If arg is nonzero, the current vt has been released,
- * so we can go ahead and complete the switch.
- */
- int newvt = vt_cons[console].vt_newvt;
- vt_cons[console].vt_newvt = -1;
- complete_change_console(newvt);
+ if (arg == 0)
+ /*
+ * Switch disallowed, so forget we were trying
+ * to do it.
+ */
+ vt_cons[console].vt_newvt = -1;
+
+ else
+ {
+ /*
+ * The current vt has been released, so
+ * complete the switch.
+ */
+ int newvt = vt_cons[console].vt_newvt;
+ vt_cons[console].vt_newvt = -1;
+ complete_change_console(newvt);
+ }
}
+
+ /*
+ * Switched-to response
+ */
else
{
/*
- * Mark that we've performed our part and return.
+ * If it's just an ACK, ignore it
*/
- vt_cons[console].vt_newvt = -1;
+ if (arg != VT_ACKACQ)
+ return -EINVAL;
}
+
return 0;
default:
#define CR0_NE 32
static unsigned long intr_count=0;
+static unsigned char cache_21 = 0xff;
+static unsigned char cache_A1 = 0xff;
-/* I'll use an array for speed. and bitmap for speed. */
-int bh_active=0;
+unsigned long bh_active = 0;
+unsigned long bh_mask = 0xFFFFFFFF;
struct bh_struct bh_base[32];
/*
* called only when bh_active is non-zero and when there aren't any
* nested irq's active.
*/
-void do_bottom_half(void)
+void do_bottom_half(int nr)
{
struct bh_struct *bh;
- int nr;
- __asm__ __volatile__("bsfl %1,%0":"=r" (nr):"m" (bh_active));
- __asm__ __volatile__("btcl %1,%0":"=m" (bh_active):"r" (nr));
bh = bh_base+nr;
if (bh->routine != NULL)
bh->routine(bh->data);
set_intr_gate(0x20+irq,fast_interrupt[irq]);
else
set_intr_gate(0x20+irq,interrupt[irq]);
- if (irq < 8)
- outb(inb_p(0x21) & ~(1<<irq),0x21);
- else {
- outb(inb_p(0x21) & ~(1<<2),0x21);
- outb(inb_p(0xA1) & ~(1<<(irq-8)),0xA1);
+ if (irq < 8) {
+ cache_21 &= ~(1<<irq);
+ outb(cache_21,0x21);
+ } else {
+ cache_21 &= ~(1<<2);
+ cache_A1 &= ~(1<<(irq-8));
+ outb(cache_21,0x21);
+ outb(cache_A1,0xA1);
}
restore_flags(flags);
return 0;
}
save_flags(flags);
cli();
- if (irq < 8)
- outb(inb_p(0x21) | (1<<irq),0x21);
- else
- outb(inb_p(0xA1) | (1<<(irq-8)),0xA1);
+ if (irq < 8) {
+ cache_21 |= 1 << irq;
+ outb(cache_21,0x21);
+ } else {
+ cache_A1 |= 1 << (irq-8);
+ outb(cache_A1,0xA1);
+ }
set_intr_gate(0x20+irq,bad_interrupt[irq]);
sa->sa_handler = NULL;
sa->sa_flags = 0;
static unsigned long log_page = 0;
static unsigned long log_start = 0;
-static unsigned long log_size = 0;
-static struct wait_queue * log_wait = NULL;
+unsigned long log_size = 0;
+struct wait_queue * log_wait = NULL;
int sys_syslog(int type, char * buf, int len)
{
call _schedule
.align 4,0x90
ret_from_sys_call:
-/*
- * XXX - interrupts are masked here about 3 times in 1000. Fishy.
- */
movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
testl $VM_MASK,%eax # different then
jne 4f
jne 2f
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
jne 2f
-4: orl $IF_MASK,%eax # these just try to make sure
+4: sti # slow interrupts get here with interrupts disabled
+ 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
1: cmpl $0,_need_resched
void do_coprocessor_error(long esp, long error_code)
{
send_sig(SIGFPE, last_task_used_math, 1);
- __asm__("fnclex");
+ __asm__("fninit");
}
void do_reserved(long esp, long error_code)
extern int sock_awaitconn(struct socket *mysock, struct socket *servsock);
#ifdef SOCK_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK (void)
+#define PRINTK(x) /**/
#endif
#endif /* _KERN_SOCK_H */
}
SOCK_INODE(sock)->i_mode = S_IFSOCK;
sock->wait = &SOCK_INODE(sock)->i_wait;
- PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
- sock, SOCK_INODE(sock));
+ PRINTK(("sock_alloc: socket 0x%x, inode 0x%x\n",
+ sock, SOCK_INODE(sock)));
return sock;
}
sti();
if (!wait)
return NULL;
- PRINTK("sock_alloc: no free sockets, sleeping...\n");
+ PRINTK(("sock_alloc: no free sockets, sleeping...\n"));
interruptible_sleep_on(&socket_wait_free);
if (current->signal & ~current->blocked) {
- PRINTK("sock_alloc: sleep was interrupted\n");
+ PRINTK(("sock_alloc: sleep was interrupted\n"));
return NULL;
}
- PRINTK("sock_alloc: wakeup... trying again...\n");
+ PRINTK(("sock_alloc: wakeup... trying again...\n"));
}
}
int oldstate;
struct socket *peersock, *nextsock;
- PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock,
- SOCK_INODE(sock));
+ PRINTK(("sock_release: socket 0x%x, inode 0x%x\n", sock,
+ SOCK_INODE(sock)));
if ((oldstate = sock->state) != SS_UNCONNECTED)
sock->state = SS_DISCONNECTING;
/*
static int
sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
{
- PRINTK("sock_lseek: huh?\n");
- return -EBADF;
+ PRINTK(("sock_lseek: huh?\n"));
+ return -ESPIPE;
}
static int
{
struct socket *sock;
- PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size);
+ PRINTK(("sock_read: buf=0x%x, size=%d\n", ubuf, size));
if (!(sock = socki_lookup(inode))) {
printk("sock_read: can't find socket for inode!\n");
return -EBADF;
{
struct socket *sock;
- PRINTK("sock_write: buf=0x%x, size=%d\n", ubuf, size);
+ PRINTK(("sock_write: buf=0x%x, size=%d\n", ubuf, size));
if (!(sock = socki_lookup(inode))) {
printk("sock_write: can't find socket for inode!\n");
return -EBADF;
sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
int count)
{
- PRINTK("sock_readdir: huh?\n");
+ PRINTK(("sock_readdir: huh?\n"));
return -EBADF;
}
{
struct socket *sock;
- PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg);
+ PRINTK(("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg));
if (!(sock = socki_lookup(inode))) {
printk("sock_ioctl: can't find socket for inode!\n");
return -EBADF;
{
struct socket *sock;
- PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode,
+ PRINTK(("sock_select: inode = 0x%x, kind = %s\n", inode,
(sel_type == SEL_IN) ? "in" :
- (sel_type == SEL_OUT) ? "out" : "ex");
+ (sel_type == SEL_OUT) ? "out" : "ex"));
if (!(sock = socki_lookup(inode))) {
printk("sock_select: can't find socket for inode!\n");
return 0;
{
struct socket *sock;
- PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count);
+ PRINTK(("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count));
/*
* it's possible the inode is NULL if we're closing an unfinished
* socket.
{
struct socket *last;
- PRINTK("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
- mysock, servsock);
+ PRINTK(("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
+ mysock, servsock));
if (!(servsock->flags & SO_ACCEPTCON)) {
- PRINTK("sock_awaitconn: server not accepting connections\n");
+ PRINTK(("sock_awaitconn: server not accepting connections\n"));
return -EINVAL;
}
struct socket *sock;
struct proto_ops *ops;
- PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
- family, family_name(family), type, protocol);
+ PRINTK(("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
+ family, family_name(family), type, protocol));
/*
* locate the correct protocol family
if (proto_table[i].family == family)
break;
if (i == NPROTO) {
- PRINTK("sys_socket: family not found\n");
+ PRINTK(("sys_socket: family not found\n"));
return -EINVAL;
}
ops = proto_table[i].ops;
int fd1, fd2, i;
struct socket *sock1, *sock2;
- PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n",
- family, type, protocol);
+ PRINTK(("sys_socketpair: family = %d, type = %d, protocol = %d\n",
+ family, type, protocol));
/*
* obtain the first socket and check if the underlying protocol
struct socket *sock;
int i;
- PRINTK("sys_bind: fd = %d\n", fd);
+ PRINTK(("sys_bind: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, NULL)))
return -EBADF;
if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
- PRINTK("sys_bind: bind failed\n");
+ PRINTK(("sys_bind: bind failed\n"));
return i;
}
return 0;
{
struct socket *sock;
- PRINTK("sys_listen: fd = %d\n", fd);
+ PRINTK(("sys_listen: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, NULL)))
return -EBADF;
if (sock->state != SS_UNCONNECTED) {
- PRINTK("sys_listen: socket isn't unconnected\n");
+ PRINTK(("sys_listen: socket isn't unconnected\n"));
return -EINVAL;
}
if (sock->flags & SO_ACCEPTCON) {
- PRINTK("sys_listen: socket already accepting connections!\n");
+ PRINTK(("sys_listen: socket already accepting connections!\n"));
return -EINVAL;
}
if (sock->ops && sock->ops->listen)
struct socket *sock, *newsock;
int i;
- PRINTK("sys_accept: fd = %d\n", fd);
+ PRINTK(("sys_accept: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, &file)))
return -EBADF;
if (sock->state != SS_UNCONNECTED) {
- PRINTK("sys_accept: socket isn't unconnected\n");
+ PRINTK(("sys_accept: socket isn't unconnected\n"));
return -EINVAL;
}
if (!(sock->flags & SO_ACCEPTCON)) {
- PRINTK("sys_accept: socket not accepting connections!\n");
+ PRINTK(("sys_accept: socket not accepting connections!\n"));
return -EINVAL;
}
return -EINVAL;
}
- PRINTK("sys_accept: connected socket 0x%x via 0x%x\n",
- sock, newsock);
+ PRINTK(("sys_accept: connected socket 0x%x via 0x%x\n",
+ sock, newsock));
if (upeer_sockaddr)
newsock->ops->getname(newsock, upeer_sockaddr,
struct file *file;
int i;
- PRINTK("sys_connect: fd = %d\n", fd);
+ PRINTK(("sys_connect: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, &file)))
return -EBADF;
switch (sock->state) {
/* we will check this. */
return (sock->ops->connect(sock, uservaddr, addrlen, file->f_flags));
default:
- PRINTK("sys_connect: socket not unconnected\n");
+ PRINTK(("sys_connect: socket not unconnected\n"));
return -EINVAL;
}
i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
if (i < 0) {
- PRINTK("sys_connect: connect failed\n");
+ PRINTK(("sys_connect: connect failed\n"));
return i;
}
return 0;
{
struct socket *sock;
- PRINTK("sys_getsockname: fd = %d\n", fd);
+ PRINTK(("sys_getsockname: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, NULL)))
return -EBADF;
return sock->ops->getname(sock, usockaddr, usockaddr_len, 0);
{
struct socket *sock;
- PRINTK("sys_getpeername: fd = %d\n", fd);
+ PRINTK(("sys_getpeername: fd = %d\n", fd));
if (!(sock = sockfd_lookup(fd, NULL)))
return -EBADF;
return sock->ops->getname(sock, usockaddr, usockaddr_len, 1);
struct socket *sock;
struct file *file;
- PRINTK("sys_send (fd = %d, buff = %X, len = %d, flags = %X)\n",
- fd, buff, len, flags);
+ PRINTK(("sys_send (fd = %d, buff = %X, len = %d, flags = %X)\n",
+ fd, buff, len, flags));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
struct socket *sock;
struct file *file;
- PRINTK("sys_sendto (fd = %d, buff = %X, len = %d, flags = %X,"
- " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len);
+ PRINTK(("sys_sendto (fd = %d, buff = %X, len = %d, flags = %X,"
+ " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
struct socket *sock;
struct file *file;
- PRINTK("sys_recv (fd = %d, buff = %X, len = %d, flags = %X)\n",
- fd, buff, len, flags);
+ PRINTK(("sys_recv (fd = %d, buff = %X, len = %d, flags = %X)\n",
+ fd, buff, len, flags));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
struct socket *sock;
struct file *file;
- PRINTK("sys_recvfrom (fd = %d, buff = %X, len = %d, flags = %X,"
- " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len);
+ PRINTK(("sys_recvfrom (fd = %d, buff = %X, len = %d, flags = %X,"
+ " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
struct socket *sock;
struct file *file;
- PRINTK ("sys_setsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
- optname);
- PRINTK (" optval = %X, optlen = %d)\n", optval, optlen);
+ PRINTK (("sys_setsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
+ optname));
+ PRINTK ((" optval = %X, optlen = %d)\n", optval, optlen));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
{
struct socket *sock;
struct file *file;
- PRINTK ("sys_getsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
- optname);
- PRINTK (" optval = %X, optlen = %X)\n", optval, optlen);
+ PRINTK (("sys_getsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
+ optname));
+ PRINTK ((" optval = %X, optlen = %X)\n", optval, optlen));
if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
return (-EBADF);
if (!(sock = sockfd_lookup(fd, NULL)))
return (-ENOTSOCK);
- return (0);
- return (sock->ops->getsockopt (sock, level, optname, optval, optlen));
+ if (!sock->ops || !sock->ops->getsockopt)
+ return 0;
+ return sock->ops->getsockopt(sock, level, optname, optval, optlen);
}
struct socket *sock;
struct file *file;
- PRINTK("sys_shutdown (fd = %d, how = %d)\n",fd, how);
+ PRINTK(("sys_shutdown (fd = %d, how = %d)\n",fd, how));
file = current->filp[fd];
if (fd < 0 || fd >= NR_OPEN || file == NULL)
#include "arp.h"
#undef ARP_DEBUG
+
#ifdef ARP_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
static struct arp_table *arp_table[ARP_TABLE_SIZE] ={NULL, };
int i;
unsigned long *lptr;
unsigned char *ptr;
- PRINTK ("arp: \n");
+ PRINTK (("arp: \n"));
if (arp == NULL)
{
- PRINTK ("(null)\n");
+ PRINTK (("(null)\n"));
return;
}
- PRINTK (" hrd = %d\n",net16(arp->hrd));
- PRINTK (" pro = %d\n",net16(arp->pro));
- PRINTK (" hlen = %d plen = %d\n",arp->hlen, arp->plen);
- PRINTK (" op = %d\n", net16(arp->op));
+ PRINTK ((" hrd = %d\n",net16(arp->hrd)));
+ PRINTK ((" pro = %d\n",net16(arp->pro)));
+ PRINTK ((" hlen = %d plen = %d\n",arp->hlen, arp->plen));
+ PRINTK ((" op = %d\n", net16(arp->op)));
ptr = (unsigned char *)(arp+1);
- PRINTK (" sender haddr = ");
+ PRINTK ((" sender haddr = "));
for (i = 0; i < arp->hlen; i++)
{
- PRINTK ("0x%02X ",*ptr++);
+ PRINTK (("0x%02X ",*ptr++));
}
lptr = (void *)ptr;
- PRINTK (" send paddr = %X\n",*lptr);
+ PRINTK ((" send paddr = %X\n",*lptr));
lptr ++;
ptr = (void *)lptr;
- PRINTK (" destination haddr = ");
+ PRINTK ((" destination haddr = "));
for (i = 0; i < arp->hlen; i++)
{
- PRINTK ("0x%02X ",*ptr++);
+ PRINTK (("0x%02X ",*ptr++));
}
lptr = (void *)ptr;
- PRINTK (" destination paddr = %X\n",*lptr);
+ PRINTK ((" destination paddr = %X\n",*lptr));
}
static unsigned char *
skb->arp = 1; /* so the code will know it's not waiting on an arp. */
skb->sk = NULL;
skb->next = NULL;
- PRINTK (">>");
+ PRINTK ((">>"));
print_arp(arp2);
/* send it. */
dev->queue_xmit (skb, dev, 0);
{
unsigned long hash;
struct arp_table *apt;
- PRINTK ("arp_lookup(paddr=%X)\n", paddr);
+ PRINTK (("arp_lookup(paddr=%X)\n", paddr));
/* we don't want to arp ourselves. */
if (my_ip_addr(paddr)) return (NULL);
hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
unsigned long hash;
struct arp_table *apt;
struct arp_table *lapt;
- PRINTK ("arp_destroy (paddr=%X)\n",paddr);
+ PRINTK (("arp_destroy (paddr=%X)\n",paddr));
/* we don't want to destroy are own arp */
if (my_ip_addr(paddr)) return;
hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
struct arp_table *tbl;
int ret;
- PRINTK ("<<\n");
+ PRINTK (("<<\n"));
arp = skb->h.arp;
print_arp(arp);
struct arp *arp;
struct arp_table *apt;
int tmp;
- PRINTK ("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr);
+ PRINTK (("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr));
/* first we build a dummy arp table entry. */
apt = create_arp (paddr, NULL, 0);
*arp_targetp(arp) = paddr;
memcpy (arp_sourceh(arp), dev->dev_addr, dev->addr_len);
memcpy (arp_targeth(arp), dev->broadcast, dev->addr_len);
- PRINTK(">>\n");
+ PRINTK((">>\n"));
print_arp(arp);
dev->queue_xmit (skb, dev, 0);
}
unsigned long saddr)
{
struct arp_table *apt;
- PRINTK ("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n",
- haddr, paddr, dev, saddr);
+ PRINTK (("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n",
+ haddr, paddr, dev, saddr));
if (my_ip_addr (paddr))
{
memcpy (haddr, dev->dev_addr, dev->addr_len);
#undef DEV_DEBUG
#ifdef DEV_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
{
struct sk_buff *skb2;
- PRINTK ("dev_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri);
+ PRINTK (("dev_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri));
if (dev == NULL)
{
}
/* put skb into a bidirectional circular linked list. */
- PRINTK ("dev_queue_xmit dev->buffs[%d]=%X\n",pri, dev->buffs[pri]);
+ PRINTK (("dev_queue_xmit dev->buffs[%d]=%X\n",pri, dev->buffs[pri]));
/* interrupts should already be cleared by hard_start_xmit. */
cli();
if (dev->buffs[pri] == NULL)
if (!flag)
{
- PRINTK ("discarding packet type = %X\n", type);
+ PRINTK (("discarding packet type = %X\n", type));
kfree_skb (skb, FREE_READ);
}
}
if (buff != NULL)
memcpy (buff, skb + 1, tmp);
- PRINTK (">>\n");
+ PRINTK ((">>\n"));
print_eth ((struct enet_header *)(skb+1));
}
else
return (tmp);
}
}
- PRINTK ("dev_tint returning 0 \n");
+ PRINTK (("dev_tint returning 0 \n"));
return (0);
}
-
#undef ETH_DEBUG
#ifdef ETH_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
void
print_eth (struct enet_header *eth)
{
int i;
- PRINTK ("ether source addr: ");
+ PRINTK (("ether source addr: "));
for (i =0 ; i < ETHER_ADDR_LEN; i++)
{
- PRINTK ("0x%2X ",eth->saddr[i]);
+ PRINTK (("0x%2X ",eth->saddr[i]));
}
- PRINTK ("\n");
+ PRINTK (("\n"));
- PRINTK ("ether dest addr: ");
+ PRINTK (("ether dest addr: "));
for (i =0 ; i < ETHER_ADDR_LEN; i++)
{
- PRINTK ("0x%2X ",eth->daddr[i]);
+ PRINTK (("0x%2X ",eth->daddr[i]));
}
- PRINTK ("\n");
- PRINTK ("ethertype = %X\n",net16(eth->type));
+ PRINTK (("\n"));
+ PRINTK (("ethertype = %X\n",net16(eth->type)));
}
int
#endif
#undef ICMP_DEBUG
+
#ifdef ICMP_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
#define min(a,b) ((a)<(b)?(a):(b))
void
print_icmph (struct icmp_header *icmph)
{
- PRINTK (" type = %d, code = %d, checksum = %X\n", icmph->type,
- icmph->code, icmph->checksum);
- PRINTK (" gateway = %X\n", icmph->un.gateway);
+ PRINTK ((" type = %d, code = %d, checksum = %X\n", icmph->type,
+ icmph->code, icmph->checksum));
+ PRINTK ((" gateway = %X\n", icmph->un.gateway));
}
/* sends an icmp message in response to a packet. */
struct icmp_header *icmph;
int len;
- PRINTK ("icmp_reply (skb_in = %X, type = %d, code = %d, dev=%X)\n",
- skb_in, type, code, dev);
+ PRINTK (("icmp_reply (skb_in = %X, type = %d, code = %d, dev=%X)\n",
+ skb_in, type, code, dev));
/* get some memory for the reply. */
len = sizeof (*skb) + 8 /* amount of header to return. */ +
if( ip_compute_csum( (unsigned char *)icmph, len ) )
{
/* Failed checksum! */
- PRINTK("ICMP ECHO failed checksum!\n");
+ PRINTK(("ICMP ECHO failed checksum!\n"));
skb1->sk = NULL;
kfree_skb (skb1, FREE_READ);
return (0);
if (offset < 0)
{
/* Problems building header */
- PRINTK("Could not build IP Header for ICMP ECHO Response\n");
+ PRINTK(("Could not build IP Header for ICMP ECHO Response\n"));
kfree_s (skb->mem_addr, skb->mem_len);
skb1->sk = NULL;
kfree_skb (skb1, FREE_READ);
return( 0 );
default:
- PRINTK("Unsupported ICMP type = x%x\n", icmph->type );
+ PRINTK(("Unsupported ICMP type = x%x\n", icmph->type ));
skb1->sk = NULL;
kfree_skb (skb1, FREE_READ);
return( 0 ); /* just toss the packet */
unsigned long ip_addr[MAX_IP_ADDRES]={0,0,0};
#undef IP_DEBUG
+
#ifdef IP_DEBUG
-#define PRINTK printk
+#define PRINTK(X) printk X
#else
-#define PRINTK dummy_routine
+#define PRINTK(X) /**/
#endif
static struct rtable *rt_base=NULL; /* used to base all the routing data. */
{
unsigned char hash;
struct ip_protocol *p;
- PRINTK ("get_protocol (%d)\n ", prot);
+ PRINTK (("get_protocol (%d)\n ", prot));
hash = prot & (MAX_IP_PROTOS -1);
for (p = ip_protos[hash] ; p != NULL; p=p->next)
{
- PRINTK ("trying protocol %d\n", p->protocol);
+ PRINTK (("trying protocol %d\n", p->protocol));
if (p->protocol == prot)
return (p);
}
void
print_rt(struct rtable *rt)
{
- PRINTK ("net = %08X router = %08X\n",rt->net, rt->router);
- PRINTK ("dev = %X, next = %X\n",rt->dev, rt->next);
+ PRINTK (("net = %08X router = %08X\n",rt->net, rt->router));
+ PRINTK (("dev = %X, next = %X\n",rt->dev, rt->next));
}
void
print_ipprot (struct ip_protocol *ipprot)
{
- PRINTK ("handler = %X, protocol = %d, copy=%d \n",
- ipprot->handler, ipprot->protocol, ipprot->copy);
+ PRINTK (("handler = %X, protocol = %d, copy=%d \n",
+ ipprot->handler, ipprot->protocol, ipprot->copy));
}
/* This assumes that address are all in net order. */
static struct device *
-ip_route(struct options *opt, unsigned long daddr , unsigned long *raddr)
+ip_route(struct options *opt, unsigned long daddr, unsigned long *raddr)
{
struct rtable *rt;
/* look through the routing table for some
/* see if we found one. */
if (ip_addr_match (rt->net, daddr))
{
+ PRINTK (("IP: %X via %s (%X)\n", daddr, rt->dev->name, rt->router));
*raddr = rt->router;
return (rt->dev);
}
int mask;
struct rtable *r;
struct rtable *r1;
- PRINTK ("add_route (rt=%X):\n",rt);
+ PRINTK (("add_route (rt=%X):\n",rt));
print_rt(rt);
if (rt_base == NULL)
break;
}
}
- PRINTK ("mask = %X\n",mask);
+ PRINTK (("mask = %X\n",mask));
r1=rt_base;
for (r=rt_base; r != NULL; r=r->next)
{
if (!(r->net & mask))
{
- PRINTK("adding before r=%X\n",r);
+ PRINTK (("adding before r=%X\n",r));
print_rt(r);
if (r == rt_base)
{
}
r1 = r;
}
- PRINTK ("adding after r1=%X\n",r1);
+ PRINTK (("adding after r1=%X\n",r1));
print_rt(r1);
/* goes at the end. */
rt->next = NULL;
/* see if we need to add a broadcast address. */
if (ipc.net != -1)
{
+ PRINTK (("new broadcast for %s: %08X\n", dev->name, ipc.net));
arp_add_broad (ipc.net, dev);
rt = kmalloc (sizeof (*rt), GFP_KERNEL);
if (rt == NULL) return (-ENOMEM);
-
rt->net = ipc.net;
rt->dev = dev;
rt->router = 0;
if (ipc.router != -1)
{
+ PRINTK (("new router for %s: %08X\n", dev->name, ipc.router));
rt = kmalloc (sizeof (*rt),GFP_KERNEL);
if (rt == NULL) return (-ENOMEM);
rt->net = 0;
if (dev->loopback)
{
+ PRINTK (("new loopback addr: %08X\n", ipc.paddr));
rt = kmalloc (sizeof (*rt), GFP_KERNEL);
if (rt == NULL) return (-ENOMEM);
rt->net = ipc.paddr;
rt->dev = dev;
rt->router = 0;
add_route (rt);
-
}
if (!my_ip_addr (ipc.paddr))
- ip_addr[ip_ads++] = ipc.paddr;
+ {
+ PRINTK (("new identity: %08X\n", ipc.paddr));
+ ip_addr[ip_ads++] = ipc.paddr;
+ }
dev->up = ipc.up;
if (dev->up)
if (dev->stop)
dev->stop(dev);
}
- return (0);
+ return (0);
}
/* this routine will check to see if we have lost a gateway. */
unsigned long raddr; /* for the router. */
int tmp;
if (saddr == 0) saddr = MY_IP_ADDR;
- PRINTK ("ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
- " type=%d, opt=%X, len = %d)\n",
- skb, saddr, daddr, *dev, type, opt, len);
+ PRINTK (("ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
+ " type=%d, opt=%X, len = %d)\n",
+ skb, saddr, daddr, *dev, type, opt, len));
buff = (unsigned char *)(skb + 1);
/* see if we need to look up the device. */
if (*dev == NULL)
iph=skb->h.iph;
- PRINTK("<<\n");
+ PRINTK (("<<\n"));
print_iph(iph);
if (ip_csum (iph) || do_options (iph,&opt) || iph->version != 4)
{
- PRINTK ("ip packet thrown out. \n");
+ PRINTK (("ip packet thrown out. \n"));
skb->sk = NULL;
kfree_skb(skb, 0);
return (0);
/* for now we will only deal with packets meant for us. */
if (!my_ip_addr(iph->daddr))
{
- PRINTK ("packet meant for someone else.\n");
+ PRINTK (("packet meant for someone else.\n"));
skb->sk = NULL;
kfree_skb(skb, 0);
return (0);
{
struct sk_buff *skb2;
if (ipprot->protocol != iph->protocol) continue;
- PRINTK ("Using protocol = %X:\n", ipprot);
+ PRINTK (("Using protocol = %X:\n", ipprot));
print_ipprot (ipprot);
/* pass it off to everyone who wants it. */
/* we should check the return values here. */
skb->free = free;
skb->dev = dev;
skb->when = jiffies;
- PRINTK(">>\n");
+ PRINTK ((">>\n"));
ptr = (unsigned char *)(skb + 1);
ptr += dev->hard_header_len;
iph = (struct ip_header *)ptr;
void
print_iph (struct ip_header *ip)
{
- PRINTK ("ip header:\n");
- PRINTK (" ihl = %d, version = %d, tos = %d, tot_len = %d\n",
- ip->ihl, ip->version, ip->tos, net16(ip->tot_len));
- PRINTK (" id = %x, ttl = %d, prot = %d, check=%x\n",
- ip->id, ip->ttl, ip->protocol, ip->check);
- PRINTK (" frag_off=%d\n", ip->frag_off);
- PRINTK (" saddr = %X, daddr = %X\n",ip->saddr, ip->daddr);
+ PRINTK (("ip header:\n"));
+ PRINTK ((" ihl = %d, version = %d, tos = %d, tot_len = %d\n",
+ ip->ihl, ip->version, ip->tos, net16(ip->tot_len)));
+ PRINTK ((" id = %x, ttl = %d, prot = %d, check=%x\n",
+ ip->id, ip->ttl, ip->protocol, ip->check));
+ PRINTK ((" frag_off=%d\n", ip->frag_off));
+ PRINTK ((" saddr = %X, daddr = %X\n",ip->saddr, ip->daddr));
}
#if 0
#endif
#ifdef LOOPBACK_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
static int
static unsigned char buff[2048];
unsigned char *tmp;
- PRINTK ("loopback_xmit (dev = %X)\n", dev);
+ PRINTK (("loopback_xmit (dev = %X)\n", dev));
cli();
if (inuse)
{
if (done != -1 && (i = dev_tint (buff,dev)) != 0)
{
/* print out the buffer. */
- PRINTK ("loopback xmit: \n");
+ PRINTK (("loopback xmit: \n"));
eth = (struct enet_header *)buff;
print_eth (eth);
tmp = buff;
#undef RAW_DEBUG
#ifdef RAW_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
extern struct proto raw_prot;
{
volatile struct sock *sk;
- PRINTK ("raw_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n");
+ PRINTK (("raw_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n"));
if (protocol == NULL) return;
volatile struct sock *sk;
- PRINTK ("raw_rcv (skb=%X, dev=%X, opt=%X, daddr=%X,\n"
+ PRINTK (("raw_rcv (skb=%X, dev=%X, opt=%X, daddr=%X,\n"
" len=%d, saddr=%X, redo=%d, protocol=%X)\n",
- skb, dev, opt, daddr, len, saddr, redo, protocol);
+ skb, dev, opt, daddr, len, saddr, redo, protocol));
if (skb == NULL) return (0);
if (protocol == NULL)
cli();
if (sk->inuse)
{
- PRINTK ("raw_rcv adding to backlog. \n");
+ PRINTK (("raw_rcv adding to backlog. \n"));
if (sk->back_log == NULL)
{
sk->back_log = skb;
struct sockaddr_in sin;
int tmp;
- PRINTK ("raw_sendto (sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
+ PRINTK (("raw_sendto (sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
" usin=%X, addr_len = %d)\n", sk, from, len, noblock,
- flags, usin, addr_len);
+ flags, usin, addr_len));
/* check the flags. */
if (flags) return (-EINVAL);
if (skb == NULL)
{
int tmp;
- PRINTK ("raw_sendto: write buffer full?\n");
+ PRINTK (("raw_sendto: write buffer full?\n"));
print_sk (sk);
if (noblock) return (-EAGAIN);
tmp = sk->wmem_alloc;
sk->protocol, sk->opt, skb->mem_len);
if (tmp < 0)
{
- PRINTK ("raw_sendto: error building ip header.\n");
+ PRINTK (("raw_sendto: error building ip header.\n"));
sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
release_sock (sk);
return (tmp);
{
sk->inuse = 1;
sk->state = TCP_CLOSE;
- PRINTK ("raw_close: deleting ip_protocol %d\n",
- ((struct ip_protocol *)sk->pair)->protocol);
+ PRINTK (("raw_close: deleting ip_protocol %d\n",
+ ((struct ip_protocol *)sk->pair)->protocol));
if (delete_ip_protocol ((struct ip_protocol *)sk->pair) < 0)
- PRINTK ("raw_close: delete_ip_protocol failed. \n");
+ PRINTK (("raw_close: delete_ip_protocol failed. \n"));
kfree_s ((void *)sk->pair, sizeof (struct ip_protocol));
sk->pair = NULL;
release_sock (sk);
/* we need to remember this somewhere. */
sk->pair = (volatile struct sock *)p;
- PRINTK ("raw init added protocol %d\n", sk->protocol);
+ PRINTK (("raw init added protocol %d\n", sk->protocol));
return (0);
}
int copied=0;
struct sk_buff *skb;
- PRINTK ("raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
+ PRINTK (("raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
" sin=%X, addr_len=%X)\n", sk, to, len, noblock,
- flags, sin, addr_len);
+ flags, sin, addr_len));
if (len == 0) return (0);
if (len < 0) return (-EINVAL);
#endif
#ifdef ISOCK_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
#ifdef MEM_DEBUG
-#define MPRINTK printk
+#define MPRINTK(x) printk x
#else
-#define MPRINTK dummy_routine
+#define MPRINTK(x) /**/
#endif
#define min(a,b) ((a)<(b)?(a):(b))
print_sk (volatile struct sock *sk)
{
if (!sk) {
- PRINTK (" print_sk(NULL)\n");
+ PRINTK ((" print_sk(NULL)\n"));
return;
}
- PRINTK (" wmem_alloc = %d\n", sk->wmem_alloc);
- PRINTK (" rmem_alloc = %d\n", sk->rmem_alloc);
- PRINTK (" send_head = %X\n", sk->send_head);
- PRINTK (" state = %d\n",sk->state);
- PRINTK (" wback = %X, rqueue = %X\n", sk->wback, sk->rqueue);
- PRINTK (" wfront = %X\n", sk->wfront);
- PRINTK (" daddr = %X, saddr = %X\n", sk->daddr,sk->saddr);
- PRINTK (" num = %d", sk->num);
- PRINTK (" next = %X\n", sk->next);
- PRINTK (" send_seq = %d, acked_seq = %d, copied_seq = %d\n",
- sk->send_seq, sk->acked_seq, sk->copied_seq);
- PRINTK (" rcv_ack_seq = %d, window_seq = %d, fin_seq = %d\n",
- sk->rcv_ack_seq, sk->window_seq, sk->fin_seq);
- PRINTK (" prot = %X\n", sk->prot);
- PRINTK (" pair = %X, back_log = %X\n", sk->pair,sk->back_log);
- PRINTK (" inuse = %d , blog = %d\n", sk->inuse, sk->blog);
- PRINTK (" dead = %d delay_acks=%d\n", sk->dead, sk->delay_acks);
- PRINTK (" retransmits = %d, timeout = %d\n", sk->retransmits, sk->timeout);
- PRINTK (" cong_window = %d, packets_out = %d\n", sk->cong_window,
- sk->packets_out);
+ PRINTK ((" wmem_alloc = %d\n", sk->wmem_alloc));
+ PRINTK ((" rmem_alloc = %d\n", sk->rmem_alloc));
+ PRINTK ((" send_head = %X\n", sk->send_head));
+ PRINTK ((" state = %d\n",sk->state));
+ PRINTK ((" wback = %X, rqueue = %X\n", sk->wback, sk->rqueue));
+ PRINTK ((" wfront = %X\n", sk->wfront));
+ PRINTK ((" daddr = %X, saddr = %X\n", sk->daddr,sk->saddr));
+ PRINTK ((" num = %d", sk->num));
+ PRINTK ((" next = %X\n", sk->next));
+ PRINTK ((" send_seq = %d, acked_seq = %d, copied_seq = %d\n",
+ sk->send_seq, sk->acked_seq, sk->copied_seq));
+ PRINTK ((" rcv_ack_seq = %d, window_seq = %d, fin_seq = %d\n",
+ sk->rcv_ack_seq, sk->window_seq, sk->fin_seq));
+ PRINTK ((" prot = %X\n", sk->prot));
+ PRINTK ((" pair = %X, back_log = %X\n", sk->pair,sk->back_log));
+ PRINTK ((" inuse = %d , blog = %d\n", sk->inuse, sk->blog));
+ PRINTK ((" dead = %d delay_acks=%d\n", sk->dead, sk->delay_acks));
+ PRINTK ((" retransmits = %d, timeout = %d\n", sk->retransmits, sk->timeout));
+ PRINTK ((" cong_window = %d, packets_out = %d\n", sk->cong_window,
+ sk->packets_out));
}
void
print_skb(struct sk_buff *skb)
{
if (!skb) {
- PRINTK (" print_skb(NULL)\n");
+ PRINTK ((" print_skb(NULL)\n"));
return;
}
- PRINTK (" prev = %X, next = %X\n", skb->prev, skb->next);
- PRINTK (" sk = %X link3 = %X\n", skb->sk, skb->link3);
- PRINTK (" mem_addr = %X, mem_len = %d\n", skb->mem_addr, skb->mem_len);
- PRINTK (" used = %d free = %d\n", skb->used,skb->free);
+ PRINTK ((" prev = %X, next = %X\n", skb->prev, skb->next));
+ PRINTK ((" sk = %X link3 = %X\n", skb->sk, skb->link3));
+ PRINTK ((" mem_addr = %X, mem_len = %d\n", skb->mem_addr, skb->mem_len));
+ PRINTK ((" used = %d free = %d\n", skb->used,skb->free));
}
/* just used to reference some pointers to keep gcc from over optimizing
if (j == 0)
{
start = (i+1+start )%1024;
- PRINTK ("get_new_socknum returning %d, start = %d\n",
- i+base+1,start);
+ PRINTK (("get_new_socknum returning %d, start = %d\n",
+ i+base+1,start));
return (i+base+1);
}
if (j < size)
{
best += SOCK_ARRAY_SIZE;
}
- PRINTK ("get_new_socknum returning %d, start = %d\n", best+base+1,start);
+ PRINTK (("get_new_socknum returning %d, start = %d\n", best+base+1,start));
return (best+base+1);
}
volatile struct sock *sk2;
int mask;
- PRINTK ("put_sock (num = %d, sk = %X\n", num, sk);
+ PRINTK (("put_sock (num = %d, sk = %X\n", num, sk));
sk->num = num;
sk->next = NULL;
num = num & (SOCK_ARRAY_SIZE -1);
}
}
- PRINTK ("mask = %X\n", mask);
+ PRINTK (("mask = %X\n", mask));
cli();
sk1 = sk->prot->sock_array[num];
remove_sock(volatile struct sock *sk1)
{
volatile struct sock *sk2;
- PRINTK ("remove_sock(sk1=%X)\n",sk1);
+ PRINTK (("remove_sock(sk1=%X)\n",sk1));
if (!sk1)
{
sti();
if (sk1->num != 0)
- PRINTK ("remove_sock: sock not found.\n");
+ PRINTK (("remove_sock: sock not found.\n"));
}
void
{
struct sk_buff *skb;
- PRINTK ("destroying socket %X\n",sk);
+ PRINTK (("destroying socket %X\n",sk));
/* just to be safe. */
sk->inuse = 1;
{
/* this should never happen. */
/* actually it can if an ack has just been sent. */
- PRINTK ("possible memory leak in socket = %X\n", sk);
+ PRINTK (("possible memory leak in socket = %X\n", sk));
print_sk (sk);
sk->destroy = 1;
sk->ack_backlog = 0;
reset_timer ((struct timer *)&sk->time_wait);
}
- PRINTK ("leaving destroy_sock\n");
+ PRINTK (("leaving destroy_sock\n"));
}
volatile struct sock *sk;
sk = sock->data;
if (sk == NULL) return (0);
- PRINTK ("ip_proto_release (sock = %X, peer = %X)\n", sock, peer);
+ PRINTK (("ip_proto_release (sock = %X, peer = %X)\n", sock, peer));
wake_up (sk->sleep);
/* start closing the connection. This may take a while. */
/* if linger is set, we don't return until the close is
}
else
{
- PRINTK ("sk->linger set.\n");
+ PRINTK (("sk->linger set.\n"));
sk->prot->close(sk, 0);
cli();
while (sk->state != TCP_CLOSE)
/* this will destroy it. */
release_sock (sk);
sock->data = NULL;
- PRINTK ("ip_proto_release returning\n");
+ PRINTK (("ip_proto_release returning\n"));
return (0);
}
return (-EINVAL); /* this needs to be changed. */
snum = net16(addr.sin_port);
- PRINTK ("bind sk =%X to port = %d\n", sk, snum);
+ PRINTK (("bind sk =%X to port = %d\n", sk, snum));
print_sk (sk);
sk = sock->data;
if (my_ip_addr(addr.sin_addr.s_addr) || addr.sin_addr.s_addr == 0)
sk->saddr = addr.sin_addr.s_addr;
- PRINTK ("sock_array[%d] = %X:\n", snum & (SOCK_ARRAY_SIZE -1),
- sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);
+ PRINTK (("sock_array[%d] = %X:\n", snum & (SOCK_ARRAY_SIZE -1),
+ sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]));
print_sk (sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);
/* make sure we are allowed to bind here. */
if (sk->prot->select == NULL)
{
- PRINTK ("select on non-selectable socket. \n");
+ PRINTK (("select on non-selectable socket. \n"));
return (0);
}
return (sk->prot->select(sk, sel_type, wait));
return (0);
}
- PRINTK ("in ip_proto_ioctl\n");
+ PRINTK (("in ip_proto_ioctl\n"));
switch (cmd)
{
sti();
return (kmalloc (size, priority));
}
- MPRINTK ("sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
- sk, size, force, priority);
+ MPRINTK (("sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
+ sk, size, force, priority));
return (NULL);
}
return (kmalloc(size, priority));
sti();
return (kmalloc (size, priority));
}
- MPRINTK ("sock_rmalloc(%X,%d,%d,%d) returning NULL\n",
- sk,size,force, priority);
+ MPRINTK (("sock_rmalloc(%X,%d,%d,%d) returning NULL\n",
+ sk,size,force, priority));
return (NULL);
}
return (kmalloc (size, priority));
void
sock_wfree (volatile struct sock *sk, void *mem, unsigned long size)
{
- MPRINTK ("sock_wfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size);
+ MPRINTK (("sock_wfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size));
kfree_s (mem, size);
if (sk)
{
if (!sk->dead) wake_up(sk->sleep);
if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0)
{
- MPRINTK ("recovered lost memory, destroying sock = %X\n",sk);
+ MPRINTK (("recovered lost memory, destroying sock = %X\n",sk));
delete_timer ((struct timer *)&sk->time_wait);
kfree_s ((void *)sk, sizeof (*sk));
}
void
sock_rfree (volatile struct sock *sk, void *mem, unsigned long size)
{
- MPRINTK ("sock_rfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size);
+ MPRINTK (("sock_rfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size));
kfree_s (mem, size);
if (sk)
{
unsigned short rnum, unsigned long laddr)
{
volatile struct sock *s;
- PRINTK ("get_sock (prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n",
- prot, num, raddr, rnum, laddr);
+ PRINTK (("get_sock (prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n",
+ prot, num, raddr, rnum, laddr));
/* SOCK_ARRAY_SIZE must be a power of two. This will work better
than a prime unless 3 or more sockets end up using the same
struct sk_buff *skb;
sk->blog = 1;
skb = sk->back_log;
- PRINTK ("release_sock: skb = %X:\n",skb);
+ PRINTK (("release_sock: skb = %X:\n",skb));
print_skb(skb);
if (skb->next != skb)
{
sk->back_log = NULL;
}
sti();
- PRINTK ("sk->back_log = %X\n",sk->back_log);
+ PRINTK (("sk->back_log = %X\n",sk->back_log));
if (sk->prot->rcv)
sk->prot->rcv(skb, skb->dev, sk->opt,
skb->saddr, skb->len, skb->daddr, 1,
#undef TCP_DEBUG
#ifdef TCP_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
#define tmax(a,b) (before ((a),(b)) ? (b) : (a))
{
unsigned char *ptr;
ptr = (unsigned char *)(th + 1);
- PRINTK ("tcp header:\n");
- PRINTK (" source=%d, dest=%d, seq =%d, ack_seq = %d\n",
+ PRINTK (("tcp header:\n"));
+ PRINTK ((" source=%d, dest=%d, seq =%d, ack_seq = %d\n",
net16(th->source), net16(th->dest), net32(th->seq),
- net32(th->ack_seq));
- PRINTK (" fin=%d, syn=%d, rst=%d, psh=%d, ack=%d, urg=%d res1=%d res2=%d\n"
+ net32(th->ack_seq)));
+ PRINTK ((" fin=%d, syn=%d, rst=%d, psh=%d, ack=%d, urg=%d res1=%d res2=%d\n"
,th->fin, th->syn, th->rst, th->psh, th->ack, th->urg,
- th->res1, th->res2);
- PRINTK (" window = %d, check = %d urg_ptr = %d\n",
- net16(th->window), net16(th->check), net16(th->urg_ptr));
- PRINTK (" doff = %d\n",th->doff);
- PRINTK ("options = %d %d %d %d\n", ptr[0], ptr[1], ptr[2], ptr[3]);
+ th->res1, th->res2));
+ PRINTK ((" window = %d, check = %d urg_ptr = %d\n",
+ net16(th->window), net16(th->check), net16(th->urg_ptr)));
+ PRINTK ((" doff = %d\n",th->doff));
+ PRINTK (("options = %d %d %d %d\n", ptr[0], ptr[1], ptr[2], ptr[3]));
}
/* This routine grabs the first thing off of a rcv queue. */
struct tcp_header *th;
volatile struct sock *sk;
- PRINTK ("tcp_err(err=%d, header=%X, daddr=%X saddr=%X, protocol=%X)\n",
- err, header, daddr, saddr, protocol);
+ PRINTK (("tcp_err(err=%d, header=%X, daddr=%X saddr=%X, protocol=%X)\n",
+ err, header, daddr, saddr, protocol));
th = (struct tcp_header *)header;
sk = get_sock (&tcp_prot, net16(th->dest), saddr, th->source, daddr);
static int
tcp_ioctl (volatile struct sock *sk, int cmd, unsigned long arg)
{
- PRINTK ("tcp_ioctl (sk=%X, cmd = %d, arg=%X)\n", sk, cmd, arg);
+ PRINTK (("tcp_ioctl (sk=%X, cmd = %d, arg=%X)\n", sk, cmd, arg));
switch (cmd)
{
default:
amount = tcp_readable(sk);
}
release_sock (sk);
- PRINTK ("returning %d\n", amount);
+ PRINTK (("returning %d\n", amount));
verify_area ((void *)arg, sizeof (unsigned long));
put_fs_long (amount, (unsigned long *)arg);
return (0);
if (after (sk->send_seq , sk->window_seq) ||
sk->packets_out >= sk->cong_window)
{
- PRINTK ("sk->cong_window = %d, sk->packets_out = %d\n",
- sk->cong_window, sk->packets_out);
- PRINTK ("sk->send_seq = %d, sk->window_seq = %d\n",
- sk->send_seq, sk->window_seq);
+ PRINTK (("sk->cong_window = %d, sk->packets_out = %d\n",
+ sk->cong_window, sk->packets_out));
+ PRINTK (("sk->send_seq = %d, sk->window_seq = %d\n",
+ sk->send_seq, sk->window_seq));
skb->next = NULL;
skb->magic = TCP_WRITE_QUEUE_MAGIC;
if (sk->wback == NULL)
struct proto *prot;
struct device *dev=NULL;
- PRINTK ("tcp_write (sk=%X, from=%X, len=%d, nonblock=%d, flags=%X)\n",
- sk, from, len, nonblock, flags);
+ PRINTK (("tcp_write (sk=%X, from=%X, len=%d, nonblock=%d, flags=%X)\n",
+ sk, from, len, nonblock, flags));
print_sk (sk);
sk->state != TCP_SYN_RECV)
{
release_sock (sk);
- PRINTK ("tcp_write: return 1\n");
+ PRINTK (("tcp_write: return 1\n"));
if (copied) return (copied);
if (sk->err)
if (nonblock)
{
release_sock (sk);
- PRINTK ("tcp_write: return 2\n");
+ PRINTK (("tcp_write: return 2\n"));
if (copied) return (copied);
return (-EAGAIN);
}
if (current->signal & ~current->blocked)
{
sti();
- PRINTK ("tcp_write: return 3\n");
+ PRINTK (("tcp_write: return 3\n"));
if (copied) return (copied);
return (-ERESTARTSYS);
}
if (nonblock)
{
release_sock (sk);
- PRINTK ("tcp_write: return 4\n");
+ PRINTK (("tcp_write: return 4\n"));
if (copied) return (copied);
return (-EAGAIN);
}
if (current->signal & ~current->blocked)
{
sti();
- PRINTK ("tcp_write: return 5\n");
+ PRINTK (("tcp_write: return 5\n"));
if (copied) return (copied);
return (-ERESTARTSYS);
}
{
prot->wfree (sk, skb->mem_addr, skb->mem_len);
release_sock (sk);
- PRINTK ("tcp_write: return 6\n");
+ PRINTK (("tcp_write: return 6\n"));
if (copied) return (copied);
return (tmp);
}
{
prot->wfree (sk, skb->mem_addr, skb->mem_len);
release_sock (sk);
- PRINTK ("tcp_write: return 7\n");
+ PRINTK (("tcp_write: return 7\n"));
if (copied) return (copied);
return (tmp);
}
if (after (sk->send_seq , sk->window_seq) ||
sk->packets_out >= sk->cong_window)
{
- PRINTK ("sk->cong_window = %d, sk->packets_out = %d\n",
- sk->cong_window, sk->packets_out);
- PRINTK ("sk->send_seq = %d, sk->window_seq = %d\n",
- sk->send_seq, sk->window_seq);
+ PRINTK (("sk->cong_window = %d, sk->packets_out = %d\n",
+ sk->cong_window, sk->packets_out));
+ PRINTK (("sk->send_seq = %d, sk->window_seq = %d\n",
+ sk->send_seq, sk->window_seq));
skb->next = NULL;
skb->magic = TCP_WRITE_QUEUE_MAGIC;
if (sk->wback == NULL)
}
sk->err = 0;
release_sock (sk);
- PRINTK ("tcp_write: return 8\n");
+ PRINTK (("tcp_write: return 8\n"));
return (copied);
}
struct sk_buff *buff;
if (!sk->ack_backlog ) return;
- PRINTK ("in tcp read wakeup\n");
+ PRINTK (("in tcp read wakeup\n"));
/* we need to put code here to prevent this routine from being called. */
/* being called once in a while is ok, so only check if this is the
second time in a row. */
static void
cleanup_rbuf (volatile struct sock *sk)
{
-/* PRINTK ("cleaning rbuf for sk=%X\n",sk);*/
+/* PRINTK (("cleaning rbuf for sk=%X\n",sk));*/
/* we have to loop through all the buffer headers, and
try to free up all the space we can. */
while (sk->rqueue != NULL )
/* at this point we should send an ack if the difference in
the window, and the amount of space is bigger than
TCP_WINDOW_DIFF */
- PRINTK ("sk->window left = %d, sk->prot->rspace(sk)=%d\n",
- sk->window - sk->bytes_rcv, sk->prot->rspace(sk));
+ PRINTK (("sk->window left = %d, sk->prot->rspace(sk)=%d\n",
+ sk->window - sk->bytes_rcv, sk->prot->rspace(sk)));
if ((sk->prot->rspace(sk) >
(sk->window - sk->bytes_rcv + TCP_WINDOW_DIFF)))
{
int copied = 0;
struct sk_buff *skb;
- PRINTK ("tcp_read_urg(sk=%X, to=%X, len=%d, flags=%X)\n",
- sk, to, len, flags);
+ PRINTK (("tcp_read_urg(sk=%X, to=%X, len=%d, flags=%X)\n",
+ sk, to, len, flags));
print_sk(sk);
while (len > 0)
{
else
skb = NULL;
- PRINTK("tcp_read (sk=%X, to=%X, len=%d, nonblock=%d, flags=%X)\n",
- sk, to, len, nonblock, flags);
+ PRINTK(("tcp_read (sk=%X, to=%X, len=%d, nonblock=%d, flags=%X)\n",
+ sk, to, len, nonblock, flags));
while ( len > 0)
{
gone all the way around. */
{
- PRINTK("skb = %X:\n",skb);
+ PRINTK(("skb = %X:\n",skb));
print_skb(skb);
print_sk (sk);
return (copied);
}
- PRINTK ("tcp_read about to sleep. state = %d\n",sk->state);
+ PRINTK (("tcp_read about to sleep. state = %d\n",sk->state));
release_sock (sk); /* now we may have some data waiting. */
/* or we could have changed state. */
}
}
sti();
- PRINTK ("tcp_read woke up. \n");
+ PRINTK (("tcp_read woke up. \n"));
sk->inuse = 1;
cleanup_rbuf (sk);
release_sock (sk);
if (copied == 0 && nonblock) return (-EAGAIN);
- PRINTK ("tcp_read returning %d\n", copied);
+ PRINTK (("tcp_read returning %d\n", copied));
return (copied);
}
sk->inuse = 1;
- PRINTK("tcp_shutdown_send buff = %X\n", buff);
+ PRINTK(("tcp_shutdown_send buff = %X\n", buff));
buff->mem_addr = buff;
buff->mem_len = MAX_RESET_SIZE;
buff->lock = 0;
{
prot->wfree (sk,buff->mem_addr, buff->mem_len);
release_sock(sk);
- PRINTK ("Unable to build header for fin.\n");
+ PRINTK (("Unable to build header for fin.\n"));
return;
}
buff=prot->wmalloc(NULL, MAX_RESET_SIZE,1, GFP_ATOMIC);
if (buff == NULL) return;
- PRINTK("tcp_reset buff = %X\n", buff);
+ PRINTK(("tcp_reset buff = %X\n", buff));
buff->mem_addr = buff;
buff->mem_len = MAX_RESET_SIZE;
buff->lock = 0;
int tmp;
th = skb->h.th;
- PRINTK ("tcp_conn_request (sk = %X, skb = %X, daddr = %X, sadd4= %X, \n"
+ PRINTK (("tcp_conn_request (sk = %X, skb = %X, daddr = %X, sadd4= %X, \n"
" opt = %X, dev = %X)\n",
- sk, skb, daddr, saddr, opt, dev);
+ sk, skb, daddr, saddr, opt, dev));
/* if the socket is dead, don't accept the connection. */
if (!sk->dead)
}
else
{
- PRINTK ("tcp_conn_request on dead socket\n");
+ PRINTK (("tcp_conn_request on dead socket\n"));
tcp_reset (daddr, saddr, th, sk->prot, opt, dev);
kfree_skb (skb, FREE_READ);
return;
}
- PRINTK ("newsk = %X\n", newsk);
+ PRINTK (("newsk = %X\n", newsk));
memcpy ((void *)newsk, (void *)sk, sizeof (*newsk));
newsk->wback = NULL;
newsk->wfront = NULL;
newsk->prot->queue_xmit(newsk, dev, buff, 0);
newsk->time_wait.len = TCP_CONNECT_TIME;
- PRINTK ("newsk->time_wait.sk = %X\n", newsk->time_wait.sk);
+ PRINTK (("newsk->time_wait.sk = %X\n", newsk->time_wait.sk));
reset_timer ((struct timer *)&newsk->time_wait);
skb->sk = newsk;
/* charge the sock_buff to newsk. */
struct proto *prot;
struct device *dev=NULL;
int tmp;
- PRINTK ("tcp_close ((struct sock *)%X, %d)\n",sk, timeout);
+ PRINTK (("tcp_close ((struct sock *)%X, %d)\n",sk, timeout));
print_sk (sk);
sk->inuse = 1;
sk->keepopen = 1;
if (tmp < 0)
{
prot->wfree (sk,buff->mem_addr, buff->mem_len);
- PRINTK ("Unable to build header for fin.\n");
+ PRINTK (("Unable to build header for fin.\n"));
release_sock(sk);
return;
}
tcp_write_xmit (volatile struct sock *sk)
{
struct sk_buff *skb;
- PRINTK ("tcp_write_xmit (sk=%X)\n",sk);
+ PRINTK (("tcp_write_xmit (sk=%X)\n",sk));
while (sk->wfront != NULL && before (sk->wfront->h.seq, sk->window_seq) &&
sk->packets_out < sk->cong_window)
{
skb->next = NULL;
if (skb->magic != TCP_WRITE_QUEUE_MAGIC)
{
- PRINTK ("tcp.c skb with bad magic (%X) on write queue. Squashing "
- "queue\n", skb->magic);
+ PRINTK (("tcp.c skb with bad magic (%X) on write queue. Squashing "
+ "queue\n", skb->magic));
sk->wfront = NULL;
sk->wback = NULL;
return;
}
skb->magic = 0;
- PRINTK("Sending a packet.\n");
+ PRINTK(("Sending a packet.\n"));
sk->prot->queue_xmit (sk, skb->dev, skb, skb->free);
}
}
unsigned long ack;
ack = net32(th->ack_seq);
- PRINTK ("tcp_ack ack=%d, window=%d, "
+ PRINTK (("tcp_ack ack=%d, window=%d, "
"sk->rcv_ack_seq=%d, sk->window_seq = %d\n",
- ack, net16(th->window), sk->rcv_ack_seq, sk->window_seq);
+ ack, net16(th->window), sk->rcv_ack_seq, sk->window_seq));
if (after (ack, sk->send_seq+1) || before (ack, sk->rcv_ack_seq-1))
{
if (after (ack, sk->send_seq) || (sk->state != TCP_ESTABLISHED &&
sk->cong_window++;
}
- PRINTK ("tcp_ack: Updating rcv ack sequence. \n");
+ PRINTK (("tcp_ack: Updating rcv ack sequence. \n"));
sk->rcv_ack_seq = ack;
/* see if we can take anything off of the retransmit queue. */
struct sk_buff *oskb;
/* we have one less packet out there. */
sk->packets_out --;
- PRINTK ("skb=%X acked\n", sk->send_head);
+ PRINTK (("skb=%X acked\n", sk->send_head));
/* wake up the process, it can probably
write more. */
if (!sk->dead)
if (sk->retransmits && sk->send_head != NULL)
{
- PRINTK ("retransmitting\n");
+ PRINTK (("retransmitting\n"));
sk->prot->retransmit (sk,1);
}
sk->retransmits = 0;
if (sk->send_head == NULL && sk->ack_backlog == 0 &&
sk->state != TCP_TIME_WAIT && !sk->keepopen)
{
- PRINTK ("Nothing to do, going to sleep.\n");
+ PRINTK (("Nothing to do, going to sleep.\n"));
if (!sk->dead)
wake_up (sk->sleep);
}
else
{
- PRINTK ("tcp_ack closing socket - %X\n", sk);
+ PRINTK (("tcp_ack closing socket - %X\n", sk));
print_sk (sk);
tcp_send_ack (sk->send_seq, sk->acked_seq, sk, th, sk->daddr);
sk->shutdown = SHUTDOWN_MASK;
}
}
- PRINTK ("leaving tcp_ack\n");
+ PRINTK (("leaving tcp_ack\n"));
return (1);
}
print_th (th);
skb->len = len - (th->doff*4);
- PRINTK("tcp_data len = %d sk = %X:\n",skb->len, sk);
+ PRINTK(("tcp_data len = %d sk = %X:\n",skb->len, sk));
print_sk(sk);
sk->bytes_rcv += skb->len;
sk->state = TCP_CLOSE;
sk->err = EPIPE;
sk->shutdown = SHUTDOWN_MASK;
- PRINTK ("tcp_data: closing socket - %X\n", sk);
+ PRINTK (("tcp_data: closing socket - %X\n", sk));
print_sk (sk);
kfree_skb (skb, FREE_READ);
if (!sk->dead) wake_up (sk->sleep);
if (sk->rqueue == NULL)
{
- PRINTK ("tcp_data: skb = %X:\n",skb);
+ PRINTK (("tcp_data: skb = %X:\n",skb));
print_skb (skb);
sk->rqueue = skb;
}
else
{
- PRINTK ("tcp_data adding to chain sk = %X:\n",sk);
+ PRINTK (("tcp_data adding to chain sk = %X:\n",sk));
print_sk (sk);
for (skb1=sk->rqueue; ; skb1=skb1->prev)
{
- PRINTK ("skb1=%X\n",skb1);
+ PRINTK (("skb1=%X\n",skb1));
print_skb(skb1);
- PRINTK ("skb1->h.th->seq = %d\n", skb1->h.th->seq);
+ PRINTK (("skb1->h.th->seq = %d\n", skb1->h.th->seq));
if (after ( th->seq+1, skb1->h.th->seq))
{
skb->prev = skb1;
}
}
- PRINTK ("skb = %X:\n",skb);
+ PRINTK (("skb = %X:\n",skb));
print_skb (skb);
- PRINTK ("sk now equals:\n");
+ PRINTK (("sk now equals:\n"));
print_sk (sk);
}
}
else
{
- PRINTK ("data received on dead socket. \n");
+ PRINTK (("data received on dead socket. \n"));
}
if (sk->state == TCP_FIN_WAIT2 && sk->acked_seq == sk->fin_seq
&& sk->rcv_ack_seq == sk->send_seq)
{
- PRINTK ("tcp_data: entering last_ack state sk = %X\n", sk);
+ PRINTK (("tcp_data: entering last_ack state sk = %X\n", sk));
print_sk (sk);
tcp_send_ack (sk->send_seq, sk->acked_seq, sk, th, saddr);
sk->shutdown = SHUTDOWN_MASK;
tcp_fin (volatile struct sock *sk, struct tcp_header *th,
unsigned long saddr, struct device *dev)
{
- PRINTK ("tcp_fin (sk=%X, th=%X, saddr=%X, dev=%X)\n",
- sk, th, saddr, dev);
+ PRINTK (("tcp_fin (sk=%X, th=%X, saddr=%X, dev=%X)\n",
+ sk, th, saddr, dev));
if (!sk->dead)
{
volatile struct sock *newsk;
struct sk_buff *skb;
- PRINTK ("tcp_accept(sk=%X, flags=%X)\n", sk, flags);
+ PRINTK (("tcp_accept(sk=%X, flags=%X)\n", sk, flags));
print_sk(sk);
/* we need to make sure that this socket is listening, and that
it has something pending. */
slightly more packets than we should, but it should not cause
problems unless someone is trying to forge packets. */
- PRINTK ("tcp_sequence (sk=%X, th=%X, len = %d, opt=%d, saddr=%X)\n",
- sk, th, len, opt, saddr);
+ PRINTK (("tcp_sequence (sk=%X, th=%X, len = %d, opt=%d, saddr=%X)\n",
+ sk, th, len, opt, saddr));
if (between(th->seq, sk->acked_seq, sk->acked_seq + sk->window)||
between(th->seq + len-sizeof (*th), sk->acked_seq,
return (1);
}
- PRINTK ("tcp_sequence: rejecting packet. \n");
+ PRINTK (("tcp_sequence: rejecting packet. \n"));
/* if it's too far ahead, send an ack to let the other end
know what we expect. */
if (!skb)
{
- PRINTK ("tcp.c: tcp_rcv skb = NULL\n");
+ PRINTK (("tcp.c: tcp_rcv skb = NULL\n"));
return (0);
}
#if 0 /* it's ok for protocol to be NULL */
if (!protocol)
{
- PRINTK ("tcp.c: tcp_rcv protocol = NULL\n");
+ PRINTK (("tcp.c: tcp_rcv protocol = NULL\n"));
return (0);
}
if (!opt) /* it's ok for opt to be NULL */
{
- PRINTK ("tcp.c: tcp_rcv opt = NULL\n");
+ PRINTK (("tcp.c: tcp_rcv opt = NULL\n"));
}
#endif
if (!dev)
{
- PRINTK ("tcp.c: tcp_rcv dev = NULL\n");
+ PRINTK (("tcp.c: tcp_rcv dev = NULL\n"));
return (0);
}
/* find the socket. */
sk=get_sock(&tcp_prot, net16(th->dest), saddr, th->source, daddr);
- PRINTK("<<\n");
- PRINTK("len = %d, redo = %d, skb=%X\n", len, redo, skb);
+ PRINTK(("<<\n"));
+ PRINTK(("len = %d, redo = %d, skb=%X\n", len, redo, skb));
if (sk)
{
- PRINTK ("sk = %X:\n",sk);
+ PRINTK (("sk = %X:\n",sk));
print_sk (sk);
}
if (th->check && tcp_check (th, len, saddr, daddr ))
{
skb->sk = NULL;
- PRINTK ("packet dropped with bad checksum.\n");
+ PRINTK (("packet dropped with bad checksum.\n"));
kfree_skb (skb, 0);
/* we don't release the socket because it was never
marked in use. */
{
if (!sk)
{
- PRINTK ("tcp.c: tcp_rcv bug sk=NULL redo = 1\n");
+ PRINTK (("tcp.c: tcp_rcv bug sk=NULL redo = 1\n"));
return (0);
}
}
if (!sk->prot)
{
- PRINTK ("tcp.c: tcp_rcv sk->prot = NULL \n");
+ PRINTK (("tcp.c: tcp_rcv sk->prot = NULL \n"));
return (0);
}
if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
{
skb->sk = NULL;
- PRINTK ("dropping packet due to lack of buffer space.\n");
+ PRINTK (("dropping packet due to lack of buffer space.\n"));
kfree_skb (skb, 0);
release_sock (sk);
return (0);
sk->rmem_alloc += skb->mem_len;
- PRINTK ("About to do switch. \n");
+ PRINTK (("About to do switch. \n"));
/* now deal with it. */
if (sk->dead || sk->daddr)
{
- PRINTK ("packet received for closed,dead socket\n");
+ PRINTK (("packet received for closed,dead socket\n"));
kfree_skb (skb, FREE_READ);
release_sock (sk);
return (0);
buff->len=sizeof (struct tcp_header);
buff->free = 1;
buff->sk = sk;
- PRINTK ("in tcp_write_wakeup\n");
+ PRINTK (("in tcp_write_wakeup\n"));
t1=(struct tcp_header *)(buff + 1);
/* put in the ip_header and routing stuff. */
#ifdef TIMER_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
static struct timer *timer_base=NULL;
delete_timer (struct timer *t)
{
struct timer *tm;
- PRINTK ("delete_timer (t=%X)\n",t);
+ PRINTK (("delete_timer (t=%X)\n",t));
if (timer_base == NULL || t == NULL) return;
cli();
if (t == timer_base)
delete_timer (t);
t->when = timer_seq + t->len;
- PRINTK ("reset_timer (t=%X) when = %d jiffies = %d\n",t, t->when, jiffies);
+ PRINTK (("reset_timer (t=%X) when = %d jiffies = %d\n",t, t->when, jiffies));
if (t == NULL)
{
printk ("*** reset timer NULL timer\n");
sti();
why = sk->timeout;
- PRINTK ("net_timer: found sk=%X why = %d\n",sk, why);
+ PRINTK (("net_timer: found sk=%X why = %d\n",sk, why));
if (sk->keepopen)
{
the memory assosiated with the
socket to be freed. We need to
print an error message. */
- PRINTK ("possible memory leak. sk = %X\n", sk);
+ PRINTK (("possible memory leak. sk = %X\n", sk));
print_sk (sk);
reset_timer ((struct timer *)&sk->time_wait);
sk->inuse = 0;
release_sock (sk);
break;
}
- PRINTK ("retransmitting.\n");
+ PRINTK (("retransmitting.\n"));
sk->prot->retransmit (sk, 0);
if (sk->retransmits > TCP_RETR1)
{
- PRINTK ("timer.c TIME_WRITE time-out 1\n");
+ PRINTK (("timer.c TIME_WRITE time-out 1\n"));
arp_destroy (sk->daddr);
ip_route_check (sk->daddr);
}
if (sk->retransmits > TCP_RETR2)
{
- PRINTK ("timer.c TIME_WRITE time-out 2\n");
+ PRINTK (("timer.c TIME_WRITE time-out 2\n"));
sk->err = ETIMEDOUT;
if (sk->state == TCP_FIN_WAIT1 ||
sk->state == TCP_FIN_WAIT2 ||
if (sk->retransmits > TCP_RETR1)
{
- PRINTK ("timer.c TIME_KEEPOPEN time-out 1\n");
+ PRINTK (("timer.c TIME_KEEPOPEN time-out 1\n"));
arp_destroy (sk->daddr);
ip_route_check (sk->daddr);
release_sock (sk);
}
if (sk->retransmits > TCP_RETR2)
{
- PRINTK ("timer.c TIME_KEEPOPEN time-out 2\n");
+ PRINTK (("timer.c TIME_KEEPOPEN time-out 2\n"));
arp_destroy (sk->daddr);
sk->err = ETIMEDOUT;
if (sk->state == TCP_FIN_WAIT1 ||
#endif
#ifdef UDP_DEBUG
-#define PRINTK printk
+#define PRINTK(x) printk x
#else
-#define PRINTK dummy_routine
+#define PRINTK(x) /**/
#endif
#define min(a,b) ((a)<(b)?(a):(b))
{
if (uh == NULL)
{
- PRINTK ("(NULL)\n");
+ PRINTK (("(NULL)\n"));
return;
}
- PRINTK("source = %d, dest = %d\n", net16(uh->source), net16(uh->dest));
- PRINTK("len = %d, check = %d\n", net16(uh->len), net16(uh->check));
+ PRINTK(("source = %d, dest = %d\n", net16(uh->source), net16(uh->dest)));
+ PRINTK(("len = %d, check = %d\n", net16(uh->len), net16(uh->check)));
}
struct udp_header *th;
volatile struct sock *sk;
- PRINTK ("udp_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n");
+ PRINTK (("udp_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n"));
th = (struct udp_header *)header;
sk = get_sock (&udp_prot, net16(th->dest), saddr, th->source, daddr);
unsigned long saddr, unsigned long daddr)
{
unsigned long sum;
- PRINTK ("udp_check (uh=%X, len = %d, saddr = %X, daddr = %X)\n",
- uh, len, saddr, daddr);
+ PRINTK (("udp_check (uh=%X, len = %d, saddr = %X, daddr = %X)\n",
+ uh, len, saddr, daddr));
print_uh (uh);
volatile struct sock *pair;
sk->inuse = 1;
- PRINTK ("udp_loopback \n");
+ PRINTK (("udp_loopback \n"));
pair = get_sock (sk->prot, net16(port), saddr,
sk->dummy_th.source, daddr);
if (len < 0) return (-EINVAL);
if (len == 0) return (0);
- PRINTK ("sendto len = %d\n", len);
+ PRINTK (("sendto len = %d\n", len));
/* get and verify the address. */
if (usin)
let the ip protocol fragment the packet. */
amt = min (len + tmp + sizeof (*uh), dev->mtu);
- PRINTK ("amt = %d, dev = %X, dev->mtu = %d\n",
- amt, dev, dev->mtu);
+ PRINTK (("amt = %d, dev = %X, dev->mtu = %d\n",
+ amt, dev, dev->mtu));
skb->len = amt;
amt -= tmp;
{
if (uh->check && udp_check (uh, len, saddr, daddr))
{
- PRINTK ("bad udp checksum\n");
+ PRINTK (("bad udp checksum\n"));
skb->sk = NULL;
kfree_skb (skb, 0);
return (0);
sk->rmem_alloc += skb->mem_len;
/* At this point we should print the thing out. */
- PRINTK ("<< \n");
+ PRINTK (("<< \n"));
print_sk (sk);
/* now add it to the data chain and wake things up. */
unix_data_ref(struct unix_proto_data *upd)
{
++upd->refcnt;
- PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt);
+ PRINTK(("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt));
}
static void
unix_data_deref(struct unix_proto_data *upd)
{
if (upd->refcnt == 1) {
- PRINTK("unix_data_deref: releasing data 0x%x\n", upd);
+ PRINTK(("unix_data_deref: releasing data 0x%x\n", upd));
if (upd->buf) {
free_page((unsigned long)upd->buf);
upd->buf = NULL;
{
struct unix_proto_data *upd;
- PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol);
+ PRINTK(("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol));
if (protocol != 0) {
- PRINTK("unix_proto_create: protocol != 0\n");
+ PRINTK(("unix_proto_create: protocol != 0\n"));
return -EINVAL;
}
if (!(upd = unix_data_alloc())) {
upd->protocol = protocol;
upd->socket = sock;
UN_DATA(sock) = upd;
- PRINTK("unix_proto_create: allocated data 0x%x\n", upd);
+ PRINTK(("unix_proto_create: allocated data 0x%x\n", upd));
return 0;
}
{
struct unix_proto_data *upd = UN_DATA(sock);
- PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n",
- sock, upd);
+ PRINTK(("unix_proto_release: socket 0x%x, unix_data 0x%x\n",
+ sock, upd));
if (!upd)
return 0;
if (upd->socket != sock) {
return -EINVAL;
}
if (upd->inode) {
- PRINTK("unix_proto_release: releasing inode 0x%x\n",
- upd->inode);
+ PRINTK(("unix_proto_release: releasing inode 0x%x\n",
+ upd->inode));
iput(upd->inode);
upd->inode = NULL;
}
int i;
unsigned long old_fs;
- PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
- sockaddr_len);
+ PRINTK(("unix_proto_bind: socket 0x%x, len=%d\n", sock,
+ sockaddr_len));
if (sockaddr_len <= UN_PATH_OFFSET ||
sockaddr_len > sizeof(struct sockaddr_un)) {
- PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
+ PRINTK(("unix_proto_bind: bad length %d\n", sockaddr_len));
return -EINVAL;
}
if (upd->sockaddr_len || upd->inode) {
verify_area(umyaddr, sockaddr_len);
memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
if (upd->sockaddr_un.sun_family != AF_UNIX) {
- PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
- upd->sockaddr_un.sun_family, AF_UNIX);
+ PRINTK(("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
+ upd->sockaddr_un.sun_family, AF_UNIX));
return -EINVAL;
}
}
upd->sockaddr_len = sockaddr_len; /* now its legal */
- PRINTK("unix_proto_bind: bound socket address: ");
+ PRINTK(("unix_proto_bind: bound socket address: "));
#ifdef SOCK_DEBUG
sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
#endif
- PRINTK("to inode 0x%x\n", upd->inode);
+ PRINTK(("to inode 0x%x\n", upd->inode));
return 0;
}
unsigned long old_fs;
struct inode *inode;
- PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
- sockaddr_len);
+ PRINTK(("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
+ sockaddr_len));
if (sockaddr_len <= UN_PATH_OFFSET ||
sockaddr_len > sizeof(struct sockaddr_un)) {
- PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
+ PRINTK(("unix_proto_connect: bad length %d\n", sockaddr_len));
return -EINVAL;
}
verify_area(uservaddr, sockaddr_len);
memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
if (sockun.sun_family != AF_UNIX) {
- PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
- sockun.sun_family, AF_UNIX);
+ PRINTK(("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
+ sockun.sun_family, AF_UNIX));
return -EINVAL;
}
i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
set_fs(old_fs);
if (i < 0) {
- PRINTK("unix_proto_connect: can't open socket %s\n", fname);
+ PRINTK(("unix_proto_connect: can't open socket %s\n", fname));
return i;
}
serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
iput(inode);
if (!serv_upd) {
- PRINTK("unix_proto_connect: can't locate peer %s at inode 0x%x\n",
- fname, inode);
+ PRINTK(("unix_proto_connect: can't locate peer %s at inode 0x%x\n",
+ fname, inode));
return -EINVAL;
}
if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
- PRINTK("unix_proto_connect: can't await connection\n");
+ PRINTK(("unix_proto_connect: can't await connection\n"));
return i;
}
unix_data_ref(UN_DATA(sock->conn));
{
struct socket *clientsock;
- PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
- sock, newsock);
+ PRINTK(("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
+ sock, newsock));
/*
* if there aren't any sockets awaiting connection, then wait for
return -EAGAIN;
interruptible_sleep_on(sock->wait);
if (current->signal & ~current->blocked) {
- PRINTK("sys_accept: sleep was interrupted\n");
+ PRINTK(("sys_accept: sleep was interrupted\n"));
return -ERESTARTSYS;
}
}
struct unix_proto_data *upd;
int len;
- PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock,
- peer ? "peer" : "self");
+ PRINTK(("unix_proto_getname: socket 0x%x for %s\n", sock,
+ peer ? "peer" : "self"));
if (peer) {
if (sock->state != SS_CONNECTED) {
- PRINTK("unix_proto_getname: socket not connected\n");
+ PRINTK(("unix_proto_getname: socket not connected\n"));
return -EINVAL;
}
upd = UN_DATA(sock->conn);
upd = UN_DATA(sock);
while (!(avail = UN_BUF_AVAIL(upd))) {
if (sock->state != SS_CONNECTED) {
- PRINTK("unix_proto_read: socket not connected\n");
+ PRINTK(("unix_proto_read: socket not connected\n"));
return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
}
- PRINTK("unix_proto_read: no data available...\n");
+ PRINTK(("unix_proto_read: no data available...\n"));
if (nonblock)
return -EAGAIN;
interruptible_sleep_on(sock->wait);
if (current->signal & ~current->blocked) {
- PRINTK("unix_proto_read: interrupted\n");
+ PRINTK(("unix_proto_read: interrupted\n"));
return -ERESTARTSYS;
}
if (sock->state == SS_DISCONNECTING) {
- PRINTK("unix_proto_read: disconnected\n");
+ PRINTK(("unix_proto_read: disconnected\n"));
return 0;
}
}
int part, cando;
if (avail <= 0) {
- PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n");
+ PRINTK(("unix_proto_read: AVAIL IS NEGATIVE!!!\n"));
send_sig(SIGKILL,current,1);
return -EINTR;
}
cando = avail;
if (cando > (part = BUF_SIZE - upd->bp_tail))
cando = part;
- PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
- avail, todo, cando);
+ PRINTK(("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
+ avail, todo, cando));
verify_area(ubuf, cando);
memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
if ((todo = size) <= 0)
return 0;
if (sock->state != SS_CONNECTED) {
- PRINTK("unix_proto_write: socket not connected\n");
+ PRINTK(("unix_proto_write: socket not connected\n"));
if (sock->state == SS_DISCONNECTING) {
send_sig(SIGPIPE,current,1);
return -EINTR;
pupd = UN_DATA(sock)->peerupd; /* safer than sock->conn */
while (!(space = UN_BUF_SPACE(pupd))) {
- PRINTK("unix_proto_write: no space left...\n");
+ PRINTK(("unix_proto_write: no space left...\n"));
if (nonblock)
return -EAGAIN;
interruptible_sleep_on(sock->wait);
if (current->signal & ~current->blocked) {
- PRINTK("unix_proto_write: interrupted\n");
+ PRINTK(("unix_proto_write: interrupted\n"));
return -ERESTARTSYS;
}
if (sock->state == SS_DISCONNECTING) {
- PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");
+ PRINTK(("unix_proto_write: disconnected (SIGPIPE)\n"));
send_sig(SIGPIPE,current,1);
return -EINTR;
}
int part, cando;
if (space <= 0) {
- PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n");
+ PRINTK(("unix_proto_write: SPACE IS NEGATIVE!!!\n"));
send_sig(SIGKILL,current,1);
return -EINTR;
}
cando = space;
if (cando > (part = BUF_SIZE - pupd->bp_head))
cando = part;
- PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n",
- space, todo, cando);
+ PRINTK(("unix_proto_write: space=%d, todo=%d, cando=%d\n",
+ space, todo, cando));
verify_area(ubuf, cando);
memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
*/
if (sock->flags & SO_ACCEPTCON) {
if (sel_type == SEL_IN) {
- PRINTK("sock_select: %sconnections pending\n",
- sock->iconn ? "" : "no ");
+ PRINTK(("sock_select: %sconnections pending\n",
+ sock->iconn ? "" : "no "));
if (sock->iconn)
return 1;
select_wait(sock->wait, wait);
return sock->iconn ? 1 : 0;
}
- PRINTK("sock_select: nothing else for server socket\n");
+ PRINTK(("sock_select: nothing else for server socket\n"));
select_wait(sock->wait, wait);
return 0;
}
if (sel_type == SEL_IN) {
upd = UN_DATA(sock);
- PRINTK("unix_proto_select: there is%s data available\n",
- UN_BUF_AVAIL(upd) ? "" : " no");
+ PRINTK(("unix_proto_select: there is%s data available\n",
+ UN_BUF_AVAIL(upd) ? "" : " no"));
if (UN_BUF_AVAIL(upd)) /* even if disconnected */
return 1;
else if (sock->state != SS_CONNECTED) {
- PRINTK("unix_proto_select: socket not connected (read EOF)\n");
+ PRINTK(("unix_proto_select: socket not connected (read EOF)\n"));
return 1;
}
select_wait(sock->wait,wait);
}
if (sel_type == SEL_OUT) {
if (sock->state != SS_CONNECTED) {
- PRINTK("unix_proto_select: socket not connected (write EOF)\n");
+ PRINTK(("unix_proto_select: socket not connected (write EOF)\n"));
return 1;
}
peerupd = UN_DATA(sock->conn);
- PRINTK("unix_proto_select: there is%s space available\n",
- UN_BUF_SPACE(peerupd) ? "" : " no");
+ PRINTK(("unix_proto_select: there is%s space available\n",
+ UN_BUF_SPACE(peerupd) ? "" : " no"));
if (UN_BUF_SPACE(peerupd) > 0)
return 1;
select_wait(sock->wait,wait);
return 0;
}
/* SEL_EX */
- PRINTK("unix_proto_select: there are no exceptions here?!\n");
+ PRINTK(("unix_proto_select: there are no exceptions here?!\n"));
return 0;
}
{
struct unix_proto_data *upd;
- PRINTK("unix_proto_init: initializing...\n");
+ PRINTK(("unix_proto_init: initializing...\n"));
for (upd = unix_datas; upd <= last_unix_data; ++upd)
upd->refcnt = 0;
return 0;