diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1995-11-05 23:25:13 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1995-11-05 23:25:13 +0000 |
commit | 86f1bc4514fdcfd255f37f3218fe234bdc3664fc (patch) | |
tree | a863e5e6db622c86c23e80527b0a47988efef1f3 /sys/gnu | |
parent | 65a271ba6d03e08c6a9486e645d658f5a04f03a6 (diff) | |
download | FreeBSD-src-86f1bc4514fdcfd255f37f3218fe234bdc3664fc.zip FreeBSD-src-86f1bc4514fdcfd255f37f3218fe234bdc3664fc.tar.gz |
This commit was manufactured by cvs2svn to create branch 'LINUX'.
Diffstat (limited to 'sys/gnu')
119 files changed, 0 insertions, 44442 deletions
diff --git a/sys/gnu/ext2fs/COPYRIGHT.INFO b/sys/gnu/ext2fs/COPYRIGHT.INFO deleted file mode 100644 index bbb0214..0000000 --- a/sys/gnu/ext2fs/COPYRIGHT.INFO +++ /dev/null @@ -1,30 +0,0 @@ -Most of the files in this directory are written by Godmar Back or modified -by him using the CSRG sources. Those files are covered by the Berkeley-style -copyright. However the following files are covered by GPL. Since the policy -of the FreeBSD project is to keep the files with the more restrictive -copyright in the gnu tree and it is a good idea to keep the filesystem code -all together, the EXT2FS in it's entirety resides under the gnu tree. Note -that only the files below are under the GPL. In the eventuality that these -files are redesigned or rewritten, this tree can be moved back into the less -restrictive FreeBSD tree. - - ext2_fs.h - ext2_fs_i.h - ext2_fs_sb.h - ext2_linux_balloc.c - ext2_linux_ialloc.c - i386-bitops.h - -PS. - THANKS GODMAR!!! - -Note that this port has been modified by John Dyson and others on -the FreeBSD team, and it is best to send the bug reports to the FreeBSD -team. If there are any non-FreeBSD specific bugs, fixes will be sent to -Godmar to help him fix the original code base. It is also our intention -to send Godmar any FreeBSD specific porting changes so that he can keep -control of his code.... - -John -dyson@freebsd.org - diff --git a/sys/gnu/ext2fs/ext2_alloc.c b/sys/gnu/ext2fs/ext2_alloc.c deleted file mode 100644 index 6a0f5d3..0000000 --- a/sys/gnu/ext2fs/ext2_alloc.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_alloc.c 8.8 (Berkeley) 2/21/94 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/stat.h> -#include <sys/mount.h> -#include <sys/kernel.h> -#include <sys/syslog.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -extern u_long nextgennumber; - -static void ext2_fserr __P((struct ext2_sb_info *, u_int, char *)); - -/* - * Linux calls this functions at the following locations: - * (1) the inode is freed - * (2) a preallocation miss occurs - * (3) truncate is called - * (4) release_file is called and f_mode & 2 - * - * I call it in ext2_inactive, ext2_truncate, ext2_vfree and in (2) - * the call in vfree might be redundant - */ -void ext2_discard_prealloc (struct inode * ip) -{ -#ifdef EXT2_PREALLOCATE - if (ip->i_prealloc_count) { - int i = ip->i_prealloc_count; - ip->i_prealloc_count = 0; - ext2_free_blocks (ITOV(ip)->v_mount, - ip->i_prealloc_block, - i); - } -#endif -} - -/* - * Allocate a block in the file system. - * - * this takes the framework from ffs_alloc. To implement the - * actual allocation, it calls ext2_new_block, the ported version - * of the same Linux routine. - * - * we note that this is always called in connection with ext2_blkpref - * - * preallocation is done as Linux does it - */ -int -ext2_alloc(ip, lbn, bpref, size, cred, bnp) - register struct inode *ip; - daddr_t lbn, bpref; - int size; - struct ucred *cred; - daddr_t *bnp; -{ - register struct ext2_sb_info *fs; - daddr_t bno; - int cg, error; - - *bnp = 0; - fs = ip->i_e2fs; -#if DIAGNOSTIC - if ((u_int)size > fs->s_blocksize || blkoff(fs, size) != 0) { - printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", - ip->i_dev, fs->s_blocksize, size, fs->fs_fsmnt); - panic("ext2_alloc: bad size"); - } - if (cred == NOCRED) - panic("ext2_alloc: missing credential\n"); -#endif /* DIAGNOSTIC */ - if (size == fs->s_blocksize && fs->s_es->s_free_blocks_count == 0) - goto nospace; - if (cred->cr_uid != 0 && - fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count) - goto nospace; -#if QUOTA - if (error = chkdq(ip, (long)btodb(size), cred, 0)) - return (error); -#endif - if (bpref >= fs->s_es->s_blocks_count) - bpref = 0; - /* call the Linux code */ -#ifdef EXT2_PREALLOCATE - /* To have a preallocation hit, we must - * - have at least one block preallocated - * - and our preferred block must have that block number or one below - */ - if (ip->i_prealloc_count && - (bpref == ip->i_prealloc_block || - bpref + 1 == ip->i_prealloc_block)) - { - bno = ip->i_prealloc_block++; - ip->i_prealloc_count--; - /* ext2_debug ("preallocation hit (%lu/%lu).\n", - ++alloc_hits, ++alloc_attempts); */ - - /* Linux gets, clears, and releases the buffer at this - point - we don't have to that; we leave it to the caller - */ - } else { - ext2_discard_prealloc (ip); - /* ext2_debug ("preallocation miss (%lu/%lu).\n", - alloc_hits, ++alloc_attempts); */ - if (S_ISREG(ip->i_mode)) - bno = ext2_new_block - (ITOV(ip)->v_mount, bpref, - &ip->i_prealloc_count, - &ip->i_prealloc_block); - else - bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, - bpref, 0, 0); - } -#else - bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, bpref, 0, 0); -#endif - - if (bno > 0) { - /* set next_alloc fields as done in block_getblk */ - ip->i_next_alloc_block = lbn; - ip->i_next_alloc_goal = bno; - - ip->i_blocks += btodb(size); - ip->i_flag |= IN_CHANGE | IN_UPDATE; - *bnp = bno; - return (0); - } -#if QUOTA - /* - * Restore user's disk quota because allocation failed. - */ - (void) chkdq(ip, (long)-btodb(size), cred, FORCE); -#endif -nospace: - ext2_fserr(fs, cred->cr_uid, "file system full"); - uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); - return (ENOSPC); -} - -/* - * Reallocate a sequence of blocks into a contiguous sequence of blocks. - * - * The vnode and an array of buffer pointers for a range of sequential - * logical blocks to be made contiguous is given. The allocator attempts - * to find a range of sequential blocks starting as close as possible to - * an fs_rotdelay offset from the end of the allocation for the logical - * block immediately preceeding the current range. If successful, the - * physical block numbers in the buffer pointers and in the inode are - * changed to reflect the new allocation. If unsuccessful, the allocation - * is left unchanged. The success in doing the reallocation is returned. - * Note that the error return is not reflected back to the user. Rather - * the previous block allocation will be used. - */ -#include <sys/sysctl.h> -static int doasyncfree = 1; -#ifdef OPT_DEBUG -struct ctldebug debug14 = { "doasyncfree", &doasyncfree }; -#endif /* OPT_DEBUG */ -int -ext2_reallocblks(ap) - struct vop_reallocblks_args /* { - struct vnode *a_vp; - struct cluster_save *a_buflist; - } */ *ap; -{ -#ifndef FANCY_REALLOC -/* printf("ext2_reallocblks not implemented\n"); */ -return ENOSPC; -#else - - struct ext2_sb_info *fs; - struct inode *ip; - struct vnode *vp; - struct buf *sbp, *ebp; - daddr_t *bap, *sbap, *ebap; - struct cluster_save *buflist; - daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno; - struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; - int i, len, start_lvl, end_lvl, pref, ssize; - - vp = ap->a_vp; - ip = VTOI(vp); - fs = ip->i_e2fs; -#ifdef UNKLAR - if (fs->fs_contigsumsize <= 0) - return (ENOSPC); -#endif - buflist = ap->a_buflist; - len = buflist->bs_nchildren; - start_lbn = buflist->bs_children[0]->b_lblkno; - end_lbn = start_lbn + len - 1; -#if DIAGNOSTIC - for (i = 1; i < len; i++) - if (buflist->bs_children[i]->b_lblkno != start_lbn + i) - panic("ext2_reallocblks: non-cluster"); -#endif - /* - * If the latest allocation is in a new cylinder group, assume that - * the filesystem has decided to move and do not force it back to - * the previous cylinder group. - */ - if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) != - dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno))) - return (ENOSPC); - if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) || - ufs_getlbns(vp, end_lbn, end_ap, &end_lvl)) - return (ENOSPC); - /* - * Get the starting offset and block map for the first block. - */ - if (start_lvl == 0) { - sbap = &ip->i_db[0]; - soff = start_lbn; - } else { - idp = &start_ap[start_lvl - 1]; - if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &sbp)) { - brelse(sbp); - return (ENOSPC); - } - sbap = (daddr_t *)sbp->b_data; - soff = idp->in_off; - } - /* - * Find the preferred location for the cluster. - */ - pref = ext2_blkpref(ip, start_lbn, soff, sbap); - /* - * If the block range spans two block maps, get the second map. - */ - if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) { - ssize = len; - } else { -#if DIAGNOSTIC - if (start_ap[start_lvl-1].in_lbn == idp->in_lbn) - panic("ext2_reallocblk: start == end"); -#endif - ssize = len - (idp->in_off + 1); - if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &ebp)) - goto fail; - ebap = (daddr_t *)ebp->b_data; - } - /* - * Search the block map looking for an allocation of the desired size. - */ - if ((newblk = (daddr_t)ext2_hashalloc(ip, dtog(fs, pref), (long)pref, - len, (u_long (*)())ext2_clusteralloc)) == 0) - goto fail; - /* - * We have found a new contiguous block. - * - * First we have to replace the old block pointers with the new - * block pointers in the inode and indirect blocks associated - * with the file. - */ - blkno = newblk; - for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->s_frags_per_block) { - if (i == ssize) - bap = ebap; -#if DIAGNOSTIC - if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap)) - panic("ext2_reallocblks: alloc mismatch"); -#endif - *bap++ = blkno; - } - /* - * Next we must write out the modified inode and indirect blocks. - * For strict correctness, the writes should be synchronous since - * the old block values may have been written to disk. In practise - * they are almost never written, but if we are concerned about - * strict correctness, the `doasyncfree' flag should be set to zero. - * - * The test on `doasyncfree' should be changed to test a flag - * that shows whether the associated buffers and inodes have - * been written. The flag should be set when the cluster is - * started and cleared whenever the buffer or inode is flushed. - * We can then check below to see if it is set, and do the - * synchronous write only when it has been cleared. - */ - if (sbap != &ip->i_db[0]) { - if (doasyncfree) - bdwrite(sbp); - else - bwrite(sbp); - } else { -#if !defined(__FreeBSD__) - struct timeval time; - get_time(&time); -#endif - ip->i_flag |= IN_CHANGE | IN_UPDATE; - if (!doasyncfree) - VOP_UPDATE(vp, &time, &time, MNT_WAIT); - } - if (ssize < len) - if (doasyncfree) - bdwrite(ebp); - else - bwrite(ebp); - /* - * Last, free the old blocks and assign the new blocks to the buffers. - */ - for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) { - ext2_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno), - fs->s_blocksize); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); - } - return (0); - -fail: - if (ssize < len) - brelse(ebp); - if (sbap != &ip->i_db[0]) - brelse(sbp); - return (ENOSPC); - -#endif /* FANCY_REALLOC */ -} - -/* - * Allocate an inode in the file system. - * - * we leave the actual allocation strategy to the (modified) - * ext2_new_inode(), to make sure we get the policies right - */ -int -ext2_valloc(ap) - struct vop_valloc_args /* { - struct vnode *a_pvp; - int a_mode; - struct ucred *a_cred; - struct vnode **a_vpp; - } */ *ap; -{ - register struct vnode *pvp = ap->a_pvp; - register struct inode *pip; - register struct ext2_sb_info *fs; - register struct inode *ip; - mode_t mode = ap->a_mode; - ino_t ino, ipref; - int i, error; -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - *ap->a_vpp = NULL; - pip = VTOI(pvp); - fs = pip->i_e2fs; - if (fs->s_es->s_free_inodes_count == 0) - goto noinodes; - - /* call the Linux routine - it returns the inode number only */ - ino = ext2_new_inode(pip, mode); - - if (ino == 0) - goto noinodes; - error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp); - if (error) { - VOP_VFREE(pvp, ino, mode); - return (error); - } - ip = VTOI(*ap->a_vpp); - - /* - the question is whether using VGET was such good idea at all - - Linux doesn't read the old inode in when it's allocating a - new one. I will set at least i_size & i_blocks the zero. - */ - ip->i_mode = 0; - ip->i_size = 0; - ip->i_blocks = 0; - ip->i_flags = 0; - /* now we want to make sure that the block pointers are zeroed out */ - for(i = 0; i < EXT2_NDIR_BLOCKS; i++) - ip->i_db[i] = 0; - - /* - * Set up a new generation number for this inode. - * XXX check if this makes sense in ext2 - */ -#if !defined(__FreeBSD__) - get_time(&time); -#endif - if (++nextgennumber < (u_long)time.tv_sec) - nextgennumber = time.tv_sec; - ip->i_gen = nextgennumber; -/* -printf("ext2_valloc: allocated inode %d\n", ino); -*/ - return (0); -noinodes: - ext2_fserr(fs, ap->a_cred->cr_uid, "out of inodes"); - uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); - return (ENOSPC); -} - -/* - * Select the desired position for the next block in a file. - * - * we try to mimic what Remy does in inode_getblk/block_getblk - * - * we note: blocknr == 0 means that we're about to allocate either - * a direct block or a pointer block at the first level of indirection - * (In other words, stuff that will go in i_db[] or i_ib[]) - * - * blocknr != 0 means that we're allocating a block that is none - * of the above. Then, blocknr tells us the number of the block - * that will hold the pointer - */ -daddr_t -ext2_blkpref(ip, lbn, indx, bap, blocknr) - struct inode *ip; - daddr_t lbn; - int indx; - daddr_t *bap; - daddr_t blocknr; -{ - register struct ext2_sb_info *fs; - int tmp; - - /* if the next block is actually what we thought it is, - then set the goal to what we thought it should be - */ - if(ip->i_next_alloc_block == lbn) - return ip->i_next_alloc_goal; - - /* now check whether we were provided with an array that basically - tells us previous blocks to which we want to stay closeby - */ - if(bap) - for (tmp = indx - 1; tmp >= 0; tmp--) - if (bap[tmp]) - return bap[tmp]; - - /* else let's fall back to the blocknr, or, if there is none, - follow the rule that a block should be allocated near it's inode - */ - return blocknr ? blocknr : - (daddr_t)(ip->i_block_group * - EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + - ip->i_e2fs->s_es->s_first_data_block; -} - -/* - * Free a block or fragment. - * - * pass on to the Linux code - */ -void -ext2_blkfree(ip, bno, size) - register struct inode *ip; - daddr_t bno; - long size; -{ - register struct ext2_sb_info *fs; - - fs = ip->i_e2fs; - /* - * call Linux code with mount *, block number, count - */ - ext2_free_blocks(ITOV(ip)->v_mount, bno, size / fs->s_frag_size); -} - -/* - * Free an inode. - * - * the maintenance of the actual bitmaps is again up to the linux code - */ -int -ext2_vfree(ap) - struct vop_vfree_args /* { - struct vnode *a_pvp; - ino_t a_ino; - int a_mode; - } */ *ap; -{ - register struct ext2_sb_info *fs; - register struct inode *pip; - ino_t ino = ap->a_ino; - int mode; - - pip = VTOI(ap->a_pvp); - fs = pip->i_e2fs; - if ((u_int)ino >= fs->s_inodes_per_group * fs->s_groups_count) - panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n", - pip->i_dev, ino, fs->fs_fsmnt); - -/* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, ap->a_mode); - */ - ext2_discard_prealloc(pip); - - /* we need to make sure that ext2_free_inode can adjust the - used_dir_counts in the group summary information - I'd - really like to know what the rationale behind this - 'set i_mode to zero to denote an unused inode' is - */ - mode = pip->i_mode; - pip->i_mode = ap->a_mode; - ext2_free_inode(pip); - pip->i_mode = mode; - return (0); -} - -/* - * Fserr prints the name of a file system with an error diagnostic. - * - * The form of the error message is: - * fs: error message - */ -static void -ext2_fserr(fs, uid, cp) - struct ext2_sb_info *fs; - u_int uid; - char *cp; -{ - - log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp); -} diff --git a/sys/gnu/ext2fs/ext2_balloc.c b/sys/gnu/ext2fs/ext2_balloc.c deleted file mode 100644 index 44d75ae..0000000 --- a/sys/gnu/ext2fs/ext2_balloc.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/file.h> -#include <sys/vnode.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -/* - * Balloc defines the structure of file system storage - * by allocating the physical blocks on a device given - * the inode and the logical block number in a file. - */ -int -ext2_balloc(ip, bn, size, cred, bpp, flags) - register struct inode *ip; - register daddr_t bn; - int size; - struct ucred *cred; - struct buf **bpp; - int flags; -{ - register struct ext2_sb_info *fs; - register daddr_t nb; - struct buf *bp, *nbp; - struct vnode *vp = ITOV(ip); - struct indir indirs[NIADDR + 2]; - daddr_t newb, lbn, *bap, pref; - int osize, nsize, num, i, error; -/* -ext2_debug("ext2_balloc called (%d, %d, %d)\n", - ip->i_number, (int)bn, (int)size); -*/ - *bpp = NULL; - if (bn < 0) - return (EFBIG); - fs = ip->i_e2fs; - lbn = bn; - - /* - * check if this is a sequential block allocation. - * If so, increment next_alloc fields to allow ext2_blkpref - * to make a good guess - */ - if (lbn == ip->i_next_alloc_block + 1) { - ip->i_next_alloc_block++; - ip->i_next_alloc_goal++; - } - - /* - * The first NDADDR blocks are direct blocks - */ - if (bn < NDADDR) { - nb = ip->i_db[bn]; - /* no new block is to be allocated, and no need to expand - the file */ - if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) { - error = bread(vp, bn, fs->s_blocksize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - *bpp = bp; - return (0); - } - if (nb != 0) { - /* - * Consider need to reallocate a fragment. - */ - osize = fragroundup(fs, blkoff(fs, ip->i_size)); - nsize = fragroundup(fs, size); - if (nsize <= osize) { - error = bread(vp, bn, osize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - } else { - /* Godmar thinks: this shouldn't happen w/o fragments */ - printf("nsize %d(%d) > osize %d(%d) nb %d\n", - (int)nsize, (int)size, (int)osize, - (int)ip->i_size, (int)nb); - panic("ext2_balloc: " - "Something is terribly wrong\n"); -/* - * please note there haven't been any changes from here on - - * FFS seems to work. - */ - } - } else { - if (ip->i_size < (bn + 1) * fs->s_blocksize) - nsize = fragroundup(fs, size); - else - nsize = fs->s_blocksize; - error = ext2_alloc(ip, bn, - ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0), - nsize, cred, &newb); - if (error) - return (error); - bp = getblk(vp, bn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); - if (flags & B_CLRBUF) -#if defined(__FreeBSD__) - vfs_bio_clrbuf(bp); -#else - clrbuf(bp); -#endif - } - ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); - ip->i_flag |= IN_CHANGE | IN_UPDATE; - *bpp = bp; - return (0); - } - /* - * Determine the number of levels of indirection. - */ - pref = 0; - if (error = ufs_getlbns(vp, bn, indirs, &num)) - return(error); -#if DIAGNOSTIC - if (num < 1) - panic ("ext2_balloc: ufs_bmaparray returned indirect block\n"); -#endif - /* - * Fetch the first indirect block allocating if necessary. - */ - --num; - nb = ip->i_ib[indirs[0].in_off]; - if (nb == 0) { -#if 0 - pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0); -#else - /* see the comment by ext2_blkpref. What we do here is - to pretend that it'd be good for a block holding indirect - pointers to be allocated near its predecessor in terms - of indirection, or the last direct block. - We shamelessly exploit the fact that i_ib immediately - follows i_db. - Godmar thinks it make sense to allocate i_ib[0] immediately - after i_db[11], but it's not utterly clear whether this also - applies to i_ib[1] and i_ib[0] - */ - - pref = ext2_blkpref(ip, lbn, indirs[0].in_off + - EXT2_NDIR_BLOCKS, &ip->i_db[0], 0); -#endif - if (error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, - cred, &newb)) - return (error); - nb = newb; - bp = getblk(vp, indirs[1].in_lbn, fs->s_blocksize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); -#if defined(__FreeBSD__) - vfs_bio_clrbuf(bp); -#else - clrbuf(bp); -#endif - /* - * Write synchronously so that indirect blocks - * never point at garbage. - */ - if (error = bwrite(bp)) { - ext2_blkfree(ip, nb, fs->s_blocksize); - return (error); - } - ip->i_ib[indirs[0].in_off] = newb; - ip->i_flag |= IN_CHANGE | IN_UPDATE; - } - /* - * Fetch through the indirect blocks, allocating as necessary. - */ - for (i = 1;;) { - error = bread(vp, - indirs[i].in_lbn, (int)fs->s_blocksize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - bap = (daddr_t *)bp->b_data; - nb = bap[indirs[i].in_off]; - if (i == num) - break; - i += 1; - if (nb != 0) { - brelse(bp); - continue; - } - if (pref == 0) -#if 1 - /* see the comment above and by ext2_blkpref - * I think this implements Linux policy, but - * does it really make sense to allocate to - * block containing pointers together ? - * Also, will it ever succeed ? - */ - pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap, - bp->b_lblkno); -#else - pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0); -#endif - if (error = - ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) { - brelse(bp); - return (error); - } - nb = newb; - nbp = getblk(vp, indirs[i].in_lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); -#if defined(__FreeBSD__) - vfs_bio_clrbuf(nbp); -#else - clrbuf(nbp); -#endif - /* - * Write synchronously so that indirect blocks - * never point at garbage. - */ - if (error = bwrite(nbp)) { - ext2_blkfree(ip, nb, fs->s_blocksize); - brelse(bp); - return (error); - } - bap[indirs[i - 1].in_off] = nb; - /* - * If required, write synchronously, otherwise use - * delayed write. - */ - if (flags & B_SYNC) { - bwrite(bp); - } else { - bdwrite(bp); - } - } - /* - * Get the data block, allocating if necessary. - */ - if (nb == 0) { - pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0], - bp->b_lblkno); - if (error = ext2_alloc(ip, - lbn, pref, (int)fs->s_blocksize, cred, &newb)) { - brelse(bp); - return (error); - } - nb = newb; - nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - if (flags & B_CLRBUF) -#if defined(__FreeBSD__) - vfs_bio_clrbuf(nbp); -#else - clrbuf(nbp); -#endif - bap[indirs[i].in_off] = nb; - /* - * If required, write synchronously, otherwise use - * delayed write. - */ - if (flags & B_SYNC) { - bwrite(bp); - } else { - bdwrite(bp); - } - *bpp = nbp; - return (0); - } - brelse(bp); - if (flags & B_CLRBUF) { - error = bread(vp, lbn, (int)fs->s_blocksize, NOCRED, &nbp); - if (error) { - brelse(nbp); - return (error); - } - } else { - nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - } - *bpp = nbp; - return (0); -} diff --git a/sys/gnu/ext2fs/ext2_bmap.c b/sys/gnu/ext2fs/ext2_bmap.c deleted file mode 100644 index c8b3cd4..0000000 --- a/sys/gnu/ext2fs/ext2_bmap.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_bmap.c 8.6 (Berkeley) 1/21/94 - * $Id: ufs_bmap.c,v 1.9 1995/09/04 00:21:09 dyson Exp $ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/resourcevar.h> - -#include <miscfs/specfs/specdev.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/ufs_extern.h> - -/* - * Bmap converts a the logical block number of a file to its physical block - * number on the disk. The conversion is done by using the logical block - * number to index into the array of block pointers described by the dinode. - */ -int -ufs_bmap(ap) - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - int *a_runb; - } */ *ap; -{ - /* - * Check for underlying vnode requests and ensure that logical - * to physical mapping is requested. - */ - if (ap->a_vpp != NULL) - *ap->a_vpp = VTOI(ap->a_vp)->i_devvp; - if (ap->a_bnp == NULL) - return (0); - - return (ufs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL, - ap->a_runp, ap->a_runb)); -} - -/* - * Indirect blocks are now on the vnode for the file. They are given negative - * logical block numbers. Indirect blocks are addressed by the negative - * address of the first data block to which they point. Double indirect blocks - * are addressed by one less than the address of the first indirect block to - * which they point. Triple indirect blocks are addressed by one less than - * the address of the first double indirect block to which they point. - * - * ufs_bmaparray does the bmap conversion, and if requested returns the - * array of logical blocks which must be traversed to get to a block. - * Each entry contains the offset into that block that gets you to the - * next block and the disk address of the block (if it is assigned). - */ - -int -ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb) - struct vnode *vp; - register daddr_t bn; - daddr_t *bnp; - struct indir *ap; - int *nump; - int *runp; - int *runb; -{ - register struct inode *ip; - struct buf *bp; - struct ufsmount *ump; - struct mount *mp; - struct vnode *devvp; - struct indir a[NIADDR+1], *xap; - daddr_t daddr; - long metalbn; - int error, maxrun = 0, num; - - ip = VTOI(vp); - mp = vp->v_mount; - ump = VFSTOUFS(mp); -#ifdef DIAGNOSTIC - if (ap != NULL && nump == NULL || ap == NULL && nump != NULL) - panic("ufs_bmaparray: invalid arguments"); -#endif - - if (runp) { - /* - * XXX - * If MAXPHYS is the largest transfer the disks can handle, - * we probably want maxrun to be 1 block less so that we - * don't create a block larger than the device can handle. - */ - *runp = 0; - maxrun = MAXPHYS / mp->mnt_stat.f_iosize - 1; - } - - if (runb) { - *runb = 0; - } - - xap = ap == NULL ? a : ap; - if (!nump) - nump = # - error = ufs_getlbns(vp, bn, xap, nump); - if (error) - return (error); - - num = *nump; - if (num == 0) { - *bnp = blkptrtodb(ump, ip->i_db[bn]); - if (*bnp == 0) - *bnp = -1; - else if (runp) { - daddr_t bnb = bn; - for (++bn; bn < NDADDR && *runp < maxrun && - is_sequential(ump, ip->i_db[bn - 1], ip->i_db[bn]); - ++bn, ++*runp); - bn = bnb; - if (runb && (bn > 0)) { - for (--bn; (bn >= 0) && (*runb < maxrun) && - is_sequential(ump, ip->i_db[bn], - ip->i_db[bn+1]); - --bn, ++*runb); - } - } - return (0); - } - - - /* Get disk address out of indirect block array */ - daddr = ip->i_ib[xap->in_off]; - - devvp = VFSTOUFS(vp->v_mount)->um_devvp; - for (bp = NULL, ++xap; --num; ++xap) { - /* - * Exit the loop if there is no disk address assigned yet and - * the indirect block isn't in the cache, or if we were - * looking for an indirect block and we've found it. - */ - - metalbn = xap->in_lbn; - if ((daddr == 0 && !incore(vp, metalbn)) || metalbn == bn) - break; - /* - * If we get here, we've either got the block in the cache - * or we have a disk address for it, go fetch it. - */ - if (bp) - brelse(bp); - - xap->in_exists = 1; - bp = getblk(vp, metalbn, mp->mnt_stat.f_iosize, 0, 0); - if ((bp->b_flags & B_CACHE) == 0) { -#ifdef DIAGNOSTIC - if (!daddr) - panic("ufs_bmaparry: indirect block not in cache"); -#endif - bp->b_blkno = blkptrtodb(ump, daddr); - bp->b_flags |= B_READ; - vfs_busy_pages(bp, 0); - VOP_STRATEGY(bp); - curproc->p_stats->p_ru.ru_inblock++; /* XXX */ - error = biowait(bp); - if (error) { - brelse(bp); - return (error); - } - } - - daddr = ((daddr_t *)bp->b_data)[xap->in_off]; - if (num == 1 && daddr && runp) { - for (bn = xap->in_off + 1; - bn < MNINDIR(ump) && *runp < maxrun && - is_sequential(ump, ((daddr_t *)bp->b_data)[bn - 1], - ((daddr_t *)bp->b_data)[bn]); - ++bn, ++*runp); - bn = xap->in_off; - if (runb && bn) { - for(--bn; bn > 0 && *runb < maxrun && - is_sequential(ump, ((daddr_t *)bp->b_data)[bn], - ((daddr_t *)bp->b_data)[bn+1]); - --bn, ++*runb); - } - } - } - if (bp) - brelse(bp); - - daddr = blkptrtodb(ump, daddr); - *bnp = daddr == 0 ? -1 : daddr; - return (0); -} - -/* - * Create an array of logical block number/offset pairs which represent the - * path of indirect blocks required to access a data block. The first "pair" - * contains the logical block number of the appropriate single, double or - * triple indirect block and the offset into the inode indirect block array. - * Note, the logical block number of the inode single/double/triple indirect - * block appears twice in the array, once with the offset into the i_ib and - * once with the offset into the page itself. - */ -int -ufs_getlbns(vp, bn, ap, nump) - struct vnode *vp; - register daddr_t bn; - struct indir *ap; - int *nump; -{ - long metalbn, realbn; - struct ufsmount *ump; - int blockcnt, i, numlevels, off; - - ump = VFSTOUFS(vp->v_mount); - if (nump) - *nump = 0; - numlevels = 0; - realbn = bn; - if ((long)bn < 0) - bn = -(long)bn; - - /* The first NDADDR blocks are direct blocks. */ - if (bn < NDADDR) - return (0); - - /* - * Determine the number of levels of indirection. After this loop - * is done, blockcnt indicates the number of data blocks possible - * at the given level of indirection, and NIADDR - i is the number - * of levels of indirection needed to locate the requested block. - */ - for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { - if (i == 0) - return (EFBIG); - blockcnt *= MNINDIR(ump); - if (bn < blockcnt) - break; - } - - /* Calculate the address of the first meta-block. */ - if (realbn >= 0) - metalbn = -(realbn - bn + NIADDR - i); - else - metalbn = -(-realbn - bn + NIADDR - i); - - /* - * At each iteration, off is the offset into the bap array which is - * an array of disk addresses at the current level of indirection. - * The logical block number and the offset in that block are stored - * into the argument array. - */ - ap->in_lbn = metalbn; - ap->in_off = off = NIADDR - i; - ap->in_exists = 0; - ap++; - for (++numlevels; i <= NIADDR; i++) { - /* If searching for a meta-data block, quit when found. */ - if (metalbn == realbn) - break; - - blockcnt /= MNINDIR(ump); - off = (bn / blockcnt) % MNINDIR(ump); - - ++numlevels; - ap->in_lbn = metalbn; - ap->in_off = off; - ap->in_exists = 0; - ++ap; - - metalbn -= -1 + off * blockcnt; - } - if (nump) - *nump = numlevels; - return (0); -} diff --git a/sys/gnu/ext2fs/ext2_extern.h b/sys/gnu/ext2fs/ext2_extern.h deleted file mode 100644 index 92ec042..0000000 --- a/sys/gnu/ext2fs/ext2_extern.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/*- - * Copyright (c) 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_extern.h 8.3 (Berkeley) 4/16/94 - */ - -struct buf; -struct fid; -struct fs; -struct inode; -struct mount; -struct nameidata; -struct proc; -struct statfs; -struct timeval; -struct ucred; -struct uio; -struct vnode; -struct mbuf; -struct dinode; -struct ext2_group_desc; -struct ext2_inode; - -__BEGIN_DECLS -int ext2_alloc __P((struct inode *, - daddr_t, daddr_t, int, struct ucred *, daddr_t *)); -int ext2_balloc __P((struct inode *, - daddr_t, int, struct ucred *, struct buf **, int)); -int ext2_blkatoff __P((struct vop_blkatoff_args *)); -void ext2_blkfree __P((struct inode *, daddr_t, long)); -daddr_t ext2_blkpref __P((struct inode *, daddr_t, int, daddr_t *, daddr_t)); -int ext2_bmap __P((struct vop_bmap_args *)); -int ext2_fhtovp __P((struct mount *, struct fid *, struct mbuf *, - struct vnode **, int *, struct ucred **)); -int ext2_fsync __P((struct vop_fsync_args *)); -int ext2_init __P((void)); -int ext2_mount __P((struct mount *, - char *, caddr_t, struct nameidata *, struct proc *)); -int ext2_mountfs __P((struct vnode *, struct mount *, struct proc *)); -int ext2_mountroot __P((void)); -int ext2_read __P((struct vop_read_args *)); -int ext2_reallocblks __P((struct vop_reallocblks_args *)); -int ext2_reclaim __P((struct vop_reclaim_args *)); -void ext2_setblock __P((struct ext2_sb_info *, u_char *, daddr_t)); -int ext2_statfs __P((struct mount *, struct statfs *, struct proc *)); -int ext2_sync __P((struct mount *, int, struct ucred *, struct proc *)); -int ext2_truncate __P((struct vop_truncate_args *)); -int ext2_unmount __P((struct mount *, int, struct proc *)); -int ext2_update __P((struct vop_update_args *)); -int ext2_valloc __P((struct vop_valloc_args *)); -int ext2_vfree __P((struct vop_vfree_args *)); -int ext2_vget __P((struct mount *, ino_t, struct vnode **)); -int ext2_vptofh __P((struct vnode *, struct fid *)); -int ext2_write __P((struct vop_write_args *)); -int ext2_lookup __P((struct vop_lookup_args *)); -int ext2_readdir __P((struct vop_readdir_args *)); -void ext2_print_dinode __P((struct dinode *)); -void ext2_print_inode __P((struct inode *)); -int ext2_direnter __P((struct inode *, - struct vnode *, struct componentname *)); -int ext2_dirremove __P((struct vnode *, struct componentname *)); -int ext2_dirrewrite __P((struct inode *, - struct inode *, struct componentname *)); -int ext2_dirempty __P((struct inode *, ino_t, struct ucred *)); -int ext2_checkpath __P((struct inode *, struct inode *, struct ucred *)); -struct ext2_group_desc * get_group_desc __P((struct mount * , - unsigned int , struct buf ** )); -void ext2_discard_prealloc __P((struct inode *)); -int ext2_inactive __P((struct vop_inactive_args *)); -int ll_w_block __P((struct buf *, int )); -int ext2_di2ei __P((struct dinode *di, struct ext2_inode *ei)); -int ext2_ei2di __P((struct ext2_inode *ei, struct dinode *di)); -int ext2_new_block __P ((struct mount * mp, unsigned long goal, - long * prealloc_count, - long * prealloc_block)); -ino_t ext2_new_inode __P ((const struct inode * dir, int mode)); -void ext2_free_blocks (struct mount * mp, unsigned long block, - unsigned long count); -void ext2_free_inode (struct inode * inode); -int ext2_flushfiles __P((struct mount *mp, int flags, struct proc *p)); -int ext2_reload __P((struct mount *mountp, struct ucred *cred, - struct proc *p)); - -#if !defined(__FreeBSD__) -int bwrite(); /* FFS needs a bwrite routine. XXX */ -#endif - -/* this macros allows some of the ufs code to distinguish between - * an EXT2 and a non-ext2(FFS/LFS) vnode. - */ -#define IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS) - -#ifdef DIAGNOSTIC -void ext2_checkoverlap __P((struct buf *, struct inode *)); -#endif -__END_DECLS - -extern int (**ext2_vnodeop_p)(); -extern int (**ext2_specop_p)(); -#ifdef FIFO -extern int (**ext2_fifoop_p)(); -#define EXT2_FIFOOPS ext2_fifoop_p -#else -#define EXT2_FIFOOPS NULL -#endif diff --git a/sys/gnu/ext2fs/ext2_ihash.c b/sys/gnu/ext2fs/ext2_ihash.c deleted file mode 100644 index 18ac11c..0000000 --- a/sys/gnu/ext2fs/ext2_ihash.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_ihash.c 8.4 (Berkeley) 12/30/93 - * $Id: ufs_ihash.c,v 1.4 1994/10/08 06:57:23 phk Exp $ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/proc.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - -/* - * Structures associated with inode cacheing. - */ -struct inode **ihashtbl; -u_long ihash; /* size of hash table - 1 */ -#define INOHASH(device, inum) (((device) + (inum)) & ihash) - -/* - * Initialize inode hash table. - */ -void -ufs_ihashinit() -{ - - ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash); -} - -/* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, return it, even if it is locked. - */ -struct vnode * -ufs_ihashlookup(device, inum) - dev_t device; - ino_t inum; -{ - register struct inode *ip; - - for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) { - if (ip == NULL) - return (NULL); - if (inum == ip->i_number && device == ip->i_dev) - return (ITOV(ip)); - } - /* NOTREACHED */ -} - -/* - * Use the device/inum pair to find the incore inode, and return a pointer - * to it. If it is in core, but locked, wait for it. - */ -struct vnode * -ufs_ihashget(device, inum) - dev_t device; - ino_t inum; -{ - register struct inode *ip; - struct vnode *vp; - - for (;;) - for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) { - if (ip == NULL) - return (NULL); - if (inum == ip->i_number && device == ip->i_dev) { - if (ip->i_flag & IN_LOCKED) { - if( curproc->p_pid != ip->i_lockholder) { - ip->i_flag |= IN_WANTED; - (void) tsleep(ip, PINOD, "uihget", 0); - break; - } else if (ip->i_flag & IN_RECURSE) { - ip->i_lockcount++; - } else { - panic("ufs_ihashget: recursive lock not expected -- pid %d\n", ip->i_lockholder); - } - } - vp = ITOV(ip); - if (!vget(vp, 1)) - return (vp); - break; - } - } - /* NOTREACHED */ -} - -/* - * Insert the inode into the hash table, and return it locked. - */ -void -ufs_ihashins(ip) - struct inode *ip; -{ - struct inode **ipp, *iq; - - ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)]; - iq = *ipp; - if (iq) - iq->i_prev = &ip->i_next; - ip->i_next = iq; - ip->i_prev = ipp; - *ipp = ip; - if ((ip->i_flag & IN_LOCKED) && - ((ip->i_flag & IN_RECURSE) == 0 || - (!curproc || (curproc && (ip->i_lockholder != curproc->p_pid))))) - panic("ufs_ihashins: already locked"); - if (curproc) { - ip->i_lockcount += 1; - ip->i_lockholder = curproc->p_pid; - } else { - ip->i_lockholder = -1; - } - ip->i_flag |= IN_LOCKED; -} - -/* - * Remove the inode from the hash table. - */ -void -ufs_ihashrem(ip) - register struct inode *ip; -{ - register struct inode *iq; - - iq = ip->i_next; - if (iq) - iq->i_prev = ip->i_prev; - *ip->i_prev = iq; -#ifdef DIAGNOSTIC - ip->i_next = NULL; - ip->i_prev = NULL; -#endif -} diff --git a/sys/gnu/ext2fs/ext2_inode.c b/sys/gnu/ext2fs/ext2_inode.c deleted file mode 100644 index f2d6fd7..0000000 --- a/sys/gnu/ext2fs/ext2_inode.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_inode.c 8.5 (Berkeley) 12/30/93 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mount.h> -#include <sys/proc.h> -#include <sys/file.h> -#include <sys/buf.h> -#include <sys/vnode.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if !defined(__FreeBSD__) -#include <sys/trace.h> -#endif -#include <sys/resourcevar.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -static int ext2_indirtrunc __P((struct inode *, daddr_t, daddr_t, daddr_t, int, - long *)); - -int -ext2_init() -{ - return (ufs_init()); -} - -/* - * Update the access, modified, and inode change times as specified by the - * IACCESS, IUPDATE, and ICHANGE flags respectively. The IMODIFIED flag is - * used to specify that the inode needs to be updated but that the times have - * already been set. The access and modified times are taken from the second - * and third parameters; the inode change time is always taken from the current - * time. If waitfor is set, then wait for the disk write of the inode to - * complete. - */ -int -ext2_update(ap) - struct vop_update_args /* { - struct vnode *a_vp; - struct timeval *a_access; - struct timeval *a_modify; - int a_waitfor; - } */ *ap; -{ - register struct ext2_sb_info *fs; - struct buf *bp; - struct inode *ip; - int error; -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - ip = VTOI(ap->a_vp); - if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) { - ip->i_flag &= - ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE); - return (0); - } - if ((ip->i_flag & - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0) - return (0); - if (ip->i_flag & IN_ACCESS) - ip->i_atime.ts_sec = ap->a_access->tv_sec; - if (ip->i_flag & IN_UPDATE) { - ip->i_mtime.ts_sec = ap->a_modify->tv_sec; - ip->i_modrev++; - } - if (ip->i_flag & IN_CHANGE) { -#if !defined(__FreeBSD__) - get_time(&time); -#endif - ip->i_ctime.ts_sec = time.tv_sec; - } - ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE); - fs = ip->i_e2fs; - if (error = bread(ip->i_devvp, - fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), - (int)fs->s_blocksize, NOCRED, &bp)) { - brelse(bp); - return (error); - } - ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * - ino_to_fsbo(fs, ip->i_number))); -/* - if (ap->a_waitfor && (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0) - return (bwrite(bp)); - else { -*/ - bdwrite(bp); - return (0); -/* - } -*/ -} - -#define SINGLE 0 /* index of single indirect block */ -#define DOUBLE 1 /* index of double indirect block */ -#define TRIPLE 2 /* index of triple indirect block */ -/* - * Truncate the inode oip to at most length size, freeing the - * disk blocks. - */ -int -ext2_truncate(ap) - struct vop_truncate_args /* { - struct vnode *a_vp; - off_t a_length; - int a_flags; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - register struct vnode *ovp = ap->a_vp; - register daddr_t lastblock; - register struct inode *oip; - daddr_t bn, lbn, lastiblock[NIADDR], indir_lbn[NIADDR]; - daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR]; - off_t length = ap->a_length; - register struct ext2_sb_info *fs; - struct buf *bp; - int offset, size, level; - long count, nblocks, vflags, blocksreleased = 0; - struct timeval tv; - register int i; - int aflags, error, allerror; - off_t osize; -/* -printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, ap->a_length); -*/ /* - * negative file sizes will totally break the code below and - * are not meaningful anyways. - */ - if (length < 0) - return EFBIG; - - oip = VTOI(ovp); -#if defined(__FreeBSD__) - tv = time; -#else - get_time(&tv); -#endif - if (ovp->v_type == VLNK && - oip->i_size < ovp->v_mount->mnt_maxsymlinklen) { -#if DIAGNOSTIC - if (length != 0) - panic("ext2_truncate: partial truncate of symlink"); -#endif - bzero((char *)&oip->i_shortlink, (u_int)oip->i_size); - oip->i_size = 0; - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 1)); - } - if (oip->i_size == length) { - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 0)); - } -#if QUOTA - if (error = getinoquota(oip)) - return (error); -#endif - vnode_pager_setsize(ovp, (u_long)length); - fs = oip->i_e2fs; - osize = oip->i_size; - ext2_discard_prealloc(oip); - /* - * Lengthen the size of the file. We must ensure that the - * last byte of the file is allocated. Since the smallest - * value of oszie is 0, length will be at least 1. - */ - if (osize < length) { - offset = blkoff(fs, length - 1); - lbn = lblkno(fs, length - 1); - aflags = B_CLRBUF; - if (ap->a_flags & IO_SYNC) - aflags |= B_SYNC; - if (error = ext2_balloc(oip, lbn, offset + 1, ap->a_cred, &bp, - aflags)) - return (error); - oip->i_size = length; -#if !defined(__FreeBSD__) - (void) vnode_pager_uncache(ovp); -#endif - if (aflags & IO_SYNC) - bwrite(bp); - else - bawrite(bp); - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 1)); - } - /* - * Shorten the size of the file. If the file is not being - * truncated to a block boundry, the contents of the - * partial block following the end of the file must be - * zero'ed in case it ever become accessable again because - * of subsequent file growth. - */ - /* I don't understand the comment above */ - offset = blkoff(fs, length); - if (offset == 0) { - oip->i_size = length; - } else { - lbn = lblkno(fs, length); - aflags = B_CLRBUF; - if (ap->a_flags & IO_SYNC) - aflags |= B_SYNC; - if (error = ext2_balloc(oip, lbn, offset, ap->a_cred, &bp, - aflags)) - return (error); - oip->i_size = length; - size = blksize(fs, oip, lbn); -#if !defined(__FreeBSD__) - (void) vnode_pager_uncache(ovp); -#endif - bzero((char *)bp->b_data + offset, (u_int)(size - offset)); - allocbuf(bp, size); - if (aflags & IO_SYNC) - bwrite(bp); - else - bawrite(bp); - } - /* - * Calculate index into inode's block list of - * last direct and indirect blocks (if any) - * which we want to keep. Lastblock is -1 when - * the file is truncated to 0. - */ - lastblock = lblkno(fs, length + fs->s_blocksize - 1) - 1; - lastiblock[SINGLE] = lastblock - NDADDR; - lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); - lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); - nblocks = btodb(fs->s_blocksize); - /* - * Update file and block pointers on disk before we start freeing - * blocks. If we crash before free'ing blocks below, the blocks - * will be returned to the free list. lastiblock values are also - * normalized to -1 for calls to ext2_indirtrunc below. - */ - bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof oldblks); - for (level = TRIPLE; level >= SINGLE; level--) - if (lastiblock[level] < 0) { - oip->i_ib[level] = 0; - lastiblock[level] = -1; - } - for (i = NDADDR - 1; i > lastblock; i--) - oip->i_db[i] = 0; - oip->i_flag |= IN_CHANGE | IN_UPDATE; - if (error = VOP_UPDATE(ovp, &tv, &tv, MNT_WAIT)) - allerror = error; - /* - * Having written the new inode to disk, save its new configuration - * and put back the old block pointers long enough to process them. - * Note that we save the new block configuration so we can check it - * when we are done. - */ - bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof newblks); - bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof oldblks); - oip->i_size = osize; - vflags = ((length > 0) ? V_SAVE : 0) | V_SAVEMETA; - allerror = vinvalbuf(ovp, vflags, ap->a_cred, ap->a_p, 0, 0); - - /* - * Indirect blocks first. - */ - indir_lbn[SINGLE] = -NDADDR; - indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; - indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; - for (level = TRIPLE; level >= SINGLE; level--) { - bn = oip->i_ib[level]; - if (bn != 0) { - error = ext2_indirtrunc(oip, indir_lbn[level], - fsbtodb(fs, bn), lastiblock[level], level, &count); - if (error) - allerror = error; - blocksreleased += count; - if (lastiblock[level] < 0) { - oip->i_ib[level] = 0; - ext2_blkfree(oip, bn, fs->s_frag_size); - blocksreleased += nblocks; - } - } - if (lastiblock[level] >= 0) - goto done; - } - - /* - * All whole direct blocks or frags. - */ - for (i = NDADDR - 1; i > lastblock; i--) { - register long bsize; - - bn = oip->i_db[i]; - if (bn == 0) - continue; - oip->i_db[i] = 0; - bsize = blksize(fs, oip, i); - ext2_blkfree(oip, bn, bsize); - blocksreleased += btodb(bsize); - } - if (lastblock < 0) - goto done; - - /* - * Finally, look for a change in size of the - * last direct block; release any frags. - */ - bn = oip->i_db[lastblock]; - if (bn != 0) { - long oldspace, newspace; - - /* - * Calculate amount of space we're giving - * back as old block size minus new block size. - */ - oldspace = blksize(fs, oip, lastblock); - oip->i_size = length; - newspace = blksize(fs, oip, lastblock); - if (newspace == 0) - panic("itrunc: newspace"); - if (oldspace - newspace > 0) { - /* - * Block number of space to be free'd is - * the old block # plus the number of frags - * required for the storage we're keeping. - */ - bn += numfrags(fs, newspace); - ext2_blkfree(oip, bn, oldspace - newspace); - blocksreleased += btodb(oldspace - newspace); - } - } -done: -#if DIAGNOSTIC - for (level = SINGLE; level <= TRIPLE; level++) - if (newblks[NDADDR + level] != oip->i_ib[level]) - panic("itrunc1"); - for (i = 0; i < NDADDR; i++) - if (newblks[i] != oip->i_db[i]) - panic("itrunc2"); - if (length == 0 && - (ovp->v_dirtyblkhd.lh_first || ovp->v_cleanblkhd.lh_first)) - panic("itrunc3"); -#endif /* DIAGNOSTIC */ - /* - * Put back the real size. - */ - oip->i_size = length; - oip->i_blocks -= blocksreleased; - if (oip->i_blocks < 0) /* sanity */ - oip->i_blocks = 0; - oip->i_flag |= IN_CHANGE; -#if QUOTA - (void) chkdq(oip, -blocksreleased, NOCRED, 0); -#endif - return (allerror); -} - -/* - * Release blocks associated with the inode ip and stored in the indirect - * block bn. Blocks are free'd in LIFO order up to (but not including) - * lastbn. If level is greater than SINGLE, the block is an indirect block - * and recursive calls to indirtrunc must be used to cleanse other indirect - * blocks. - * - * NB: triple indirect blocks are untested. - */ - -static int -ext2_indirtrunc(ip, lbn, dbn, lastbn, level, countp) - register struct inode *ip; - daddr_t lbn, lastbn; - daddr_t dbn; - int level; - long *countp; -{ - register int i; - struct buf *bp; - register struct ext2_sb_info *fs = ip->i_e2fs; - register daddr_t *bap; - struct vnode *vp; - daddr_t *copy, nb, nlbn, last; - long blkcount, factor; - int nblocks, blocksreleased = 0; - int error = 0, allerror = 0; - - /* - * Calculate index in current block of last - * block to be kept. -1 indicates the entire - * block so we need not calculate the index. - */ - factor = 1; - for (i = SINGLE; i < level; i++) - factor *= NINDIR(fs); - last = lastbn; - if (lastbn > 0) - last /= factor; - nblocks = btodb(fs->s_blocksize); - /* - * Get buffer of block pointers, zero those entries corresponding - * to blocks to be free'd, and update on disk copy first. Since - * double(triple) indirect before single(double) indirect, calls - * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field - * explicitly instead of letting bread do everything for us. - */ - vp = ITOV(ip); - bp = getblk(vp, lbn, (int)fs->s_blocksize, 0, 0); - if (bp->b_flags & (B_DONE | B_DELWRI)) { - /* Braces must be here in case trace evaluates to nothing. */ -#if !defined(__FreeBSD__) - trace(TR_BREADHIT, pack(vp, fs->s_blocksize), lbn); -#endif - } else { -#if !defined(__FreeBSD__) - trace(TR_BREADMISS, pack(vp, fs->s_blocksize), lbn); - get_proc()->p_stats->p_ru.ru_inblock++; /* pay for read */ -#endif - bp->b_flags |= B_READ; - if (bp->b_bcount > bp->b_bufsize) - panic("ext2_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; -#if defined(__FreeBSD__) - vfs_busy_pages(bp, 0); -#endif - VOP_STRATEGY(bp); - error = biowait(bp); - } - if (error) { - brelse(bp); - *countp = 0; - return (error); - } - - bap = (daddr_t *)bp->b_data; - MALLOC(copy, daddr_t *, fs->s_blocksize, M_TEMP, M_WAITOK); - bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->s_blocksize); - bzero((caddr_t)&bap[last + 1], - (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t)); - if (last == -1) - bp->b_flags |= B_INVAL; - error = bwrite(bp); - if (error) - allerror = error; - bap = copy; - - /* - * Recursively free totally unused blocks. - */ - for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; - i--, nlbn += factor) { - nb = bap[i]; - if (nb == 0) - continue; - if (level > SINGLE) { - if (error = ext2_indirtrunc(ip, nlbn, - fsbtodb(fs, nb), (daddr_t)-1, level - 1, &blkcount)) - allerror = error; - blocksreleased += blkcount; - } - ext2_blkfree(ip, nb, fs->s_blocksize); - blocksreleased += nblocks; - } - - /* - * Recursively free last partial block. - */ - if (level > SINGLE && lastbn >= 0) { - last = lastbn % factor; - nb = bap[i]; - if (nb != 0) { - if (error = ext2_indirtrunc(ip, nlbn, fsbtodb(fs, nb), - last, level - 1, &blkcount)) - allerror = error; - blocksreleased += blkcount; - } - } - FREE(copy, M_TEMP); - *countp = blocksreleased; - return (allerror); -} - -/* - * discard preallocated blocks - */ -int -ext2_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - } */ *ap; -{ - ext2_discard_prealloc(VTOI(ap->a_vp)); - return ufs_inactive(ap); -} - diff --git a/sys/gnu/ext2fs/ext2_inode_cnv.c b/sys/gnu/ext2fs/ext2_inode_cnv.c deleted file mode 100644 index 1ab48e9..0000000 --- a/sys/gnu/ext2fs/ext2_inode_cnv.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 1995 The University of Utah and - * the Computer Systems Laboratory at the University of Utah (CSL). - * All rights reserved. - * - * Permission to use, copy, modify and distribute this software is hereby - * granted provided that (1) source code retains these copyright, permission, - * and disclaimer notices, and (2) redistributions including binaries - * reproduce the notices in supporting documentation, and (3) all advertising - * materials mentioning features or use of this software display the following - * acknowledgement: ``This product includes software developed by the - * Computer Systems Laboratory at the University of Utah.'' - * - * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS - * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF - * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * CSL requests users of this software to return to csl-dist@cs.utah.edu any - * improvements that they make and grant CSL redistribution rights. - * - * Utah $Hdr$ - */ - -/* - * routines to convert on disk ext2 inodes in dinodes and back - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -/* these defs would destroy the ext2_fs_i #include */ -#undef i_atime -#undef i_blocks -#undef i_ctime -#undef i_db -#undef i_flags -#undef i_gen -#undef i_gid -#undef i_ib -#undef i_mode -#undef i_mtime -#undef i_nlink -#undef i_rdev -#undef i_shortlink -#undef i_size -#undef i_uid - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_i.h> - -void ext2_print_dinode( di ) - struct dinode *di; -{ - int i; - printf( /* "Inode: %5d" */ - " Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n", - "n/a", di->di_mode, di->di_flags, di->di_gen); - printf( "User: %5d Group: %5d Size: %d\n", - di->di_uid, di->di_gid, di->di_size); - printf( "Links: %3d Blockcount: %d\n", - di->di_nlink, di->di_blocks); - printf( "ctime: 0x%x", di->di_ctime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_ctime.ts_sec); -#endif - printf( "atime: 0x%x", di->di_atime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_atime.ts_sec); -#endif - printf( "mtime: 0x%x", di->di_mtime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_mtime.ts_sec); -#endif - printf( "BLOCKS: "); - for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++) - printf("%d ", di->di_db[i]); - printf("\n"); -} - -void ext2_print_inode( in ) - struct inode *in; -{ - printf( "Inode: %5d", in->i_number); - ext2_print_dinode(&in->i_din); -} - -/* - * raw ext2 inode to dinode - */ -int ext2_ei2di(ei, di) - struct ext2_inode *ei; - struct dinode *di; -{ - int i; - - di->di_nlink = ei->i_links_count; - /* Godmar thinks - if the link count is zero, then the inode is - unused - according to ext2 standards. Ufs marks this fact - by setting i_mode to zero - why ? - I can see that this might lead to problems in an undelete. - */ - di->di_mode = ei->i_links_count ? ei->i_mode : 0; - di->di_size = ei->i_size; - di->di_atime.ts_sec = ei->i_atime; - di->di_mtime.ts_sec = ei->i_mtime; - di->di_ctime.ts_sec = ei->i_ctime; - di->di_flags = 0; - di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0; - di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0; - di->di_blocks = ei->i_blocks; - di->di_gen = ei->i_version; /* XXX is that true ??? */ - di->di_uid = ei->i_uid; - di->di_gid = ei->i_gid; - /* XXX use memcpy */ - for(i = 0; i < NDADDR; i++) - di->di_db[i] = ei->i_block[i]; - for(i = 0; i < NIADDR; i++) - di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i]; -} - -/* - * dinode to raw ext2 inode - */ -int ext2_di2ei(di, ei) - struct dinode *di; - struct ext2_inode *ei; -{ - int i; - - ei->i_mode = di->di_mode; - ei->i_links_count = di->di_nlink; - /* - Godmar thinks: if dtime is nonzero, ext2 says this inode - has been deleted, this would correspond to a zero link count - */ - ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime.ts_sec; - ei->i_size = di->di_size; - ei->i_atime = di->di_atime.ts_sec; - ei->i_mtime = di->di_mtime.ts_sec; - ei->i_ctime = di->di_ctime.ts_sec; - ei->i_flags = di->di_flags; - ei->i_flags = 0; - ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0; - ei->i_flags |= (di->di_flags & IMMUTABLE) - ? EXT2_IMMUTABLE_FL: 0; - ei->i_blocks = di->di_blocks; - ei->i_version = di->di_gen; /* XXX is that true ??? */ - ei->i_uid = di->di_uid; - ei->i_gid = di->di_gid; - /* XXX use memcpy */ - for(i = 0; i < NDADDR; i++) - ei->i_block[i] = di->di_db[i]; - for(i = 0; i < NIADDR; i++) - ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i]; -} diff --git a/sys/gnu/ext2fs/ext2_lookup.c b/sys/gnu/ext2fs/ext2_lookup.c deleted file mode 100644 index 79f30f2..0000000 --- a/sys/gnu/ext2fs/ext2_lookup.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/namei.h> -#include <sys/buf.h> -#include <sys/file.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/dirent.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/dir.h> -#include <ufs/ufs/ufsmount.h> - -#include <gnu/ext2fs/ext2_extern.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> - -/* - DIRBLKSIZE in ffs is DEV_BSIZE (in most cases 512) - while it is the native blocksize in ext2fs - thus, a #define - is no longer appropriate -*/ -#undef DIRBLKSIZ - -#if 1 -extern struct nchstats nchstats; -static int dirchk = 1; -#else -struct nchstats nchstats; -#if DIAGNOSTIC -int dirchk = 1; -#else -int dirchk = 0; -#endif -#endif - -/* - * the problem that is tackled below is the fact that FFS - * includes the terminating zero on disk while EXT2FS doesn't - * this implies that we need to introduce some padding. - * For instance, a filename "sbin" has normally a reclen 12 - * in EXT2, but 16 in FFS. - * This reminds me of that Pepsi commercial: 'Kid saved a lousy nine cents...' - * If it wasn't for that, the complete ufs code for directories would - * have worked w/o changes (except for the difference in DIRBLKSIZ) - */ -static void -ext2_dirconv2ffs( e2dir, ffsdir) - struct ext2_dir_entry *e2dir; - struct dirent *ffsdir; -{ - struct dirent de; - - bzero(&de, sizeof(struct dirent)); - de.d_fileno = e2dir->inode; - de.d_namlen = e2dir->name_len; - -#ifndef NO_HARDWIRED_CONSTANTS - if(e2dir->name_len + 8 == e2dir->rec_len) - de.d_reclen += 4; - - de.d_type = DT_UNKNOWN; /* don't know more here */ - strncpy(de.d_name, e2dir->name, e2dir->name_len); - de.d_name[de.d_namlen] = '\0'; - /* Godmar thinks: since e2dir->rec_len can be big and means - nothing anyway, we compute our own reclen according to what - we think is right - */ - de.d_reclen = (de.d_namlen+8+1+3) & ~3; - bcopy(&de, ffsdir, de.d_reclen); -#endif - -#if 0 - printf("dirconv: ino %d rec old %d rec new %d nam %d name %s\n", - ffsdir->d_fileno, e2dir->rec_len, ffsdir->d_reclen, - ffsdir->d_namlen, ffsdir->d_name); -#endif -} - -/* - * Vnode op for reading directories. - * - * The routine below assumes that the on-disk format of a directory - * is the same as that defined by <sys/dirent.h>. If the on-disk - * format changes, then it will be necessary to do a conversion - * from the on-disk format that read returns to the format defined - * by <sys/dirent.h>. - */ -/* - * this is exactly what we do here - the problem is that the conversion - * will blow up some entries by four bytes, so it can't be done in place. - * This is too bad. Right now the conversion is done entry by entry, the - * converted entry is sent via uiomove. - * - * XXX allocate a buffer, convert as many entries as possible, then send - * the whole buffer to uiomove - */ -int -ext2_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap; -{ - register struct uio *uio = ap->a_uio; - int count, lost, error; - - struct ext2_dir_entry *edp, *dp; - struct dirent dstdp; - struct uio auio; - struct iovec aiov; - caddr_t dirbuf; - int readcnt; - u_quad_t startoffset = uio->uio_offset; - u_char tmp; - int DIRBLKSIZ = VTOI(ap->a_vp)->i_e2fs->s_blocksize; - - count = uio->uio_resid; /* legyenek boldogok akik akarnak ... */ - uio->uio_resid = count; - uio->uio_iov->iov_len = count; - -#if 0 -printf("ext2_readdir called uio->uio_offset %d uio->uio_resid %d count %d \n", - (int)uio->uio_offset, (int)uio->uio_resid, (int)count); -#endif - - auio = *uio; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_segflg = UIO_SYSSPACE; - aiov.iov_len = count; - MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK); - aiov.iov_base = dirbuf; - error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred); - if (error == 0) { - readcnt = count - auio.uio_resid; - edp = (struct ext2_dir_entry *)&dirbuf[readcnt]; - for (dp = (struct ext2_dir_entry *)dirbuf; - !error && uio->uio_resid > 0 && dp < edp; ) { - ext2_dirconv2ffs(dp, &dstdp); - if (dp->rec_len > 0) { - if(dstdp.d_reclen <= uio->uio_resid) { - /* advance dp */ - dp = (struct ext2_dir_entry *) - ((char *)dp + dp->rec_len); - error = - uiomove(&dstdp, dstdp.d_reclen, uio); - } else - break; - } else { - error = EIO; - break; - } - } - /* we need to correct uio_offset */ - uio->uio_offset = startoffset + (caddr_t)dp - dirbuf; - } - FREE(dirbuf, M_TEMP); - return (error); -} - -/* - * Convert a component of a pathname into a pointer to a locked inode. - * This is a very central and rather complicated routine. - * If the file system is not maintained in a strict tree hierarchy, - * this can result in a deadlock situation (see comments in code below). - * - * The cnp->cn_nameiop argument is LOOKUP, CREATE, RENAME, or DELETE depending - * on whether the name is to be looked up, created, renamed, or deleted. - * When CREATE, RENAME, or DELETE is specified, information usable in - * creating, renaming, or deleting a directory entry may be calculated. - * If flag has LOCKPARENT or'ed into it and the target of the pathname - * exists, lookup returns both the target and its parent directory locked. - * When creating or renaming and LOCKPARENT is specified, the target may - * not be ".". When deleting and LOCKPARENT is specified, the target may - * be "."., but the caller must check to ensure it does an vrele and vput - * instead of two vputs. - * - * Overall outline of ufs_lookup: - * - * check accessibility of directory - * look for name in cache, if found, then if at end of path - * and deleting or creating, drop it, else return name - * search for name in directory, to found or notfound - * notfound: - * if creating, return locked directory, leaving info on available slots - * else return error - * found: - * if at end of path and deleting, return information to allow delete - * if at end of path and rewriting (RENAME and LOCKPARENT), lock target - * inode and return info to allow rewrite - * if not at end, add name to cache; if at end and neither creating - * nor deleting, add name to cache - */ -int -ext2_lookup(ap) - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; -{ - register struct vnode *vdp; /* vnode for directory being searched */ - register struct inode *dp; /* inode for directory being searched */ - struct buf *bp; /* a buffer of directory entries */ - register struct ext2_dir_entry *ep; /* the current directory entry */ - int entryoffsetinblock; /* offset of ep in bp's buffer */ - enum {NONE, COMPACT, FOUND} slotstatus; - doff_t slotoffset; /* offset of area with free space */ - int slotsize; /* size of area at slotoffset */ - int slotfreespace; /* amount of space free in slot */ - int slotneeded; /* size of the entry we're seeking */ - int numdirpasses; /* strategy for directory search */ - doff_t endsearch; /* offset to end directory search */ - doff_t prevoff; /* prev entry dp->i_offset */ - struct vnode *pdp; /* saved dp during symlink work */ - struct vnode *tdp; /* returned by VFS_VGET */ - doff_t enduseful; /* pointer past last used dir slot */ - u_long bmask; /* block offset mask */ - int lockparent; /* 1 => lockparent flag is set */ - int wantparent; /* 1 => wantparent or lockparent flag */ - int namlen, error; - struct vnode **vpp = ap->a_vpp; - struct componentname *cnp = ap->a_cnp; - struct ucred *cred = cnp->cn_cred; - int flags = cnp->cn_flags; - int nameiop = cnp->cn_nameiop; - - int DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize; - - bp = NULL; - slotoffset = -1; - *vpp = NULL; - vdp = ap->a_dvp; - dp = VTOI(vdp); - lockparent = flags & LOCKPARENT; - wantparent = flags & (LOCKPARENT|WANTPARENT); - - /* - * Check accessiblity of directory. - */ - if ((dp->i_mode & IFMT) != IFDIR) - return (ENOTDIR); - if (error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) - return (error); - - /* - * We now have a segment name to search for, and a directory to search. - * - * Before tediously performing a linear scan of the directory, - * check the name cache to see if the directory/name pair - * we are looking for is known already. - */ - if (error = cache_lookup(vdp, vpp, cnp)) { - int vpid; /* capability number of vnode */ - - if (error == ENOENT) - return (error); - /* - * Get the next vnode in the path. - * See comment below starting `Step through' for - * an explaination of the locking protocol. - */ - pdp = vdp; - dp = VTOI(*vpp); - vdp = *vpp; - vpid = vdp->v_id; - if (pdp == vdp) { /* lookup on "." */ - VREF(vdp); - error = 0; - } else if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); - error = vget(vdp, 1); - if (!error && lockparent && (flags & ISLASTCN)) - error = VOP_LOCK(pdp); - } else { - error = vget(vdp, 1); - if (!lockparent || error || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); - } - /* - * Check that the capability number did not change - * while we were waiting for the lock. - */ - if (!error) { - if (vpid == vdp->v_id) - return (0); - vput(vdp); - if (lockparent && pdp != vdp && (flags & ISLASTCN)) - VOP_UNLOCK(pdp); - } - if (error = VOP_LOCK(pdp)) - return (error); - vdp = pdp; - dp = VTOI(pdp); - *vpp = NULL; - } - - /* - * Suppress search for slots unless creating - * file and at end of pathname, in which case - * we watch for a place to put the new file in - * case it doesn't already exist. - */ - slotstatus = FOUND; - slotfreespace = slotsize = slotneeded = 0; - if ((nameiop == CREATE || nameiop == RENAME) && - (flags & ISLASTCN)) { - slotstatus = NONE; - slotneeded = EXT2_DIR_REC_LEN(cnp->cn_namelen); - /* was - slotneeded = (sizeof(struct direct) - MAXNAMLEN + - cnp->cn_namelen + 3) &~ 3; */ - } - - /* - * If there is cached information on a previous search of - * this directory, pick up where we last left off. - * We cache only lookups as these are the most common - * and have the greatest payoff. Caching CREATE has little - * benefit as it usually must search the entire directory - * to determine that the entry does not exist. Caching the - * location of the last DELETE or RENAME has not reduced - * profiling time and hence has been removed in the interest - * of simplicity. - */ - bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; - if (nameiop != LOOKUP || dp->i_diroff == 0 || - dp->i_diroff > dp->i_size) { - entryoffsetinblock = 0; - dp->i_offset = 0; - numdirpasses = 1; - } else { - dp->i_offset = dp->i_diroff; - if ((entryoffsetinblock = dp->i_offset & bmask) && - (error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp))) - return (error); - numdirpasses = 2; - nchstats.ncs_2passes++; - } - prevoff = dp->i_offset; - endsearch = roundup(dp->i_size, DIRBLKSIZ); - enduseful = 0; - -searchloop: - while (dp->i_offset < endsearch) { - /* - * If necessary, get the next directory block. - */ - if ((dp->i_offset & bmask) == 0) { - if (bp != NULL) - brelse(bp); - if (error = - VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) - return (error); - entryoffsetinblock = 0; - } - /* - * If still looking for a slot, and at a DIRBLKSIZE - * boundary, have to start looking for free space again. - */ - if (slotstatus == NONE && - (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) { - slotoffset = -1; - slotfreespace = 0; - } - /* - * Get pointer to next entry. - * Full validation checks are slow, so we only check - * enough to insure forward progress through the - * directory. Complete checks can be run by patching - * "dirchk" to be true. - */ - ep = (struct ext2_dir_entry *) - ((char *)bp->b_data + entryoffsetinblock); - if (ep->rec_len == 0 || - dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock)) { - int i; - ufs_dirbad(dp, dp->i_offset, "mangled entry"); - i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1)); - dp->i_offset += i; - entryoffsetinblock += i; - continue; - } - - /* - * If an appropriate sized slot has not yet been found, - * check to see if one is available. Also accumulate space - * in the current block so that we can determine if - * compaction is viable. - */ - if (slotstatus != FOUND) { - int size = ep->rec_len; - - if (ep->inode != 0) - size -= EXT2_DIR_REC_LEN(ep->name_len); - if (size > 0) { - if (size >= slotneeded) { - slotstatus = FOUND; - slotoffset = dp->i_offset; - slotsize = ep->rec_len; - } else if (slotstatus == NONE) { - slotfreespace += size; - if (slotoffset == -1) - slotoffset = dp->i_offset; - if (slotfreespace >= slotneeded) { - slotstatus = COMPACT; - slotsize = dp->i_offset + - ep->rec_len - slotoffset; - } - } - } - } - - /* - * Check for a name match. - */ - if (ep->inode) { - namlen = ep->name_len; - if (namlen == cnp->cn_namelen && - !bcmp(cnp->cn_nameptr, ep->name, - (unsigned)namlen)) { - /* - * Save directory entry's inode number and - * reclen in ndp->ni_ufs area, and release - * directory buffer. - */ - dp->i_ino = ep->inode; - dp->i_reclen = ep->rec_len; - brelse(bp); - goto found; - } - } - prevoff = dp->i_offset; - dp->i_offset += ep->rec_len; - entryoffsetinblock += ep->rec_len; - if (ep->inode) - enduseful = dp->i_offset; - } -/* notfound: */ - /* - * If we started in the middle of the directory and failed - * to find our target, we must check the beginning as well. - */ - if (numdirpasses == 2) { - numdirpasses--; - dp->i_offset = 0; - endsearch = dp->i_diroff; - goto searchloop; - } - if (bp != NULL) - brelse(bp); - /* - * If creating, and at end of pathname and current - * directory has not been removed, then can consider - * allowing file to be created. - */ - if ((nameiop == CREATE || nameiop == RENAME) && - (flags & ISLASTCN) && dp->i_nlink != 0) { - /* - * Access for write is interpreted as allowing - * creation of files in the directory. - */ - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Return an indication of where the new directory - * entry should be put. If we didn't find a slot, - * then set dp->i_count to 0 indicating - * that the new slot belongs at the end of the - * directory. If we found a slot, then the new entry - * can be put in the range from dp->i_offset to - * dp->i_offset + dp->i_count. - */ - if (slotstatus == NONE) { - dp->i_offset = roundup(dp->i_size, DIRBLKSIZ); - dp->i_count = 0; - enduseful = dp->i_offset; - } else { - dp->i_offset = slotoffset; - dp->i_count = slotsize; - if (enduseful < slotoffset + slotsize) - enduseful = slotoffset + slotsize; - } - dp->i_endoff = roundup(enduseful, DIRBLKSIZ); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - /* - * We return with the directory locked, so that - * the parameters we set up above will still be - * valid if we actually decide to do a direnter(). - * We return ni_vp == NULL to indicate that the entry - * does not currently exist; we leave a pointer to - * the (locked) directory inode in ndp->ni_dvp. - * The pathname buffer is saved so that the name - * can be obtained later. - * - * NB - if the directory is unlocked, then this - * information cannot be used. - */ - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(vdp); - return (EJUSTRETURN); - } - /* - * Insert name into cache (as non-existent) if appropriate. - */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) - cache_enter(vdp, *vpp, cnp); - return (ENOENT); - -found: - if (numdirpasses == 2) - nchstats.ncs_pass2++; - /* - * Check that directory length properly reflects presence - * of this entry. - */ - if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len) - > dp->i_size) { - ufs_dirbad(dp, dp->i_offset, "i_size too small"); - dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - } - - /* - * Found component in pathname. - * If the final component of path name, save information - * in the cache as to where the entry was found. - */ - if ((flags & ISLASTCN) && nameiop == LOOKUP) - dp->i_diroff = dp->i_offset &~ (DIRBLKSIZ - 1); - - /* - * If deleting, and at end of pathname, return - * parameters which can be used to remove file. - * If the wantparent flag isn't set, we return only - * the directory (in ndp->ni_dvp), otherwise we go - * on and lock the inode, being careful with ".". - */ - if (nameiop == DELETE && (flags & ISLASTCN)) { - /* - * Write access to directory required to delete files. - */ - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Return pointer to current entry in dp->i_offset, - * and distance past previous entry (if there - * is a previous entry in this block) in dp->i_count. - * Save directory inode pointer in ndp->ni_dvp for dirremove(). - */ - if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0) - dp->i_count = 0; - else - dp->i_count = dp->i_offset - prevoff; - if (dp->i_number == dp->i_ino) { - VREF(vdp); - *vpp = vdp; - return (0); - } - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - /* - * If directory is "sticky", then user must own - * the directory, or the file in it, else she - * may not delete it (unless she's root). This - * implements append-only directories. - */ - if ((dp->i_mode & ISVTX) && - cred->cr_uid != 0 && - cred->cr_uid != dp->i_uid && - VTOI(tdp)->i_uid != cred->cr_uid) { - vput(tdp); - return (EPERM); - } - *vpp = tdp; - if (!lockparent) - VOP_UNLOCK(vdp); - return (0); - } - - /* - * If rewriting (RENAME), return the inode and the - * information required to rewrite the present directory - * Must get inode of directory entry to verify it's a - * regular file, or empty directory. - */ - if (nameiop == RENAME && wantparent && - (flags & ISLASTCN)) { - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Careful about locking second inode. - * This can only occur if the target is ".". - */ - if (dp->i_number == dp->i_ino) - return (EISDIR); - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - *vpp = tdp; - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(vdp); - return (0); - } - - /* - * Step through the translation in the name. We do not `vput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the VFS_VGET for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - pdp = vdp; - if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) { - VOP_LOCK(pdp); - return (error); - } - if (lockparent && (flags & ISLASTCN) && - (error = VOP_LOCK(pdp))) { - vput(tdp); - return (error); - } - *vpp = tdp; - } else if (dp->i_number == dp->i_ino) { - VREF(vdp); /* we want ourself, ie "." */ - *vpp = vdp; - } else { - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - if (!lockparent || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); - *vpp = tdp; - } - - /* - * Insert name into cache if appropriate. - */ - if (cnp->cn_flags & MAKEENTRY) - cache_enter(vdp, *vpp, cnp); - return (0); -} - -/* - * Do consistency checking on a directory entry: - * record length must be multiple of 4 - * entry must fit in rest of its DIRBLKSIZ block - * record must be large enough to contain entry - * name is not longer than MAXNAMLEN - * name must be as long as advertised, and null terminated - */ -/* - * changed so that it confirms to ext2_check_dir_entry - */ -int -ext2_dirbadentry(dp, de, entryoffsetinblock) - struct vnode *dp; - register struct ext2_dir_entry *de; - int entryoffsetinblock; -{ - register int i; - int namlen; - int DIRBLKSIZ = VTOI(dp)->i_e2fs->s_blocksize; - - char * error_msg = NULL; - - if (de->rec_len < EXT2_DIR_REC_LEN(1)) - error_msg = "rec_len is smaller than minimal"; - else if (de->rec_len % 4 != 0) - error_msg = "rec_len % 4 != 0"; - else if (de->rec_len < EXT2_DIR_REC_LEN(de->name_len)) - error_msg = "reclen is too small for name_len"; - else if (entryoffsetinblock + de->rec_len > DIRBLKSIZ) - error_msg = "directory entry across blocks"; - /* else LATER - if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) - error_msg = "inode out of bounds"; - */ - - if (error_msg != NULL) - printf( "bad directory entry: %s\n" - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d \n", - error_msg, entryoffsetinblock, - (unsigned long) de->inode, de->rec_len, de->name_len); - return error_msg == NULL ? 0 : 1; -} - -/* - * Write a directory entry after a call to namei, using the parameters - * that it left in nameidata. The argument ip is the inode which the new - * directory entry will refer to. Dvp is a pointer to the directory to - * be written, which was left locked by namei. Remaining parameters - * (dp->i_offset, dp->i_count) indicate how the space for the new - * entry is to be obtained. - */ -int -ext2_direnter(ip, dvp, cnp) - struct inode *ip; - struct vnode *dvp; - register struct componentname *cnp; -{ - register struct ext2_dir_entry *ep, *nep; - register struct inode *dp; - struct buf *bp; - struct ext2_dir_entry newdir; - struct iovec aiov; - struct uio auio; - u_int dsize; - int error, loc, newentrysize, spacefree; - char *dirbuf; - int DIRBLKSIZ = ip->i_e2fs->s_blocksize; - - -#if DIAGNOSTIC - if ((cnp->cn_flags & SAVENAME) == 0) - panic("direnter: missing name"); -#endif - dp = VTOI(dvp); - newdir.inode = ip->i_number; - newdir.name_len = cnp->cn_namelen; - bcopy(cnp->cn_nameptr, newdir.name, (unsigned)cnp->cn_namelen + 1); - newentrysize = EXT2_DIR_REC_LEN(newdir.name_len); - if (dp->i_count == 0) { - /* - * If dp->i_count is 0, then namei could find no - * space in the directory. Here, dp->i_offset will - * be on a directory block boundary and we will write the - * new entry into a fresh block. - */ - if (dp->i_offset & (DIRBLKSIZ - 1)) - panic("ext2_direnter: newblk"); - auio.uio_offset = dp->i_offset; - newdir.rec_len = DIRBLKSIZ; - auio.uio_resid = newentrysize; - aiov.iov_len = newentrysize; - aiov.iov_base = (caddr_t)&newdir; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_rw = UIO_WRITE; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_procp = (struct proc *)0; - error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred); - if (DIRBLKSIZ > - VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize) - /* XXX should grow with balloc() */ - panic("ext2_direnter: frag size"); - else if (!error) { - dp->i_size = roundup(dp->i_size, DIRBLKSIZ); - dp->i_flag |= IN_CHANGE; - } - return (error); - } - - /* - * If dp->i_count is non-zero, then namei found space - * for the new entry in the range dp->i_offset to - * dp->i_offset + dp->i_count in the directory. - * To use this space, we may have to compact the entries located - * there, by copying them together towards the beginning of the - * block, leaving the free space in one usable chunk at the end. - */ - - /* - * Increase size of directory if entry eats into new space. - * This should never push the size past a new multiple of - * DIRBLKSIZE. - * - * N.B. - THIS IS AN ARTIFACT OF 4.2 AND SHOULD NEVER HAPPEN. - */ - if (dp->i_offset + dp->i_count > dp->i_size) - dp->i_size = dp->i_offset + dp->i_count; - /* - * Get the block containing the space for the new directory entry. - */ - if (error = VOP_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) - return (error); - /* - * Find space for the new entry. In the simple case, the entry at - * offset base will have the space. If it does not, then namei - * arranged that compacting the region dp->i_offset to - * dp->i_offset + dp->i_count would yield the - * space. - */ - ep = (struct ext2_dir_entry *)dirbuf; - dsize = EXT2_DIR_REC_LEN(ep->name_len); - spacefree = ep->rec_len - dsize; - for (loc = ep->rec_len; loc < dp->i_count; ) { - nep = (struct ext2_dir_entry *)(dirbuf + loc); - if (ep->inode) { - /* trim the existing slot */ - ep->rec_len = dsize; - ep = (struct ext2_dir_entry *)((char *)ep + dsize); - } else { - /* overwrite; nothing there; header is ours */ - spacefree += dsize; - } - dsize = EXT2_DIR_REC_LEN(ep->name_len); - spacefree += nep->rec_len - dsize; - loc += nep->rec_len; - bcopy((caddr_t)nep, (caddr_t)ep, dsize); - } - /* - * Update the pointer fields in the previous entry (if any), - * copy in the new entry, and write out the block. - */ - if (ep->inode == 0) { - if (spacefree + dsize < newentrysize) - panic("ext2_direnter: compact1"); - newdir.rec_len = spacefree + dsize; - } else { - if (spacefree < newentrysize) - panic("ext2_direnter: compact2"); - newdir.rec_len = spacefree; - ep->rec_len = dsize; - ep = (struct ext2_dir_entry *)((char *)ep + dsize); - } - bcopy((caddr_t)&newdir, (caddr_t)ep, (u_int)newentrysize); - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - if (!error && dp->i_endoff && dp->i_endoff < dp->i_size) - error = VOP_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC, - cnp->cn_cred, cnp->cn_proc); - return (error); -} - -/* - * Remove a directory entry after a call to namei, using - * the parameters which it left in nameidata. The entry - * dp->i_offset contains the offset into the directory of the - * entry to be eliminated. The dp->i_count field contains the - * size of the previous record in the directory. If this - * is 0, the first entry is being deleted, so we need only - * zero the inode number to mark the entry as free. If the - * entry is not the first in the directory, we must reclaim - * the space of the now empty record by adding the record size - * to the size of the previous entry. - */ -int -ext2_dirremove(dvp, cnp) - struct vnode *dvp; - struct componentname *cnp; -{ - register struct inode *dp; - struct ext2_dir_entry *ep; - struct buf *bp; - int error; - int DIRBLKSIZ = VTOI(dvp)->i_e2fs->s_blocksize; - - dp = VTOI(dvp); - if (dp->i_count == 0) { - /* - * First entry in block: set d_ino to zero. - */ - if (error = - VOP_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) - return (error); - ep->inode = 0; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); - } - /* - * Collapse new free space into previous entry. - */ - if (error = VOP_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count), - (char **)&ep, &bp)) - return (error); - ep->rec_len += dp->i_reclen; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); -} - -/* - * Rewrite an existing directory entry to point at the inode - * supplied. The parameters describing the directory entry are - * set up by a call to namei. - */ -int -ext2_dirrewrite(dp, ip, cnp) - struct inode *dp, *ip; - struct componentname *cnp; -{ - struct buf *bp; - struct ext2_dir_entry *ep; - struct vnode *vdp = ITOV(dp); - int error; - - if (error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) - return (error); - ep->inode = ip->i_number; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); -} - -/* - * Check if a directory is empty or not. - * Inode supplied must be locked. - * - * Using a struct dirtemplate here is not precisely - * what we want, but better than using a struct direct. - * - * NB: does not handle corrupted directories. - */ -int -ext2_dirempty(ip, parentino, cred) - register struct inode *ip; - ino_t parentino; - struct ucred *cred; -{ - register off_t off; - struct dirtemplate dbuf; - register struct ext2_dir_entry *dp = (struct ext2_dir_entry *)&dbuf; - int error, count, namlen; - int DIRBLKSIZ = ip->i_e2fs->s_blocksize; - -#define MINDIRSIZ (sizeof (struct dirtemplate) / 2) - - for (off = 0; off < ip->i_size; off += dp->rec_len) { - error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off, - UIO_SYSSPACE, IO_NODELOCKED, cred, &count, (struct proc *)0); - /* - * Since we read MINDIRSIZ, residual must - * be 0 unless we're at end of file. - */ - if (error || count != 0) - return (0); - /* avoid infinite loops */ - if (dp->rec_len == 0) - return (0); - /* skip empty entries */ - if (dp->inode == 0) - continue; - /* accept only "." and ".." */ - namlen = dp->name_len; - if (namlen > 2) - return (0); - if (dp->name[0] != '.') - return (0); - /* - * At this point namlen must be 1 or 2. - * 1 implies ".", 2 implies ".." if second - * char is also "." - */ - if (namlen == 1) - continue; - if (dp->name[1] == '.' && dp->inode == parentino) - continue; - return (0); - } - return (1); -} - -/* - * Check if source directory is in the path of the target directory. - * Target is supplied locked, source is unlocked. - * The target is always vput before returning. - */ -int -ext2_checkpath(source, target, cred) - struct inode *source, *target; - struct ucred *cred; -{ - struct vnode *vp; - int error, rootino, namlen; - struct dirtemplate dirbuf; - - vp = ITOV(target); - if (target->i_number == source->i_number) { - error = EEXIST; - goto out; - } - rootino = ROOTINO; - error = 0; - if (target->i_number == rootino) - goto out; - - for (;;) { - if (vp->v_type != VDIR) { - error = ENOTDIR; - break; - } - error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf, - sizeof (struct dirtemplate), (off_t)0, UIO_SYSSPACE, - IO_NODELOCKED, cred, (int *)0, (struct proc *)0); - if (error != 0) - break; - namlen = dirbuf.dotdot_namlen; - if (namlen != 2 || - dirbuf.dotdot_name[0] != '.' || - dirbuf.dotdot_name[1] != '.') { - error = ENOTDIR; - break; - } - if (dirbuf.dotdot_ino == source->i_number) { - error = EINVAL; - break; - } - if (dirbuf.dotdot_ino == rootino) - break; - vput(vp); - if (error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp)) { - vp = NULL; - break; - } - } - -out: - if (error == ENOTDIR) - printf("checkpath: .. not a directory\n"); - if (vp != NULL) - vput(vp); - return (error); -} - diff --git a/sys/gnu/ext2fs/ext2_mount.h b/sys/gnu/ext2fs/ext2_mount.h deleted file mode 100644 index 02fdff2..0000000 --- a/sys/gnu/ext2fs/ext2_mount.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufsmount.h 8.2 (Berkeley) 1/12/94 - * $Id: ufsmount.h,v 1.2 1994/08/02 07:55:04 davidg Exp $ - */ - -#ifndef _UFS_UFS_UFSMOUNT_H_ -#define _UFS_UFS_UFSMOUNT_H_ - -struct buf; -struct inode; -struct nameidata; -struct timeval; -struct ucred; -struct uio; -struct vnode; -struct netexport; - -/* This structure describes the UFS specific mount structure data. */ -struct ufsmount { - struct mount *um_mountp; /* filesystem vfs structure */ - dev_t um_dev; /* device mounted */ - struct vnode *um_devvp; /* block device mounted vnode */ - union { /* pointer to superblock */ - struct lfs *lfs; /* LFS */ - struct fs *fs; /* FFS */ - } ufsmount_u; -#define um_fs ufsmount_u.fs -#define um_lfs ufsmount_u.lfs - struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */ - struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */ - u_long um_nindir; /* indirect ptrs per block */ - u_long um_bptrtodb; /* indir ptr to disk block */ - u_long um_seqinc; /* inc between seq blocks */ - time_t um_btime[MAXQUOTAS]; /* block quota time limit */ - time_t um_itime[MAXQUOTAS]; /* inode quota time limit */ - char um_qflags[MAXQUOTAS]; /* quota specific flags */ - struct netexport um_export; /* export information */ -}; -/* - * Flags describing the state of quotas. - */ -#define QTF_OPENING 0x01 /* Q_QUOTAON in progress */ -#define QTF_CLOSING 0x02 /* Q_QUOTAOFF in progress */ - -/* Convert mount ptr to ufsmount ptr. */ -#define VFSTOUFS(mp) ((struct ufsmount *)((mp)->mnt_data)) - -/* - * Macros to access file system parameters in the ufsmount structure. - * Used by ufs_bmap. - */ -#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb) -#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc) -#define MNINDIR(ump) ((ump)->um_nindir) - -#endif diff --git a/sys/gnu/ext2fs/ext2_readwrite.c b/sys/gnu/ext2fs/ext2_readwrite.c deleted file mode 100644 index be01831..0000000 --- a/sys/gnu/ext2fs/ext2_readwrite.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_readwrite.c 8.7 (Berkeley) 1/21/94 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#define BLKSIZE(a, b, c) blksize(a, b, c) -#define FS struct ext2_sb_info -#define I_FS i_e2fs -#define READ ext2_read -#define READ_S "ext2_read" -#define WRITE ext2_write -#define WRITE_S "ext2_write" - -/* - * Vnode op for reading. - */ -/* ARGSUSED */ -int -READ(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp; - register struct inode *ip; - register struct uio *uio; - register FS *fs; - struct buf *bp; - daddr_t lbn, nextlbn; - off_t bytesinfile; - long size, xfersize, blkoffset; - int error; - u_short mode; - - vp = ap->a_vp; - ip = VTOI(vp); - mode = ip->i_mode; - uio = ap->a_uio; - -#if DIAGNOSTIC - if (uio->uio_rw != UIO_READ) - panic("%s: mode", READ_S); - - if (vp->v_type == VLNK) { - if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen) - panic("%s: short symlink", READ_S); - } else if (vp->v_type != VREG && vp->v_type != VDIR) - panic("%s: type %d", READ_S, vp->v_type); -#endif - fs = ip->I_FS; -#if 0 - if ((u_quad_t)uio->uio_offset > fs->fs_maxfilesize) - return (EFBIG); -#endif - - for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { - if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0) - break; - lbn = lblkno(fs, uio->uio_offset); - nextlbn = lbn + 1; - size = BLKSIZE(fs, ip, lbn); - blkoffset = blkoff(fs, uio->uio_offset); - xfersize = fs->s_frag_size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - if (bytesinfile < xfersize) - xfersize = bytesinfile; - - if (lblktosize(fs, nextlbn) > ip->i_size) - error = bread(vp, lbn, size, NOCRED, &bp); - else if (doclusterread) - error = cluster_read(vp, - ip->i_size, lbn, size, NOCRED, &bp); - else if (lbn - 1 == vp->v_lastr) { - int nextsize = BLKSIZE(fs, ip, nextlbn); - error = breadn(vp, lbn, - size, &nextlbn, &nextsize, 1, NOCRED, &bp); - } else - error = bread(vp, lbn, size, NOCRED, &bp); - if (error) - break; - vp->v_lastr = lbn; - - /* - * We should only get non-zero b_resid when an I/O error - * has occurred, which should cause us to break above. - * However, if the short read did not cause an error, - * then we want to ensure that we do not uiomove bad - * or uninitialized data. - */ - size -= bp->b_resid; - if (size < xfersize) { - if (size == 0) - break; - xfersize = size; - } - if (error = - uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio)) - break; - -#if !defined(__FreeBSD__) - if (S_ISREG(mode) && (xfersize + blkoffset == fs->s_frag_size || - uio->uio_offset == ip->i_size)) - bp->b_flags |= B_AGE; -#endif - brelse(bp); - } - if (bp != NULL) - brelse(bp); - ip->i_flag |= IN_ACCESS; - return (error); -} - -/* - * Vnode op for writing. - */ -int -WRITE(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp; - register struct uio *uio; - register struct inode *ip; - register FS *fs; - struct buf *bp; - struct proc *p; - daddr_t lbn; - off_t osize; - int blkoffset, error, flags, ioflag, resid, size, xfersize; - - ioflag = ap->a_ioflag; - uio = ap->a_uio; - vp = ap->a_vp; - ip = VTOI(vp); - -#if DIAGNOSTIC - if (uio->uio_rw != UIO_WRITE) - panic("%s: mode", WRITE_S); -#endif - - switch (vp->v_type) { - case VREG: - if (ioflag & IO_APPEND) - uio->uio_offset = ip->i_size; - if ((ip->i_flags & APPEND) && uio->uio_offset != ip->i_size) - return (EPERM); - /* FALLTHROUGH */ - case VLNK: - break; - case VDIR: - if ((ioflag & IO_SYNC) == 0) - panic("%s: nonsync dir write", WRITE_S); - break; - default: - panic("%s: type", WRITE_S); - } - - fs = ip->I_FS; -#if 0 - if (uio->uio_offset < 0 || - (u_quad_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize) - return (EFBIG); -#endif - /* - * Maybe this should be above the vnode op call, but so long as - * file servers have no limits, I don't think it matters. - */ - p = uio->uio_procp; - if (vp->v_type == VREG && p && - uio->uio_offset + uio->uio_resid > - p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { - psignal(p, SIGXFSZ); - return (EFBIG); - } - - resid = uio->uio_resid; - osize = ip->i_size; - flags = ioflag & IO_SYNC ? B_SYNC : 0; - - for (error = 0; uio->uio_resid > 0;) { - lbn = lblkno(fs, uio->uio_offset); - blkoffset = blkoff(fs, uio->uio_offset); - xfersize = fs->s_frag_size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - -#if defined(__FreeBSD__) - if (uio->uio_offset + xfersize > ip->i_size) - vnode_pager_setsize(vp, (u_long)uio->uio_offset + xfersize); -#endif - - if (fs->s_frag_size > xfersize) - flags |= B_CLRBUF; - else - flags &= ~B_CLRBUF; - - error = ext2_balloc(ip, - lbn, blkoffset + xfersize, ap->a_cred, &bp, flags); - - if (error) - break; - if (uio->uio_offset + xfersize > ip->i_size) { - ip->i_size = uio->uio_offset + xfersize; -#if !defined(__FreeBSD__) - vnode_pager_setsize(vp, (u_long)ip->i_size); -#endif - } -#if !defined(__FreeBSD__) - (void)vnode_pager_uncache(vp); -#endif - - size = BLKSIZE(fs, ip, lbn) - bp->b_resid; - if (size < xfersize) - xfersize = size; - - error = - uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); - - if (ioflag & IO_SYNC) - (void)bwrite(bp); - else if (xfersize + blkoffset == fs->s_frag_size) { - if (doclusterwrite) { -#if defined(__FreeBSD__) - bp->b_flags |= B_CLUSTEROK; -#endif - cluster_write(bp, ip->i_size); - } else { -#if !defined(__FreeBSD__) - bp->b_flags |= B_AGE; -#endif - bawrite(bp); - } - } else { -#if defined(__FreeBSD__) - bp->b_flags |= B_CLUSTEROK; -#endif - bdwrite(bp); - } - - if (error || xfersize == 0) - break; - ip->i_flag |= IN_CHANGE | IN_UPDATE; - } - /* - * If we successfully wrote any data, and we are not the superuser - * we clear the setuid and setgid bits as a precaution against - * tampering. - */ - if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0) - ip->i_mode &= ~(ISUID | ISGID); - if (error) { - if (ioflag & IO_UNIT) { - (void)VOP_TRUNCATE(vp, osize, - ioflag & IO_SYNC, ap->a_cred, uio->uio_procp); - uio->uio_offset -= resid - uio->uio_resid; - uio->uio_resid = resid; - } - } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { - struct timeval tv; -#if !defined(__FreeBSD__) - get_time(&tv); -#else - tv = time; -#endif - error = VOP_UPDATE(vp, &tv, &tv, 1); - } - return (error); -} diff --git a/sys/gnu/ext2fs/ext2_subr.c b/sys/gnu/ext2fs/ext2_subr.c deleted file mode 100644 index c27abe5..0000000 --- a/sys/gnu/ext2fs/ext2_subr.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_subr.c 8.2 (Berkeley) 9/21/93 - */ - -#include <sys/param.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> - -#include <sys/systm.h> -#include <sys/vnode.h> -#include <gnu/ext2fs/ext2_extern.h> -#include <sys/buf.h> -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -/* - * Return buffer with the contents of block "offset" from the beginning of - * directory "ip". If "res" is non-zero, fill it in with a pointer to the - * remaining space in the directory. - */ -int -ext2_blkatoff(ap) - struct vop_blkatoff_args /* { - struct vnode *a_vp; - off_t a_offset; - char **a_res; - struct buf **a_bpp; - } */ *ap; -{ - struct inode *ip; - register struct ext2_sb_info *fs; - struct buf *bp; - daddr_t lbn; - int bsize, error; - - ip = VTOI(ap->a_vp); - fs = ip->i_e2fs; - lbn = lblkno(fs, ap->a_offset); - bsize = blksize(fs, ip, lbn); - - *ap->a_bpp = NULL; - if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { - brelse(bp); - return (error); - } - if (ap->a_res) - *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset); - *ap->a_bpp = bp; - return (0); -} - -#if defined(KERNEL) && defined(DIAGNOSTIC) -void -ext2_checkoverlap(bp, ip) - struct buf *bp; - struct inode *ip; -{ - register struct buf *ebp, *ep; - register daddr_t start, last; - struct vnode *vp; - - ebp = &buf[nbuf]; - start = bp->b_blkno; - last = start + btodb(bp->b_bcount) - 1; - for (ep = buf; ep < ebp; ep++) { - if (ep == bp || (ep->b_flags & B_INVAL) || - ep->b_vp == NULLVP) - continue; -#if !defined(__FreeBSD__) - if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL)) - continue; -#else - if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL, NULL)) - continue; -#endif - if (vp != ip->i_devvp) - continue; - /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) - continue; - vprint("Disk overlap", vp); - (void)printf("\tstart %d, end %d overlap start %d, end %d\n", - start, last, ep->b_blkno, - ep->b_blkno + btodb(ep->b_bcount) - 1); - panic("Disk buffer overlap"); - } -} -#endif /* DIAGNOSTIC */ - diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c deleted file mode 100644 index 596eb35..0000000 --- a/sys/gnu/ext2fs/ext2_vfsops.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1989, 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/namei.h> -#include <sys/proc.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/socket.h> -#include <sys/mount.h> -#include <sys/buf.h> -#include <sys/mbuf.h> -#include <sys/file.h> -#include <sys/disklabel.h> -#include <sys/ioctl.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/stat.h> - -#include <miscfs/specfs/specdev.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> - -int ext2_sbupdate __P((struct ufsmount *, int)); - -struct vfsops ext2fs_vfsops = { - ext2_mount, - ufs_start, /* empty function */ - ext2_unmount, - ufs_root, /* root inode via vget */ - ufs_quotactl, /* does operations associated with quotas */ - ext2_statfs, - ext2_sync, - ext2_vget, - ext2_fhtovp, - ext2_vptofh, - ext2_init, -}; - -#if defined(__FreeBSD__) -VFS_SET(ext2fs_vfsops, ext2fs, MOUNT_EXT2FS, 0); -#define bsd_malloc malloc -#define bsd_free free -#endif - -extern u_long nextgennumber; - -/* - * Called by main() when ufs is going to be mounted as root. - * - * Name is updated by mount(8) after booting. - */ -#define ROOTNAME "root_device" - -int -ext2_mountroot() -{ -#if !defined(__FreeBSD__) - extern struct vnode *rootvp; -#endif - register struct ext2_sb_info *fs; - register struct mount *mp; -#if defined(__FreeBSD__) - struct proc *p = curproc; -#else - struct proc *p = get_proc(); /* XXX */ -#endif - struct ufsmount *ump; - u_int size; - int error; - - /* - * Get vnodes for swapdev and rootdev. - */ - if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) - panic("ext2_mountroot: can't setup bdevvp's"); - - mp = bsd_malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - mp->mnt_op = &ext2fs_vfsops; - mp->mnt_flag = MNT_RDONLY; - if (error = ext2_mountfs(rootvp, mp, p)) { - bsd_free(mp, M_MOUNT); - return (error); - } - if (error = vfs_lock(mp)) { - (void)ext2_unmount(mp, 0, p); - bsd_free(mp, M_MOUNT); - return (error); - } -#if defined(__FreeBSD__) - CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); -#else - TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); -#endif - mp->mnt_flag |= MNT_ROOTFS; - mp->mnt_vnodecovered = NULLVP; - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); - fs->fs_fsmnt[0] = '/'; - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ext2_statfs(mp, &mp->mnt_stat, p); - vfs_unlock(mp); - inittodr(fs->s_es->s_wtime); /* this helps to set the time */ - return (0); -} - -/* - * VFS Operations. - * - * mount system call - */ -int -ext2_mount(mp, path, data, ndp, p) - register struct mount *mp; - char *path; - caddr_t data; /* this is actually a (struct ufs_args *) */ - struct nameidata *ndp; - struct proc *p; -{ - struct vnode *devvp; - struct ufs_args args; - struct ufsmount *ump = 0; - register struct ext2_sb_info *fs; - u_int size; - int error, flags; - - if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) - return (error); - /* - * If updating, check whether changing from read-only to - * read/write; if there is no device name, that's all we do. - */ - if (mp->mnt_flag & MNT_UPDATE) { - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - error = 0; - if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) { - flags = WRITECLOSE; - if (mp->mnt_flag & MNT_FORCE) - flags |= FORCECLOSE; - if (vfs_busy(mp)) - return (EBUSY); - error = ext2_flushfiles(mp, flags, p); - vfs_unbusy(mp); - } - if (!error && (mp->mnt_flag & MNT_RELOAD)) - error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p); - if (error) - return (error); - if (fs->s_rd_only && (mp->mnt_flag & MNT_WANTRDWR)) - fs->s_rd_only = 0; - if (fs->s_rd_only == 0) { - /* don't say it's clean */ - fs->s_es->s_state &= ~EXT2_VALID_FS; - ext2_sbupdate(ump, MNT_WAIT); - } - if (args.fspec == 0) { - /* - * Process export requests. - */ - return (vfs_export(mp, &ump->um_export, &args.export)); - } - } - /* - * Not an update, or updating the name: look up the name - * and verify that it refers to a sensible block device. - */ - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - if (error = namei(ndp)) - return (error); - devvp = ndp->ni_vp; - - if (devvp->v_type != VBLK) { - vrele(devvp); - return (ENOTBLK); - } - if (major(devvp->v_rdev) >= nblkdev) { - vrele(devvp); - return (ENXIO); - } - if ((mp->mnt_flag & MNT_UPDATE) == 0) - error = ext2_mountfs(devvp, mp, p); - else { - if (devvp != ump->um_devvp) - error = EINVAL; /* needs translation */ - else - vrele(devvp); - } - if (error) { - vrele(devvp); - return (error); - } - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); - bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ext2_statfs(mp, &mp->mnt_stat, p); - return (0); -} - -/* - * checks that the data in the descriptor blocks make sense - * this is taken from ext2/super.c - */ -static int ext2_check_descriptors (struct ext2_sb_info * sb) -{ - int i; - int desc_block = 0; - unsigned long block = sb->s_es->s_first_data_block; - struct ext2_group_desc * gdp = NULL; - - /* ext2_debug ("Checking group descriptors"); */ - - for (i = 0; i < sb->s_groups_count; i++) - { - /* examine next descriptor block */ - if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext2_group_desc *) - sb->s_group_desc[desc_block++]->b_data; - if (gdp->bg_block_bitmap < block || - gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Block bitmap for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_block_bitmap); - return 0; - } - if (gdp->bg_inode_bitmap < block || - gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode bitmap for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_inode_bitmap); - return 0; - } - if (gdp->bg_inode_table < block || - gdp->bg_inode_table + sb->s_itb_per_group >= - block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode table for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_inode_table); - return 0; - } - block += EXT2_BLOCKS_PER_GROUP(sb); - gdp++; - } - return 1; -} - -/* - * this computes the fields of the ext2_sb_info structure from the - * data in the ext2_super_block structure read in - */ -static int compute_sb_data(devvp, es, fs) - struct vnode * devvp; - struct ext2_super_block * es; - struct ext2_sb_info * fs; -{ - int db_count, error; - int i, j; - int logic_sb_block = 1; /* XXX for now */ - -#if 1 -#define V(v) -#else -#define V(v) printf(#v"= %d\n", fs->v); -#endif - - fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; - V(s_blocksize) - fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; - V(s_bshift) - fs->s_fsbtodb = es->s_log_block_size + 1; - V(s_fsbtodb) - fs->s_qbmask = fs->s_blocksize - 1; - V(s_bmask) - fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); - V(s_blocksize_bits) - fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; - V(s_frag_size) - if (fs->s_frag_size) - fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; - V(s_frags_per_block) - fs->s_blocks_per_group = es->s_blocks_per_group; - V(s_blocks_per_group) - fs->s_frags_per_group = es->s_frags_per_group; - V(s_frags_per_group) - fs->s_inodes_per_group = es->s_inodes_per_group; - V(s_inodes_per_group) - fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE; - V(s_inodes_per_block) - fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; - V(s_itb_per_group) - fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); - V(s_desc_per_block) - /* s_resuid / s_resgid ? */ - fs->s_groups_count = (es->s_blocks_count - - es->s_first_data_block + - EXT2_BLOCKS_PER_GROUP(fs) - 1) / - EXT2_BLOCKS_PER_GROUP(fs); - V(s_groups_count) - db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / - EXT2_DESC_PER_BLOCK(fs); - fs->s_db_per_group = db_count; - V(s_db_per_group) - - fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), - M_UFSMNT, M_WAITOK); - - /* adjust logic_sb_block */ - if(fs->s_blocksize > SBSIZE) - /* Godmar thinks: if the blocksize is greater than 1024, then - the superblock is logically part of block zero. - */ - logic_sb_block = 0; - - for (i = 0; i < db_count; i++) { - error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), - fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); - if(error) { - for (j = 0; j < i; j++) - brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_UFSMNT); - printf("EXT2-fs: unable to read group descriptors (%d)\n", error); - return EIO; - } - } - if(!ext2_check_descriptors(fs)) { - for (j = 0; j < db_count; j++) - brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_UFSMNT); - printf("EXT2-fs: (ext2_check_descriptors failure) " - "unable to read group descriptors\n"); - return EIO; - } - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { - fs->s_inode_bitmap_number[i] = 0; - fs->s_inode_bitmap[i] = NULL; - fs->s_block_bitmap_number[i] = 0; - fs->s_block_bitmap[i] = NULL; - } - fs->s_loaded_inode_bitmaps = 0; - fs->s_loaded_block_bitmaps = 0; - return 0; -} - -/* - * Reload all incore data for a filesystem (used after running fsck on - * the root filesystem and finding things to fix). The filesystem must - * be mounted read-only. - * - * Things to do to update the mount: - * 1) invalidate all cached meta-data. - * 2) re-read superblock from disk. - * 3) re-read summary information from disk. - * 4) invalidate all inactive vnodes. - * 5) invalidate all cached file data. - * 6) re-read inode data for all active vnodes. - */ -int -ext2_reload(mountp, cred, p) - register struct mount *mountp; - struct ucred *cred; - struct proc *p; -{ - register struct vnode *vp, *nvp, *devvp; - struct inode *ip; - struct buf *bp; - struct ext2_super_block * es; - struct ext2_sb_info *fs; - int i, size, error; - - if ((mountp->mnt_flag & MNT_RDONLY) == 0) - return (EINVAL); - /* - * Step 1: invalidate all cached meta-data. - */ - devvp = VFSTOUFS(mountp)->um_devvp; - if (vinvalbuf(devvp, 0, cred, p, 0, 0)) - panic("ext2_reload: dirty1"); - /* - * Step 2: re-read superblock from disk. - * constants have been adjusted for ext2 - */ - if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) - return (error); - es = (struct ext2_super_block *)bp->b_data; - if (es->s_magic != EXT2_SUPER_MAGIC) { - if(es->s_magic == EXT2_PRE_02B_MAGIC) - printf("This filesystem bears the magic number of a pre " - "0.2b version of ext2. This is not supported by " - "Lites.\n"); - else - printf("Wrong magic number: %x (expected %x for ext2 fs\n", - es->s_magic, EXT2_SUPER_MAGIC); - brelse(bp); - return (EIO); /* XXX needs translation */ - } - fs = VFSTOUFS(mountp)->um_e2fs; - bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block)); - - if(error = compute_sb_data(devvp, es, fs)) { - brelse(bp); - return error; - } -#ifdef UNKLAR - if (fs->fs_sbsize < SBSIZE) - bp->b_flags |= B_INVAL; -#endif - brelse(bp); - -loop: - for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { - nvp = vp->v_mntvnodes.le_next; - /* - * Step 4: invalidate all inactive vnodes. - */ - if (vp->v_usecount == 0) { - vgone(vp); - continue; - } - /* - * Step 5: invalidate all cached file data. - */ - if (vget(vp, 1)) - goto loop; - if (vinvalbuf(vp, 0, cred, p, 0, 0)) - panic("ext2_reload: dirty2"); - /* - * Step 6: re-read inode data for all active vnodes. - */ - ip = VTOI(vp); - if (error = - bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), - (int)fs->s_blocksize, NOCRED, &bp)) { - vput(vp); - return (error); - } - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + - EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), - &ip->i_din); - brelse(bp); - vput(vp); - if (vp->v_mount != mountp) - goto loop; - } - return (0); -} - -/* - * Common code for mount and mountroot - */ -int -ext2_mountfs(devvp, mp, p) - register struct vnode *devvp; - struct mount *mp; - struct proc *p; -{ - register struct ufsmount *ump; - struct buf *bp; - register struct ext2_sb_info *fs; - struct ext2_super_block * es; - dev_t dev = devvp->v_rdev; - struct partinfo dpart; - caddr_t base; - int havepart = 0; - int error, i, size; - int ronly; -#if !defined(__FreeBSD__) - extern struct vnode *rootvp; -#endif - - /* - * Disallow multiple mounts of the same device. - * Disallow mounting of a device that is currently in use - * (except for root, which might share swap device for miniroot). - * Flush out any old buffers remaining from a previous use. - */ - if (error = vfs_mountedon(devvp)) - return (error); - if (vcount(devvp) > 1 && devvp != rootvp) - return (EBUSY); - if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) - return (error); -#ifdef READONLY -/* turn on this to force it to be read-only */ - mp->mnt_flag |= MNT_RDONLY; -#endif - - ronly = (mp->mnt_flag & MNT_RDONLY) != 0; - if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) - return (error); - if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) - size = DEV_BSIZE; - else { - havepart = 1; - size = dpart.disklab->d_secsize; - } - - bp = NULL; - ump = NULL; - if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) - goto out; - es = (struct ext2_super_block *)bp->b_data; - if (es->s_magic != EXT2_SUPER_MAGIC) { - if(es->s_magic == EXT2_PRE_02B_MAGIC) - printf("This filesystem bears the magic number of a pre " - "0.2b version of ext2. This is not supported by " - "Lites.\n"); - else - printf("Wrong magic number: %x (expected %x for EXT2FS)\n", - es->s_magic, EXT2_SUPER_MAGIC); - error = EINVAL; /* XXX needs translation */ - goto out; - } - ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK); - bzero((caddr_t)ump, sizeof *ump); - /* I don't know whether this is the right strategy. Note that - we dynamically allocate both a ext2_sb_info and a ext2_super_block - while Linux keeps the super block in a locked buffer - */ - ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), - M_UFSMNT, M_WAITOK); - ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), - M_UFSMNT, M_WAITOK); - bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); - if(error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)) { - brelse(bp); - return error; - } - brelse(bp); - bp = NULL; - fs = ump->um_e2fs; - fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */ - if (!(fs->s_es->s_state & EXT2_VALID_FS)) { - printf("WARNING: %s was not properly dismounted\n", - fs->fs_fsmnt); - } - /* if the fs is not mounted read-only, make sure the super block is - always written back on a sync() - */ - if (ronly == 0) { - fs->s_dirt = 1; /* mark it modified */ - fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */ - } - mp->mnt_data = (qaddr_t)ump; - mp->mnt_stat.f_fsid.val[0] = (long)dev; - mp->mnt_stat.f_fsid.val[1] = MOUNT_EXT2FS; - mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; - mp->mnt_flag |= MNT_LOCAL; - ump->um_mountp = mp; - ump->um_dev = dev; - ump->um_devvp = devvp; - /* setting those two parameters allows us to use - ufs_bmap w/o changse ! - */ - ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); - ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; - ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); - for (i = 0; i < MAXQUOTAS; i++) - ump->um_quotas[i] = NULLVP; - devvp->v_specflags |= SI_MOUNTEDON; - if (ronly == 0) - ext2_sbupdate(ump, MNT_WAIT); - return (0); -out: - if (bp) - brelse(bp); - (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); - if (ump) { - bsd_free(ump->um_fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); - mp->mnt_data = (qaddr_t)0; - } - return (error); -} - -/* - * unmount system call - */ -int -ext2_unmount(mp, mntflags, p) - struct mount *mp; - int mntflags; - struct proc *p; -{ - register struct ufsmount *ump; - register struct ext2_sb_info *fs; - int error, flags, ronly, i; - - flags = 0; - if (mntflags & MNT_FORCE) { - if (mp->mnt_flag & MNT_ROOTFS) - return (EINVAL); - flags |= FORCECLOSE; - } - if (error = ext2_flushfiles(mp, flags, p)) - return (error); - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - ronly = fs->s_rd_only; - if (!ronly) { - fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */ - ext2_sbupdate(ump, MNT_WAIT); - } - /* release buffers containing group descriptors */ - for(i = 0; i < fs->s_db_per_group; i++) - brelse(fs->s_group_desc[i]); - /* release cached inode/block bitmaps */ - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_inode_bitmap[i]) - brelse (fs->s_inode_bitmap[i]); - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_block_bitmap[i]) - brelse (fs->s_block_bitmap[i]); - - ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; - error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, - NOCRED, p); - vrele(ump->um_devvp); - bsd_free(fs->s_es, M_UFSMNT); - bsd_free(fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); - mp->mnt_data = (qaddr_t)0; - mp->mnt_flag &= ~MNT_LOCAL; - return (error); -} - -/* - * Flush out all the files in a filesystem. - */ -int -ext2_flushfiles(mp, flags, p) - register struct mount *mp; - int flags; - struct proc *p; -{ -#if !defined(__FreeBSD__) - extern int doforce; -#endif - register struct ufsmount *ump; - int i, error; - - if (!doforce) - flags &= ~FORCECLOSE; - ump = VFSTOUFS(mp); -#if QUOTA - if (mp->mnt_flag & MNT_QUOTA) { - if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) - return (error); - for (i = 0; i < MAXQUOTAS; i++) { - if (ump->um_quotas[i] == NULLVP) - continue; - quotaoff(p, mp, i); - } - /* - * Here we fall through to vflush again to ensure - * that we have gotten rid of all the system vnodes. - */ - } -#endif - error = vflush(mp, NULLVP, flags); - return (error); -} - -/* - * Get file system statistics. - * taken from ext2/super.c ext2_statfs - */ -int -ext2_statfs(mp, sbp, p) - struct mount *mp; - register struct statfs *sbp; - struct proc *p; -{ - unsigned long overhead; - unsigned long overhead_per_group; - - register struct ufsmount *ump; - register struct ext2_sb_info *fs; - register struct ext2_super_block *es; - - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - es = fs->s_es; - - if (es->s_magic != EXT2_SUPER_MAGIC) - panic("ext2_statfs - magic number spoiled"); - - /* - * Compute the overhead (FS structures) - */ - overhead_per_group = 1 /* super block */ + - fs->s_db_per_group + - 1 /* block bitmap */ + - 1 /* inode bitmap */ + - fs->s_itb_per_group; - overhead = es->s_first_data_block + - fs->s_groups_count * overhead_per_group; - - sbp->f_type = MOUNT_EXT2FS; - sbp->f_bsize = EXT2_FRAG_SIZE(fs); - sbp->f_iosize = EXT2_BLOCK_SIZE(fs); - sbp->f_blocks = es->s_blocks_count - overhead; - sbp->f_bfree = es->s_free_blocks_count; - sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; - sbp->f_files = es->s_inodes_count; - sbp->f_ffree = es->s_free_inodes_count; - if (sbp != &mp->mnt_stat) { - bcopy((caddr_t)mp->mnt_stat.f_mntonname, - (caddr_t)&sbp->f_mntonname[0], MNAMELEN); - bcopy((caddr_t)mp->mnt_stat.f_mntfromname, - (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); - } - return (0); -} - -/* - * Go through the disk queues to initiate sandbagged IO; - * go through the inodes to write those that have been modified; - * initiate the writing of the super block if it has been modified. - * - * Note: we are always called with the filesystem marked `MPBUSY'. - */ -int -ext2_sync(mp, waitfor, cred, p) - struct mount *mp; - int waitfor; - struct ucred *cred; - struct proc *p; -{ - register struct vnode *vp; - register struct inode *ip; - register struct ufsmount *ump = VFSTOUFS(mp); - register struct ext2_sb_info *fs; - int error, allerror = 0; - - fs = ump->um_e2fs; - /* - * Write back modified superblock. - * Consistency check that the superblock - * is still in the buffer cache. - */ - if (fs->s_dirt) { -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - if (fs->s_rd_only != 0) { /* XXX */ - printf("fs = %s\n", fs->fs_fsmnt); - panic("update: rofs mod"); - } - fs->s_dirt = 0; -#if !defined(__FreeBSD__) - get_time(&time); -#endif - fs->s_es->s_wtime = time.tv_sec; - allerror = ext2_sbupdate(ump, waitfor); - } - /* - * Write back each (modified) inode. - */ -loop: - for (vp = mp->mnt_vnodelist.lh_first; - vp != NULL; - vp = vp->v_mntvnodes.le_next) { - /* - * If the vnode that we are about to sync is no longer - * associated with this mount point, start over. - */ - if (vp->v_mount != mp) - goto loop; - if (VOP_ISLOCKED(vp)) - continue; - ip = VTOI(vp); - if ((ip->i_flag & - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && - vp->v_dirtyblkhd.lh_first == NULL) - continue; - if (vget(vp, 1)) - goto loop; - if (error = VOP_FSYNC(vp, cred, waitfor, p)) - allerror = error; - vput(vp); - } - /* - * Force stale file system control information to be flushed. - */ - if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) - allerror = error; -#if QUOTA - qsync(mp); -#endif - return (allerror); -} - -/* - * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it - * in from disk. If it is in core, wait for the lock bit to clear, then - * return the inode locked. Detection and handling of mount points must be - * done by the calling routine. - */ -int -ext2_vget(mp, ino, vpp) - struct mount *mp; - ino_t ino; - struct vnode **vpp; -{ - register struct ext2_sb_info *fs; - register struct inode *ip; - struct ufsmount *ump; - struct buf *bp; - struct vnode *vp; - dev_t dev; - int i, type, error; - int used_blocks; - - ump = VFSTOUFS(mp); - dev = ump->um_dev; - if ((*vpp = ufs_ihashget(dev, ino)) != NULL) - return (0); - - /* Allocate a new vnode/inode. */ - if (error = getnewvnode(VT_UFS, mp, ext2_vnodeop_p, &vp)) { - *vpp = NULL; - return (error); - } - /* I don't really know what this 'type' does. I suppose it's some kind - * of memory accounting. Let's just book this memory on FFS's account - * If I'm not mistaken, this stuff isn't implemented anyway in Lites - */ - type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ - MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); - insmntque(vp, mp); - bzero((caddr_t)ip, sizeof(struct inode)); - vp->v_data = ip; - ip->i_vnode = vp; - ip->i_e2fs = fs = ump->um_e2fs; - ip->i_dev = dev; - ip->i_number = ino; -#if QUOTA - for (i = 0; i < MAXQUOTAS; i++) - ip->i_dquot[i] = NODQUOT; -#endif - /* - * Put it onto its hash chain and lock it so that other requests for - * this inode will block if they arrive while we are sleeping waiting - * for old data structures to be purged or for the contents of the - * disk portion of this inode to be read. - */ - ufs_ihashins(ip); - - /* Read in the disk contents for the inode, copy into the inode. */ -#if 0 -printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); -#endif - if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), - (int)fs->s_blocksize, NOCRED, &bp)) { - /* - * The inode does not contain anything useful, so it would - * be misleading to leave it on its hash chain. With mode - * still zero, it will be unlinked and returned to the free - * list by vput(). - */ - vput(vp); - brelse(bp); - *vpp = NULL; - return (error); - } - /* convert ext2 inode to dinode */ - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * - ino_to_fsbo(fs, ino)), &ip->i_din); - ip->i_block_group = ino_to_cg(fs, ino); - ip->i_next_alloc_block = 0; - ip->i_next_alloc_goal = 0; - ip->i_prealloc_count = 0; - ip->i_prealloc_block = 0; - /* now we want to make sure that block pointers for unused - blocks are zeroed out - ext2_balloc depends on this - although for regular files and directories only - */ - if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) { - used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize; - for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) - ip->i_db[i] = 0; - } -/* - ext2_print_inode(ip); -*/ - brelse(bp); - - /* - * Initialize the vnode from the inode, check for aliases. - * Note that the underlying vnode may have changed. - */ - if (error = ufs_vinit(mp, ext2_specop_p, EXT2_FIFOOPS, &vp)) { - vput(vp); - *vpp = NULL; - return (error); - } - /* - * Finish inode initialization now that aliasing has been resolved. - */ - ip->i_devvp = ump->um_devvp; - VREF(ip->i_devvp); - /* - * Set up a generation number for this inode if it does not - * already have one. This should only happen on old filesystems. - */ - if (ip->i_gen == 0) { -#if !defined(__FreeBSD__) - struct timeval time; - get_time(&time); -#endif - if (++nextgennumber < (u_long)time.tv_sec) - nextgennumber = time.tv_sec; - ip->i_gen = nextgennumber; - if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) - ip->i_flag |= IN_MODIFIED; - } - *vpp = vp; - return (0); -} - -/* - * File handle to vnode - * - * Have to be really careful about stale file handles: - * - check that the inode number is valid - * - call ext2_vget() to get the locked inode - * - check for an unallocated inode (i_mode == 0) - * - check that the given client host has export rights and return - * those rights via. exflagsp and credanonp - */ -int -ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) - register struct mount *mp; - struct fid *fhp; - struct mbuf *nam; - struct vnode **vpp; - int *exflagsp; - struct ucred **credanonp; -{ - register struct ufid *ufhp; - struct ext2_sb_info *fs; - - ufhp = (struct ufid *)fhp; - fs = VFSTOUFS(mp)->um_e2fs; - if (ufhp->ufid_ino < ROOTINO || - ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group) - return (ESTALE); - return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); -} - -/* - * Vnode pointer to File handle - */ -/* ARGSUSED */ -int -ext2_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - register struct inode *ip; - register struct ufid *ufhp; - - ip = VTOI(vp); - ufhp = (struct ufid *)fhp; - ufhp->ufid_len = sizeof(struct ufid); - ufhp->ufid_ino = ip->i_number; - ufhp->ufid_gen = ip->i_gen; - return (0); -} - -/* - * Write a superblock and associated information back to disk. - */ -int -ext2_sbupdate(mp, waitfor) - struct ufsmount *mp; - int waitfor; -{ - register struct ext2_sb_info *fs = mp->um_e2fs; - register struct ext2_super_block *es = fs->s_es; - register struct buf *bp; - int blks; - caddr_t space; - int i, size, error = 0; -/* -printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); -*/ - bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0); - bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block)); - if (waitfor == MNT_WAIT) - error = bwrite(bp); - else - bawrite(bp); - - /* write group descriptors back on disk */ - for(i = 0; i < fs->s_db_per_group; i++) - /* Godmar thinks: we must avoid using any of the b*write - * functions here: we want to keep the buffer locked - * so we use my 'housemade' write routine: - */ - error |= ll_w_block(fs->s_group_desc[i], waitfor == MNT_WAIT); - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_inode_bitmap[i]) - ll_w_block (fs->s_inode_bitmap[i], 1); - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_block_bitmap[i]) - ll_w_block (fs->s_block_bitmap[i], 1); - - return (error); -} diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c deleted file mode 100644 index 1bf9113..0000000 --- a/sys/gnu/ext2fs/ext2_vnops.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_vnops.c 8.7 (Berkeley) 2/3/94 - */ - -#if !defined(__FreeBSD__) -#include "fifo.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/resourcevar.h> -#include <sys/kernel.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/conf.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/malloc.h> - -#include <vm/vm.h> - -#include <miscfs/specfs/specdev.h> -#include <miscfs/fifofs/fifo.h> - -#if !defined(__FreeBSD__) -#include <ufs/ufs/lockf.h> -#else -#include <lockf.h> -#include <sys/signalvar.h> -#endif -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/dir.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -/* Global vfs data structures for ufs. */ -int (**ext2_vnodeop_p)(); -struct vnodeopv_entry_desc ext2_vnodeop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, ext2_lookup }, /* lookup */ - { &vop_create_desc, ufs_create }, /* create */ - { &vop_mknod_desc, ufs_mknod }, /* mknod */ - { &vop_open_desc, ufs_open }, /* open */ - { &vop_close_desc, ufs_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ext2_read }, /* read */ - { &vop_write_desc, ext2_write }, /* write */ - { &vop_ioctl_desc, ufs_ioctl }, /* ioctl */ - { &vop_select_desc, ufs_select }, /* select */ - { &vop_mmap_desc, ufs_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, ufs_seek }, /* seek */ - { &vop_remove_desc, ufs_remove }, /* remove */ - { &vop_link_desc, ufs_link }, /* link */ - { &vop_rename_desc, ufs_rename }, /* rename */ - { &vop_mkdir_desc, ufs_mkdir }, /* mkdir */ - { &vop_rmdir_desc, ufs_rmdir }, /* rmdir */ - { &vop_symlink_desc, ufs_symlink }, /* symlink */ - { &vop_readdir_desc, ext2_readdir }, /* readdir */ - { &vop_readlink_desc, ufs_readlink }, /* readlink */ - { &vop_abortop_desc, ufs_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, ufs_bmap }, /* bmap */ - { &vop_strategy_desc, ufs_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, ufs_pathconf }, /* pathconf */ - { &vop_advlock_desc, ufs_advlock }, /* advlock */ - { &vop_blkatoff_desc, ext2_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, ext2_valloc }, /* valloc */ - { &vop_reallocblks_desc, ext2_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, ext2_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_vnodeop_opv_desc = - { &ext2_vnodeop_p, ext2_vnodeop_entries }; - -int (**ext2_specop_p)(); -struct vnodeopv_entry_desc ext2_specop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, spec_lookup }, /* lookup */ - { &vop_create_desc, spec_create }, /* create */ - { &vop_mknod_desc, spec_mknod }, /* mknod */ - { &vop_open_desc, spec_open }, /* open */ - { &vop_close_desc, ufsspec_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ufsspec_read }, /* read */ - { &vop_write_desc, ufsspec_write }, /* write */ - { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ - { &vop_select_desc, spec_select }, /* select */ - { &vop_mmap_desc, spec_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, spec_seek }, /* seek */ - { &vop_remove_desc, spec_remove }, /* remove */ - { &vop_link_desc, spec_link }, /* link */ - { &vop_rename_desc, spec_rename }, /* rename */ - { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ - { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ - { &vop_symlink_desc, spec_symlink }, /* symlink */ - { &vop_readdir_desc, spec_readdir }, /* readdir */ - { &vop_readlink_desc, spec_readlink }, /* readlink */ - { &vop_abortop_desc, spec_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, spec_bmap }, /* bmap */ - { &vop_strategy_desc, spec_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ - { &vop_advlock_desc, spec_advlock }, /* advlock */ - { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, spec_valloc }, /* valloc */ - { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, spec_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_specop_opv_desc = - { &ext2_specop_p, ext2_specop_entries }; - -#if FIFO -int (**ext2_fifoop_p)(); -struct vnodeopv_entry_desc ext2_fifoop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, fifo_lookup }, /* lookup */ - { &vop_create_desc, fifo_create }, /* create */ - { &vop_mknod_desc, fifo_mknod }, /* mknod */ - { &vop_open_desc, fifo_open }, /* open */ - { &vop_close_desc, ufsfifo_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ufsfifo_read }, /* read */ - { &vop_write_desc, ufsfifo_write }, /* write */ - { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ - { &vop_select_desc, fifo_select }, /* select */ - { &vop_mmap_desc, fifo_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, fifo_seek }, /* seek */ - { &vop_remove_desc, fifo_remove }, /* remove */ - { &vop_link_desc, fifo_link }, /* link */ - { &vop_rename_desc, fifo_rename }, /* rename */ - { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ - { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ - { &vop_symlink_desc, fifo_symlink }, /* symlink */ - { &vop_readdir_desc, fifo_readdir }, /* readdir */ - { &vop_readlink_desc, fifo_readlink }, /* readlink */ - { &vop_abortop_desc, fifo_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, fifo_bmap }, /* bmap */ - { &vop_strategy_desc, fifo_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ - { &vop_advlock_desc, fifo_advlock }, /* advlock */ - { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, fifo_valloc }, /* valloc */ - { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, fifo_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_fifoop_opv_desc = - { &ext2_fifoop_p, ext2_fifoop_entries }; -#endif /* FIFO */ - -#if defined(__FreeBSD__) - VNODEOP_SET(ext2fs_vnodeop_opv_desc); - VNODEOP_SET(ext2fs_specop_opv_desc); - VNODEOP_SET(ext2fs_fifoop_opv_desc); -#endif - -/* - * Enabling cluster read/write operations. - */ -#ifdef DEBUG -#include <sys/sysctl.h> -int doclusterread = 1; -struct ctldebug debug11 = { "doclusterread", &doclusterread }; -int doclusterwrite = 1; -struct ctldebug debug12 = { "doclusterwrite", &doclusterwrite }; -#endif - -#if defined(__FreeBSD__) -#define doclusterwrite 1 -#define doclusterread 1 -#else -/* doclusterwrite is being tested - note that reallocblks is called when it's on, but this is not implemented */ -#define doclusterwrite 0 -/* doclusterread should work with new pagemove */ -#define doclusterread 1 -#endif - -#include <gnu/ext2fs/ext2_readwrite.c> - -/* - * Synch an open file. - */ -/* ARGSUSED */ -int -ext2_fsync(ap) - struct vop_fsync_args /* { - struct vnode *a_vp; - struct ucred *a_cred; - int a_waitfor; - struct proc *a_p; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct buf *bp; - struct timeval tv; - struct buf *nbp; - int s; - - /* - * Clean memory object. - * XXX add this to all file systems. - * XXX why is all this fs specific? - */ -#if !defined(__FreeBSD__) - vn_pager_sync(vp, ap->a_waitfor); -#endif - - /* - * Flush all dirty buffers associated with a vnode. - */ - ext2_discard_prealloc(VTOI(vp)); - -loop: - s = splbio(); - for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { - nbp = bp->b_vnbufs.le_next; - if ((bp->b_flags & B_BUSY)) - continue; - if ((bp->b_flags & B_DELWRI) == 0) - panic("ext2_fsync: not dirty"); - bremfree(bp); - bp->b_flags |= B_BUSY; - splx(s); - /* - * Wait for I/O associated with indirect blocks to complete, - * since there is no way to quickly wait for them below. - */ - if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT) - (void) bawrite(bp); - else - (void) bwrite(bp); - goto loop; - } - if (ap->a_waitfor == MNT_WAIT) { - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; -#if !defined(__FreeBSD__) - sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1); -#else - tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "extfsn", 0); -#endif - } -#if DIAGNOSTIC - if (vp->v_dirtyblkhd.lh_first) { - vprint("ext2_fsync: dirty", vp); - goto loop; - } -#endif - } - splx(s); -#if defined(__FreeBSD__) - tv = time; -#else - get_time(&tv); -#endif - return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT)); -} diff --git a/sys/gnu/ext2fs/fs.h b/sys/gnu/ext2fs/fs.h deleted file mode 100644 index 28071d4..0000000 --- a/sys/gnu/ext2fs/fs.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)fs.h 8.7 (Berkeley) 4/19/94 - */ - -/* - * Each disk drive contains some number of file systems. - * A file system consists of a number of cylinder groups. - * Each cylinder group has inodes and data. - * - * A file system is described by its super-block, which in turn - * describes the cylinder groups. The super-block is critical - * data and is replicated in each cylinder group to protect against - * catastrophic loss. This is done at `newfs' time and the critical - * super-block data does not change, so the copies need not be - * referenced further unless disaster strikes. - * - * The first boot and super blocks are given in absolute disk addresses. - * The byte-offset forms are preferred, as they don't imply a sector size. - */ -#define BBSIZE 1024 -#define SBSIZE 1024 -#define BBOFF ((off_t)(0)) -#define SBOFF ((off_t)(BBOFF + BBSIZE)) -#define BBLOCK ((daddr_t)(0)) -#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE)) - -/* - * The path name on which the file system is mounted is maintained - * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in - * the super block for this name. - */ -#define MAXMNTLEN 512 - -/* - * Macros for access to superblock array structures - */ - -/* - * Convert cylinder group to base address of its global summary info. - */ -#define fs_cs(fs, cgindx) (((struct ext2_group_desc *) \ - (fs->s_group_desc[cgindx / EXT2_DESC_PER_BLOCK(fs)]->b_data)) \ - [cgindx % EXT2_DESC_PER_BLOCK(fs)]) - -/* - * Turn file system block numbers into disk block addresses. - * This maps file system blocks to device size blocks. - */ -#define fsbtodb(fs, b) ((b) << ((fs)->s_fsbtodb)) -#define dbtofsb(fs, b) ((b) >> ((fs)->s_fsbtodb)) - -/* get group containing inode */ -#define ino_to_cg(fs, x) (((x) - 1) / EXT2_INODES_PER_GROUP(fs)) - -/* get block containing inode from its number x */ -#define ino_to_fsba(fs, x) fs_cs(fs, ino_to_cg(fs, x)).bg_inode_table + \ - (((x)-1) % EXT2_INODES_PER_GROUP(fs))/EXT2_INODES_PER_BLOCK(fs) - -/* get offset for inode in block */ -#define ino_to_fsbo(fs, x) ((x-1) % EXT2_INODES_PER_BLOCK(fs)) - -/* - * Give cylinder group number for a file system block. - * Give cylinder group block number for a file system block. - */ -#define dtog(fs, d) (((d) - fs->s_es->s_first_data_block) / \ - EXT2_BLOCKS_PER_GROUP(fs)) -#define dtogd(fs, d) (((d) - fs->s_es->s_first_data_block) % \ - EXT2_BLOCKS_PER_GROUP(fs)) - -/* - * The following macros optimize certain frequently calculated - * quantities by using shifts and masks in place of divisions - * modulos and multiplications. - */ -#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \ - ((loc) & (fs)->s_qbmask) - -#define lblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ - ((blk) << (fs->s_bshift)) - -#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ - ((loc) >> (fs->s_bshift)) - -/* no fragments -> logical block number equal # of frags */ -#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ - ((loc) >> (fs->s_bshift)) - -#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \ - roundup(size, fs->s_frag_size) - /* was (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) */ - -/* - * Determining the size of a file block in the file system. - * easy w/o fragments - */ -#define blksize(fs, ip, lbn) ((fs)->s_frag_size) - -/* - * INOPB is the number of inodes in a secondary storage block. - */ -#define INOPB(fs) EXT2_INODES_PER_BLOCK(fs) - -/* - * NINDIR is the number of indirects in a file system block. - */ -#define NINDIR(fs) (EXT2_ADDR_PER_BLOCK(fs)) - -extern int inside[], around[]; -extern u_char *fragtbl[]; - -/* a few remarks about superblock locking/unlocking - * Linux provides special routines for doing so - * I haven't figured out yet what BSD does - * I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode - */ -#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp) -#define lock_super(devvp) VOP_LOCK(devvp) -#define unlock_super(devvp) VOP_UNLOCK(devvp) - diff --git a/sys/gnu/ext2fs/inode.h b/sys/gnu/ext2fs/inode.h deleted file mode 100644 index 00105ea..0000000 --- a/sys/gnu/ext2fs/inode.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 1982, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)inode.h 8.4 (Berkeley) 1/21/94 - * $Id: inode.h,v 1.5 1995/04/24 05:13:11 dyson Exp $ - */ - -#ifndef _UFS_UFS_INODE_H_ -#define _UFS_UFS_INODE_H_ - -#include <ufs/ufs/dinode.h> - -/* - * Theoretically, directories can be more than 2Gb in length, however, in - * practice this seems unlikely. So, we define the type doff_t as a long - * to keep down the cost of doing lookup on a 32-bit machine. If you are - * porting to a 64-bit architecture, you should make doff_t the same as off_t. - */ -#define doff_t long - -/* - * The inode is used to describe each active (or recently active) - * file in the UFS filesystem. It is composed of two types of - * information. The first part is the information that is needed - * only while the file is active (such as the identity of the file - * and linkage to speed its lookup). The second part is the - * permannent meta-data associated with the file which is read - * in from the permanent dinode from long term storage when the - * file becomes active, and is put back when the file is no longer - * being used. - */ -struct inode { - struct inode *i_next; /* Hash chain forward. */ - struct inode **i_prev; /* Hash chain back. */ - struct vnode *i_vnode; /* Vnode associated with this inode. */ - struct vnode *i_devvp; /* Vnode for block I/O. */ - u_long i_flag; /* I* flags. */ - dev_t i_dev; /* Device associated with the inode. */ - ino_t i_number; /* The identity of the inode. */ - union { /* Associated filesystem. */ - struct fs *fs; /* FFS */ - struct lfs *lfs; /* LFS */ - } inode_u; -#define i_fs inode_u.fs -#define i_lfs inode_u.lfs - struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ - u_quad_t i_modrev; /* Revision level for lease. */ - struct lockf *i_lockf; /* Head of byte-level lock list. */ - pid_t i_lockholder; /* DEBUG: holder of inode lock. */ - pid_t i_lockwaiter; /* DEBUG: latest blocked for inode lock. */ - /* - * Side effects; used during directory lookup. - */ - long i_count; /* Size of free slot in directory. */ - doff_t i_endoff; /* End of useful stuff in directory. */ - doff_t i_diroff; /* Offset in dir, where we found last entry. */ - doff_t i_offset; /* Offset of free space in directory. */ - ino_t i_ino; /* Inode number of found directory. */ - u_long i_reclen; /* Size of found directory entry. */ - int i_lockcount; /* Process lock count (recursion) */ - long i_spare[10]; /* Spares to round up to 128 bytes. */ - /* - * The on-disk dinode itself. - */ - struct dinode i_din; /* 128 bytes of the on-disk dinode. */ -}; - -#define i_atime i_din.di_atime -#define i_blocks i_din.di_blocks -#define i_ctime i_din.di_ctime -#define i_db i_din.di_db -#define i_flags i_din.di_flags -#define i_gen i_din.di_gen -#define i_gid i_din.di_gid -#define i_ib i_din.di_ib -#define i_mode i_din.di_mode -#define i_mtime i_din.di_mtime -#define i_nlink i_din.di_nlink -#define i_rdev i_din.di_rdev -#define i_shortlink i_din.di_shortlink -#define i_size i_din.di_size -#define i_uid i_din.di_uid - -/* These flags are kept in i_flag. */ -#define IN_ACCESS 0x0001 /* Access time update request. */ -#define IN_CHANGE 0x0002 /* Inode change time update request. */ -#define IN_EXLOCK 0x0004 /* File has exclusive lock. */ -#define IN_LOCKED 0x0008 /* Inode lock. */ -#define IN_LWAIT 0x0010 /* Process waiting on file lock. */ -#define IN_MODIFIED 0x0020 /* Inode has been modified. */ -#define IN_RENAME 0x0040 /* Inode is being renamed. */ -#define IN_SHLOCK 0x0080 /* File has shared lock. */ -#define IN_UPDATE 0x0100 /* Modification time update request. */ -#define IN_WANTED 0x0200 /* Inode is wanted by a process. */ -#define IN_RECURSE 0x0400 /* Recursion expected */ - -#ifdef KERNEL -/* - * Structure used to pass around logical block paths generated by - * ufs_getlbns and used by truncate and bmap code. - */ -struct indir { - daddr_t in_lbn; /* Logical block number. */ - int in_off; /* Offset in buffer. */ - int in_exists; /* Flag if the block exists. */ -}; - -/* Convert between inode pointers and vnode pointers. */ -#define VTOI(vp) ((struct inode *)(vp)->v_data) -#define ITOV(ip) ((ip)->i_vnode) - -/* - * XXX this is too long to be a macro, and isn't used in any time-critical - * place; in fact it is only used in ufs_vnops.c so it shouldn't be in a - * header file. - */ -#define ITIMES(ip, t1, t2) { \ - long tv_sec = time.tv_sec; \ - if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ - (ip)->i_flag |= IN_MODIFIED; \ - if ((ip)->i_flag & IN_ACCESS) \ - (ip)->i_atime.ts_sec \ - = ((t1) == &time ? tv_sec : (t1)->tv_sec); \ - if ((ip)->i_flag & IN_UPDATE) { \ - (ip)->i_mtime.ts_sec \ - = ((t2) == &time ? tv_sec : (t2)->tv_sec); \ - (ip)->i_modrev++; \ - } \ - if ((ip)->i_flag & IN_CHANGE) \ - (ip)->i_ctime.ts_sec = tv_sec; \ - (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ - } \ -} - -/* This overlays the fid structure (see mount.h). */ -struct ufid { - u_short ufid_len; /* Length of structure. */ - u_short ufid_pad; /* Force long alignment. */ - ino_t ufid_ino; /* File number (ino). */ - long ufid_gen; /* Generation number. */ -}; -#endif /* KERNEL */ - -#endif /* !_UFS_UFS_INODE_H_ */ diff --git a/sys/gnu/fs/ext2fs/COPYRIGHT.INFO b/sys/gnu/fs/ext2fs/COPYRIGHT.INFO deleted file mode 100644 index bbb0214..0000000 --- a/sys/gnu/fs/ext2fs/COPYRIGHT.INFO +++ /dev/null @@ -1,30 +0,0 @@ -Most of the files in this directory are written by Godmar Back or modified -by him using the CSRG sources. Those files are covered by the Berkeley-style -copyright. However the following files are covered by GPL. Since the policy -of the FreeBSD project is to keep the files with the more restrictive -copyright in the gnu tree and it is a good idea to keep the filesystem code -all together, the EXT2FS in it's entirety resides under the gnu tree. Note -that only the files below are under the GPL. In the eventuality that these -files are redesigned or rewritten, this tree can be moved back into the less -restrictive FreeBSD tree. - - ext2_fs.h - ext2_fs_i.h - ext2_fs_sb.h - ext2_linux_balloc.c - ext2_linux_ialloc.c - i386-bitops.h - -PS. - THANKS GODMAR!!! - -Note that this port has been modified by John Dyson and others on -the FreeBSD team, and it is best to send the bug reports to the FreeBSD -team. If there are any non-FreeBSD specific bugs, fixes will be sent to -Godmar to help him fix the original code base. It is also our intention -to send Godmar any FreeBSD specific porting changes so that he can keep -control of his code.... - -John -dyson@freebsd.org - diff --git a/sys/gnu/fs/ext2fs/ext2_alloc.c b/sys/gnu/fs/ext2fs/ext2_alloc.c deleted file mode 100644 index 6a0f5d3..0000000 --- a/sys/gnu/fs/ext2fs/ext2_alloc.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_alloc.c 8.8 (Berkeley) 2/21/94 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/stat.h> -#include <sys/mount.h> -#include <sys/kernel.h> -#include <sys/syslog.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -extern u_long nextgennumber; - -static void ext2_fserr __P((struct ext2_sb_info *, u_int, char *)); - -/* - * Linux calls this functions at the following locations: - * (1) the inode is freed - * (2) a preallocation miss occurs - * (3) truncate is called - * (4) release_file is called and f_mode & 2 - * - * I call it in ext2_inactive, ext2_truncate, ext2_vfree and in (2) - * the call in vfree might be redundant - */ -void ext2_discard_prealloc (struct inode * ip) -{ -#ifdef EXT2_PREALLOCATE - if (ip->i_prealloc_count) { - int i = ip->i_prealloc_count; - ip->i_prealloc_count = 0; - ext2_free_blocks (ITOV(ip)->v_mount, - ip->i_prealloc_block, - i); - } -#endif -} - -/* - * Allocate a block in the file system. - * - * this takes the framework from ffs_alloc. To implement the - * actual allocation, it calls ext2_new_block, the ported version - * of the same Linux routine. - * - * we note that this is always called in connection with ext2_blkpref - * - * preallocation is done as Linux does it - */ -int -ext2_alloc(ip, lbn, bpref, size, cred, bnp) - register struct inode *ip; - daddr_t lbn, bpref; - int size; - struct ucred *cred; - daddr_t *bnp; -{ - register struct ext2_sb_info *fs; - daddr_t bno; - int cg, error; - - *bnp = 0; - fs = ip->i_e2fs; -#if DIAGNOSTIC - if ((u_int)size > fs->s_blocksize || blkoff(fs, size) != 0) { - printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", - ip->i_dev, fs->s_blocksize, size, fs->fs_fsmnt); - panic("ext2_alloc: bad size"); - } - if (cred == NOCRED) - panic("ext2_alloc: missing credential\n"); -#endif /* DIAGNOSTIC */ - if (size == fs->s_blocksize && fs->s_es->s_free_blocks_count == 0) - goto nospace; - if (cred->cr_uid != 0 && - fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count) - goto nospace; -#if QUOTA - if (error = chkdq(ip, (long)btodb(size), cred, 0)) - return (error); -#endif - if (bpref >= fs->s_es->s_blocks_count) - bpref = 0; - /* call the Linux code */ -#ifdef EXT2_PREALLOCATE - /* To have a preallocation hit, we must - * - have at least one block preallocated - * - and our preferred block must have that block number or one below - */ - if (ip->i_prealloc_count && - (bpref == ip->i_prealloc_block || - bpref + 1 == ip->i_prealloc_block)) - { - bno = ip->i_prealloc_block++; - ip->i_prealloc_count--; - /* ext2_debug ("preallocation hit (%lu/%lu).\n", - ++alloc_hits, ++alloc_attempts); */ - - /* Linux gets, clears, and releases the buffer at this - point - we don't have to that; we leave it to the caller - */ - } else { - ext2_discard_prealloc (ip); - /* ext2_debug ("preallocation miss (%lu/%lu).\n", - alloc_hits, ++alloc_attempts); */ - if (S_ISREG(ip->i_mode)) - bno = ext2_new_block - (ITOV(ip)->v_mount, bpref, - &ip->i_prealloc_count, - &ip->i_prealloc_block); - else - bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, - bpref, 0, 0); - } -#else - bno = (daddr_t)ext2_new_block(ITOV(ip)->v_mount, bpref, 0, 0); -#endif - - if (bno > 0) { - /* set next_alloc fields as done in block_getblk */ - ip->i_next_alloc_block = lbn; - ip->i_next_alloc_goal = bno; - - ip->i_blocks += btodb(size); - ip->i_flag |= IN_CHANGE | IN_UPDATE; - *bnp = bno; - return (0); - } -#if QUOTA - /* - * Restore user's disk quota because allocation failed. - */ - (void) chkdq(ip, (long)-btodb(size), cred, FORCE); -#endif -nospace: - ext2_fserr(fs, cred->cr_uid, "file system full"); - uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); - return (ENOSPC); -} - -/* - * Reallocate a sequence of blocks into a contiguous sequence of blocks. - * - * The vnode and an array of buffer pointers for a range of sequential - * logical blocks to be made contiguous is given. The allocator attempts - * to find a range of sequential blocks starting as close as possible to - * an fs_rotdelay offset from the end of the allocation for the logical - * block immediately preceeding the current range. If successful, the - * physical block numbers in the buffer pointers and in the inode are - * changed to reflect the new allocation. If unsuccessful, the allocation - * is left unchanged. The success in doing the reallocation is returned. - * Note that the error return is not reflected back to the user. Rather - * the previous block allocation will be used. - */ -#include <sys/sysctl.h> -static int doasyncfree = 1; -#ifdef OPT_DEBUG -struct ctldebug debug14 = { "doasyncfree", &doasyncfree }; -#endif /* OPT_DEBUG */ -int -ext2_reallocblks(ap) - struct vop_reallocblks_args /* { - struct vnode *a_vp; - struct cluster_save *a_buflist; - } */ *ap; -{ -#ifndef FANCY_REALLOC -/* printf("ext2_reallocblks not implemented\n"); */ -return ENOSPC; -#else - - struct ext2_sb_info *fs; - struct inode *ip; - struct vnode *vp; - struct buf *sbp, *ebp; - daddr_t *bap, *sbap, *ebap; - struct cluster_save *buflist; - daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno; - struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; - int i, len, start_lvl, end_lvl, pref, ssize; - - vp = ap->a_vp; - ip = VTOI(vp); - fs = ip->i_e2fs; -#ifdef UNKLAR - if (fs->fs_contigsumsize <= 0) - return (ENOSPC); -#endif - buflist = ap->a_buflist; - len = buflist->bs_nchildren; - start_lbn = buflist->bs_children[0]->b_lblkno; - end_lbn = start_lbn + len - 1; -#if DIAGNOSTIC - for (i = 1; i < len; i++) - if (buflist->bs_children[i]->b_lblkno != start_lbn + i) - panic("ext2_reallocblks: non-cluster"); -#endif - /* - * If the latest allocation is in a new cylinder group, assume that - * the filesystem has decided to move and do not force it back to - * the previous cylinder group. - */ - if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) != - dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno))) - return (ENOSPC); - if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) || - ufs_getlbns(vp, end_lbn, end_ap, &end_lvl)) - return (ENOSPC); - /* - * Get the starting offset and block map for the first block. - */ - if (start_lvl == 0) { - sbap = &ip->i_db[0]; - soff = start_lbn; - } else { - idp = &start_ap[start_lvl - 1]; - if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &sbp)) { - brelse(sbp); - return (ENOSPC); - } - sbap = (daddr_t *)sbp->b_data; - soff = idp->in_off; - } - /* - * Find the preferred location for the cluster. - */ - pref = ext2_blkpref(ip, start_lbn, soff, sbap); - /* - * If the block range spans two block maps, get the second map. - */ - if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) { - ssize = len; - } else { -#if DIAGNOSTIC - if (start_ap[start_lvl-1].in_lbn == idp->in_lbn) - panic("ext2_reallocblk: start == end"); -#endif - ssize = len - (idp->in_off + 1); - if (bread(vp, idp->in_lbn, (int)fs->s_blocksize, NOCRED, &ebp)) - goto fail; - ebap = (daddr_t *)ebp->b_data; - } - /* - * Search the block map looking for an allocation of the desired size. - */ - if ((newblk = (daddr_t)ext2_hashalloc(ip, dtog(fs, pref), (long)pref, - len, (u_long (*)())ext2_clusteralloc)) == 0) - goto fail; - /* - * We have found a new contiguous block. - * - * First we have to replace the old block pointers with the new - * block pointers in the inode and indirect blocks associated - * with the file. - */ - blkno = newblk; - for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->s_frags_per_block) { - if (i == ssize) - bap = ebap; -#if DIAGNOSTIC - if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap)) - panic("ext2_reallocblks: alloc mismatch"); -#endif - *bap++ = blkno; - } - /* - * Next we must write out the modified inode and indirect blocks. - * For strict correctness, the writes should be synchronous since - * the old block values may have been written to disk. In practise - * they are almost never written, but if we are concerned about - * strict correctness, the `doasyncfree' flag should be set to zero. - * - * The test on `doasyncfree' should be changed to test a flag - * that shows whether the associated buffers and inodes have - * been written. The flag should be set when the cluster is - * started and cleared whenever the buffer or inode is flushed. - * We can then check below to see if it is set, and do the - * synchronous write only when it has been cleared. - */ - if (sbap != &ip->i_db[0]) { - if (doasyncfree) - bdwrite(sbp); - else - bwrite(sbp); - } else { -#if !defined(__FreeBSD__) - struct timeval time; - get_time(&time); -#endif - ip->i_flag |= IN_CHANGE | IN_UPDATE; - if (!doasyncfree) - VOP_UPDATE(vp, &time, &time, MNT_WAIT); - } - if (ssize < len) - if (doasyncfree) - bdwrite(ebp); - else - bwrite(ebp); - /* - * Last, free the old blocks and assign the new blocks to the buffers. - */ - for (blkno = newblk, i = 0; i < len; i++, blkno += fs->s_frags_per_block) { - ext2_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno), - fs->s_blocksize); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); - } - return (0); - -fail: - if (ssize < len) - brelse(ebp); - if (sbap != &ip->i_db[0]) - brelse(sbp); - return (ENOSPC); - -#endif /* FANCY_REALLOC */ -} - -/* - * Allocate an inode in the file system. - * - * we leave the actual allocation strategy to the (modified) - * ext2_new_inode(), to make sure we get the policies right - */ -int -ext2_valloc(ap) - struct vop_valloc_args /* { - struct vnode *a_pvp; - int a_mode; - struct ucred *a_cred; - struct vnode **a_vpp; - } */ *ap; -{ - register struct vnode *pvp = ap->a_pvp; - register struct inode *pip; - register struct ext2_sb_info *fs; - register struct inode *ip; - mode_t mode = ap->a_mode; - ino_t ino, ipref; - int i, error; -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - *ap->a_vpp = NULL; - pip = VTOI(pvp); - fs = pip->i_e2fs; - if (fs->s_es->s_free_inodes_count == 0) - goto noinodes; - - /* call the Linux routine - it returns the inode number only */ - ino = ext2_new_inode(pip, mode); - - if (ino == 0) - goto noinodes; - error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp); - if (error) { - VOP_VFREE(pvp, ino, mode); - return (error); - } - ip = VTOI(*ap->a_vpp); - - /* - the question is whether using VGET was such good idea at all - - Linux doesn't read the old inode in when it's allocating a - new one. I will set at least i_size & i_blocks the zero. - */ - ip->i_mode = 0; - ip->i_size = 0; - ip->i_blocks = 0; - ip->i_flags = 0; - /* now we want to make sure that the block pointers are zeroed out */ - for(i = 0; i < EXT2_NDIR_BLOCKS; i++) - ip->i_db[i] = 0; - - /* - * Set up a new generation number for this inode. - * XXX check if this makes sense in ext2 - */ -#if !defined(__FreeBSD__) - get_time(&time); -#endif - if (++nextgennumber < (u_long)time.tv_sec) - nextgennumber = time.tv_sec; - ip->i_gen = nextgennumber; -/* -printf("ext2_valloc: allocated inode %d\n", ino); -*/ - return (0); -noinodes: - ext2_fserr(fs, ap->a_cred->cr_uid, "out of inodes"); - uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); - return (ENOSPC); -} - -/* - * Select the desired position for the next block in a file. - * - * we try to mimic what Remy does in inode_getblk/block_getblk - * - * we note: blocknr == 0 means that we're about to allocate either - * a direct block or a pointer block at the first level of indirection - * (In other words, stuff that will go in i_db[] or i_ib[]) - * - * blocknr != 0 means that we're allocating a block that is none - * of the above. Then, blocknr tells us the number of the block - * that will hold the pointer - */ -daddr_t -ext2_blkpref(ip, lbn, indx, bap, blocknr) - struct inode *ip; - daddr_t lbn; - int indx; - daddr_t *bap; - daddr_t blocknr; -{ - register struct ext2_sb_info *fs; - int tmp; - - /* if the next block is actually what we thought it is, - then set the goal to what we thought it should be - */ - if(ip->i_next_alloc_block == lbn) - return ip->i_next_alloc_goal; - - /* now check whether we were provided with an array that basically - tells us previous blocks to which we want to stay closeby - */ - if(bap) - for (tmp = indx - 1; tmp >= 0; tmp--) - if (bap[tmp]) - return bap[tmp]; - - /* else let's fall back to the blocknr, or, if there is none, - follow the rule that a block should be allocated near it's inode - */ - return blocknr ? blocknr : - (daddr_t)(ip->i_block_group * - EXT2_BLOCKS_PER_GROUP(ip->i_e2fs)) + - ip->i_e2fs->s_es->s_first_data_block; -} - -/* - * Free a block or fragment. - * - * pass on to the Linux code - */ -void -ext2_blkfree(ip, bno, size) - register struct inode *ip; - daddr_t bno; - long size; -{ - register struct ext2_sb_info *fs; - - fs = ip->i_e2fs; - /* - * call Linux code with mount *, block number, count - */ - ext2_free_blocks(ITOV(ip)->v_mount, bno, size / fs->s_frag_size); -} - -/* - * Free an inode. - * - * the maintenance of the actual bitmaps is again up to the linux code - */ -int -ext2_vfree(ap) - struct vop_vfree_args /* { - struct vnode *a_pvp; - ino_t a_ino; - int a_mode; - } */ *ap; -{ - register struct ext2_sb_info *fs; - register struct inode *pip; - ino_t ino = ap->a_ino; - int mode; - - pip = VTOI(ap->a_pvp); - fs = pip->i_e2fs; - if ((u_int)ino >= fs->s_inodes_per_group * fs->s_groups_count) - panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n", - pip->i_dev, ino, fs->fs_fsmnt); - -/* ext2_debug("ext2_vfree (%d, %d) called\n", pip->i_number, ap->a_mode); - */ - ext2_discard_prealloc(pip); - - /* we need to make sure that ext2_free_inode can adjust the - used_dir_counts in the group summary information - I'd - really like to know what the rationale behind this - 'set i_mode to zero to denote an unused inode' is - */ - mode = pip->i_mode; - pip->i_mode = ap->a_mode; - ext2_free_inode(pip); - pip->i_mode = mode; - return (0); -} - -/* - * Fserr prints the name of a file system with an error diagnostic. - * - * The form of the error message is: - * fs: error message - */ -static void -ext2_fserr(fs, uid, cp) - struct ext2_sb_info *fs; - u_int uid; - char *cp; -{ - - log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp); -} diff --git a/sys/gnu/fs/ext2fs/ext2_balloc.c b/sys/gnu/fs/ext2fs/ext2_balloc.c deleted file mode 100644 index 44d75ae..0000000 --- a/sys/gnu/fs/ext2fs/ext2_balloc.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_balloc.c 8.4 (Berkeley) 9/23/93 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/file.h> -#include <sys/vnode.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -/* - * Balloc defines the structure of file system storage - * by allocating the physical blocks on a device given - * the inode and the logical block number in a file. - */ -int -ext2_balloc(ip, bn, size, cred, bpp, flags) - register struct inode *ip; - register daddr_t bn; - int size; - struct ucred *cred; - struct buf **bpp; - int flags; -{ - register struct ext2_sb_info *fs; - register daddr_t nb; - struct buf *bp, *nbp; - struct vnode *vp = ITOV(ip); - struct indir indirs[NIADDR + 2]; - daddr_t newb, lbn, *bap, pref; - int osize, nsize, num, i, error; -/* -ext2_debug("ext2_balloc called (%d, %d, %d)\n", - ip->i_number, (int)bn, (int)size); -*/ - *bpp = NULL; - if (bn < 0) - return (EFBIG); - fs = ip->i_e2fs; - lbn = bn; - - /* - * check if this is a sequential block allocation. - * If so, increment next_alloc fields to allow ext2_blkpref - * to make a good guess - */ - if (lbn == ip->i_next_alloc_block + 1) { - ip->i_next_alloc_block++; - ip->i_next_alloc_goal++; - } - - /* - * The first NDADDR blocks are direct blocks - */ - if (bn < NDADDR) { - nb = ip->i_db[bn]; - /* no new block is to be allocated, and no need to expand - the file */ - if (nb != 0 && ip->i_size >= (bn + 1) * fs->s_blocksize) { - error = bread(vp, bn, fs->s_blocksize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - *bpp = bp; - return (0); - } - if (nb != 0) { - /* - * Consider need to reallocate a fragment. - */ - osize = fragroundup(fs, blkoff(fs, ip->i_size)); - nsize = fragroundup(fs, size); - if (nsize <= osize) { - error = bread(vp, bn, osize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - } else { - /* Godmar thinks: this shouldn't happen w/o fragments */ - printf("nsize %d(%d) > osize %d(%d) nb %d\n", - (int)nsize, (int)size, (int)osize, - (int)ip->i_size, (int)nb); - panic("ext2_balloc: " - "Something is terribly wrong\n"); -/* - * please note there haven't been any changes from here on - - * FFS seems to work. - */ - } - } else { - if (ip->i_size < (bn + 1) * fs->s_blocksize) - nsize = fragroundup(fs, size); - else - nsize = fs->s_blocksize; - error = ext2_alloc(ip, bn, - ext2_blkpref(ip, bn, (int)bn, &ip->i_db[0], 0), - nsize, cred, &newb); - if (error) - return (error); - bp = getblk(vp, bn, nsize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); - if (flags & B_CLRBUF) -#if defined(__FreeBSD__) - vfs_bio_clrbuf(bp); -#else - clrbuf(bp); -#endif - } - ip->i_db[bn] = dbtofsb(fs, bp->b_blkno); - ip->i_flag |= IN_CHANGE | IN_UPDATE; - *bpp = bp; - return (0); - } - /* - * Determine the number of levels of indirection. - */ - pref = 0; - if (error = ufs_getlbns(vp, bn, indirs, &num)) - return(error); -#if DIAGNOSTIC - if (num < 1) - panic ("ext2_balloc: ufs_bmaparray returned indirect block\n"); -#endif - /* - * Fetch the first indirect block allocating if necessary. - */ - --num; - nb = ip->i_ib[indirs[0].in_off]; - if (nb == 0) { -#if 0 - pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0); -#else - /* see the comment by ext2_blkpref. What we do here is - to pretend that it'd be good for a block holding indirect - pointers to be allocated near its predecessor in terms - of indirection, or the last direct block. - We shamelessly exploit the fact that i_ib immediately - follows i_db. - Godmar thinks it make sense to allocate i_ib[0] immediately - after i_db[11], but it's not utterly clear whether this also - applies to i_ib[1] and i_ib[0] - */ - - pref = ext2_blkpref(ip, lbn, indirs[0].in_off + - EXT2_NDIR_BLOCKS, &ip->i_db[0], 0); -#endif - if (error = ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, - cred, &newb)) - return (error); - nb = newb; - bp = getblk(vp, indirs[1].in_lbn, fs->s_blocksize, 0, 0); - bp->b_blkno = fsbtodb(fs, newb); -#if defined(__FreeBSD__) - vfs_bio_clrbuf(bp); -#else - clrbuf(bp); -#endif - /* - * Write synchronously so that indirect blocks - * never point at garbage. - */ - if (error = bwrite(bp)) { - ext2_blkfree(ip, nb, fs->s_blocksize); - return (error); - } - ip->i_ib[indirs[0].in_off] = newb; - ip->i_flag |= IN_CHANGE | IN_UPDATE; - } - /* - * Fetch through the indirect blocks, allocating as necessary. - */ - for (i = 1;;) { - error = bread(vp, - indirs[i].in_lbn, (int)fs->s_blocksize, NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - bap = (daddr_t *)bp->b_data; - nb = bap[indirs[i].in_off]; - if (i == num) - break; - i += 1; - if (nb != 0) { - brelse(bp); - continue; - } - if (pref == 0) -#if 1 - /* see the comment above and by ext2_blkpref - * I think this implements Linux policy, but - * does it really make sense to allocate to - * block containing pointers together ? - * Also, will it ever succeed ? - */ - pref = ext2_blkpref(ip, lbn, indirs[i].in_off, bap, - bp->b_lblkno); -#else - pref = ext2_blkpref(ip, lbn, 0, (daddr_t *)0, 0); -#endif - if (error = - ext2_alloc(ip, lbn, pref, (int)fs->s_blocksize, cred, &newb)) { - brelse(bp); - return (error); - } - nb = newb; - nbp = getblk(vp, indirs[i].in_lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); -#if defined(__FreeBSD__) - vfs_bio_clrbuf(nbp); -#else - clrbuf(nbp); -#endif - /* - * Write synchronously so that indirect blocks - * never point at garbage. - */ - if (error = bwrite(nbp)) { - ext2_blkfree(ip, nb, fs->s_blocksize); - brelse(bp); - return (error); - } - bap[indirs[i - 1].in_off] = nb; - /* - * If required, write synchronously, otherwise use - * delayed write. - */ - if (flags & B_SYNC) { - bwrite(bp); - } else { - bdwrite(bp); - } - } - /* - * Get the data block, allocating if necessary. - */ - if (nb == 0) { - pref = ext2_blkpref(ip, lbn, indirs[i].in_off, &bap[0], - bp->b_lblkno); - if (error = ext2_alloc(ip, - lbn, pref, (int)fs->s_blocksize, cred, &newb)) { - brelse(bp); - return (error); - } - nb = newb; - nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - if (flags & B_CLRBUF) -#if defined(__FreeBSD__) - vfs_bio_clrbuf(nbp); -#else - clrbuf(nbp); -#endif - bap[indirs[i].in_off] = nb; - /* - * If required, write synchronously, otherwise use - * delayed write. - */ - if (flags & B_SYNC) { - bwrite(bp); - } else { - bdwrite(bp); - } - *bpp = nbp; - return (0); - } - brelse(bp); - if (flags & B_CLRBUF) { - error = bread(vp, lbn, (int)fs->s_blocksize, NOCRED, &nbp); - if (error) { - brelse(nbp); - return (error); - } - } else { - nbp = getblk(vp, lbn, fs->s_blocksize, 0, 0); - nbp->b_blkno = fsbtodb(fs, nb); - } - *bpp = nbp; - return (0); -} diff --git a/sys/gnu/fs/ext2fs/ext2_bmap.c b/sys/gnu/fs/ext2fs/ext2_bmap.c deleted file mode 100644 index c8b3cd4..0000000 --- a/sys/gnu/fs/ext2fs/ext2_bmap.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (c) 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_bmap.c 8.6 (Berkeley) 1/21/94 - * $Id: ufs_bmap.c,v 1.9 1995/09/04 00:21:09 dyson Exp $ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/resourcevar.h> - -#include <miscfs/specfs/specdev.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/ufs_extern.h> - -/* - * Bmap converts a the logical block number of a file to its physical block - * number on the disk. The conversion is done by using the logical block - * number to index into the array of block pointers described by the dinode. - */ -int -ufs_bmap(ap) - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - int *a_runb; - } */ *ap; -{ - /* - * Check for underlying vnode requests and ensure that logical - * to physical mapping is requested. - */ - if (ap->a_vpp != NULL) - *ap->a_vpp = VTOI(ap->a_vp)->i_devvp; - if (ap->a_bnp == NULL) - return (0); - - return (ufs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL, - ap->a_runp, ap->a_runb)); -} - -/* - * Indirect blocks are now on the vnode for the file. They are given negative - * logical block numbers. Indirect blocks are addressed by the negative - * address of the first data block to which they point. Double indirect blocks - * are addressed by one less than the address of the first indirect block to - * which they point. Triple indirect blocks are addressed by one less than - * the address of the first double indirect block to which they point. - * - * ufs_bmaparray does the bmap conversion, and if requested returns the - * array of logical blocks which must be traversed to get to a block. - * Each entry contains the offset into that block that gets you to the - * next block and the disk address of the block (if it is assigned). - */ - -int -ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb) - struct vnode *vp; - register daddr_t bn; - daddr_t *bnp; - struct indir *ap; - int *nump; - int *runp; - int *runb; -{ - register struct inode *ip; - struct buf *bp; - struct ufsmount *ump; - struct mount *mp; - struct vnode *devvp; - struct indir a[NIADDR+1], *xap; - daddr_t daddr; - long metalbn; - int error, maxrun = 0, num; - - ip = VTOI(vp); - mp = vp->v_mount; - ump = VFSTOUFS(mp); -#ifdef DIAGNOSTIC - if (ap != NULL && nump == NULL || ap == NULL && nump != NULL) - panic("ufs_bmaparray: invalid arguments"); -#endif - - if (runp) { - /* - * XXX - * If MAXPHYS is the largest transfer the disks can handle, - * we probably want maxrun to be 1 block less so that we - * don't create a block larger than the device can handle. - */ - *runp = 0; - maxrun = MAXPHYS / mp->mnt_stat.f_iosize - 1; - } - - if (runb) { - *runb = 0; - } - - xap = ap == NULL ? a : ap; - if (!nump) - nump = # - error = ufs_getlbns(vp, bn, xap, nump); - if (error) - return (error); - - num = *nump; - if (num == 0) { - *bnp = blkptrtodb(ump, ip->i_db[bn]); - if (*bnp == 0) - *bnp = -1; - else if (runp) { - daddr_t bnb = bn; - for (++bn; bn < NDADDR && *runp < maxrun && - is_sequential(ump, ip->i_db[bn - 1], ip->i_db[bn]); - ++bn, ++*runp); - bn = bnb; - if (runb && (bn > 0)) { - for (--bn; (bn >= 0) && (*runb < maxrun) && - is_sequential(ump, ip->i_db[bn], - ip->i_db[bn+1]); - --bn, ++*runb); - } - } - return (0); - } - - - /* Get disk address out of indirect block array */ - daddr = ip->i_ib[xap->in_off]; - - devvp = VFSTOUFS(vp->v_mount)->um_devvp; - for (bp = NULL, ++xap; --num; ++xap) { - /* - * Exit the loop if there is no disk address assigned yet and - * the indirect block isn't in the cache, or if we were - * looking for an indirect block and we've found it. - */ - - metalbn = xap->in_lbn; - if ((daddr == 0 && !incore(vp, metalbn)) || metalbn == bn) - break; - /* - * If we get here, we've either got the block in the cache - * or we have a disk address for it, go fetch it. - */ - if (bp) - brelse(bp); - - xap->in_exists = 1; - bp = getblk(vp, metalbn, mp->mnt_stat.f_iosize, 0, 0); - if ((bp->b_flags & B_CACHE) == 0) { -#ifdef DIAGNOSTIC - if (!daddr) - panic("ufs_bmaparry: indirect block not in cache"); -#endif - bp->b_blkno = blkptrtodb(ump, daddr); - bp->b_flags |= B_READ; - vfs_busy_pages(bp, 0); - VOP_STRATEGY(bp); - curproc->p_stats->p_ru.ru_inblock++; /* XXX */ - error = biowait(bp); - if (error) { - brelse(bp); - return (error); - } - } - - daddr = ((daddr_t *)bp->b_data)[xap->in_off]; - if (num == 1 && daddr && runp) { - for (bn = xap->in_off + 1; - bn < MNINDIR(ump) && *runp < maxrun && - is_sequential(ump, ((daddr_t *)bp->b_data)[bn - 1], - ((daddr_t *)bp->b_data)[bn]); - ++bn, ++*runp); - bn = xap->in_off; - if (runb && bn) { - for(--bn; bn > 0 && *runb < maxrun && - is_sequential(ump, ((daddr_t *)bp->b_data)[bn], - ((daddr_t *)bp->b_data)[bn+1]); - --bn, ++*runb); - } - } - } - if (bp) - brelse(bp); - - daddr = blkptrtodb(ump, daddr); - *bnp = daddr == 0 ? -1 : daddr; - return (0); -} - -/* - * Create an array of logical block number/offset pairs which represent the - * path of indirect blocks required to access a data block. The first "pair" - * contains the logical block number of the appropriate single, double or - * triple indirect block and the offset into the inode indirect block array. - * Note, the logical block number of the inode single/double/triple indirect - * block appears twice in the array, once with the offset into the i_ib and - * once with the offset into the page itself. - */ -int -ufs_getlbns(vp, bn, ap, nump) - struct vnode *vp; - register daddr_t bn; - struct indir *ap; - int *nump; -{ - long metalbn, realbn; - struct ufsmount *ump; - int blockcnt, i, numlevels, off; - - ump = VFSTOUFS(vp->v_mount); - if (nump) - *nump = 0; - numlevels = 0; - realbn = bn; - if ((long)bn < 0) - bn = -(long)bn; - - /* The first NDADDR blocks are direct blocks. */ - if (bn < NDADDR) - return (0); - - /* - * Determine the number of levels of indirection. After this loop - * is done, blockcnt indicates the number of data blocks possible - * at the given level of indirection, and NIADDR - i is the number - * of levels of indirection needed to locate the requested block. - */ - for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { - if (i == 0) - return (EFBIG); - blockcnt *= MNINDIR(ump); - if (bn < blockcnt) - break; - } - - /* Calculate the address of the first meta-block. */ - if (realbn >= 0) - metalbn = -(realbn - bn + NIADDR - i); - else - metalbn = -(-realbn - bn + NIADDR - i); - - /* - * At each iteration, off is the offset into the bap array which is - * an array of disk addresses at the current level of indirection. - * The logical block number and the offset in that block are stored - * into the argument array. - */ - ap->in_lbn = metalbn; - ap->in_off = off = NIADDR - i; - ap->in_exists = 0; - ap++; - for (++numlevels; i <= NIADDR; i++) { - /* If searching for a meta-data block, quit when found. */ - if (metalbn == realbn) - break; - - blockcnt /= MNINDIR(ump); - off = (bn / blockcnt) % MNINDIR(ump); - - ++numlevels; - ap->in_lbn = metalbn; - ap->in_off = off; - ap->in_exists = 0; - ++ap; - - metalbn -= -1 + off * blockcnt; - } - if (nump) - *nump = numlevels; - return (0); -} diff --git a/sys/gnu/fs/ext2fs/ext2_extern.h b/sys/gnu/fs/ext2fs/ext2_extern.h deleted file mode 100644 index 92ec042..0000000 --- a/sys/gnu/fs/ext2fs/ext2_extern.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/*- - * Copyright (c) 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_extern.h 8.3 (Berkeley) 4/16/94 - */ - -struct buf; -struct fid; -struct fs; -struct inode; -struct mount; -struct nameidata; -struct proc; -struct statfs; -struct timeval; -struct ucred; -struct uio; -struct vnode; -struct mbuf; -struct dinode; -struct ext2_group_desc; -struct ext2_inode; - -__BEGIN_DECLS -int ext2_alloc __P((struct inode *, - daddr_t, daddr_t, int, struct ucred *, daddr_t *)); -int ext2_balloc __P((struct inode *, - daddr_t, int, struct ucred *, struct buf **, int)); -int ext2_blkatoff __P((struct vop_blkatoff_args *)); -void ext2_blkfree __P((struct inode *, daddr_t, long)); -daddr_t ext2_blkpref __P((struct inode *, daddr_t, int, daddr_t *, daddr_t)); -int ext2_bmap __P((struct vop_bmap_args *)); -int ext2_fhtovp __P((struct mount *, struct fid *, struct mbuf *, - struct vnode **, int *, struct ucred **)); -int ext2_fsync __P((struct vop_fsync_args *)); -int ext2_init __P((void)); -int ext2_mount __P((struct mount *, - char *, caddr_t, struct nameidata *, struct proc *)); -int ext2_mountfs __P((struct vnode *, struct mount *, struct proc *)); -int ext2_mountroot __P((void)); -int ext2_read __P((struct vop_read_args *)); -int ext2_reallocblks __P((struct vop_reallocblks_args *)); -int ext2_reclaim __P((struct vop_reclaim_args *)); -void ext2_setblock __P((struct ext2_sb_info *, u_char *, daddr_t)); -int ext2_statfs __P((struct mount *, struct statfs *, struct proc *)); -int ext2_sync __P((struct mount *, int, struct ucred *, struct proc *)); -int ext2_truncate __P((struct vop_truncate_args *)); -int ext2_unmount __P((struct mount *, int, struct proc *)); -int ext2_update __P((struct vop_update_args *)); -int ext2_valloc __P((struct vop_valloc_args *)); -int ext2_vfree __P((struct vop_vfree_args *)); -int ext2_vget __P((struct mount *, ino_t, struct vnode **)); -int ext2_vptofh __P((struct vnode *, struct fid *)); -int ext2_write __P((struct vop_write_args *)); -int ext2_lookup __P((struct vop_lookup_args *)); -int ext2_readdir __P((struct vop_readdir_args *)); -void ext2_print_dinode __P((struct dinode *)); -void ext2_print_inode __P((struct inode *)); -int ext2_direnter __P((struct inode *, - struct vnode *, struct componentname *)); -int ext2_dirremove __P((struct vnode *, struct componentname *)); -int ext2_dirrewrite __P((struct inode *, - struct inode *, struct componentname *)); -int ext2_dirempty __P((struct inode *, ino_t, struct ucred *)); -int ext2_checkpath __P((struct inode *, struct inode *, struct ucred *)); -struct ext2_group_desc * get_group_desc __P((struct mount * , - unsigned int , struct buf ** )); -void ext2_discard_prealloc __P((struct inode *)); -int ext2_inactive __P((struct vop_inactive_args *)); -int ll_w_block __P((struct buf *, int )); -int ext2_di2ei __P((struct dinode *di, struct ext2_inode *ei)); -int ext2_ei2di __P((struct ext2_inode *ei, struct dinode *di)); -int ext2_new_block __P ((struct mount * mp, unsigned long goal, - long * prealloc_count, - long * prealloc_block)); -ino_t ext2_new_inode __P ((const struct inode * dir, int mode)); -void ext2_free_blocks (struct mount * mp, unsigned long block, - unsigned long count); -void ext2_free_inode (struct inode * inode); -int ext2_flushfiles __P((struct mount *mp, int flags, struct proc *p)); -int ext2_reload __P((struct mount *mountp, struct ucred *cred, - struct proc *p)); - -#if !defined(__FreeBSD__) -int bwrite(); /* FFS needs a bwrite routine. XXX */ -#endif - -/* this macros allows some of the ufs code to distinguish between - * an EXT2 and a non-ext2(FFS/LFS) vnode. - */ -#define IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS) - -#ifdef DIAGNOSTIC -void ext2_checkoverlap __P((struct buf *, struct inode *)); -#endif -__END_DECLS - -extern int (**ext2_vnodeop_p)(); -extern int (**ext2_specop_p)(); -#ifdef FIFO -extern int (**ext2_fifoop_p)(); -#define EXT2_FIFOOPS ext2_fifoop_p -#else -#define EXT2_FIFOOPS NULL -#endif diff --git a/sys/gnu/fs/ext2fs/ext2_fs.h b/sys/gnu/fs/ext2fs/ext2_fs.h deleted file mode 100644 index 56a8575..0000000 --- a/sys/gnu/fs/ext2fs/ext2_fs.h +++ /dev/null @@ -1,340 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * linux/include/linux/ext2_fs.h - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ -#ifndef _LINUX_EXT2_FS_H -#define _LINUX_EXT2_FS_H - -#include <sys/types.h> - -#ifdef i386 -#if defined(__FreeBSD__) -#include <machine/types.h> -#else -#include <i386/types.h> -#endif -#else -#error need processor specific types -#endif - -#define __u32 u_int32_t -#define u32 u_int32_t -#define __u16 u_int16_t -#define __u8 u_int8_t - -#define __s32 int32_t -#define __s16 int16_t -#define __s8 int8_t - -#define umode_t mode_t -#define loff_t off_t - -/* the Linux implementation of EXT2 stores some information about - * an inode in a ext2_inode_info structure which is part of the incore - * inode in Linux - * I decided to use the i_spare[11] fields instead - we'll see how this - * works out - */ - -#define i_block_group i_spare[0] -#define i_next_alloc_block i_spare[1] -#define i_next_alloc_goal i_spare[2] -#define i_prealloc_block i_spare[3] -#define i_prealloc_count i_spare[4] - -/* - * The second extended filesystem constants/structures - */ - -/* - * Define EXT2FS_DEBUG to produce debug messages - */ -#undef EXT2FS_DEBUG - -/* - * Define EXT2FS_DEBUG_CACHE to produce cache debug messages - */ -#undef EXT2FS_DEBUG_CACHE - -/* - * Define EXT2FS_CHECK_CACHE to add some checks to the name cache code - */ -#undef EXT2FS_CHECK_CACHE - -/* - * Define EXT2FS_PRE_02B_COMPAT to convert ext 2 fs prior to 0.2b - */ -#undef EXT2FS_PRE_02B_COMPAT - -/* - * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files - */ -#define EXT2_PREALLOCATE - -/* - * The second extended file system version - */ -#define EXT2FS_DATE "95/03/19" -#define EXT2FS_VERSION "0.5a" - -/* - * Debug code - */ -#ifdef EXT2FS_DEBUG -# define ext2_debug(f, a...) { \ - printf ("EXT2-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ - printf (f, ## a); \ - } -#else -# define ext2_debug(f, a...) /**/ -#endif - -/* - * Special inodes numbers - */ -#define EXT2_BAD_INO 1 /* Bad blocks inode */ -#define EXT2_ROOT_INO 2 /* Root inode */ -#define EXT2_ACL_IDX_INO 3 /* ACL inode */ -#define EXT2_ACL_DATA_INO 4 /* ACL inode */ -#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ -#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ -#define EXT2_FIRST_INO 11 /* First non reserved inode */ - -/* - * The second extended file system magic number - */ -#define EXT2_PRE_02B_MAGIC 0xEF51 -#define EXT2_SUPER_MAGIC 0xEF53 - -/* - * Maximal count of links to a file - */ -#define EXT2_LINK_MAX 32000 - -/* - * Macro-instructions used to manage several block sizes - */ -#define EXT2_MIN_BLOCK_SIZE 1024 -#define EXT2_MAX_BLOCK_SIZE 4096 -#define EXT2_MIN_BLOCK_LOG_SIZE 10 - -#define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) -#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / \ - sizeof (struct ext2_acl_entry)) -#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) -#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) - -#define EXT2_INODE_SIZE 128 - /* ought to be sizeof (struct ext2_inode)) */ -#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block) - -/* - * Macro-instructions used to manage fragments - */ -#define EXT2_MIN_FRAG_SIZE 1024 -#define EXT2_MAX_FRAG_SIZE 4096 -#define EXT2_MIN_FRAG_LOG_SIZE 10 -#define EXT2_FRAG_SIZE(s) ((s)->s_frag_size) -#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) - -/* - * ACL structures - */ -struct ext2_acl_header /* Header of Access Control Lists */ -{ - __u32 aclh_size; - __u32 aclh_file_count; - __u32 aclh_acle_count; - __u32 aclh_first_acle; -}; - -struct ext2_acl_entry /* Access Control List Entry */ -{ - __u32 acle_size; - __u16 acle_perms; /* Access permissions */ - __u16 acle_type; /* Type of entry */ - __u16 acle_tag; /* User or group identity */ - __u16 acle_pad1; - __u32 acle_next; /* Pointer on next entry for the */ - /* same inode or on next free entry */ -}; - -/* - * Structure of a blocks group descriptor - */ -struct ext2_old_group_desc -{ - __u32 bg_block_bitmap; /* Blocks bitmap block */ - __u32 bg_inode_bitmap; /* Inodes bitmap block */ - __u32 bg_inode_table; /* Inodes table block */ - __u16 bg_free_blocks_count; /* Free blocks count */ - __u16 bg_free_inodes_count; /* Free inodes count */ -}; - -struct ext2_group_desc -{ - __u32 bg_block_bitmap; /* Blocks bitmap block */ - __u32 bg_inode_bitmap; /* Inodes bitmap block */ - __u32 bg_inode_table; /* Inodes table block */ - __u16 bg_free_blocks_count; /* Free blocks count */ - __u16 bg_free_inodes_count; /* Free inodes count */ - __u16 bg_used_dirs_count; /* Directories count */ - __u16 bg_pad; - __u32 bg_reserved[3]; -}; - -/* - * Macro-instructions used to manage group descriptors - */ -#define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) -#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) -#define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) - -/* - * Constants relative to the data blocks - */ -#define EXT2_NDIR_BLOCKS 12 -#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS -#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) -#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) -#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) -#define EXT2_MAXSYMLINKLEN (EXT2_N_BLOCKS * sizeof (__u32)) - -/* - * Inode flags - */ -#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */ -#define EXT2_UNRM_FL 0x00000002 /* Undelete */ -#define EXT2_COMPR_FL 0x00000004 /* Compress file */ -#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */ -#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */ -#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */ -#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */ - -/* - * ioctl commands - */ -#define EXT2_IOC_GETFLAGS _IOR('f', 1, long) -#define EXT2_IOC_SETFLAGS _IOW('f', 2, long) -#define EXT2_IOC_GETVERSION _IOR('v', 1, long) -#define EXT2_IOC_SETVERSION _IOW('v', 2, long) - -/* - * File system states - */ -#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ -#define EXT2_ERROR_FS 0x0002 /* Errors detected */ - -/* - * Mount flags - */ -#define EXT2_MOUNT_CHECK_NORMAL 0x0001 /* Do some more checks */ -#define EXT2_MOUNT_CHECK_STRICT 0x0002 /* Do again more checks */ -#define EXT2_MOUNT_CHECK (EXT2_MOUNT_CHECK_NORMAL | \ - EXT2_MOUNT_CHECK_STRICT) -#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ -#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ -#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ -#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ -#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ -#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ - -#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt -#define set_opt(o, opt) o |= EXT2_MOUNT_##opt -#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \ - EXT2_MOUNT_##opt) -/* - * Maximal mount counts between two filesystem checks - */ -#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ -#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ - -/* - * Behaviour when detecting errors - */ -#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ -#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ -#define EXT2_ERRORS_PANIC 3 /* Panic */ -#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE - -/* - * Structure of the super block - */ -struct ext2_super_block { - __u32 s_inodes_count; /* Inodes count */ - __u32 s_blocks_count; /* Blocks count */ - __u32 s_r_blocks_count; /* Reserved blocks count */ - __u32 s_free_blocks_count; /* Free blocks count */ - __u32 s_free_inodes_count; /* Free inodes count */ - __u32 s_first_data_block; /* First Data Block */ - __u32 s_log_block_size; /* Block size */ - __s32 s_log_frag_size; /* Fragment size */ - __u32 s_blocks_per_group; /* # Blocks per group */ - __u32 s_frags_per_group; /* # Fragments per group */ - __u32 s_inodes_per_group; /* # Inodes per group */ - __u32 s_mtime; /* Mount time */ - __u32 s_wtime; /* Write time */ - __u16 s_mnt_count; /* Mount count */ - __s16 s_max_mnt_count; /* Maximal mount count */ - __u16 s_magic; /* Magic signature */ - __u16 s_state; /* File system state */ - __u16 s_errors; /* Behaviour when detecting errors */ - __u16 s_pad; - __u32 s_lastcheck; /* time of last check */ - __u32 s_checkinterval; /* max. time between checks */ - __u32 s_creator_os; /* OS */ - __u32 s_rev_level; /* Revision level */ - __u16 s_def_resuid; /* Default uid for reserved blocks */ - __u16 s_def_resgid; /* Default gid for reserved blocks */ - __u32 s_reserved[235]; /* Padding to the end of the block */ -}; - -#define EXT2_OS_LINUX 0 -#define EXT2_OS_HURD 1 -#define EXT2_OS_MASIX 2 - -#define EXT2_CURRENT_REV 0 - -#define EXT2_DEF_RESUID 0 -#define EXT2_DEF_RESGID 0 - -/* - * Structure of a directory entry - */ -#define EXT2_NAME_LEN 255 - -struct ext2_dir_entry { - __u32 inode; /* Inode number */ - __u16 rec_len; /* Directory entry length */ - __u16 name_len; /* Name length */ - char name[EXT2_NAME_LEN]; /* File name */ -}; - -/* - * EXT2_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT2_DIR_PAD 4 -#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) - -#endif /* _LINUX_EXT2_FS_H */ diff --git a/sys/gnu/fs/ext2fs/ext2_fs_sb.h b/sys/gnu/fs/ext2fs/ext2_fs_sb.h deleted file mode 100644 index f475ce2..0000000 --- a/sys/gnu/fs/ext2fs/ext2_fs_sb.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * linux/include/linux/ext2_fs_sb.h - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs_sb.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#ifndef _LINUX_EXT2_FS_SB -#define _LINUX_EXT2_FS_SB - -/* - * The following is not needed anymore since the descriptors buffer - * heads are now dynamically allocated - */ -/* #define EXT2_MAX_GROUP_DESC 8 */ - -#define EXT2_MAX_GROUP_LOADED 8 - -#if defined(LITES) || defined(__FreeBSD__) -#define buffer_head buf -#define MAXMNTLEN 512 -#endif - -/* - * second extended-fs super-block data in memory - */ -struct ext2_sb_info { - unsigned long s_frag_size; /* Size of a fragment in bytes */ - unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ - unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_db_per_group; /* Number of descriptor blocks per group */ - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ - struct buffer_head * s_sbh; /* Buffer containing the super block */ - struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */ - struct buffer_head ** s_group_desc; - unsigned short s_loaded_inode_bitmaps; - unsigned short s_loaded_block_bitmaps; - unsigned long s_inode_bitmap_number[EXT2_MAX_GROUP_LOADED]; - struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED]; - unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED]; - struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED]; - int s_rename_lock; -#if !defined(LITES) && !defined(__FreeBSD__) - struct wait_queue * s_rename_wait; -#endif - unsigned long s_mount_opt; - unsigned short s_resuid; - unsigned short s_resgid; - unsigned short s_mount_state; -#if defined(LITES) || defined(__FreeBSD__) - /* - stuff that FFS keeps in its super block or that linux - has in its non-ext2 specific super block and which is - generally considered useful - */ - unsigned long s_blocksize; - unsigned long s_blocksize_bits; - unsigned int s_bshift; /* = log2(s_blocksize) */ - quad_t s_qbmask; /* = s_blocksize - 1 */ - unsigned int s_fsbtodb; /* shift to get disk block */ - char s_rd_only; /* read-only */ - char s_dirt; /* fs modified flag */ - - char fs_fsmnt[MAXMNTLEN]; /* name mounted on */ -#endif -}; - -#endif /* _LINUX_EXT2_FS_SB */ diff --git a/sys/gnu/fs/ext2fs/ext2_inode.c b/sys/gnu/fs/ext2fs/ext2_inode.c deleted file mode 100644 index f2d6fd7..0000000 --- a/sys/gnu/fs/ext2fs/ext2_inode.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_inode.c 8.5 (Berkeley) 12/30/93 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mount.h> -#include <sys/proc.h> -#include <sys/file.h> -#include <sys/buf.h> -#include <sys/vnode.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if !defined(__FreeBSD__) -#include <sys/trace.h> -#endif -#include <sys/resourcevar.h> - -#include <vm/vm.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -static int ext2_indirtrunc __P((struct inode *, daddr_t, daddr_t, daddr_t, int, - long *)); - -int -ext2_init() -{ - return (ufs_init()); -} - -/* - * Update the access, modified, and inode change times as specified by the - * IACCESS, IUPDATE, and ICHANGE flags respectively. The IMODIFIED flag is - * used to specify that the inode needs to be updated but that the times have - * already been set. The access and modified times are taken from the second - * and third parameters; the inode change time is always taken from the current - * time. If waitfor is set, then wait for the disk write of the inode to - * complete. - */ -int -ext2_update(ap) - struct vop_update_args /* { - struct vnode *a_vp; - struct timeval *a_access; - struct timeval *a_modify; - int a_waitfor; - } */ *ap; -{ - register struct ext2_sb_info *fs; - struct buf *bp; - struct inode *ip; - int error; -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - ip = VTOI(ap->a_vp); - if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) { - ip->i_flag &= - ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE); - return (0); - } - if ((ip->i_flag & - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0) - return (0); - if (ip->i_flag & IN_ACCESS) - ip->i_atime.ts_sec = ap->a_access->tv_sec; - if (ip->i_flag & IN_UPDATE) { - ip->i_mtime.ts_sec = ap->a_modify->tv_sec; - ip->i_modrev++; - } - if (ip->i_flag & IN_CHANGE) { -#if !defined(__FreeBSD__) - get_time(&time); -#endif - ip->i_ctime.ts_sec = time.tv_sec; - } - ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE); - fs = ip->i_e2fs; - if (error = bread(ip->i_devvp, - fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), - (int)fs->s_blocksize, NOCRED, &bp)) { - brelse(bp); - return (error); - } - ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * - ino_to_fsbo(fs, ip->i_number))); -/* - if (ap->a_waitfor && (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0) - return (bwrite(bp)); - else { -*/ - bdwrite(bp); - return (0); -/* - } -*/ -} - -#define SINGLE 0 /* index of single indirect block */ -#define DOUBLE 1 /* index of double indirect block */ -#define TRIPLE 2 /* index of triple indirect block */ -/* - * Truncate the inode oip to at most length size, freeing the - * disk blocks. - */ -int -ext2_truncate(ap) - struct vop_truncate_args /* { - struct vnode *a_vp; - off_t a_length; - int a_flags; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - register struct vnode *ovp = ap->a_vp; - register daddr_t lastblock; - register struct inode *oip; - daddr_t bn, lbn, lastiblock[NIADDR], indir_lbn[NIADDR]; - daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR]; - off_t length = ap->a_length; - register struct ext2_sb_info *fs; - struct buf *bp; - int offset, size, level; - long count, nblocks, vflags, blocksreleased = 0; - struct timeval tv; - register int i; - int aflags, error, allerror; - off_t osize; -/* -printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, ap->a_length); -*/ /* - * negative file sizes will totally break the code below and - * are not meaningful anyways. - */ - if (length < 0) - return EFBIG; - - oip = VTOI(ovp); -#if defined(__FreeBSD__) - tv = time; -#else - get_time(&tv); -#endif - if (ovp->v_type == VLNK && - oip->i_size < ovp->v_mount->mnt_maxsymlinklen) { -#if DIAGNOSTIC - if (length != 0) - panic("ext2_truncate: partial truncate of symlink"); -#endif - bzero((char *)&oip->i_shortlink, (u_int)oip->i_size); - oip->i_size = 0; - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 1)); - } - if (oip->i_size == length) { - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 0)); - } -#if QUOTA - if (error = getinoquota(oip)) - return (error); -#endif - vnode_pager_setsize(ovp, (u_long)length); - fs = oip->i_e2fs; - osize = oip->i_size; - ext2_discard_prealloc(oip); - /* - * Lengthen the size of the file. We must ensure that the - * last byte of the file is allocated. Since the smallest - * value of oszie is 0, length will be at least 1. - */ - if (osize < length) { - offset = blkoff(fs, length - 1); - lbn = lblkno(fs, length - 1); - aflags = B_CLRBUF; - if (ap->a_flags & IO_SYNC) - aflags |= B_SYNC; - if (error = ext2_balloc(oip, lbn, offset + 1, ap->a_cred, &bp, - aflags)) - return (error); - oip->i_size = length; -#if !defined(__FreeBSD__) - (void) vnode_pager_uncache(ovp); -#endif - if (aflags & IO_SYNC) - bwrite(bp); - else - bawrite(bp); - oip->i_flag |= IN_CHANGE | IN_UPDATE; - return (VOP_UPDATE(ovp, &tv, &tv, 1)); - } - /* - * Shorten the size of the file. If the file is not being - * truncated to a block boundry, the contents of the - * partial block following the end of the file must be - * zero'ed in case it ever become accessable again because - * of subsequent file growth. - */ - /* I don't understand the comment above */ - offset = blkoff(fs, length); - if (offset == 0) { - oip->i_size = length; - } else { - lbn = lblkno(fs, length); - aflags = B_CLRBUF; - if (ap->a_flags & IO_SYNC) - aflags |= B_SYNC; - if (error = ext2_balloc(oip, lbn, offset, ap->a_cred, &bp, - aflags)) - return (error); - oip->i_size = length; - size = blksize(fs, oip, lbn); -#if !defined(__FreeBSD__) - (void) vnode_pager_uncache(ovp); -#endif - bzero((char *)bp->b_data + offset, (u_int)(size - offset)); - allocbuf(bp, size); - if (aflags & IO_SYNC) - bwrite(bp); - else - bawrite(bp); - } - /* - * Calculate index into inode's block list of - * last direct and indirect blocks (if any) - * which we want to keep. Lastblock is -1 when - * the file is truncated to 0. - */ - lastblock = lblkno(fs, length + fs->s_blocksize - 1) - 1; - lastiblock[SINGLE] = lastblock - NDADDR; - lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs); - lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs); - nblocks = btodb(fs->s_blocksize); - /* - * Update file and block pointers on disk before we start freeing - * blocks. If we crash before free'ing blocks below, the blocks - * will be returned to the free list. lastiblock values are also - * normalized to -1 for calls to ext2_indirtrunc below. - */ - bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof oldblks); - for (level = TRIPLE; level >= SINGLE; level--) - if (lastiblock[level] < 0) { - oip->i_ib[level] = 0; - lastiblock[level] = -1; - } - for (i = NDADDR - 1; i > lastblock; i--) - oip->i_db[i] = 0; - oip->i_flag |= IN_CHANGE | IN_UPDATE; - if (error = VOP_UPDATE(ovp, &tv, &tv, MNT_WAIT)) - allerror = error; - /* - * Having written the new inode to disk, save its new configuration - * and put back the old block pointers long enough to process them. - * Note that we save the new block configuration so we can check it - * when we are done. - */ - bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof newblks); - bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof oldblks); - oip->i_size = osize; - vflags = ((length > 0) ? V_SAVE : 0) | V_SAVEMETA; - allerror = vinvalbuf(ovp, vflags, ap->a_cred, ap->a_p, 0, 0); - - /* - * Indirect blocks first. - */ - indir_lbn[SINGLE] = -NDADDR; - indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; - indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; - for (level = TRIPLE; level >= SINGLE; level--) { - bn = oip->i_ib[level]; - if (bn != 0) { - error = ext2_indirtrunc(oip, indir_lbn[level], - fsbtodb(fs, bn), lastiblock[level], level, &count); - if (error) - allerror = error; - blocksreleased += count; - if (lastiblock[level] < 0) { - oip->i_ib[level] = 0; - ext2_blkfree(oip, bn, fs->s_frag_size); - blocksreleased += nblocks; - } - } - if (lastiblock[level] >= 0) - goto done; - } - - /* - * All whole direct blocks or frags. - */ - for (i = NDADDR - 1; i > lastblock; i--) { - register long bsize; - - bn = oip->i_db[i]; - if (bn == 0) - continue; - oip->i_db[i] = 0; - bsize = blksize(fs, oip, i); - ext2_blkfree(oip, bn, bsize); - blocksreleased += btodb(bsize); - } - if (lastblock < 0) - goto done; - - /* - * Finally, look for a change in size of the - * last direct block; release any frags. - */ - bn = oip->i_db[lastblock]; - if (bn != 0) { - long oldspace, newspace; - - /* - * Calculate amount of space we're giving - * back as old block size minus new block size. - */ - oldspace = blksize(fs, oip, lastblock); - oip->i_size = length; - newspace = blksize(fs, oip, lastblock); - if (newspace == 0) - panic("itrunc: newspace"); - if (oldspace - newspace > 0) { - /* - * Block number of space to be free'd is - * the old block # plus the number of frags - * required for the storage we're keeping. - */ - bn += numfrags(fs, newspace); - ext2_blkfree(oip, bn, oldspace - newspace); - blocksreleased += btodb(oldspace - newspace); - } - } -done: -#if DIAGNOSTIC - for (level = SINGLE; level <= TRIPLE; level++) - if (newblks[NDADDR + level] != oip->i_ib[level]) - panic("itrunc1"); - for (i = 0; i < NDADDR; i++) - if (newblks[i] != oip->i_db[i]) - panic("itrunc2"); - if (length == 0 && - (ovp->v_dirtyblkhd.lh_first || ovp->v_cleanblkhd.lh_first)) - panic("itrunc3"); -#endif /* DIAGNOSTIC */ - /* - * Put back the real size. - */ - oip->i_size = length; - oip->i_blocks -= blocksreleased; - if (oip->i_blocks < 0) /* sanity */ - oip->i_blocks = 0; - oip->i_flag |= IN_CHANGE; -#if QUOTA - (void) chkdq(oip, -blocksreleased, NOCRED, 0); -#endif - return (allerror); -} - -/* - * Release blocks associated with the inode ip and stored in the indirect - * block bn. Blocks are free'd in LIFO order up to (but not including) - * lastbn. If level is greater than SINGLE, the block is an indirect block - * and recursive calls to indirtrunc must be used to cleanse other indirect - * blocks. - * - * NB: triple indirect blocks are untested. - */ - -static int -ext2_indirtrunc(ip, lbn, dbn, lastbn, level, countp) - register struct inode *ip; - daddr_t lbn, lastbn; - daddr_t dbn; - int level; - long *countp; -{ - register int i; - struct buf *bp; - register struct ext2_sb_info *fs = ip->i_e2fs; - register daddr_t *bap; - struct vnode *vp; - daddr_t *copy, nb, nlbn, last; - long blkcount, factor; - int nblocks, blocksreleased = 0; - int error = 0, allerror = 0; - - /* - * Calculate index in current block of last - * block to be kept. -1 indicates the entire - * block so we need not calculate the index. - */ - factor = 1; - for (i = SINGLE; i < level; i++) - factor *= NINDIR(fs); - last = lastbn; - if (lastbn > 0) - last /= factor; - nblocks = btodb(fs->s_blocksize); - /* - * Get buffer of block pointers, zero those entries corresponding - * to blocks to be free'd, and update on disk copy first. Since - * double(triple) indirect before single(double) indirect, calls - * to bmap on these blocks will fail. However, we already have - * the on disk address, so we have to set the b_blkno field - * explicitly instead of letting bread do everything for us. - */ - vp = ITOV(ip); - bp = getblk(vp, lbn, (int)fs->s_blocksize, 0, 0); - if (bp->b_flags & (B_DONE | B_DELWRI)) { - /* Braces must be here in case trace evaluates to nothing. */ -#if !defined(__FreeBSD__) - trace(TR_BREADHIT, pack(vp, fs->s_blocksize), lbn); -#endif - } else { -#if !defined(__FreeBSD__) - trace(TR_BREADMISS, pack(vp, fs->s_blocksize), lbn); - get_proc()->p_stats->p_ru.ru_inblock++; /* pay for read */ -#endif - bp->b_flags |= B_READ; - if (bp->b_bcount > bp->b_bufsize) - panic("ext2_indirtrunc: bad buffer size"); - bp->b_blkno = dbn; -#if defined(__FreeBSD__) - vfs_busy_pages(bp, 0); -#endif - VOP_STRATEGY(bp); - error = biowait(bp); - } - if (error) { - brelse(bp); - *countp = 0; - return (error); - } - - bap = (daddr_t *)bp->b_data; - MALLOC(copy, daddr_t *, fs->s_blocksize, M_TEMP, M_WAITOK); - bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->s_blocksize); - bzero((caddr_t)&bap[last + 1], - (u_int)(NINDIR(fs) - (last + 1)) * sizeof (daddr_t)); - if (last == -1) - bp->b_flags |= B_INVAL; - error = bwrite(bp); - if (error) - allerror = error; - bap = copy; - - /* - * Recursively free totally unused blocks. - */ - for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; - i--, nlbn += factor) { - nb = bap[i]; - if (nb == 0) - continue; - if (level > SINGLE) { - if (error = ext2_indirtrunc(ip, nlbn, - fsbtodb(fs, nb), (daddr_t)-1, level - 1, &blkcount)) - allerror = error; - blocksreleased += blkcount; - } - ext2_blkfree(ip, nb, fs->s_blocksize); - blocksreleased += nblocks; - } - - /* - * Recursively free last partial block. - */ - if (level > SINGLE && lastbn >= 0) { - last = lastbn % factor; - nb = bap[i]; - if (nb != 0) { - if (error = ext2_indirtrunc(ip, nlbn, fsbtodb(fs, nb), - last, level - 1, &blkcount)) - allerror = error; - blocksreleased += blkcount; - } - } - FREE(copy, M_TEMP); - *countp = blocksreleased; - return (allerror); -} - -/* - * discard preallocated blocks - */ -int -ext2_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - } */ *ap; -{ - ext2_discard_prealloc(VTOI(ap->a_vp)); - return ufs_inactive(ap); -} - diff --git a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c b/sys/gnu/fs/ext2fs/ext2_inode_cnv.c deleted file mode 100644 index 1ab48e9..0000000 --- a/sys/gnu/fs/ext2fs/ext2_inode_cnv.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 1995 The University of Utah and - * the Computer Systems Laboratory at the University of Utah (CSL). - * All rights reserved. - * - * Permission to use, copy, modify and distribute this software is hereby - * granted provided that (1) source code retains these copyright, permission, - * and disclaimer notices, and (2) redistributions including binaries - * reproduce the notices in supporting documentation, and (3) all advertising - * materials mentioning features or use of this software display the following - * acknowledgement: ``This product includes software developed by the - * Computer Systems Laboratory at the University of Utah.'' - * - * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS - * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF - * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * CSL requests users of this software to return to csl-dist@cs.utah.edu any - * improvements that they make and grant CSL redistribution rights. - * - * Utah $Hdr$ - */ - -/* - * routines to convert on disk ext2 inodes in dinodes and back - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -/* these defs would destroy the ext2_fs_i #include */ -#undef i_atime -#undef i_blocks -#undef i_ctime -#undef i_db -#undef i_flags -#undef i_gen -#undef i_gid -#undef i_ib -#undef i_mode -#undef i_mtime -#undef i_nlink -#undef i_rdev -#undef i_shortlink -#undef i_size -#undef i_uid - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_i.h> - -void ext2_print_dinode( di ) - struct dinode *di; -{ - int i; - printf( /* "Inode: %5d" */ - " Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n", - "n/a", di->di_mode, di->di_flags, di->di_gen); - printf( "User: %5d Group: %5d Size: %d\n", - di->di_uid, di->di_gid, di->di_size); - printf( "Links: %3d Blockcount: %d\n", - di->di_nlink, di->di_blocks); - printf( "ctime: 0x%x", di->di_ctime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_ctime.ts_sec); -#endif - printf( "atime: 0x%x", di->di_atime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_atime.ts_sec); -#endif - printf( "mtime: 0x%x", di->di_mtime.ts_sec); -#if !defined(__FreeBSD__) - print_time(" -- %s\n", di->di_mtime.ts_sec); -#endif - printf( "BLOCKS: "); - for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++) - printf("%d ", di->di_db[i]); - printf("\n"); -} - -void ext2_print_inode( in ) - struct inode *in; -{ - printf( "Inode: %5d", in->i_number); - ext2_print_dinode(&in->i_din); -} - -/* - * raw ext2 inode to dinode - */ -int ext2_ei2di(ei, di) - struct ext2_inode *ei; - struct dinode *di; -{ - int i; - - di->di_nlink = ei->i_links_count; - /* Godmar thinks - if the link count is zero, then the inode is - unused - according to ext2 standards. Ufs marks this fact - by setting i_mode to zero - why ? - I can see that this might lead to problems in an undelete. - */ - di->di_mode = ei->i_links_count ? ei->i_mode : 0; - di->di_size = ei->i_size; - di->di_atime.ts_sec = ei->i_atime; - di->di_mtime.ts_sec = ei->i_mtime; - di->di_ctime.ts_sec = ei->i_ctime; - di->di_flags = 0; - di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0; - di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0; - di->di_blocks = ei->i_blocks; - di->di_gen = ei->i_version; /* XXX is that true ??? */ - di->di_uid = ei->i_uid; - di->di_gid = ei->i_gid; - /* XXX use memcpy */ - for(i = 0; i < NDADDR; i++) - di->di_db[i] = ei->i_block[i]; - for(i = 0; i < NIADDR; i++) - di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i]; -} - -/* - * dinode to raw ext2 inode - */ -int ext2_di2ei(di, ei) - struct dinode *di; - struct ext2_inode *ei; -{ - int i; - - ei->i_mode = di->di_mode; - ei->i_links_count = di->di_nlink; - /* - Godmar thinks: if dtime is nonzero, ext2 says this inode - has been deleted, this would correspond to a zero link count - */ - ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime.ts_sec; - ei->i_size = di->di_size; - ei->i_atime = di->di_atime.ts_sec; - ei->i_mtime = di->di_mtime.ts_sec; - ei->i_ctime = di->di_ctime.ts_sec; - ei->i_flags = di->di_flags; - ei->i_flags = 0; - ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0; - ei->i_flags |= (di->di_flags & IMMUTABLE) - ? EXT2_IMMUTABLE_FL: 0; - ei->i_blocks = di->di_blocks; - ei->i_version = di->di_gen; /* XXX is that true ??? */ - ei->i_uid = di->di_uid; - ei->i_gid = di->di_gid; - /* XXX use memcpy */ - for(i = 0; i < NDADDR; i++) - ei->i_block[i] = di->di_db[i]; - for(i = 0; i < NIADDR; i++) - ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i]; -} diff --git a/sys/gnu/fs/ext2fs/ext2_linux_balloc.c b/sys/gnu/fs/ext2fs/ext2_linux_balloc.c deleted file mode 100644 index 25b9891..0000000 --- a/sys/gnu/fs/ext2fs/ext2_linux_balloc.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * linux/fs/ext2/balloc.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 - */ - -/* - * The free blocks are managed by bitmaps. A file system contains several - * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap - * block for inodes, N blocks for the inode table and data blocks. - * - * The file system contains group descriptors which are located after the - * super block. Each descriptor contains the number of the bitmap block and - * the free blocks count in the block. The descriptors are loaded in memory - * when a file system is mounted (see ext2_read_super). - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/vnode.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/ufsmount.h> -#include <gnu/ext2fs/ext2_extern.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <sys/stat.h> - -#ifdef i386 -#include <gnu/ext2fs/i386-bitops.h> -#else -#error Provide an bitops.h file, please ! -#endif - -unsigned long ext2_count_free __P((struct buffer_head *, unsigned int)); - -#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) - -/* got rid of get_group_desc since it can already be found in - * ext2_linux_ialloc.c - */ - -static void read_block_bitmap (struct mount * mp, - unsigned int block_group, - unsigned long bitmap_nr) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct ext2_group_desc * gdp; - struct buffer_head * bh; - int error; - - gdp = get_group_desc (mp, block_group, NULL); - if(error = bread (VFSTOUFS(mp)->um_devvp, - fsbtodb(sb, gdp->bg_block_bitmap),sb->s_blocksize, NOCRED, &bh)) - panic ( "read_block_bitmap: " - "Cannot read block bitmap - " - "block_group = %d, block_bitmap = %lu", - block_group, (unsigned long) gdp->bg_block_bitmap); - sb->s_block_bitmap_number[bitmap_nr] = block_group; - sb->s_block_bitmap[bitmap_nr] = bh; -} - -/* - * load_block_bitmap loads the block bitmap for a blocks group - * - * It maintains a cache for the last bitmaps loaded. This cache is managed - * with a LRU algorithm. - * - * Notes: - * 1/ There is one cache per mounted file system. - * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups, - * this function reads the bitmap without maintaining a LRU cache. - */ -static int load__block_bitmap (struct mount * mp, - unsigned int block_group) -{ - int i, j; - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - unsigned long block_bitmap_number; - struct buffer_head * block_bitmap; - int error; - - if (block_group >= sb->s_groups_count) - panic ( "load_block_bitmap: " - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", - block_group, sb->s_groups_count); - - if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) { - if (sb->s_block_bitmap[block_group]) { - if (sb->s_block_bitmap_number[block_group] != - block_group) - panic ( "load_block_bitmap: " - "block_group != block_bitmap_number"); - else - return block_group; - } else { - read_block_bitmap (mp, block_group, block_group); - return block_group; - } - } - - for (i = 0; i < sb->s_loaded_block_bitmaps && - sb->s_block_bitmap_number[i] != block_group; i++) - ; - if (i < sb->s_loaded_block_bitmaps && - sb->s_block_bitmap_number[i] == block_group) { - block_bitmap_number = sb->s_block_bitmap_number[i]; - block_bitmap = sb->s_block_bitmap[i]; - for (j = i; j > 0; j--) { - sb->s_block_bitmap_number[j] = - sb->s_block_bitmap_number[j - 1]; - sb->s_block_bitmap[j] = - sb->s_block_bitmap[j - 1]; - } - sb->s_block_bitmap_number[0] = block_bitmap_number; - sb->s_block_bitmap[0] = block_bitmap; - } else { - if (sb->s_loaded_block_bitmaps < EXT2_MAX_GROUP_LOADED) - sb->s_loaded_block_bitmaps++; - else - brelse (sb->s_block_bitmap[EXT2_MAX_GROUP_LOADED - 1]); - for (j = sb->s_loaded_block_bitmaps - 1; j > 0; j--) { - sb->s_block_bitmap_number[j] = - sb->s_block_bitmap_number[j - 1]; - sb->s_block_bitmap[j] = - sb->s_block_bitmap[j - 1]; - } - read_block_bitmap (mp, block_group, 0); - } - return 0; -} - -static inline int load_block_bitmap (struct mount * mp, - unsigned int block_group) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - if (sb->s_loaded_block_bitmaps > 0 && - sb->s_block_bitmap_number[0] == block_group) - return 0; - - if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED && - sb->s_block_bitmap_number[block_group] == block_group && - sb->s_block_bitmap[block_group]) - return block_group; - - return load__block_bitmap (mp, block_group); -} - -void ext2_free_blocks (struct mount * mp, unsigned long block, - unsigned long count) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct buffer_head * bh; - struct buffer_head * bh2; - unsigned long block_group; - unsigned long bit; - unsigned long i; - int bitmap_nr; - struct ext2_group_desc * gdp; - struct ext2_super_block * es = sb->s_es; - - if (!sb) { - printf ("ext2_free_blocks: nonexistent device"); - return; - } - lock_super (VFSTOUFS(mp)->um_devvp); - if (block < es->s_first_data_block || - (block + count) > es->s_blocks_count) { - printf ( "ext2_free_blocks: " - "Freeing blocks not in datazone - " - "block = %lu, count = %lu", block, count); - unlock_super (VFSTOUFS(mp)->um_devvp); - return; - } - - ext2_debug ("freeing blocks %lu to %lu\n", block, block+count-1); - - block_group = (block - es->s_first_data_block) / - EXT2_BLOCKS_PER_GROUP(sb); - bit = (block - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb); - if (bit + count > EXT2_BLOCKS_PER_GROUP(sb)) - panic ( "ext2_free_blocks: " - "Freeing blocks across group boundary - " - "Block = %lu, count = %lu", - block, count); - bitmap_nr = load_block_bitmap (mp, block_group); - bh = sb->s_block_bitmap[bitmap_nr]; - gdp = get_group_desc (mp, block_group, &bh2); - - if (/* test_opt (sb, CHECK_STRICT) && assume always strict ! */ - (in_range (gdp->bg_block_bitmap, block, count) || - in_range (gdp->bg_inode_bitmap, block, count) || - in_range (block, gdp->bg_inode_table, - sb->s_itb_per_group) || - in_range (block + count - 1, gdp->bg_inode_table, - sb->s_itb_per_group))) - panic ( "ext2_free_blocks: " - "Freeing blocks in system zones - " - "Block = %lu, count = %lu", - block, count); - - for (i = 0; i < count; i++) { - if (!clear_bit (bit + i, bh->b_data)) - printf ("ext2_free_blocks: " - "bit already cleared for block %lu", - block); - else { - gdp->bg_free_blocks_count++; - es->s_free_blocks_count++; - } - } - - mark_buffer_dirty(bh2); - mark_buffer_dirty(bh, 1); -/**** - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -****/ - sb->s_dirt = 1; - unlock_super (VFSTOUFS(mp)->um_devvp); - return; -} - -/* - * ext2_new_block uses a goal block to assist allocation. If the goal is - * free, or there is a free block within 32 blocks of the goal, that block - * is allocated. Otherwise a forward search is made for a free block; within - * each block group the search first looks for an entire free byte in the block - * bitmap, and then for any free bit if that fails. - */ -int ext2_new_block (struct mount * mp, unsigned long goal, - long * prealloc_count, - long * prealloc_block) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct buffer_head * bh; - struct buffer_head * bh2; - char * p, * r; - int i, j, k, tmp; - int bitmap_nr; - struct ext2_group_desc * gdp; - struct ext2_super_block * es = sb->s_es; - -#ifdef EXT2FS_DEBUG - static int goal_hits = 0, goal_attempts = 0; -#endif - if (!sb) { - printf ("ext2_new_block: nonexistent device"); - return 0; - } - lock_super (VFSTOUFS(mp)->um_devvp); - - ext2_debug ("goal=%lu.\n", goal); - -repeat: - /* - * First, test whether the goal block is free. - */ - if (goal < es->s_first_data_block || goal >= es->s_blocks_count) - goal = es->s_first_data_block; - i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb); - gdp = get_group_desc (mp, i, &bh2); - if (gdp->bg_free_blocks_count > 0) { - j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb)); -#ifdef EXT2FS_DEBUG - if (j) - goal_attempts++; -#endif - bitmap_nr = load_block_bitmap (mp, i); - bh = sb->s_block_bitmap[bitmap_nr]; - - ext2_debug ("goal is at %d:%d.\n", i, j); - - if (!test_bit(j, bh->b_data)) { -#ifdef EXT2FS_DEBUG - goal_hits++; - ext2_debug ("goal bit allocated.\n"); -#endif - goto got_block; - } - if (j) { - /* - * The goal was occupied; search forward for a free - * block within the next XX blocks. - * - * end_goal is more or less random, but it has to be - * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the - * next 64-bit boundary is simple.. - */ - int end_goal = (j + 63) & ~63; - j = find_next_zero_bit(bh->b_data, end_goal, j); - if (j < end_goal) - goto got_block; - } - - ext2_debug ("Bit not found near goal\n"); - - /* - * There has been no free block found in the near vicinity - * of the goal: do a search forward through the block groups, - * searching in each group first for an entire free byte in - * the bitmap and then for any free bit. - * - * Search first in the remainder of the current group; then, - * cyclicly search through the rest of the groups. - */ - p = ((char *) bh->b_data) + (j >> 3); - r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3); - k = (r - ((char *) bh->b_data)) << 3; - if (k < EXT2_BLOCKS_PER_GROUP(sb)) { - j = k; - goto search_back; - } - k = find_next_zero_bit ((unsigned long *) bh->b_data, - EXT2_BLOCKS_PER_GROUP(sb), - j); - if (k < EXT2_BLOCKS_PER_GROUP(sb)) { - j = k; - goto got_block; - } - } - - ext2_debug ("Bit not found in block group %d.\n", i); - - /* - * Now search the rest of the groups. We assume that - * i and gdp correctly point to the last group visited. - */ - for (k = 0; k < sb->s_groups_count; k++) { - i++; - if (i >= sb->s_groups_count) - i = 0; - gdp = get_group_desc (mp, i, &bh2); - if (gdp->bg_free_blocks_count > 0) - break; - } - if (k >= sb->s_groups_count) { - unlock_super (VFSTOUFS(mp)->um_devvp); - return 0; - } - bitmap_nr = load_block_bitmap (mp, i); - bh = sb->s_block_bitmap[bitmap_nr]; - r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3); - j = (r - bh->b_data) << 3; - - if (j < EXT2_BLOCKS_PER_GROUP(sb)) - goto search_back; - else - j = find_first_zero_bit ((unsigned long *) bh->b_data, - EXT2_BLOCKS_PER_GROUP(sb)); - if (j >= EXT2_BLOCKS_PER_GROUP(sb)) { - printf ( "ext2_new_block: " - "Free blocks count corrupted for block group %d", i); - unlock_super (VFSTOUFS(mp)->um_devvp); - return 0; - } - -search_back: - /* - * We have succeeded in finding a free byte in the block - * bitmap. Now search backwards up to 7 bits to find the - * start of this group of free blocks. - */ - for (k = 0; k < 7 && j > 0 && !test_bit (j - 1, bh->b_data); k++, j--); - -got_block: - - ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count); - - tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + es->s_first_data_block; - - if (/* test_opt (sb, CHECK_STRICT) && we are always strict. */ - (tmp == gdp->bg_block_bitmap || - tmp == gdp->bg_inode_bitmap || - in_range (tmp, gdp->bg_inode_table, sb->s_itb_per_group))) - panic ( "ext2_new_block: " - "Allocating block in system zone - " - "%dth block = %u in group %u", j, tmp, i); - - if (set_bit (j, bh->b_data)) { - printf ( "ext2_new_block: " - "bit already set for block %d", j); - goto repeat; - } - - ext2_debug ("found bit %d\n", j); - - /* - * Do block preallocation now if required. - */ -#ifdef EXT2_PREALLOCATE - if (prealloc_block) { - *prealloc_count = 0; - *prealloc_block = tmp + 1; - for (k = 1; - k < 8 && (j + k) < EXT2_BLOCKS_PER_GROUP(sb); k++) { - if (set_bit (j + k, bh->b_data)) - break; - (*prealloc_count)++; - } - gdp->bg_free_blocks_count -= *prealloc_count; - es->s_free_blocks_count -= *prealloc_count; - ext2_debug ("Preallocated a further %lu bits.\n", - *prealloc_count); - } -#endif - - j = tmp; - - mark_buffer_dirty(bh); -/**** - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -****/ - if (j >= es->s_blocks_count) { - printf ( "ext2_new_block: " - "block >= blocks count - " - "block_group = %d, block=%d", i, j); - unlock_super (VFSTOUFS(mp)->um_devvp); - return 0; - } - - ext2_debug ("allocating block %d. " - "Goal hits %d of %d.\n", j, goal_hits, goal_attempts); - - gdp->bg_free_blocks_count--; - mark_buffer_dirty(bh2, 1); - es->s_free_blocks_count--; - sb->s_dirt = 1; - unlock_super (VFSTOUFS(mp)->um_devvp); - return j; -} - -unsigned long ext2_count_free_blocks (struct mount * mp) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; -#ifdef EXT2FS_DEBUG - struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x; - int bitmap_nr; - struct ext2_group_desc * gdp; - int i; - - lock_super (VFSTOUFS(mp)->um_devvp); - es = sb->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - for (i = 0; i < sb->s_groups_count; i++) { - gdp = get_group_desc (mp, i, NULL); - desc_count += gdp->bg_free_blocks_count; - bitmap_nr = load_block_bitmap (mp, i); - x = ext2_count_free (sb->s_block_bitmap[bitmap_nr], - sb->s_blocksize); - ext2_debug ("group %d: stored = %d, counted = %lu\n", - i, gdp->bg_free_blocks_count, x); - bitmap_count += x; - } - ext2_debug( "stored = %lu, computed = %lu, %lu\n", - es->s_free_blocks_count, desc_count, bitmap_count); - unlock_super (VFSTOUFS(mp)->um_devvp); - return bitmap_count; -#else - return sb->s_es->s_free_blocks_count; -#endif -} - - -static inline int block_in_use (unsigned long block, - struct ext2_sb_info * sb, - unsigned char * map) -{ - return test_bit ((block - sb->s_es->s_first_data_block) % - EXT2_BLOCKS_PER_GROUP(sb), map); -} - -void ext2_check_blocks_bitmap (struct mount * mp) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct buffer_head * bh; - struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x; - unsigned long desc_blocks; - int bitmap_nr; - struct ext2_group_desc * gdp; - int i, j; - - lock_super (VFSTOUFS(mp)->um_devvp); - es = sb->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - desc_blocks = (sb->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / - EXT2_DESC_PER_BLOCK(sb); - for (i = 0; i < sb->s_groups_count; i++) { - gdp = get_group_desc (mp, i, NULL); - desc_count += gdp->bg_free_blocks_count; - bitmap_nr = load_block_bitmap (mp, i); - bh = sb->s_block_bitmap[bitmap_nr]; - - if (!test_bit (0, bh->b_data)) - printf ( "ext2_check_blocks_bitmap: " - "Superblock in group %d is marked free", i); - - for (j = 0; j < desc_blocks; j++) - if (!test_bit (j + 1, bh->b_data)) - printf ("ext2_check_blocks_bitmap: " - "Descriptor block #%d in group " - "%d is marked free", j, i); - - if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data)) - printf ("ext2_check_blocks_bitmap: " - "Block bitmap for group %d is marked free", - i); - - if (!block_in_use (gdp->bg_inode_bitmap, sb, bh->b_data)) - printf ("ext2_check_blocks_bitmap: " - "Inode bitmap for group %d is marked free", - i); - - for (j = 0; j < sb->s_itb_per_group; j++) - if (!block_in_use (gdp->bg_inode_table + j, sb, bh->b_data)) - printf ("ext2_check_blocks_bitmap: " - "Block #%d of the inode table in " - "group %d is marked free", j, i); - - x = ext2_count_free (bh, sb->s_blocksize); - if (gdp->bg_free_blocks_count != x) - printf ("ext2_check_blocks_bitmap: " - "Wrong free blocks count for group %d, " - "stored = %d, counted = %lu", i, - gdp->bg_free_blocks_count, x); - bitmap_count += x; - } - if (es->s_free_blocks_count != bitmap_count) - printf ("ext2_check_blocks_bitmap: " - "Wrong free blocks count in super block, " - "stored = %lu, counted = %lu", - (unsigned long) es->s_free_blocks_count, bitmap_count); - unlock_super (VFSTOUFS(mp)->um_devvp); -} - -/* - * this function is taken from - * linux/fs/ext2/bitmap.c - */ - -static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; - -unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) -{ - unsigned int i; - unsigned long sum = 0; - - if (!map) - return (0); - for (i = 0; i < numchars; i++) - sum += nibblemap[map->b_data[i] & 0xf] + - nibblemap[(map->b_data[i] >> 4) & 0xf]; - return (sum); -} - diff --git a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c b/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c deleted file mode 100644 index 62e7938..0000000 --- a/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * linux/fs/ext2/ialloc.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * BSD ufs-inspired inode and directory allocation by - * Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 - */ - -/* - * The free inodes are managed by bitmaps. A file system contains several - * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap - * block for inodes, N blocks for the inode table and data blocks. - * - * The file system contains group descriptors which are located after the - * super block. Each descriptor contains the number of the bitmap block and - * the free blocks count in the block. The descriptors are loaded in memory - * when a file system is mounted (see ext2_read_super). - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/vnode.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufsmount.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <sys/stat.h> - -#if (i386) -#include <gnu/ext2fs/i386-bitops.h> -#else -#error please provide bit operation functions -#endif - -/* this is supposed to mark a buffer dirty on ready for delayed writing - */ -void mark_buffer_dirty(struct buf *bh) -{ - bh->b_flags |= B_DELWRI; - bh->b_flags &= ~(B_READ | B_ERROR); -} - -/* - this should write a buffer immediately w/o releasing it - */ -int ll_w_block(struct buf * bp, int waitfor) -{ - bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI); - bp->b_flags |= B_WRITEINPROG; - bp->b_vp->v_numoutput++; -#if defined(__FreeBSD__) - vfs_busy_pages(bp, 1); -#endif - VOP_STRATEGY(bp); - return waitfor ? biowait(bp) : 0; -} - -struct ext2_group_desc * get_group_desc (struct mount * mp, - unsigned int block_group, - struct buffer_head ** bh) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - unsigned long group_desc; - unsigned long desc; - struct ext2_group_desc * gdp; - - if (block_group >= sb->s_groups_count) - panic ("get_group_desc: " - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", - block_group, sb->s_groups_count); - - group_desc = block_group / EXT2_DESC_PER_BLOCK(sb); - desc = block_group % EXT2_DESC_PER_BLOCK(sb); - if (!sb->s_group_desc[group_desc]) - panic ( "get_group_desc:" - "Group descriptor not loaded - " - "block_group = %d, group_desc = %lu, desc = %lu", - block_group, group_desc, desc); - gdp = (struct ext2_group_desc *) - sb->s_group_desc[group_desc]->b_data; - if (bh) - *bh = sb->s_group_desc[group_desc]; - return gdp + desc; -} - -static void read_inode_bitmap (struct mount * mp, - unsigned long block_group, - unsigned int bitmap_nr) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct ext2_group_desc * gdp; - struct buffer_head * bh; - int error; - - gdp = get_group_desc (mp, block_group, NULL); - if (error = bread (VFSTOUFS(mp)->um_devvp, - fsbtodb(sb, gdp->bg_inode_bitmap), - sb->s_blocksize, - NOCRED, &bh)) - panic ( "read_inode_bitmap:" - "Cannot read inode bitmap - " - "block_group = %lu, inode_bitmap = %lu", - block_group, (unsigned long) gdp->bg_inode_bitmap); - sb->s_inode_bitmap_number[bitmap_nr] = block_group; - sb->s_inode_bitmap[bitmap_nr] = bh; -} - -/* - * load_inode_bitmap loads the inode bitmap for a blocks group - * - * It maintains a cache for the last bitmaps loaded. This cache is managed - * with a LRU algorithm. - * - * Notes: - * 1/ There is one cache per mounted file system. - * 2/ If the file system contains less than EXT2_MAX_GROUP_LOADED groups, - * this function reads the bitmap without maintaining a LRU cache. - */ -static int load_inode_bitmap (struct mount * mp, - unsigned int block_group) -{ - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - int i, j; - unsigned long inode_bitmap_number; - struct buffer_head * inode_bitmap; - - if (block_group >= sb->s_groups_count) - panic ("load_inode_bitmap:" - "block_group >= groups_count - " - "block_group = %d, groups_count = %lu", - block_group, sb->s_groups_count); - if (sb->s_loaded_inode_bitmaps > 0 && - sb->s_inode_bitmap_number[0] == block_group) - return 0; - if (sb->s_groups_count <= EXT2_MAX_GROUP_LOADED) { - if (sb->s_inode_bitmap[block_group]) { - if (sb->s_inode_bitmap_number[block_group] != - block_group) - panic ( "load_inode_bitmap:" - "block_group != inode_bitmap_number"); - else - return block_group; - } else { - read_inode_bitmap (mp, block_group, block_group); - return block_group; - } - } - - for (i = 0; i < sb->s_loaded_inode_bitmaps && - sb->s_inode_bitmap_number[i] != block_group; - i++) - ; - if (i < sb->s_loaded_inode_bitmaps && - sb->s_inode_bitmap_number[i] == block_group) { - inode_bitmap_number = sb->s_inode_bitmap_number[i]; - inode_bitmap = sb->s_inode_bitmap[i]; - for (j = i; j > 0; j--) { - sb->s_inode_bitmap_number[j] = - sb->s_inode_bitmap_number[j - 1]; - sb->s_inode_bitmap[j] = - sb->s_inode_bitmap[j - 1]; - } - sb->s_inode_bitmap_number[0] = inode_bitmap_number; - sb->s_inode_bitmap[0] = inode_bitmap; - } else { - if (sb->s_loaded_inode_bitmaps < EXT2_MAX_GROUP_LOADED) - sb->s_loaded_inode_bitmaps++; - else - brelse (sb->s_inode_bitmap[EXT2_MAX_GROUP_LOADED - 1]); - for (j = sb->s_loaded_inode_bitmaps - 1; j > 0; j--) { - sb->s_inode_bitmap_number[j] = - sb->s_inode_bitmap_number[j - 1]; - sb->s_inode_bitmap[j] = - sb->s_inode_bitmap[j - 1]; - } - read_inode_bitmap (mp, block_group, 0); - } - return 0; -} - - -void ext2_free_inode (struct inode * inode) -{ - struct ext2_sb_info * sb; - struct buffer_head * bh; - struct buffer_head * bh2; - unsigned long block_group; - unsigned long bit; - int bitmap_nr; - struct ext2_group_desc * gdp; - struct ext2_super_block * es; - - if (!inode) - return; - - if (inode->i_nlink) { - printf ("ext2_free_inode: inode has nlink=%d\n", - inode->i_nlink); - return; - } - - ext2_debug ("freeing inode %lu\n", inode->i_number); - - sb = inode->i_e2fs; - lock_super (DEVVP(inode)); - if (inode->i_number < EXT2_FIRST_INO || - inode->i_number > sb->s_es->s_inodes_count) { - printf ("free_inode reserved inode or nonexistent inode"); - unlock_super (DEVVP(inode)); - return; - } - es = sb->s_es; - block_group = (inode->i_number - 1) / EXT2_INODES_PER_GROUP(sb); - bit = (inode->i_number - 1) % EXT2_INODES_PER_GROUP(sb); - bitmap_nr = load_inode_bitmap (ITOV(inode)->v_mount, block_group); - bh = sb->s_inode_bitmap[bitmap_nr]; - if (!clear_bit (bit, bh->b_data)) - printf ( "ext2_free_inode:" - "bit already cleared for inode %lu", inode->i_number); - else { - gdp = get_group_desc (ITOV(inode)->v_mount, block_group, &bh2); - gdp->bg_free_inodes_count++; - if (S_ISDIR(inode->i_mode)) - gdp->bg_used_dirs_count--; - mark_buffer_dirty(bh2); - es->s_free_inodes_count++; - } - mark_buffer_dirty(bh); -/*** XXX - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -***/ - sb->s_dirt = 1; - unlock_super (DEVVP(inode)); -} - -#if linux -/* - * This function increments the inode version number - * - * This may be used one day by the NFS server - */ -static void inc_inode_version (struct inode * inode, - struct ext2_group_desc *gdp, - int mode) -{ - unsigned long inode_block; - struct buffer_head * bh; - struct ext2_inode * raw_inode; - - inode_block = gdp->bg_inode_table + (((inode->i_number - 1) % - EXT2_INODES_PER_GROUP(inode->i_sb)) / - EXT2_INODES_PER_BLOCK(inode->i_sb)); - bh = bread (inode->i_sb->s_dev, inode_block, inode->i_sb->s_blocksize); - if (!bh) { - printf ("inc_inode_version Cannot load inode table block - " - "inode=%lu, inode_block=%lu\n", - inode->i_number, inode_block); - inode->u.ext2_i.i_version = 1; - return; - } - raw_inode = ((struct ext2_inode *) bh->b_data) + - (((inode->i_number - 1) % - EXT2_INODES_PER_GROUP(inode->i_sb)) % - EXT2_INODES_PER_BLOCK(inode->i_sb)); - raw_inode->i_version++; - inode->u.ext2_i.i_version = raw_inode->i_version; - mark_buffer_dirty(bh, 1); - brelse (bh); -} - -#endif /* linux */ - -/* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both - * free space and a low directory-to-inode ratio; if that fails, then of - * the groups with above-average free space, that group with the fewest - * directories already is chosen. - * - * For other inodes, search forward from the parent directory\'s block - * group to find a free inode. - */ -/* - * this functino has been reduced to the actual 'find the inode number' part - */ -ino_t ext2_new_inode (const struct inode * dir, int mode) -{ - struct ext2_sb_info * sb; - struct buffer_head * bh; - struct buffer_head * bh2; - int i, j, avefreei; - int bitmap_nr; - struct ext2_group_desc * gdp; - struct ext2_group_desc * tmp; - struct ext2_super_block * es; - - if (!dir) - return 0; - sb = dir->i_e2fs; - - lock_super (DEVVP(dir)); - es = sb->s_es; -repeat: - gdp = NULL; i=0; - - if (S_ISDIR(mode)) { - avefreei = es->s_free_inodes_count / - sb->s_groups_count; -/* I am not yet convinced that this next bit is necessary. - i = dir->u.ext2_i.i_block_group; - for (j = 0; j < sb->u.ext2_sb.s_groups_count; j++) { - tmp = get_group_desc (sb, i, &bh2); - if ((tmp->bg_used_dirs_count << 8) < - tmp->bg_free_inodes_count) { - gdp = tmp; - break; - } - else - i = ++i % sb->u.ext2_sb.s_groups_count; - } -*/ - if (!gdp) { - for (j = 0; j < sb->s_groups_count; j++) { - tmp = get_group_desc(ITOV(dir)->v_mount,j,&bh2); - if (tmp->bg_free_inodes_count && - tmp->bg_free_inodes_count >= avefreei) { - if (!gdp || - (tmp->bg_free_blocks_count > - gdp->bg_free_blocks_count)) { - i = j; - gdp = tmp; - } - } - } - } - } - else - { - /* - * Try to place the inode in its parent directory - */ - i = dir->i_block_group; - tmp = get_group_desc (ITOV(dir)->v_mount, i, &bh2); - if (tmp->bg_free_inodes_count) - gdp = tmp; - else - { - /* - * Use a quadratic hash to find a group with a - * free inode - */ - for (j = 1; j < sb->s_groups_count; j <<= 1) { - i += j; - if (i >= sb->s_groups_count) - i -= sb->s_groups_count; - tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2); - if (tmp->bg_free_inodes_count) { - gdp = tmp; - break; - } - } - } - if (!gdp) { - /* - * That failed: try linear search for a free inode - */ - i = dir->i_block_group + 1; - for (j = 2; j < sb->s_groups_count; j++) { - if (++i >= sb->s_groups_count) - i = 0; - tmp = get_group_desc(ITOV(dir)->v_mount,i,&bh2); - if (tmp->bg_free_inodes_count) { - gdp = tmp; - break; - } - } - } - } - - if (!gdp) { - unlock_super (DEVVP(dir)); - return 0; - } - bitmap_nr = load_inode_bitmap (ITOV(dir)->v_mount, i); - bh = sb->s_inode_bitmap[bitmap_nr]; - if ((j = find_first_zero_bit ((unsigned long *) bh->b_data, - EXT2_INODES_PER_GROUP(sb))) < - EXT2_INODES_PER_GROUP(sb)) { - if (set_bit (j, bh->b_data)) { - printf ( "ext2_new_inode:" - "bit already set for inode %d", j); - goto repeat; - } -/* Linux now does the following: - mark_buffer_dirty(bh, 1); - if (sb->s_flags & MS_SYNCHRONOUS) { - ll_rw_block (WRITE, 1, &bh); - wait_on_buffer (bh); - } -*/ - mark_buffer_dirty(bh); - } else { - if (gdp->bg_free_inodes_count != 0) { - printf ( "ext2_new_inode:" - "Free inodes count corrupted in group %d", - i); - unlock_super (DEVVP(dir)); - return 0; - } - goto repeat; - } - j += i * EXT2_INODES_PER_GROUP(sb) + 1; - if (j < EXT2_FIRST_INO || j > es->s_inodes_count) { - printf ( "ext2_new_inode:" - "reserved inode or inode > inodes count - " - "block_group = %d,inode=%d", i, j); - unlock_super (DEVVP(dir)); - return 0; - } - gdp->bg_free_inodes_count--; - if (S_ISDIR(mode)) - gdp->bg_used_dirs_count++; - mark_buffer_dirty(bh2); - es->s_free_inodes_count--; - /* mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); */ - sb->s_dirt = 1; - unlock_super (DEVVP(dir)); - return j; -} - -unsigned long ext2_count_free_inodes (struct mount * mp) -{ -#ifdef EXT2FS_DEBUG - struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs; - struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x; - int bitmap_nr; - struct ext2_group_desc * gdp; - int i; - - lock_super (VFSTOUFS(mp)->um_devvp); - es = sb->s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - for (i = 0; i < sb->s_groups_count; i++) { - gdp = get_group_desc (mp, i, NULL); - desc_count += gdp->bg_free_inodes_count; - bitmap_nr = load_inode_bitmap (mp, i); - x = ext2_count_free (sb->s_inode_bitmap[bitmap_nr], - EXT2_INODES_PER_GROUP(sb) / 8); - ext2_debug ("group %d: stored = %d, counted = %lu\n", - i, gdp->bg_free_inodes_count, x); - bitmap_count += x; - } - ext2_debug("stored = %lu, computed = %lu, %lu\n", - es->s_free_inodes_count, desc_count, bitmap_count); - unlock_super (VFSTOUFS(mp)->um_devvp); - return desc_count; -#else - return VFSTOUFS(mp)->um_e2fsb->s_free_inodes_count; -#endif -} - -#ifdef LATER -void ext2_check_inodes_bitmap (struct mount * mp) -{ - struct ext2_super_block * es; - unsigned long desc_count, bitmap_count, x; - int bitmap_nr; - struct ext2_group_desc * gdp; - int i; - - lock_super (sb); - es = sb->u.ext2_sb.s_es; - desc_count = 0; - bitmap_count = 0; - gdp = NULL; - for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) { - gdp = get_group_desc (sb, i, NULL); - desc_count += gdp->bg_free_inodes_count; - bitmap_nr = load_inode_bitmap (sb, i); - x = ext2_count_free (sb->u.ext2_sb.s_inode_bitmap[bitmap_nr], - EXT2_INODES_PER_GROUP(sb) / 8); - if (gdp->bg_free_inodes_count != x) - printf ( "ext2_check_inodes_bitmap:" - "Wrong free inodes count in group %d, " - "stored = %d, counted = %lu", i, - gdp->bg_free_inodes_count, x); - bitmap_count += x; - } - if (es->s_free_inodes_count != bitmap_count) - printf ( "ext2_check_inodes_bitmap:" - "Wrong free inodes count in super block, " - "stored = %lu, counted = %lu", - (unsigned long) es->s_free_inodes_count, bitmap_count); - unlock_super (sb); -} -#endif - diff --git a/sys/gnu/fs/ext2fs/ext2_lookup.c b/sys/gnu/fs/ext2fs/ext2_lookup.c deleted file mode 100644 index 79f30f2..0000000 --- a/sys/gnu/fs/ext2fs/ext2_lookup.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/namei.h> -#include <sys/buf.h> -#include <sys/file.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/dirent.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/dir.h> -#include <ufs/ufs/ufsmount.h> - -#include <gnu/ext2fs/ext2_extern.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> - -/* - DIRBLKSIZE in ffs is DEV_BSIZE (in most cases 512) - while it is the native blocksize in ext2fs - thus, a #define - is no longer appropriate -*/ -#undef DIRBLKSIZ - -#if 1 -extern struct nchstats nchstats; -static int dirchk = 1; -#else -struct nchstats nchstats; -#if DIAGNOSTIC -int dirchk = 1; -#else -int dirchk = 0; -#endif -#endif - -/* - * the problem that is tackled below is the fact that FFS - * includes the terminating zero on disk while EXT2FS doesn't - * this implies that we need to introduce some padding. - * For instance, a filename "sbin" has normally a reclen 12 - * in EXT2, but 16 in FFS. - * This reminds me of that Pepsi commercial: 'Kid saved a lousy nine cents...' - * If it wasn't for that, the complete ufs code for directories would - * have worked w/o changes (except for the difference in DIRBLKSIZ) - */ -static void -ext2_dirconv2ffs( e2dir, ffsdir) - struct ext2_dir_entry *e2dir; - struct dirent *ffsdir; -{ - struct dirent de; - - bzero(&de, sizeof(struct dirent)); - de.d_fileno = e2dir->inode; - de.d_namlen = e2dir->name_len; - -#ifndef NO_HARDWIRED_CONSTANTS - if(e2dir->name_len + 8 == e2dir->rec_len) - de.d_reclen += 4; - - de.d_type = DT_UNKNOWN; /* don't know more here */ - strncpy(de.d_name, e2dir->name, e2dir->name_len); - de.d_name[de.d_namlen] = '\0'; - /* Godmar thinks: since e2dir->rec_len can be big and means - nothing anyway, we compute our own reclen according to what - we think is right - */ - de.d_reclen = (de.d_namlen+8+1+3) & ~3; - bcopy(&de, ffsdir, de.d_reclen); -#endif - -#if 0 - printf("dirconv: ino %d rec old %d rec new %d nam %d name %s\n", - ffsdir->d_fileno, e2dir->rec_len, ffsdir->d_reclen, - ffsdir->d_namlen, ffsdir->d_name); -#endif -} - -/* - * Vnode op for reading directories. - * - * The routine below assumes that the on-disk format of a directory - * is the same as that defined by <sys/dirent.h>. If the on-disk - * format changes, then it will be necessary to do a conversion - * from the on-disk format that read returns to the format defined - * by <sys/dirent.h>. - */ -/* - * this is exactly what we do here - the problem is that the conversion - * will blow up some entries by four bytes, so it can't be done in place. - * This is too bad. Right now the conversion is done entry by entry, the - * converted entry is sent via uiomove. - * - * XXX allocate a buffer, convert as many entries as possible, then send - * the whole buffer to uiomove - */ -int -ext2_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap; -{ - register struct uio *uio = ap->a_uio; - int count, lost, error; - - struct ext2_dir_entry *edp, *dp; - struct dirent dstdp; - struct uio auio; - struct iovec aiov; - caddr_t dirbuf; - int readcnt; - u_quad_t startoffset = uio->uio_offset; - u_char tmp; - int DIRBLKSIZ = VTOI(ap->a_vp)->i_e2fs->s_blocksize; - - count = uio->uio_resid; /* legyenek boldogok akik akarnak ... */ - uio->uio_resid = count; - uio->uio_iov->iov_len = count; - -#if 0 -printf("ext2_readdir called uio->uio_offset %d uio->uio_resid %d count %d \n", - (int)uio->uio_offset, (int)uio->uio_resid, (int)count); -#endif - - auio = *uio; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_segflg = UIO_SYSSPACE; - aiov.iov_len = count; - MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK); - aiov.iov_base = dirbuf; - error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred); - if (error == 0) { - readcnt = count - auio.uio_resid; - edp = (struct ext2_dir_entry *)&dirbuf[readcnt]; - for (dp = (struct ext2_dir_entry *)dirbuf; - !error && uio->uio_resid > 0 && dp < edp; ) { - ext2_dirconv2ffs(dp, &dstdp); - if (dp->rec_len > 0) { - if(dstdp.d_reclen <= uio->uio_resid) { - /* advance dp */ - dp = (struct ext2_dir_entry *) - ((char *)dp + dp->rec_len); - error = - uiomove(&dstdp, dstdp.d_reclen, uio); - } else - break; - } else { - error = EIO; - break; - } - } - /* we need to correct uio_offset */ - uio->uio_offset = startoffset + (caddr_t)dp - dirbuf; - } - FREE(dirbuf, M_TEMP); - return (error); -} - -/* - * Convert a component of a pathname into a pointer to a locked inode. - * This is a very central and rather complicated routine. - * If the file system is not maintained in a strict tree hierarchy, - * this can result in a deadlock situation (see comments in code below). - * - * The cnp->cn_nameiop argument is LOOKUP, CREATE, RENAME, or DELETE depending - * on whether the name is to be looked up, created, renamed, or deleted. - * When CREATE, RENAME, or DELETE is specified, information usable in - * creating, renaming, or deleting a directory entry may be calculated. - * If flag has LOCKPARENT or'ed into it and the target of the pathname - * exists, lookup returns both the target and its parent directory locked. - * When creating or renaming and LOCKPARENT is specified, the target may - * not be ".". When deleting and LOCKPARENT is specified, the target may - * be "."., but the caller must check to ensure it does an vrele and vput - * instead of two vputs. - * - * Overall outline of ufs_lookup: - * - * check accessibility of directory - * look for name in cache, if found, then if at end of path - * and deleting or creating, drop it, else return name - * search for name in directory, to found or notfound - * notfound: - * if creating, return locked directory, leaving info on available slots - * else return error - * found: - * if at end of path and deleting, return information to allow delete - * if at end of path and rewriting (RENAME and LOCKPARENT), lock target - * inode and return info to allow rewrite - * if not at end, add name to cache; if at end and neither creating - * nor deleting, add name to cache - */ -int -ext2_lookup(ap) - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; -{ - register struct vnode *vdp; /* vnode for directory being searched */ - register struct inode *dp; /* inode for directory being searched */ - struct buf *bp; /* a buffer of directory entries */ - register struct ext2_dir_entry *ep; /* the current directory entry */ - int entryoffsetinblock; /* offset of ep in bp's buffer */ - enum {NONE, COMPACT, FOUND} slotstatus; - doff_t slotoffset; /* offset of area with free space */ - int slotsize; /* size of area at slotoffset */ - int slotfreespace; /* amount of space free in slot */ - int slotneeded; /* size of the entry we're seeking */ - int numdirpasses; /* strategy for directory search */ - doff_t endsearch; /* offset to end directory search */ - doff_t prevoff; /* prev entry dp->i_offset */ - struct vnode *pdp; /* saved dp during symlink work */ - struct vnode *tdp; /* returned by VFS_VGET */ - doff_t enduseful; /* pointer past last used dir slot */ - u_long bmask; /* block offset mask */ - int lockparent; /* 1 => lockparent flag is set */ - int wantparent; /* 1 => wantparent or lockparent flag */ - int namlen, error; - struct vnode **vpp = ap->a_vpp; - struct componentname *cnp = ap->a_cnp; - struct ucred *cred = cnp->cn_cred; - int flags = cnp->cn_flags; - int nameiop = cnp->cn_nameiop; - - int DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize; - - bp = NULL; - slotoffset = -1; - *vpp = NULL; - vdp = ap->a_dvp; - dp = VTOI(vdp); - lockparent = flags & LOCKPARENT; - wantparent = flags & (LOCKPARENT|WANTPARENT); - - /* - * Check accessiblity of directory. - */ - if ((dp->i_mode & IFMT) != IFDIR) - return (ENOTDIR); - if (error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) - return (error); - - /* - * We now have a segment name to search for, and a directory to search. - * - * Before tediously performing a linear scan of the directory, - * check the name cache to see if the directory/name pair - * we are looking for is known already. - */ - if (error = cache_lookup(vdp, vpp, cnp)) { - int vpid; /* capability number of vnode */ - - if (error == ENOENT) - return (error); - /* - * Get the next vnode in the path. - * See comment below starting `Step through' for - * an explaination of the locking protocol. - */ - pdp = vdp; - dp = VTOI(*vpp); - vdp = *vpp; - vpid = vdp->v_id; - if (pdp == vdp) { /* lookup on "." */ - VREF(vdp); - error = 0; - } else if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); - error = vget(vdp, 1); - if (!error && lockparent && (flags & ISLASTCN)) - error = VOP_LOCK(pdp); - } else { - error = vget(vdp, 1); - if (!lockparent || error || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); - } - /* - * Check that the capability number did not change - * while we were waiting for the lock. - */ - if (!error) { - if (vpid == vdp->v_id) - return (0); - vput(vdp); - if (lockparent && pdp != vdp && (flags & ISLASTCN)) - VOP_UNLOCK(pdp); - } - if (error = VOP_LOCK(pdp)) - return (error); - vdp = pdp; - dp = VTOI(pdp); - *vpp = NULL; - } - - /* - * Suppress search for slots unless creating - * file and at end of pathname, in which case - * we watch for a place to put the new file in - * case it doesn't already exist. - */ - slotstatus = FOUND; - slotfreespace = slotsize = slotneeded = 0; - if ((nameiop == CREATE || nameiop == RENAME) && - (flags & ISLASTCN)) { - slotstatus = NONE; - slotneeded = EXT2_DIR_REC_LEN(cnp->cn_namelen); - /* was - slotneeded = (sizeof(struct direct) - MAXNAMLEN + - cnp->cn_namelen + 3) &~ 3; */ - } - - /* - * If there is cached information on a previous search of - * this directory, pick up where we last left off. - * We cache only lookups as these are the most common - * and have the greatest payoff. Caching CREATE has little - * benefit as it usually must search the entire directory - * to determine that the entry does not exist. Caching the - * location of the last DELETE or RENAME has not reduced - * profiling time and hence has been removed in the interest - * of simplicity. - */ - bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; - if (nameiop != LOOKUP || dp->i_diroff == 0 || - dp->i_diroff > dp->i_size) { - entryoffsetinblock = 0; - dp->i_offset = 0; - numdirpasses = 1; - } else { - dp->i_offset = dp->i_diroff; - if ((entryoffsetinblock = dp->i_offset & bmask) && - (error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp))) - return (error); - numdirpasses = 2; - nchstats.ncs_2passes++; - } - prevoff = dp->i_offset; - endsearch = roundup(dp->i_size, DIRBLKSIZ); - enduseful = 0; - -searchloop: - while (dp->i_offset < endsearch) { - /* - * If necessary, get the next directory block. - */ - if ((dp->i_offset & bmask) == 0) { - if (bp != NULL) - brelse(bp); - if (error = - VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) - return (error); - entryoffsetinblock = 0; - } - /* - * If still looking for a slot, and at a DIRBLKSIZE - * boundary, have to start looking for free space again. - */ - if (slotstatus == NONE && - (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) { - slotoffset = -1; - slotfreespace = 0; - } - /* - * Get pointer to next entry. - * Full validation checks are slow, so we only check - * enough to insure forward progress through the - * directory. Complete checks can be run by patching - * "dirchk" to be true. - */ - ep = (struct ext2_dir_entry *) - ((char *)bp->b_data + entryoffsetinblock); - if (ep->rec_len == 0 || - dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock)) { - int i; - ufs_dirbad(dp, dp->i_offset, "mangled entry"); - i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1)); - dp->i_offset += i; - entryoffsetinblock += i; - continue; - } - - /* - * If an appropriate sized slot has not yet been found, - * check to see if one is available. Also accumulate space - * in the current block so that we can determine if - * compaction is viable. - */ - if (slotstatus != FOUND) { - int size = ep->rec_len; - - if (ep->inode != 0) - size -= EXT2_DIR_REC_LEN(ep->name_len); - if (size > 0) { - if (size >= slotneeded) { - slotstatus = FOUND; - slotoffset = dp->i_offset; - slotsize = ep->rec_len; - } else if (slotstatus == NONE) { - slotfreespace += size; - if (slotoffset == -1) - slotoffset = dp->i_offset; - if (slotfreespace >= slotneeded) { - slotstatus = COMPACT; - slotsize = dp->i_offset + - ep->rec_len - slotoffset; - } - } - } - } - - /* - * Check for a name match. - */ - if (ep->inode) { - namlen = ep->name_len; - if (namlen == cnp->cn_namelen && - !bcmp(cnp->cn_nameptr, ep->name, - (unsigned)namlen)) { - /* - * Save directory entry's inode number and - * reclen in ndp->ni_ufs area, and release - * directory buffer. - */ - dp->i_ino = ep->inode; - dp->i_reclen = ep->rec_len; - brelse(bp); - goto found; - } - } - prevoff = dp->i_offset; - dp->i_offset += ep->rec_len; - entryoffsetinblock += ep->rec_len; - if (ep->inode) - enduseful = dp->i_offset; - } -/* notfound: */ - /* - * If we started in the middle of the directory and failed - * to find our target, we must check the beginning as well. - */ - if (numdirpasses == 2) { - numdirpasses--; - dp->i_offset = 0; - endsearch = dp->i_diroff; - goto searchloop; - } - if (bp != NULL) - brelse(bp); - /* - * If creating, and at end of pathname and current - * directory has not been removed, then can consider - * allowing file to be created. - */ - if ((nameiop == CREATE || nameiop == RENAME) && - (flags & ISLASTCN) && dp->i_nlink != 0) { - /* - * Access for write is interpreted as allowing - * creation of files in the directory. - */ - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Return an indication of where the new directory - * entry should be put. If we didn't find a slot, - * then set dp->i_count to 0 indicating - * that the new slot belongs at the end of the - * directory. If we found a slot, then the new entry - * can be put in the range from dp->i_offset to - * dp->i_offset + dp->i_count. - */ - if (slotstatus == NONE) { - dp->i_offset = roundup(dp->i_size, DIRBLKSIZ); - dp->i_count = 0; - enduseful = dp->i_offset; - } else { - dp->i_offset = slotoffset; - dp->i_count = slotsize; - if (enduseful < slotoffset + slotsize) - enduseful = slotoffset + slotsize; - } - dp->i_endoff = roundup(enduseful, DIRBLKSIZ); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - /* - * We return with the directory locked, so that - * the parameters we set up above will still be - * valid if we actually decide to do a direnter(). - * We return ni_vp == NULL to indicate that the entry - * does not currently exist; we leave a pointer to - * the (locked) directory inode in ndp->ni_dvp. - * The pathname buffer is saved so that the name - * can be obtained later. - * - * NB - if the directory is unlocked, then this - * information cannot be used. - */ - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(vdp); - return (EJUSTRETURN); - } - /* - * Insert name into cache (as non-existent) if appropriate. - */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) - cache_enter(vdp, *vpp, cnp); - return (ENOENT); - -found: - if (numdirpasses == 2) - nchstats.ncs_pass2++; - /* - * Check that directory length properly reflects presence - * of this entry. - */ - if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len) - > dp->i_size) { - ufs_dirbad(dp, dp->i_offset, "i_size too small"); - dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - } - - /* - * Found component in pathname. - * If the final component of path name, save information - * in the cache as to where the entry was found. - */ - if ((flags & ISLASTCN) && nameiop == LOOKUP) - dp->i_diroff = dp->i_offset &~ (DIRBLKSIZ - 1); - - /* - * If deleting, and at end of pathname, return - * parameters which can be used to remove file. - * If the wantparent flag isn't set, we return only - * the directory (in ndp->ni_dvp), otherwise we go - * on and lock the inode, being careful with ".". - */ - if (nameiop == DELETE && (flags & ISLASTCN)) { - /* - * Write access to directory required to delete files. - */ - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Return pointer to current entry in dp->i_offset, - * and distance past previous entry (if there - * is a previous entry in this block) in dp->i_count. - * Save directory inode pointer in ndp->ni_dvp for dirremove(). - */ - if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0) - dp->i_count = 0; - else - dp->i_count = dp->i_offset - prevoff; - if (dp->i_number == dp->i_ino) { - VREF(vdp); - *vpp = vdp; - return (0); - } - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - /* - * If directory is "sticky", then user must own - * the directory, or the file in it, else she - * may not delete it (unless she's root). This - * implements append-only directories. - */ - if ((dp->i_mode & ISVTX) && - cred->cr_uid != 0 && - cred->cr_uid != dp->i_uid && - VTOI(tdp)->i_uid != cred->cr_uid) { - vput(tdp); - return (EPERM); - } - *vpp = tdp; - if (!lockparent) - VOP_UNLOCK(vdp); - return (0); - } - - /* - * If rewriting (RENAME), return the inode and the - * information required to rewrite the present directory - * Must get inode of directory entry to verify it's a - * regular file, or empty directory. - */ - if (nameiop == RENAME && wantparent && - (flags & ISLASTCN)) { - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) - return (error); - /* - * Careful about locking second inode. - * This can only occur if the target is ".". - */ - if (dp->i_number == dp->i_ino) - return (EISDIR); - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - *vpp = tdp; - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(vdp); - return (0); - } - - /* - * Step through the translation in the name. We do not `vput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the VFS_VGET for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - pdp = vdp; - if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) { - VOP_LOCK(pdp); - return (error); - } - if (lockparent && (flags & ISLASTCN) && - (error = VOP_LOCK(pdp))) { - vput(tdp); - return (error); - } - *vpp = tdp; - } else if (dp->i_number == dp->i_ino) { - VREF(vdp); /* we want ourself, ie "." */ - *vpp = vdp; - } else { - if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) - return (error); - if (!lockparent || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); - *vpp = tdp; - } - - /* - * Insert name into cache if appropriate. - */ - if (cnp->cn_flags & MAKEENTRY) - cache_enter(vdp, *vpp, cnp); - return (0); -} - -/* - * Do consistency checking on a directory entry: - * record length must be multiple of 4 - * entry must fit in rest of its DIRBLKSIZ block - * record must be large enough to contain entry - * name is not longer than MAXNAMLEN - * name must be as long as advertised, and null terminated - */ -/* - * changed so that it confirms to ext2_check_dir_entry - */ -int -ext2_dirbadentry(dp, de, entryoffsetinblock) - struct vnode *dp; - register struct ext2_dir_entry *de; - int entryoffsetinblock; -{ - register int i; - int namlen; - int DIRBLKSIZ = VTOI(dp)->i_e2fs->s_blocksize; - - char * error_msg = NULL; - - if (de->rec_len < EXT2_DIR_REC_LEN(1)) - error_msg = "rec_len is smaller than minimal"; - else if (de->rec_len % 4 != 0) - error_msg = "rec_len % 4 != 0"; - else if (de->rec_len < EXT2_DIR_REC_LEN(de->name_len)) - error_msg = "reclen is too small for name_len"; - else if (entryoffsetinblock + de->rec_len > DIRBLKSIZ) - error_msg = "directory entry across blocks"; - /* else LATER - if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) - error_msg = "inode out of bounds"; - */ - - if (error_msg != NULL) - printf( "bad directory entry: %s\n" - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d \n", - error_msg, entryoffsetinblock, - (unsigned long) de->inode, de->rec_len, de->name_len); - return error_msg == NULL ? 0 : 1; -} - -/* - * Write a directory entry after a call to namei, using the parameters - * that it left in nameidata. The argument ip is the inode which the new - * directory entry will refer to. Dvp is a pointer to the directory to - * be written, which was left locked by namei. Remaining parameters - * (dp->i_offset, dp->i_count) indicate how the space for the new - * entry is to be obtained. - */ -int -ext2_direnter(ip, dvp, cnp) - struct inode *ip; - struct vnode *dvp; - register struct componentname *cnp; -{ - register struct ext2_dir_entry *ep, *nep; - register struct inode *dp; - struct buf *bp; - struct ext2_dir_entry newdir; - struct iovec aiov; - struct uio auio; - u_int dsize; - int error, loc, newentrysize, spacefree; - char *dirbuf; - int DIRBLKSIZ = ip->i_e2fs->s_blocksize; - - -#if DIAGNOSTIC - if ((cnp->cn_flags & SAVENAME) == 0) - panic("direnter: missing name"); -#endif - dp = VTOI(dvp); - newdir.inode = ip->i_number; - newdir.name_len = cnp->cn_namelen; - bcopy(cnp->cn_nameptr, newdir.name, (unsigned)cnp->cn_namelen + 1); - newentrysize = EXT2_DIR_REC_LEN(newdir.name_len); - if (dp->i_count == 0) { - /* - * If dp->i_count is 0, then namei could find no - * space in the directory. Here, dp->i_offset will - * be on a directory block boundary and we will write the - * new entry into a fresh block. - */ - if (dp->i_offset & (DIRBLKSIZ - 1)) - panic("ext2_direnter: newblk"); - auio.uio_offset = dp->i_offset; - newdir.rec_len = DIRBLKSIZ; - auio.uio_resid = newentrysize; - aiov.iov_len = newentrysize; - aiov.iov_base = (caddr_t)&newdir; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_rw = UIO_WRITE; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_procp = (struct proc *)0; - error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred); - if (DIRBLKSIZ > - VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize) - /* XXX should grow with balloc() */ - panic("ext2_direnter: frag size"); - else if (!error) { - dp->i_size = roundup(dp->i_size, DIRBLKSIZ); - dp->i_flag |= IN_CHANGE; - } - return (error); - } - - /* - * If dp->i_count is non-zero, then namei found space - * for the new entry in the range dp->i_offset to - * dp->i_offset + dp->i_count in the directory. - * To use this space, we may have to compact the entries located - * there, by copying them together towards the beginning of the - * block, leaving the free space in one usable chunk at the end. - */ - - /* - * Increase size of directory if entry eats into new space. - * This should never push the size past a new multiple of - * DIRBLKSIZE. - * - * N.B. - THIS IS AN ARTIFACT OF 4.2 AND SHOULD NEVER HAPPEN. - */ - if (dp->i_offset + dp->i_count > dp->i_size) - dp->i_size = dp->i_offset + dp->i_count; - /* - * Get the block containing the space for the new directory entry. - */ - if (error = VOP_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) - return (error); - /* - * Find space for the new entry. In the simple case, the entry at - * offset base will have the space. If it does not, then namei - * arranged that compacting the region dp->i_offset to - * dp->i_offset + dp->i_count would yield the - * space. - */ - ep = (struct ext2_dir_entry *)dirbuf; - dsize = EXT2_DIR_REC_LEN(ep->name_len); - spacefree = ep->rec_len - dsize; - for (loc = ep->rec_len; loc < dp->i_count; ) { - nep = (struct ext2_dir_entry *)(dirbuf + loc); - if (ep->inode) { - /* trim the existing slot */ - ep->rec_len = dsize; - ep = (struct ext2_dir_entry *)((char *)ep + dsize); - } else { - /* overwrite; nothing there; header is ours */ - spacefree += dsize; - } - dsize = EXT2_DIR_REC_LEN(ep->name_len); - spacefree += nep->rec_len - dsize; - loc += nep->rec_len; - bcopy((caddr_t)nep, (caddr_t)ep, dsize); - } - /* - * Update the pointer fields in the previous entry (if any), - * copy in the new entry, and write out the block. - */ - if (ep->inode == 0) { - if (spacefree + dsize < newentrysize) - panic("ext2_direnter: compact1"); - newdir.rec_len = spacefree + dsize; - } else { - if (spacefree < newentrysize) - panic("ext2_direnter: compact2"); - newdir.rec_len = spacefree; - ep->rec_len = dsize; - ep = (struct ext2_dir_entry *)((char *)ep + dsize); - } - bcopy((caddr_t)&newdir, (caddr_t)ep, (u_int)newentrysize); - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - if (!error && dp->i_endoff && dp->i_endoff < dp->i_size) - error = VOP_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC, - cnp->cn_cred, cnp->cn_proc); - return (error); -} - -/* - * Remove a directory entry after a call to namei, using - * the parameters which it left in nameidata. The entry - * dp->i_offset contains the offset into the directory of the - * entry to be eliminated. The dp->i_count field contains the - * size of the previous record in the directory. If this - * is 0, the first entry is being deleted, so we need only - * zero the inode number to mark the entry as free. If the - * entry is not the first in the directory, we must reclaim - * the space of the now empty record by adding the record size - * to the size of the previous entry. - */ -int -ext2_dirremove(dvp, cnp) - struct vnode *dvp; - struct componentname *cnp; -{ - register struct inode *dp; - struct ext2_dir_entry *ep; - struct buf *bp; - int error; - int DIRBLKSIZ = VTOI(dvp)->i_e2fs->s_blocksize; - - dp = VTOI(dvp); - if (dp->i_count == 0) { - /* - * First entry in block: set d_ino to zero. - */ - if (error = - VOP_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) - return (error); - ep->inode = 0; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); - } - /* - * Collapse new free space into previous entry. - */ - if (error = VOP_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count), - (char **)&ep, &bp)) - return (error); - ep->rec_len += dp->i_reclen; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); -} - -/* - * Rewrite an existing directory entry to point at the inode - * supplied. The parameters describing the directory entry are - * set up by a call to namei. - */ -int -ext2_dirrewrite(dp, ip, cnp) - struct inode *dp, *ip; - struct componentname *cnp; -{ - struct buf *bp; - struct ext2_dir_entry *ep; - struct vnode *vdp = ITOV(dp); - int error; - - if (error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) - return (error); - ep->inode = ip->i_number; - error = VOP_BWRITE(bp); - dp->i_flag |= IN_CHANGE | IN_UPDATE; - return (error); -} - -/* - * Check if a directory is empty or not. - * Inode supplied must be locked. - * - * Using a struct dirtemplate here is not precisely - * what we want, but better than using a struct direct. - * - * NB: does not handle corrupted directories. - */ -int -ext2_dirempty(ip, parentino, cred) - register struct inode *ip; - ino_t parentino; - struct ucred *cred; -{ - register off_t off; - struct dirtemplate dbuf; - register struct ext2_dir_entry *dp = (struct ext2_dir_entry *)&dbuf; - int error, count, namlen; - int DIRBLKSIZ = ip->i_e2fs->s_blocksize; - -#define MINDIRSIZ (sizeof (struct dirtemplate) / 2) - - for (off = 0; off < ip->i_size; off += dp->rec_len) { - error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ, off, - UIO_SYSSPACE, IO_NODELOCKED, cred, &count, (struct proc *)0); - /* - * Since we read MINDIRSIZ, residual must - * be 0 unless we're at end of file. - */ - if (error || count != 0) - return (0); - /* avoid infinite loops */ - if (dp->rec_len == 0) - return (0); - /* skip empty entries */ - if (dp->inode == 0) - continue; - /* accept only "." and ".." */ - namlen = dp->name_len; - if (namlen > 2) - return (0); - if (dp->name[0] != '.') - return (0); - /* - * At this point namlen must be 1 or 2. - * 1 implies ".", 2 implies ".." if second - * char is also "." - */ - if (namlen == 1) - continue; - if (dp->name[1] == '.' && dp->inode == parentino) - continue; - return (0); - } - return (1); -} - -/* - * Check if source directory is in the path of the target directory. - * Target is supplied locked, source is unlocked. - * The target is always vput before returning. - */ -int -ext2_checkpath(source, target, cred) - struct inode *source, *target; - struct ucred *cred; -{ - struct vnode *vp; - int error, rootino, namlen; - struct dirtemplate dirbuf; - - vp = ITOV(target); - if (target->i_number == source->i_number) { - error = EEXIST; - goto out; - } - rootino = ROOTINO; - error = 0; - if (target->i_number == rootino) - goto out; - - for (;;) { - if (vp->v_type != VDIR) { - error = ENOTDIR; - break; - } - error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf, - sizeof (struct dirtemplate), (off_t)0, UIO_SYSSPACE, - IO_NODELOCKED, cred, (int *)0, (struct proc *)0); - if (error != 0) - break; - namlen = dirbuf.dotdot_namlen; - if (namlen != 2 || - dirbuf.dotdot_name[0] != '.' || - dirbuf.dotdot_name[1] != '.') { - error = ENOTDIR; - break; - } - if (dirbuf.dotdot_ino == source->i_number) { - error = EINVAL; - break; - } - if (dirbuf.dotdot_ino == rootino) - break; - vput(vp); - if (error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, &vp)) { - vp = NULL; - break; - } - } - -out: - if (error == ENOTDIR) - printf("checkpath: .. not a directory\n"); - if (vp != NULL) - vput(vp); - return (error); -} - diff --git a/sys/gnu/fs/ext2fs/ext2_mount.h b/sys/gnu/fs/ext2fs/ext2_mount.h deleted file mode 100644 index 02fdff2..0000000 --- a/sys/gnu/fs/ext2fs/ext2_mount.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufsmount.h 8.2 (Berkeley) 1/12/94 - * $Id: ufsmount.h,v 1.2 1994/08/02 07:55:04 davidg Exp $ - */ - -#ifndef _UFS_UFS_UFSMOUNT_H_ -#define _UFS_UFS_UFSMOUNT_H_ - -struct buf; -struct inode; -struct nameidata; -struct timeval; -struct ucred; -struct uio; -struct vnode; -struct netexport; - -/* This structure describes the UFS specific mount structure data. */ -struct ufsmount { - struct mount *um_mountp; /* filesystem vfs structure */ - dev_t um_dev; /* device mounted */ - struct vnode *um_devvp; /* block device mounted vnode */ - union { /* pointer to superblock */ - struct lfs *lfs; /* LFS */ - struct fs *fs; /* FFS */ - } ufsmount_u; -#define um_fs ufsmount_u.fs -#define um_lfs ufsmount_u.lfs - struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */ - struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */ - u_long um_nindir; /* indirect ptrs per block */ - u_long um_bptrtodb; /* indir ptr to disk block */ - u_long um_seqinc; /* inc between seq blocks */ - time_t um_btime[MAXQUOTAS]; /* block quota time limit */ - time_t um_itime[MAXQUOTAS]; /* inode quota time limit */ - char um_qflags[MAXQUOTAS]; /* quota specific flags */ - struct netexport um_export; /* export information */ -}; -/* - * Flags describing the state of quotas. - */ -#define QTF_OPENING 0x01 /* Q_QUOTAON in progress */ -#define QTF_CLOSING 0x02 /* Q_QUOTAOFF in progress */ - -/* Convert mount ptr to ufsmount ptr. */ -#define VFSTOUFS(mp) ((struct ufsmount *)((mp)->mnt_data)) - -/* - * Macros to access file system parameters in the ufsmount structure. - * Used by ufs_bmap. - */ -#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb) -#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc) -#define MNINDIR(ump) ((ump)->um_nindir) - -#endif diff --git a/sys/gnu/fs/ext2fs/ext2_readwrite.c b/sys/gnu/fs/ext2fs/ext2_readwrite.c deleted file mode 100644 index be01831..0000000 --- a/sys/gnu/fs/ext2fs/ext2_readwrite.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ufs_readwrite.c 8.7 (Berkeley) 1/21/94 - */ - -#if !defined(__FreeBSD__) -#include "diagnostic.h" -#endif - -#define BLKSIZE(a, b, c) blksize(a, b, c) -#define FS struct ext2_sb_info -#define I_FS i_e2fs -#define READ ext2_read -#define READ_S "ext2_read" -#define WRITE ext2_write -#define WRITE_S "ext2_write" - -/* - * Vnode op for reading. - */ -/* ARGSUSED */ -int -READ(ap) - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp; - register struct inode *ip; - register struct uio *uio; - register FS *fs; - struct buf *bp; - daddr_t lbn, nextlbn; - off_t bytesinfile; - long size, xfersize, blkoffset; - int error; - u_short mode; - - vp = ap->a_vp; - ip = VTOI(vp); - mode = ip->i_mode; - uio = ap->a_uio; - -#if DIAGNOSTIC - if (uio->uio_rw != UIO_READ) - panic("%s: mode", READ_S); - - if (vp->v_type == VLNK) { - if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen) - panic("%s: short symlink", READ_S); - } else if (vp->v_type != VREG && vp->v_type != VDIR) - panic("%s: type %d", READ_S, vp->v_type); -#endif - fs = ip->I_FS; -#if 0 - if ((u_quad_t)uio->uio_offset > fs->fs_maxfilesize) - return (EFBIG); -#endif - - for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { - if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0) - break; - lbn = lblkno(fs, uio->uio_offset); - nextlbn = lbn + 1; - size = BLKSIZE(fs, ip, lbn); - blkoffset = blkoff(fs, uio->uio_offset); - xfersize = fs->s_frag_size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - if (bytesinfile < xfersize) - xfersize = bytesinfile; - - if (lblktosize(fs, nextlbn) > ip->i_size) - error = bread(vp, lbn, size, NOCRED, &bp); - else if (doclusterread) - error = cluster_read(vp, - ip->i_size, lbn, size, NOCRED, &bp); - else if (lbn - 1 == vp->v_lastr) { - int nextsize = BLKSIZE(fs, ip, nextlbn); - error = breadn(vp, lbn, - size, &nextlbn, &nextsize, 1, NOCRED, &bp); - } else - error = bread(vp, lbn, size, NOCRED, &bp); - if (error) - break; - vp->v_lastr = lbn; - - /* - * We should only get non-zero b_resid when an I/O error - * has occurred, which should cause us to break above. - * However, if the short read did not cause an error, - * then we want to ensure that we do not uiomove bad - * or uninitialized data. - */ - size -= bp->b_resid; - if (size < xfersize) { - if (size == 0) - break; - xfersize = size; - } - if (error = - uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio)) - break; - -#if !defined(__FreeBSD__) - if (S_ISREG(mode) && (xfersize + blkoffset == fs->s_frag_size || - uio->uio_offset == ip->i_size)) - bp->b_flags |= B_AGE; -#endif - brelse(bp); - } - if (bp != NULL) - brelse(bp); - ip->i_flag |= IN_ACCESS; - return (error); -} - -/* - * Vnode op for writing. - */ -int -WRITE(ap) - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap; -{ - register struct vnode *vp; - register struct uio *uio; - register struct inode *ip; - register FS *fs; - struct buf *bp; - struct proc *p; - daddr_t lbn; - off_t osize; - int blkoffset, error, flags, ioflag, resid, size, xfersize; - - ioflag = ap->a_ioflag; - uio = ap->a_uio; - vp = ap->a_vp; - ip = VTOI(vp); - -#if DIAGNOSTIC - if (uio->uio_rw != UIO_WRITE) - panic("%s: mode", WRITE_S); -#endif - - switch (vp->v_type) { - case VREG: - if (ioflag & IO_APPEND) - uio->uio_offset = ip->i_size; - if ((ip->i_flags & APPEND) && uio->uio_offset != ip->i_size) - return (EPERM); - /* FALLTHROUGH */ - case VLNK: - break; - case VDIR: - if ((ioflag & IO_SYNC) == 0) - panic("%s: nonsync dir write", WRITE_S); - break; - default: - panic("%s: type", WRITE_S); - } - - fs = ip->I_FS; -#if 0 - if (uio->uio_offset < 0 || - (u_quad_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize) - return (EFBIG); -#endif - /* - * Maybe this should be above the vnode op call, but so long as - * file servers have no limits, I don't think it matters. - */ - p = uio->uio_procp; - if (vp->v_type == VREG && p && - uio->uio_offset + uio->uio_resid > - p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { - psignal(p, SIGXFSZ); - return (EFBIG); - } - - resid = uio->uio_resid; - osize = ip->i_size; - flags = ioflag & IO_SYNC ? B_SYNC : 0; - - for (error = 0; uio->uio_resid > 0;) { - lbn = lblkno(fs, uio->uio_offset); - blkoffset = blkoff(fs, uio->uio_offset); - xfersize = fs->s_frag_size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - -#if defined(__FreeBSD__) - if (uio->uio_offset + xfersize > ip->i_size) - vnode_pager_setsize(vp, (u_long)uio->uio_offset + xfersize); -#endif - - if (fs->s_frag_size > xfersize) - flags |= B_CLRBUF; - else - flags &= ~B_CLRBUF; - - error = ext2_balloc(ip, - lbn, blkoffset + xfersize, ap->a_cred, &bp, flags); - - if (error) - break; - if (uio->uio_offset + xfersize > ip->i_size) { - ip->i_size = uio->uio_offset + xfersize; -#if !defined(__FreeBSD__) - vnode_pager_setsize(vp, (u_long)ip->i_size); -#endif - } -#if !defined(__FreeBSD__) - (void)vnode_pager_uncache(vp); -#endif - - size = BLKSIZE(fs, ip, lbn) - bp->b_resid; - if (size < xfersize) - xfersize = size; - - error = - uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); - - if (ioflag & IO_SYNC) - (void)bwrite(bp); - else if (xfersize + blkoffset == fs->s_frag_size) { - if (doclusterwrite) { -#if defined(__FreeBSD__) - bp->b_flags |= B_CLUSTEROK; -#endif - cluster_write(bp, ip->i_size); - } else { -#if !defined(__FreeBSD__) - bp->b_flags |= B_AGE; -#endif - bawrite(bp); - } - } else { -#if defined(__FreeBSD__) - bp->b_flags |= B_CLUSTEROK; -#endif - bdwrite(bp); - } - - if (error || xfersize == 0) - break; - ip->i_flag |= IN_CHANGE | IN_UPDATE; - } - /* - * If we successfully wrote any data, and we are not the superuser - * we clear the setuid and setgid bits as a precaution against - * tampering. - */ - if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0) - ip->i_mode &= ~(ISUID | ISGID); - if (error) { - if (ioflag & IO_UNIT) { - (void)VOP_TRUNCATE(vp, osize, - ioflag & IO_SYNC, ap->a_cred, uio->uio_procp); - uio->uio_offset -= resid - uio->uio_resid; - uio->uio_resid = resid; - } - } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { - struct timeval tv; -#if !defined(__FreeBSD__) - get_time(&tv); -#else - tv = time; -#endif - error = VOP_UPDATE(vp, &tv, &tv, 1); - } - return (error); -} diff --git a/sys/gnu/fs/ext2fs/ext2_subr.c b/sys/gnu/fs/ext2fs/ext2_subr.c deleted file mode 100644 index c27abe5..0000000 --- a/sys/gnu/fs/ext2fs/ext2_subr.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * modified for Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_subr.c 8.2 (Berkeley) 9/21/93 - */ - -#include <sys/param.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> - -#include <sys/systm.h> -#include <sys/vnode.h> -#include <gnu/ext2fs/ext2_extern.h> -#include <sys/buf.h> -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> - -/* - * Return buffer with the contents of block "offset" from the beginning of - * directory "ip". If "res" is non-zero, fill it in with a pointer to the - * remaining space in the directory. - */ -int -ext2_blkatoff(ap) - struct vop_blkatoff_args /* { - struct vnode *a_vp; - off_t a_offset; - char **a_res; - struct buf **a_bpp; - } */ *ap; -{ - struct inode *ip; - register struct ext2_sb_info *fs; - struct buf *bp; - daddr_t lbn; - int bsize, error; - - ip = VTOI(ap->a_vp); - fs = ip->i_e2fs; - lbn = lblkno(fs, ap->a_offset); - bsize = blksize(fs, ip, lbn); - - *ap->a_bpp = NULL; - if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { - brelse(bp); - return (error); - } - if (ap->a_res) - *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset); - *ap->a_bpp = bp; - return (0); -} - -#if defined(KERNEL) && defined(DIAGNOSTIC) -void -ext2_checkoverlap(bp, ip) - struct buf *bp; - struct inode *ip; -{ - register struct buf *ebp, *ep; - register daddr_t start, last; - struct vnode *vp; - - ebp = &buf[nbuf]; - start = bp->b_blkno; - last = start + btodb(bp->b_bcount) - 1; - for (ep = buf; ep < ebp; ep++) { - if (ep == bp || (ep->b_flags & B_INVAL) || - ep->b_vp == NULLVP) - continue; -#if !defined(__FreeBSD__) - if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL)) - continue; -#else - if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL, NULL)) - continue; -#endif - if (vp != ip->i_devvp) - continue; - /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) - continue; - vprint("Disk overlap", vp); - (void)printf("\tstart %d, end %d overlap start %d, end %d\n", - start, last, ep->b_blkno, - ep->b_blkno + btodb(ep->b_bcount) - 1); - panic("Disk buffer overlap"); - } -} -#endif /* DIAGNOSTIC */ - diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c deleted file mode 100644 index 596eb35..0000000 --- a/sys/gnu/fs/ext2fs/ext2_vfsops.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1989, 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 - */ - -#if !defined(__FreeBSD__) -#include "quota.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/namei.h> -#include <sys/proc.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/socket.h> -#include <sys/mount.h> -#include <sys/buf.h> -#include <sys/mbuf.h> -#include <sys/file.h> -#include <sys/disklabel.h> -#include <sys/ioctl.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/stat.h> - -#include <miscfs/specfs/specdev.h> - -#include <ufs/ufs/quota.h> -#include <ufs/ufs/ufsmount.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> - -int ext2_sbupdate __P((struct ufsmount *, int)); - -struct vfsops ext2fs_vfsops = { - ext2_mount, - ufs_start, /* empty function */ - ext2_unmount, - ufs_root, /* root inode via vget */ - ufs_quotactl, /* does operations associated with quotas */ - ext2_statfs, - ext2_sync, - ext2_vget, - ext2_fhtovp, - ext2_vptofh, - ext2_init, -}; - -#if defined(__FreeBSD__) -VFS_SET(ext2fs_vfsops, ext2fs, MOUNT_EXT2FS, 0); -#define bsd_malloc malloc -#define bsd_free free -#endif - -extern u_long nextgennumber; - -/* - * Called by main() when ufs is going to be mounted as root. - * - * Name is updated by mount(8) after booting. - */ -#define ROOTNAME "root_device" - -int -ext2_mountroot() -{ -#if !defined(__FreeBSD__) - extern struct vnode *rootvp; -#endif - register struct ext2_sb_info *fs; - register struct mount *mp; -#if defined(__FreeBSD__) - struct proc *p = curproc; -#else - struct proc *p = get_proc(); /* XXX */ -#endif - struct ufsmount *ump; - u_int size; - int error; - - /* - * Get vnodes for swapdev and rootdev. - */ - if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) - panic("ext2_mountroot: can't setup bdevvp's"); - - mp = bsd_malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - mp->mnt_op = &ext2fs_vfsops; - mp->mnt_flag = MNT_RDONLY; - if (error = ext2_mountfs(rootvp, mp, p)) { - bsd_free(mp, M_MOUNT); - return (error); - } - if (error = vfs_lock(mp)) { - (void)ext2_unmount(mp, 0, p); - bsd_free(mp, M_MOUNT); - return (error); - } -#if defined(__FreeBSD__) - CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); -#else - TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); -#endif - mp->mnt_flag |= MNT_ROOTFS; - mp->mnt_vnodecovered = NULLVP; - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); - fs->fs_fsmnt[0] = '/'; - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ext2_statfs(mp, &mp->mnt_stat, p); - vfs_unlock(mp); - inittodr(fs->s_es->s_wtime); /* this helps to set the time */ - return (0); -} - -/* - * VFS Operations. - * - * mount system call - */ -int -ext2_mount(mp, path, data, ndp, p) - register struct mount *mp; - char *path; - caddr_t data; /* this is actually a (struct ufs_args *) */ - struct nameidata *ndp; - struct proc *p; -{ - struct vnode *devvp; - struct ufs_args args; - struct ufsmount *ump = 0; - register struct ext2_sb_info *fs; - u_int size; - int error, flags; - - if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) - return (error); - /* - * If updating, check whether changing from read-only to - * read/write; if there is no device name, that's all we do. - */ - if (mp->mnt_flag & MNT_UPDATE) { - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - error = 0; - if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) { - flags = WRITECLOSE; - if (mp->mnt_flag & MNT_FORCE) - flags |= FORCECLOSE; - if (vfs_busy(mp)) - return (EBUSY); - error = ext2_flushfiles(mp, flags, p); - vfs_unbusy(mp); - } - if (!error && (mp->mnt_flag & MNT_RELOAD)) - error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p); - if (error) - return (error); - if (fs->s_rd_only && (mp->mnt_flag & MNT_WANTRDWR)) - fs->s_rd_only = 0; - if (fs->s_rd_only == 0) { - /* don't say it's clean */ - fs->s_es->s_state &= ~EXT2_VALID_FS; - ext2_sbupdate(ump, MNT_WAIT); - } - if (args.fspec == 0) { - /* - * Process export requests. - */ - return (vfs_export(mp, &ump->um_export, &args.export)); - } - } - /* - * Not an update, or updating the name: look up the name - * and verify that it refers to a sensible block device. - */ - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - if (error = namei(ndp)) - return (error); - devvp = ndp->ni_vp; - - if (devvp->v_type != VBLK) { - vrele(devvp); - return (ENOTBLK); - } - if (major(devvp->v_rdev) >= nblkdev) { - vrele(devvp); - return (ENXIO); - } - if ((mp->mnt_flag & MNT_UPDATE) == 0) - error = ext2_mountfs(devvp, mp, p); - else { - if (devvp != ump->um_devvp) - error = EINVAL; /* needs translation */ - else - vrele(devvp); - } - if (error) { - vrele(devvp); - return (error); - } - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); - bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); - bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, - MNAMELEN); - (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)ext2_statfs(mp, &mp->mnt_stat, p); - return (0); -} - -/* - * checks that the data in the descriptor blocks make sense - * this is taken from ext2/super.c - */ -static int ext2_check_descriptors (struct ext2_sb_info * sb) -{ - int i; - int desc_block = 0; - unsigned long block = sb->s_es->s_first_data_block; - struct ext2_group_desc * gdp = NULL; - - /* ext2_debug ("Checking group descriptors"); */ - - for (i = 0; i < sb->s_groups_count; i++) - { - /* examine next descriptor block */ - if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext2_group_desc *) - sb->s_group_desc[desc_block++]->b_data; - if (gdp->bg_block_bitmap < block || - gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Block bitmap for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_block_bitmap); - return 0; - } - if (gdp->bg_inode_bitmap < block || - gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode bitmap for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_inode_bitmap); - return 0; - } - if (gdp->bg_inode_table < block || - gdp->bg_inode_table + sb->s_itb_per_group >= - block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode table for group %d" - " not in group (block %lu)!", - i, (unsigned long) gdp->bg_inode_table); - return 0; - } - block += EXT2_BLOCKS_PER_GROUP(sb); - gdp++; - } - return 1; -} - -/* - * this computes the fields of the ext2_sb_info structure from the - * data in the ext2_super_block structure read in - */ -static int compute_sb_data(devvp, es, fs) - struct vnode * devvp; - struct ext2_super_block * es; - struct ext2_sb_info * fs; -{ - int db_count, error; - int i, j; - int logic_sb_block = 1; /* XXX for now */ - -#if 1 -#define V(v) -#else -#define V(v) printf(#v"= %d\n", fs->v); -#endif - - fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; - V(s_blocksize) - fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; - V(s_bshift) - fs->s_fsbtodb = es->s_log_block_size + 1; - V(s_fsbtodb) - fs->s_qbmask = fs->s_blocksize - 1; - V(s_bmask) - fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); - V(s_blocksize_bits) - fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; - V(s_frag_size) - if (fs->s_frag_size) - fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; - V(s_frags_per_block) - fs->s_blocks_per_group = es->s_blocks_per_group; - V(s_blocks_per_group) - fs->s_frags_per_group = es->s_frags_per_group; - V(s_frags_per_group) - fs->s_inodes_per_group = es->s_inodes_per_group; - V(s_inodes_per_group) - fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE; - V(s_inodes_per_block) - fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; - V(s_itb_per_group) - fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); - V(s_desc_per_block) - /* s_resuid / s_resgid ? */ - fs->s_groups_count = (es->s_blocks_count - - es->s_first_data_block + - EXT2_BLOCKS_PER_GROUP(fs) - 1) / - EXT2_BLOCKS_PER_GROUP(fs); - V(s_groups_count) - db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / - EXT2_DESC_PER_BLOCK(fs); - fs->s_db_per_group = db_count; - V(s_db_per_group) - - fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), - M_UFSMNT, M_WAITOK); - - /* adjust logic_sb_block */ - if(fs->s_blocksize > SBSIZE) - /* Godmar thinks: if the blocksize is greater than 1024, then - the superblock is logically part of block zero. - */ - logic_sb_block = 0; - - for (i = 0; i < db_count; i++) { - error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), - fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); - if(error) { - for (j = 0; j < i; j++) - brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_UFSMNT); - printf("EXT2-fs: unable to read group descriptors (%d)\n", error); - return EIO; - } - } - if(!ext2_check_descriptors(fs)) { - for (j = 0; j < db_count; j++) - brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_UFSMNT); - printf("EXT2-fs: (ext2_check_descriptors failure) " - "unable to read group descriptors\n"); - return EIO; - } - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { - fs->s_inode_bitmap_number[i] = 0; - fs->s_inode_bitmap[i] = NULL; - fs->s_block_bitmap_number[i] = 0; - fs->s_block_bitmap[i] = NULL; - } - fs->s_loaded_inode_bitmaps = 0; - fs->s_loaded_block_bitmaps = 0; - return 0; -} - -/* - * Reload all incore data for a filesystem (used after running fsck on - * the root filesystem and finding things to fix). The filesystem must - * be mounted read-only. - * - * Things to do to update the mount: - * 1) invalidate all cached meta-data. - * 2) re-read superblock from disk. - * 3) re-read summary information from disk. - * 4) invalidate all inactive vnodes. - * 5) invalidate all cached file data. - * 6) re-read inode data for all active vnodes. - */ -int -ext2_reload(mountp, cred, p) - register struct mount *mountp; - struct ucred *cred; - struct proc *p; -{ - register struct vnode *vp, *nvp, *devvp; - struct inode *ip; - struct buf *bp; - struct ext2_super_block * es; - struct ext2_sb_info *fs; - int i, size, error; - - if ((mountp->mnt_flag & MNT_RDONLY) == 0) - return (EINVAL); - /* - * Step 1: invalidate all cached meta-data. - */ - devvp = VFSTOUFS(mountp)->um_devvp; - if (vinvalbuf(devvp, 0, cred, p, 0, 0)) - panic("ext2_reload: dirty1"); - /* - * Step 2: re-read superblock from disk. - * constants have been adjusted for ext2 - */ - if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) - return (error); - es = (struct ext2_super_block *)bp->b_data; - if (es->s_magic != EXT2_SUPER_MAGIC) { - if(es->s_magic == EXT2_PRE_02B_MAGIC) - printf("This filesystem bears the magic number of a pre " - "0.2b version of ext2. This is not supported by " - "Lites.\n"); - else - printf("Wrong magic number: %x (expected %x for ext2 fs\n", - es->s_magic, EXT2_SUPER_MAGIC); - brelse(bp); - return (EIO); /* XXX needs translation */ - } - fs = VFSTOUFS(mountp)->um_e2fs; - bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block)); - - if(error = compute_sb_data(devvp, es, fs)) { - brelse(bp); - return error; - } -#ifdef UNKLAR - if (fs->fs_sbsize < SBSIZE) - bp->b_flags |= B_INVAL; -#endif - brelse(bp); - -loop: - for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { - nvp = vp->v_mntvnodes.le_next; - /* - * Step 4: invalidate all inactive vnodes. - */ - if (vp->v_usecount == 0) { - vgone(vp); - continue; - } - /* - * Step 5: invalidate all cached file data. - */ - if (vget(vp, 1)) - goto loop; - if (vinvalbuf(vp, 0, cred, p, 0, 0)) - panic("ext2_reload: dirty2"); - /* - * Step 6: re-read inode data for all active vnodes. - */ - ip = VTOI(vp); - if (error = - bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), - (int)fs->s_blocksize, NOCRED, &bp)) { - vput(vp); - return (error); - } - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + - EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), - &ip->i_din); - brelse(bp); - vput(vp); - if (vp->v_mount != mountp) - goto loop; - } - return (0); -} - -/* - * Common code for mount and mountroot - */ -int -ext2_mountfs(devvp, mp, p) - register struct vnode *devvp; - struct mount *mp; - struct proc *p; -{ - register struct ufsmount *ump; - struct buf *bp; - register struct ext2_sb_info *fs; - struct ext2_super_block * es; - dev_t dev = devvp->v_rdev; - struct partinfo dpart; - caddr_t base; - int havepart = 0; - int error, i, size; - int ronly; -#if !defined(__FreeBSD__) - extern struct vnode *rootvp; -#endif - - /* - * Disallow multiple mounts of the same device. - * Disallow mounting of a device that is currently in use - * (except for root, which might share swap device for miniroot). - * Flush out any old buffers remaining from a previous use. - */ - if (error = vfs_mountedon(devvp)) - return (error); - if (vcount(devvp) > 1 && devvp != rootvp) - return (EBUSY); - if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) - return (error); -#ifdef READONLY -/* turn on this to force it to be read-only */ - mp->mnt_flag |= MNT_RDONLY; -#endif - - ronly = (mp->mnt_flag & MNT_RDONLY) != 0; - if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) - return (error); - if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) - size = DEV_BSIZE; - else { - havepart = 1; - size = dpart.disklab->d_secsize; - } - - bp = NULL; - ump = NULL; - if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) - goto out; - es = (struct ext2_super_block *)bp->b_data; - if (es->s_magic != EXT2_SUPER_MAGIC) { - if(es->s_magic == EXT2_PRE_02B_MAGIC) - printf("This filesystem bears the magic number of a pre " - "0.2b version of ext2. This is not supported by " - "Lites.\n"); - else - printf("Wrong magic number: %x (expected %x for EXT2FS)\n", - es->s_magic, EXT2_SUPER_MAGIC); - error = EINVAL; /* XXX needs translation */ - goto out; - } - ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK); - bzero((caddr_t)ump, sizeof *ump); - /* I don't know whether this is the right strategy. Note that - we dynamically allocate both a ext2_sb_info and a ext2_super_block - while Linux keeps the super block in a locked buffer - */ - ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), - M_UFSMNT, M_WAITOK); - ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), - M_UFSMNT, M_WAITOK); - bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); - if(error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)) { - brelse(bp); - return error; - } - brelse(bp); - bp = NULL; - fs = ump->um_e2fs; - fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */ - if (!(fs->s_es->s_state & EXT2_VALID_FS)) { - printf("WARNING: %s was not properly dismounted\n", - fs->fs_fsmnt); - } - /* if the fs is not mounted read-only, make sure the super block is - always written back on a sync() - */ - if (ronly == 0) { - fs->s_dirt = 1; /* mark it modified */ - fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */ - } - mp->mnt_data = (qaddr_t)ump; - mp->mnt_stat.f_fsid.val[0] = (long)dev; - mp->mnt_stat.f_fsid.val[1] = MOUNT_EXT2FS; - mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; - mp->mnt_flag |= MNT_LOCAL; - ump->um_mountp = mp; - ump->um_dev = dev; - ump->um_devvp = devvp; - /* setting those two parameters allows us to use - ufs_bmap w/o changse ! - */ - ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); - ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; - ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); - for (i = 0; i < MAXQUOTAS; i++) - ump->um_quotas[i] = NULLVP; - devvp->v_specflags |= SI_MOUNTEDON; - if (ronly == 0) - ext2_sbupdate(ump, MNT_WAIT); - return (0); -out: - if (bp) - brelse(bp); - (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); - if (ump) { - bsd_free(ump->um_fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); - mp->mnt_data = (qaddr_t)0; - } - return (error); -} - -/* - * unmount system call - */ -int -ext2_unmount(mp, mntflags, p) - struct mount *mp; - int mntflags; - struct proc *p; -{ - register struct ufsmount *ump; - register struct ext2_sb_info *fs; - int error, flags, ronly, i; - - flags = 0; - if (mntflags & MNT_FORCE) { - if (mp->mnt_flag & MNT_ROOTFS) - return (EINVAL); - flags |= FORCECLOSE; - } - if (error = ext2_flushfiles(mp, flags, p)) - return (error); - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - ronly = fs->s_rd_only; - if (!ronly) { - fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */ - ext2_sbupdate(ump, MNT_WAIT); - } - /* release buffers containing group descriptors */ - for(i = 0; i < fs->s_db_per_group; i++) - brelse(fs->s_group_desc[i]); - /* release cached inode/block bitmaps */ - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_inode_bitmap[i]) - brelse (fs->s_inode_bitmap[i]); - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_block_bitmap[i]) - brelse (fs->s_block_bitmap[i]); - - ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; - error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, - NOCRED, p); - vrele(ump->um_devvp); - bsd_free(fs->s_es, M_UFSMNT); - bsd_free(fs, M_UFSMNT); - bsd_free(ump, M_UFSMNT); - mp->mnt_data = (qaddr_t)0; - mp->mnt_flag &= ~MNT_LOCAL; - return (error); -} - -/* - * Flush out all the files in a filesystem. - */ -int -ext2_flushfiles(mp, flags, p) - register struct mount *mp; - int flags; - struct proc *p; -{ -#if !defined(__FreeBSD__) - extern int doforce; -#endif - register struct ufsmount *ump; - int i, error; - - if (!doforce) - flags &= ~FORCECLOSE; - ump = VFSTOUFS(mp); -#if QUOTA - if (mp->mnt_flag & MNT_QUOTA) { - if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) - return (error); - for (i = 0; i < MAXQUOTAS; i++) { - if (ump->um_quotas[i] == NULLVP) - continue; - quotaoff(p, mp, i); - } - /* - * Here we fall through to vflush again to ensure - * that we have gotten rid of all the system vnodes. - */ - } -#endif - error = vflush(mp, NULLVP, flags); - return (error); -} - -/* - * Get file system statistics. - * taken from ext2/super.c ext2_statfs - */ -int -ext2_statfs(mp, sbp, p) - struct mount *mp; - register struct statfs *sbp; - struct proc *p; -{ - unsigned long overhead; - unsigned long overhead_per_group; - - register struct ufsmount *ump; - register struct ext2_sb_info *fs; - register struct ext2_super_block *es; - - ump = VFSTOUFS(mp); - fs = ump->um_e2fs; - es = fs->s_es; - - if (es->s_magic != EXT2_SUPER_MAGIC) - panic("ext2_statfs - magic number spoiled"); - - /* - * Compute the overhead (FS structures) - */ - overhead_per_group = 1 /* super block */ + - fs->s_db_per_group + - 1 /* block bitmap */ + - 1 /* inode bitmap */ + - fs->s_itb_per_group; - overhead = es->s_first_data_block + - fs->s_groups_count * overhead_per_group; - - sbp->f_type = MOUNT_EXT2FS; - sbp->f_bsize = EXT2_FRAG_SIZE(fs); - sbp->f_iosize = EXT2_BLOCK_SIZE(fs); - sbp->f_blocks = es->s_blocks_count - overhead; - sbp->f_bfree = es->s_free_blocks_count; - sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; - sbp->f_files = es->s_inodes_count; - sbp->f_ffree = es->s_free_inodes_count; - if (sbp != &mp->mnt_stat) { - bcopy((caddr_t)mp->mnt_stat.f_mntonname, - (caddr_t)&sbp->f_mntonname[0], MNAMELEN); - bcopy((caddr_t)mp->mnt_stat.f_mntfromname, - (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); - } - return (0); -} - -/* - * Go through the disk queues to initiate sandbagged IO; - * go through the inodes to write those that have been modified; - * initiate the writing of the super block if it has been modified. - * - * Note: we are always called with the filesystem marked `MPBUSY'. - */ -int -ext2_sync(mp, waitfor, cred, p) - struct mount *mp; - int waitfor; - struct ucred *cred; - struct proc *p; -{ - register struct vnode *vp; - register struct inode *ip; - register struct ufsmount *ump = VFSTOUFS(mp); - register struct ext2_sb_info *fs; - int error, allerror = 0; - - fs = ump->um_e2fs; - /* - * Write back modified superblock. - * Consistency check that the superblock - * is still in the buffer cache. - */ - if (fs->s_dirt) { -#if !defined(__FreeBSD__) - struct timeval time; -#endif - - if (fs->s_rd_only != 0) { /* XXX */ - printf("fs = %s\n", fs->fs_fsmnt); - panic("update: rofs mod"); - } - fs->s_dirt = 0; -#if !defined(__FreeBSD__) - get_time(&time); -#endif - fs->s_es->s_wtime = time.tv_sec; - allerror = ext2_sbupdate(ump, waitfor); - } - /* - * Write back each (modified) inode. - */ -loop: - for (vp = mp->mnt_vnodelist.lh_first; - vp != NULL; - vp = vp->v_mntvnodes.le_next) { - /* - * If the vnode that we are about to sync is no longer - * associated with this mount point, start over. - */ - if (vp->v_mount != mp) - goto loop; - if (VOP_ISLOCKED(vp)) - continue; - ip = VTOI(vp); - if ((ip->i_flag & - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && - vp->v_dirtyblkhd.lh_first == NULL) - continue; - if (vget(vp, 1)) - goto loop; - if (error = VOP_FSYNC(vp, cred, waitfor, p)) - allerror = error; - vput(vp); - } - /* - * Force stale file system control information to be flushed. - */ - if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) - allerror = error; -#if QUOTA - qsync(mp); -#endif - return (allerror); -} - -/* - * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it - * in from disk. If it is in core, wait for the lock bit to clear, then - * return the inode locked. Detection and handling of mount points must be - * done by the calling routine. - */ -int -ext2_vget(mp, ino, vpp) - struct mount *mp; - ino_t ino; - struct vnode **vpp; -{ - register struct ext2_sb_info *fs; - register struct inode *ip; - struct ufsmount *ump; - struct buf *bp; - struct vnode *vp; - dev_t dev; - int i, type, error; - int used_blocks; - - ump = VFSTOUFS(mp); - dev = ump->um_dev; - if ((*vpp = ufs_ihashget(dev, ino)) != NULL) - return (0); - - /* Allocate a new vnode/inode. */ - if (error = getnewvnode(VT_UFS, mp, ext2_vnodeop_p, &vp)) { - *vpp = NULL; - return (error); - } - /* I don't really know what this 'type' does. I suppose it's some kind - * of memory accounting. Let's just book this memory on FFS's account - * If I'm not mistaken, this stuff isn't implemented anyway in Lites - */ - type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ - MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); - insmntque(vp, mp); - bzero((caddr_t)ip, sizeof(struct inode)); - vp->v_data = ip; - ip->i_vnode = vp; - ip->i_e2fs = fs = ump->um_e2fs; - ip->i_dev = dev; - ip->i_number = ino; -#if QUOTA - for (i = 0; i < MAXQUOTAS; i++) - ip->i_dquot[i] = NODQUOT; -#endif - /* - * Put it onto its hash chain and lock it so that other requests for - * this inode will block if they arrive while we are sleeping waiting - * for old data structures to be purged or for the contents of the - * disk portion of this inode to be read. - */ - ufs_ihashins(ip); - - /* Read in the disk contents for the inode, copy into the inode. */ -#if 0 -printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); -#endif - if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), - (int)fs->s_blocksize, NOCRED, &bp)) { - /* - * The inode does not contain anything useful, so it would - * be misleading to leave it on its hash chain. With mode - * still zero, it will be unlinked and returned to the free - * list by vput(). - */ - vput(vp); - brelse(bp); - *vpp = NULL; - return (error); - } - /* convert ext2 inode to dinode */ - ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * - ino_to_fsbo(fs, ino)), &ip->i_din); - ip->i_block_group = ino_to_cg(fs, ino); - ip->i_next_alloc_block = 0; - ip->i_next_alloc_goal = 0; - ip->i_prealloc_count = 0; - ip->i_prealloc_block = 0; - /* now we want to make sure that block pointers for unused - blocks are zeroed out - ext2_balloc depends on this - although for regular files and directories only - */ - if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) { - used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize; - for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) - ip->i_db[i] = 0; - } -/* - ext2_print_inode(ip); -*/ - brelse(bp); - - /* - * Initialize the vnode from the inode, check for aliases. - * Note that the underlying vnode may have changed. - */ - if (error = ufs_vinit(mp, ext2_specop_p, EXT2_FIFOOPS, &vp)) { - vput(vp); - *vpp = NULL; - return (error); - } - /* - * Finish inode initialization now that aliasing has been resolved. - */ - ip->i_devvp = ump->um_devvp; - VREF(ip->i_devvp); - /* - * Set up a generation number for this inode if it does not - * already have one. This should only happen on old filesystems. - */ - if (ip->i_gen == 0) { -#if !defined(__FreeBSD__) - struct timeval time; - get_time(&time); -#endif - if (++nextgennumber < (u_long)time.tv_sec) - nextgennumber = time.tv_sec; - ip->i_gen = nextgennumber; - if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) - ip->i_flag |= IN_MODIFIED; - } - *vpp = vp; - return (0); -} - -/* - * File handle to vnode - * - * Have to be really careful about stale file handles: - * - check that the inode number is valid - * - call ext2_vget() to get the locked inode - * - check for an unallocated inode (i_mode == 0) - * - check that the given client host has export rights and return - * those rights via. exflagsp and credanonp - */ -int -ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) - register struct mount *mp; - struct fid *fhp; - struct mbuf *nam; - struct vnode **vpp; - int *exflagsp; - struct ucred **credanonp; -{ - register struct ufid *ufhp; - struct ext2_sb_info *fs; - - ufhp = (struct ufid *)fhp; - fs = VFSTOUFS(mp)->um_e2fs; - if (ufhp->ufid_ino < ROOTINO || - ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group) - return (ESTALE); - return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); -} - -/* - * Vnode pointer to File handle - */ -/* ARGSUSED */ -int -ext2_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - register struct inode *ip; - register struct ufid *ufhp; - - ip = VTOI(vp); - ufhp = (struct ufid *)fhp; - ufhp->ufid_len = sizeof(struct ufid); - ufhp->ufid_ino = ip->i_number; - ufhp->ufid_gen = ip->i_gen; - return (0); -} - -/* - * Write a superblock and associated information back to disk. - */ -int -ext2_sbupdate(mp, waitfor) - struct ufsmount *mp; - int waitfor; -{ - register struct ext2_sb_info *fs = mp->um_e2fs; - register struct ext2_super_block *es = fs->s_es; - register struct buf *bp; - int blks; - caddr_t space; - int i, size, error = 0; -/* -printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); -*/ - bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0); - bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block)); - if (waitfor == MNT_WAIT) - error = bwrite(bp); - else - bawrite(bp); - - /* write group descriptors back on disk */ - for(i = 0; i < fs->s_db_per_group; i++) - /* Godmar thinks: we must avoid using any of the b*write - * functions here: we want to keep the buffer locked - * so we use my 'housemade' write routine: - */ - error |= ll_w_block(fs->s_group_desc[i], waitfor == MNT_WAIT); - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_inode_bitmap[i]) - ll_w_block (fs->s_inode_bitmap[i], 1); - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_block_bitmap[i]) - ll_w_block (fs->s_block_bitmap[i], 1); - - return (error); -} diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c deleted file mode 100644 index 1bf9113..0000000 --- a/sys/gnu/fs/ext2fs/ext2_vnops.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)ext2_vnops.c 8.7 (Berkeley) 2/3/94 - */ - -#if !defined(__FreeBSD__) -#include "fifo.h" -#include "diagnostic.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/resourcevar.h> -#include <sys/kernel.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/conf.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <sys/malloc.h> - -#include <vm/vm.h> - -#include <miscfs/specfs/specdev.h> -#include <miscfs/fifofs/fifo.h> - -#if !defined(__FreeBSD__) -#include <ufs/ufs/lockf.h> -#else -#include <lockf.h> -#include <sys/signalvar.h> -#endif -#include <ufs/ufs/quota.h> -#include <ufs/ufs/inode.h> -#include <ufs/ufs/dir.h> -#include <ufs/ufs/ufs_extern.h> - -#include <gnu/ext2fs/ext2_fs.h> -#include <gnu/ext2fs/ext2_fs_sb.h> -#include <gnu/ext2fs/fs.h> -#include <gnu/ext2fs/ext2_extern.h> - -/* Global vfs data structures for ufs. */ -int (**ext2_vnodeop_p)(); -struct vnodeopv_entry_desc ext2_vnodeop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, ext2_lookup }, /* lookup */ - { &vop_create_desc, ufs_create }, /* create */ - { &vop_mknod_desc, ufs_mknod }, /* mknod */ - { &vop_open_desc, ufs_open }, /* open */ - { &vop_close_desc, ufs_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ext2_read }, /* read */ - { &vop_write_desc, ext2_write }, /* write */ - { &vop_ioctl_desc, ufs_ioctl }, /* ioctl */ - { &vop_select_desc, ufs_select }, /* select */ - { &vop_mmap_desc, ufs_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, ufs_seek }, /* seek */ - { &vop_remove_desc, ufs_remove }, /* remove */ - { &vop_link_desc, ufs_link }, /* link */ - { &vop_rename_desc, ufs_rename }, /* rename */ - { &vop_mkdir_desc, ufs_mkdir }, /* mkdir */ - { &vop_rmdir_desc, ufs_rmdir }, /* rmdir */ - { &vop_symlink_desc, ufs_symlink }, /* symlink */ - { &vop_readdir_desc, ext2_readdir }, /* readdir */ - { &vop_readlink_desc, ufs_readlink }, /* readlink */ - { &vop_abortop_desc, ufs_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, ufs_bmap }, /* bmap */ - { &vop_strategy_desc, ufs_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, ufs_pathconf }, /* pathconf */ - { &vop_advlock_desc, ufs_advlock }, /* advlock */ - { &vop_blkatoff_desc, ext2_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, ext2_valloc }, /* valloc */ - { &vop_reallocblks_desc, ext2_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, ext2_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_vnodeop_opv_desc = - { &ext2_vnodeop_p, ext2_vnodeop_entries }; - -int (**ext2_specop_p)(); -struct vnodeopv_entry_desc ext2_specop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, spec_lookup }, /* lookup */ - { &vop_create_desc, spec_create }, /* create */ - { &vop_mknod_desc, spec_mknod }, /* mknod */ - { &vop_open_desc, spec_open }, /* open */ - { &vop_close_desc, ufsspec_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ufsspec_read }, /* read */ - { &vop_write_desc, ufsspec_write }, /* write */ - { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ - { &vop_select_desc, spec_select }, /* select */ - { &vop_mmap_desc, spec_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, spec_seek }, /* seek */ - { &vop_remove_desc, spec_remove }, /* remove */ - { &vop_link_desc, spec_link }, /* link */ - { &vop_rename_desc, spec_rename }, /* rename */ - { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ - { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ - { &vop_symlink_desc, spec_symlink }, /* symlink */ - { &vop_readdir_desc, spec_readdir }, /* readdir */ - { &vop_readlink_desc, spec_readlink }, /* readlink */ - { &vop_abortop_desc, spec_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, spec_bmap }, /* bmap */ - { &vop_strategy_desc, spec_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ - { &vop_advlock_desc, spec_advlock }, /* advlock */ - { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, spec_valloc }, /* valloc */ - { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, spec_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_specop_opv_desc = - { &ext2_specop_p, ext2_specop_entries }; - -#if FIFO -int (**ext2_fifoop_p)(); -struct vnodeopv_entry_desc ext2_fifoop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, fifo_lookup }, /* lookup */ - { &vop_create_desc, fifo_create }, /* create */ - { &vop_mknod_desc, fifo_mknod }, /* mknod */ - { &vop_open_desc, fifo_open }, /* open */ - { &vop_close_desc, ufsfifo_close }, /* close */ - { &vop_access_desc, ufs_access }, /* access */ - { &vop_getattr_desc, ufs_getattr }, /* getattr */ - { &vop_setattr_desc, ufs_setattr }, /* setattr */ - { &vop_read_desc, ufsfifo_read }, /* read */ - { &vop_write_desc, ufsfifo_write }, /* write */ - { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ - { &vop_select_desc, fifo_select }, /* select */ - { &vop_mmap_desc, fifo_mmap }, /* mmap */ - { &vop_fsync_desc, ext2_fsync }, /* fsync */ - { &vop_seek_desc, fifo_seek }, /* seek */ - { &vop_remove_desc, fifo_remove }, /* remove */ - { &vop_link_desc, fifo_link }, /* link */ - { &vop_rename_desc, fifo_rename }, /* rename */ - { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ - { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ - { &vop_symlink_desc, fifo_symlink }, /* symlink */ - { &vop_readdir_desc, fifo_readdir }, /* readdir */ - { &vop_readlink_desc, fifo_readlink }, /* readlink */ - { &vop_abortop_desc, fifo_abortop }, /* abortop */ - { &vop_inactive_desc, ext2_inactive }, /* inactive */ - { &vop_reclaim_desc, ufs_reclaim }, /* reclaim */ - { &vop_lock_desc, ufs_lock }, /* lock */ - { &vop_unlock_desc, ufs_unlock }, /* unlock */ - { &vop_bmap_desc, fifo_bmap }, /* bmap */ - { &vop_strategy_desc, fifo_strategy }, /* strategy */ - { &vop_print_desc, ufs_print }, /* print */ - { &vop_islocked_desc, ufs_islocked }, /* islocked */ - { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ - { &vop_advlock_desc, fifo_advlock }, /* advlock */ - { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ - { &vop_valloc_desc, fifo_valloc }, /* valloc */ - { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */ - { &vop_vfree_desc, ext2_vfree }, /* vfree */ - { &vop_truncate_desc, fifo_truncate }, /* truncate */ - { &vop_update_desc, ext2_update }, /* update */ - { &vop_bwrite_desc, vn_bwrite }, - { (struct vnodeop_desc*)NULL, (int(*)())NULL } -}; -struct vnodeopv_desc ext2fs_fifoop_opv_desc = - { &ext2_fifoop_p, ext2_fifoop_entries }; -#endif /* FIFO */ - -#if defined(__FreeBSD__) - VNODEOP_SET(ext2fs_vnodeop_opv_desc); - VNODEOP_SET(ext2fs_specop_opv_desc); - VNODEOP_SET(ext2fs_fifoop_opv_desc); -#endif - -/* - * Enabling cluster read/write operations. - */ -#ifdef DEBUG -#include <sys/sysctl.h> -int doclusterread = 1; -struct ctldebug debug11 = { "doclusterread", &doclusterread }; -int doclusterwrite = 1; -struct ctldebug debug12 = { "doclusterwrite", &doclusterwrite }; -#endif - -#if defined(__FreeBSD__) -#define doclusterwrite 1 -#define doclusterread 1 -#else -/* doclusterwrite is being tested - note that reallocblks is called when it's on, but this is not implemented */ -#define doclusterwrite 0 -/* doclusterread should work with new pagemove */ -#define doclusterread 1 -#endif - -#include <gnu/ext2fs/ext2_readwrite.c> - -/* - * Synch an open file. - */ -/* ARGSUSED */ -int -ext2_fsync(ap) - struct vop_fsync_args /* { - struct vnode *a_vp; - struct ucred *a_cred; - int a_waitfor; - struct proc *a_p; - } */ *ap; -{ - register struct vnode *vp = ap->a_vp; - register struct buf *bp; - struct timeval tv; - struct buf *nbp; - int s; - - /* - * Clean memory object. - * XXX add this to all file systems. - * XXX why is all this fs specific? - */ -#if !defined(__FreeBSD__) - vn_pager_sync(vp, ap->a_waitfor); -#endif - - /* - * Flush all dirty buffers associated with a vnode. - */ - ext2_discard_prealloc(VTOI(vp)); - -loop: - s = splbio(); - for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { - nbp = bp->b_vnbufs.le_next; - if ((bp->b_flags & B_BUSY)) - continue; - if ((bp->b_flags & B_DELWRI) == 0) - panic("ext2_fsync: not dirty"); - bremfree(bp); - bp->b_flags |= B_BUSY; - splx(s); - /* - * Wait for I/O associated with indirect blocks to complete, - * since there is no way to quickly wait for them below. - */ - if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT) - (void) bawrite(bp); - else - (void) bwrite(bp); - goto loop; - } - if (ap->a_waitfor == MNT_WAIT) { - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; -#if !defined(__FreeBSD__) - sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1); -#else - tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "extfsn", 0); -#endif - } -#if DIAGNOSTIC - if (vp->v_dirtyblkhd.lh_first) { - vprint("ext2_fsync: dirty", vp); - goto loop; - } -#endif - } - splx(s); -#if defined(__FreeBSD__) - tv = time; -#else - get_time(&tv); -#endif - return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT)); -} diff --git a/sys/gnu/fs/ext2fs/fs.h b/sys/gnu/fs/ext2fs/fs.h deleted file mode 100644 index 28071d4..0000000 --- a/sys/gnu/fs/ext2fs/fs.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * modified for EXT2FS support in Lites 1.1 - * - * Aug 1995, Godmar Back (gback@cs.utah.edu) - * University of Utah, Department of Computer Science - */ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)fs.h 8.7 (Berkeley) 4/19/94 - */ - -/* - * Each disk drive contains some number of file systems. - * A file system consists of a number of cylinder groups. - * Each cylinder group has inodes and data. - * - * A file system is described by its super-block, which in turn - * describes the cylinder groups. The super-block is critical - * data and is replicated in each cylinder group to protect against - * catastrophic loss. This is done at `newfs' time and the critical - * super-block data does not change, so the copies need not be - * referenced further unless disaster strikes. - * - * The first boot and super blocks are given in absolute disk addresses. - * The byte-offset forms are preferred, as they don't imply a sector size. - */ -#define BBSIZE 1024 -#define SBSIZE 1024 -#define BBOFF ((off_t)(0)) -#define SBOFF ((off_t)(BBOFF + BBSIZE)) -#define BBLOCK ((daddr_t)(0)) -#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE)) - -/* - * The path name on which the file system is mounted is maintained - * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in - * the super block for this name. - */ -#define MAXMNTLEN 512 - -/* - * Macros for access to superblock array structures - */ - -/* - * Convert cylinder group to base address of its global summary info. - */ -#define fs_cs(fs, cgindx) (((struct ext2_group_desc *) \ - (fs->s_group_desc[cgindx / EXT2_DESC_PER_BLOCK(fs)]->b_data)) \ - [cgindx % EXT2_DESC_PER_BLOCK(fs)]) - -/* - * Turn file system block numbers into disk block addresses. - * This maps file system blocks to device size blocks. - */ -#define fsbtodb(fs, b) ((b) << ((fs)->s_fsbtodb)) -#define dbtofsb(fs, b) ((b) >> ((fs)->s_fsbtodb)) - -/* get group containing inode */ -#define ino_to_cg(fs, x) (((x) - 1) / EXT2_INODES_PER_GROUP(fs)) - -/* get block containing inode from its number x */ -#define ino_to_fsba(fs, x) fs_cs(fs, ino_to_cg(fs, x)).bg_inode_table + \ - (((x)-1) % EXT2_INODES_PER_GROUP(fs))/EXT2_INODES_PER_BLOCK(fs) - -/* get offset for inode in block */ -#define ino_to_fsbo(fs, x) ((x-1) % EXT2_INODES_PER_BLOCK(fs)) - -/* - * Give cylinder group number for a file system block. - * Give cylinder group block number for a file system block. - */ -#define dtog(fs, d) (((d) - fs->s_es->s_first_data_block) / \ - EXT2_BLOCKS_PER_GROUP(fs)) -#define dtogd(fs, d) (((d) - fs->s_es->s_first_data_block) % \ - EXT2_BLOCKS_PER_GROUP(fs)) - -/* - * The following macros optimize certain frequently calculated - * quantities by using shifts and masks in place of divisions - * modulos and multiplications. - */ -#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \ - ((loc) & (fs)->s_qbmask) - -#define lblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ - ((blk) << (fs->s_bshift)) - -#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ - ((loc) >> (fs->s_bshift)) - -/* no fragments -> logical block number equal # of frags */ -#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ - ((loc) >> (fs->s_bshift)) - -#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \ - roundup(size, fs->s_frag_size) - /* was (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) */ - -/* - * Determining the size of a file block in the file system. - * easy w/o fragments - */ -#define blksize(fs, ip, lbn) ((fs)->s_frag_size) - -/* - * INOPB is the number of inodes in a secondary storage block. - */ -#define INOPB(fs) EXT2_INODES_PER_BLOCK(fs) - -/* - * NINDIR is the number of indirects in a file system block. - */ -#define NINDIR(fs) (EXT2_ADDR_PER_BLOCK(fs)) - -extern int inside[], around[]; -extern u_char *fragtbl[]; - -/* a few remarks about superblock locking/unlocking - * Linux provides special routines for doing so - * I haven't figured out yet what BSD does - * I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode - */ -#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp) -#define lock_super(devvp) VOP_LOCK(devvp) -#define unlock_super(devvp) VOP_UNLOCK(devvp) - diff --git a/sys/gnu/fs/ext2fs/i386-bitops.h b/sys/gnu/fs/ext2fs/i386-bitops.h deleted file mode 100644 index a66679e..0000000 --- a/sys/gnu/fs/ext2fs/i386-bitops.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * this is mixture of i386/bitops.h and asm/string.h - * taken from the Linux source tree - * - * XXX replace with Mach routines or reprogram in C - */ -#ifndef _I386_BITOPS_H -#define _I386_BITOPS_H - -/* - * Copyright 1992, Linus Torvalds. - */ - -/* - * These have to be done with inline assembly: that way the bit-setting - * is guaranteed to be atomic. All bit operations return 0 if the bit - * was cleared before the operation and != 0 if it was not. - * - * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). - */ - -/* - * Some hacks to defeat gcc over-optimizations.. - */ -struct __dummy { unsigned long a[100]; }; -#define ADDR (*(struct __dummy *) addr) - -extern __inline__ int set_bit(int nr, void * addr) -{ - int oldbit; - - __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); - return oldbit; -} - -extern __inline__ int clear_bit(int nr, void * addr) -{ - int oldbit; - - __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); - return oldbit; -} - -extern __inline__ int change_bit(int nr, void * addr) -{ - int oldbit; - - __asm__ __volatile__("btcl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); - return oldbit; -} - -/* - * This routine doesn't need to be atomic, but it's faster to code it - * this way. - */ -extern __inline__ int test_bit(int nr, void * addr) -{ - int oldbit; - - __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"ir" (nr)); - return oldbit; -} - -/* - * Find-bit routines.. - */ -extern inline int find_first_zero_bit(void * addr, unsigned size) -{ - int res; - - if (!size) - return 0; - __asm__(" - cld - movl $-1,%%eax - xorl %%edx,%%edx - repe; scasl - je 1f - xorl -4(%%edi),%%eax - subl $4,%%edi - bsfl %%eax,%%edx -1: subl %%ebx,%%edi - shll $3,%%edi - addl %%edi,%%edx" - :"=d" (res) - :"c" ((size + 31) >> 5), "D" (addr), "b" (addr) - :"ax", "cx", "di"); - return res; -} - -extern inline int find_next_zero_bit (void * addr, int size, int offset) -{ - unsigned long * p = ((unsigned long *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - - if (bit) { - /* - * Look for zero in first byte - */ - __asm__(" - bsfl %1,%0 - jne 1f - movl $32, %0 -1: " - : "=r" (set) - : "r" (~(*p >> bit))); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); - return (offset + set + res); -} - -/* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. - */ -extern inline unsigned long ffz(unsigned long word) -{ - __asm__("bsfl %1,%0" - :"=r" (word) - :"r" (~word)); - return word; -} - -/* - * memscan() taken from linux asm/string.h - */ -/* - * find the first occurrence of byte 'c', or 1 past the area if none - */ -extern inline char * memscan(void * addr, unsigned char c, int size) -{ - if (!size) - return addr; - __asm__("cld - repnz; scasb - jnz 1f - dec %%edi -1: " - : "=D" (addr), "=c" (size) - : "0" (addr), "1" (size), "a" (c)); - return addr; -} - -#endif /* _I386_BITOPS_H */ diff --git a/sys/gnu/fs/ext2fs/inode.h b/sys/gnu/fs/ext2fs/inode.h deleted file mode 100644 index 00105ea..0000000 --- a/sys/gnu/fs/ext2fs/inode.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 1982, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)inode.h 8.4 (Berkeley) 1/21/94 - * $Id: inode.h,v 1.5 1995/04/24 05:13:11 dyson Exp $ - */ - -#ifndef _UFS_UFS_INODE_H_ -#define _UFS_UFS_INODE_H_ - -#include <ufs/ufs/dinode.h> - -/* - * Theoretically, directories can be more than 2Gb in length, however, in - * practice this seems unlikely. So, we define the type doff_t as a long - * to keep down the cost of doing lookup on a 32-bit machine. If you are - * porting to a 64-bit architecture, you should make doff_t the same as off_t. - */ -#define doff_t long - -/* - * The inode is used to describe each active (or recently active) - * file in the UFS filesystem. It is composed of two types of - * information. The first part is the information that is needed - * only while the file is active (such as the identity of the file - * and linkage to speed its lookup). The second part is the - * permannent meta-data associated with the file which is read - * in from the permanent dinode from long term storage when the - * file becomes active, and is put back when the file is no longer - * being used. - */ -struct inode { - struct inode *i_next; /* Hash chain forward. */ - struct inode **i_prev; /* Hash chain back. */ - struct vnode *i_vnode; /* Vnode associated with this inode. */ - struct vnode *i_devvp; /* Vnode for block I/O. */ - u_long i_flag; /* I* flags. */ - dev_t i_dev; /* Device associated with the inode. */ - ino_t i_number; /* The identity of the inode. */ - union { /* Associated filesystem. */ - struct fs *fs; /* FFS */ - struct lfs *lfs; /* LFS */ - } inode_u; -#define i_fs inode_u.fs -#define i_lfs inode_u.lfs - struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ - u_quad_t i_modrev; /* Revision level for lease. */ - struct lockf *i_lockf; /* Head of byte-level lock list. */ - pid_t i_lockholder; /* DEBUG: holder of inode lock. */ - pid_t i_lockwaiter; /* DEBUG: latest blocked for inode lock. */ - /* - * Side effects; used during directory lookup. - */ - long i_count; /* Size of free slot in directory. */ - doff_t i_endoff; /* End of useful stuff in directory. */ - doff_t i_diroff; /* Offset in dir, where we found last entry. */ - doff_t i_offset; /* Offset of free space in directory. */ - ino_t i_ino; /* Inode number of found directory. */ - u_long i_reclen; /* Size of found directory entry. */ - int i_lockcount; /* Process lock count (recursion) */ - long i_spare[10]; /* Spares to round up to 128 bytes. */ - /* - * The on-disk dinode itself. - */ - struct dinode i_din; /* 128 bytes of the on-disk dinode. */ -}; - -#define i_atime i_din.di_atime -#define i_blocks i_din.di_blocks -#define i_ctime i_din.di_ctime -#define i_db i_din.di_db -#define i_flags i_din.di_flags -#define i_gen i_din.di_gen -#define i_gid i_din.di_gid -#define i_ib i_din.di_ib -#define i_mode i_din.di_mode -#define i_mtime i_din.di_mtime -#define i_nlink i_din.di_nlink -#define i_rdev i_din.di_rdev -#define i_shortlink i_din.di_shortlink -#define i_size i_din.di_size -#define i_uid i_din.di_uid - -/* These flags are kept in i_flag. */ -#define IN_ACCESS 0x0001 /* Access time update request. */ -#define IN_CHANGE 0x0002 /* Inode change time update request. */ -#define IN_EXLOCK 0x0004 /* File has exclusive lock. */ -#define IN_LOCKED 0x0008 /* Inode lock. */ -#define IN_LWAIT 0x0010 /* Process waiting on file lock. */ -#define IN_MODIFIED 0x0020 /* Inode has been modified. */ -#define IN_RENAME 0x0040 /* Inode is being renamed. */ -#define IN_SHLOCK 0x0080 /* File has shared lock. */ -#define IN_UPDATE 0x0100 /* Modification time update request. */ -#define IN_WANTED 0x0200 /* Inode is wanted by a process. */ -#define IN_RECURSE 0x0400 /* Recursion expected */ - -#ifdef KERNEL -/* - * Structure used to pass around logical block paths generated by - * ufs_getlbns and used by truncate and bmap code. - */ -struct indir { - daddr_t in_lbn; /* Logical block number. */ - int in_off; /* Offset in buffer. */ - int in_exists; /* Flag if the block exists. */ -}; - -/* Convert between inode pointers and vnode pointers. */ -#define VTOI(vp) ((struct inode *)(vp)->v_data) -#define ITOV(ip) ((ip)->i_vnode) - -/* - * XXX this is too long to be a macro, and isn't used in any time-critical - * place; in fact it is only used in ufs_vnops.c so it shouldn't be in a - * header file. - */ -#define ITIMES(ip, t1, t2) { \ - long tv_sec = time.tv_sec; \ - if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \ - (ip)->i_flag |= IN_MODIFIED; \ - if ((ip)->i_flag & IN_ACCESS) \ - (ip)->i_atime.ts_sec \ - = ((t1) == &time ? tv_sec : (t1)->tv_sec); \ - if ((ip)->i_flag & IN_UPDATE) { \ - (ip)->i_mtime.ts_sec \ - = ((t2) == &time ? tv_sec : (t2)->tv_sec); \ - (ip)->i_modrev++; \ - } \ - if ((ip)->i_flag & IN_CHANGE) \ - (ip)->i_ctime.ts_sec = tv_sec; \ - (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \ - } \ -} - -/* This overlays the fid structure (see mount.h). */ -struct ufid { - u_short ufid_len; /* Length of structure. */ - u_short ufid_pad; /* Force long alignment. */ - ino_t ufid_ino; /* File number (ino). */ - long ufid_gen; /* Generation number. */ -}; -#endif /* KERNEL */ - -#endif /* !_UFS_UFS_INODE_H_ */ diff --git a/sys/gnu/i386/fpemul/Changelog b/sys/gnu/i386/fpemul/Changelog deleted file mode 100644 index a2fbccd1..0000000 --- a/sys/gnu/i386/fpemul/Changelog +++ /dev/null @@ -1,36 +0,0 @@ -This file contains the changes made to W. Metzenthem's 387 FPU -emulator to make it work under NetBSD. - -a, Changes to make it compile: - - 1 - Changed the #include's to get the appropriate .h files. - 2 - Renamed .S to .s, to satisfy the kernel Makefile. - 3 - Changed the C++ style // comments to /* */ - 4 - Changed the FPU_ORIG_EIP macro. A letter from bde included - in the package suggested using tf_isp for using instead - of the linux __orig_eip. This later turned out to interfere - with the user stack, so i created a separate variable, stored - in the i387_union. - 5 - Changed the get_fs_.. put_fs_.. fns to fubyte,fuword,subyte, - suword. - 6 - Removed the verify_area fns. I don't really know what they do, - i suppose they verify access to memory. The sufu routines - should do this. - -b, Changes to make it work: - - 1 - Made math_emulate() to return 0 when successful, so trap() won't - try to generate a signal. - 2 - Changed the size of the save87 struct in /sys/arch/i387/include/ - npx.h to accomodate the i387_union. - -d, Other changes: - - 1 - Removed obsolate and/or linux specific stuff. - 2 - Changed the RE_ENTRANT_CHECK_[ON|OFF] macro to - REENTRANT_CHECK([ON|OFF]) so indent can grok it. - 3 - Re-indented to Berkeley style. - 4 - Limited max no of lookaheads. LOOKAHEAD_LIMIT in fpu_entry.c - - - Szabolcs Szigeti (pink@fsz.bme.hu) diff --git a/sys/gnu/i386/fpemul/README b/sys/gnu/i386/fpemul/README deleted file mode 100644 index 0cef6c4..0000000 --- a/sys/gnu/i386/fpemul/README +++ /dev/null @@ -1,277 +0,0 @@ -/* - * wm-FPU-emu an FPU emulator for 80386 and 80486SX microprocessors. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - */ - -wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387 -which is my 80387 emulator for djgpp (gcc under msdos); wm-emu387 was -in turn based upon emu387 which was written by DJ Delorie for djgpp. -The interface to the Linux kernel is based upon the original Linux -math emulator by Linus Torvalds. - -My target FPU for wm-FPU-emu is that described in the Intel486 -Programmer's Reference Manual (1992 edition). Numerous facets of the -functioning of the FPU are not well covered in the Reference Manual; -in the absence of clear details I have made guesses about the most -reasonable behaviour. Recently, this situation has improved because -I now have some access to the results produced by a real 80486 FPU. - -wm-FPU-emu does not implement all of the behaviour of the 80486 FPU. -See "Limitations" later in this file for a partial list of some -differences. I believe that the missing features are never used by -normal C or FORTRAN programs. - - -Please report bugs, etc to me at: - apm233m@vaxc.cc.monash.edu.au - - ---Bill Metzenthen - May 1993 - - ------------------------ Internals of wm-FPU-emu ----------------------- - -Numeric algorithms: -(1) Add, subtract, and multiply. Nothing remarkable in these. -(2) Divide has been tuned to get reasonable performance. The algorithm - is not the obvious one which most people seem to use, but is designed - to take advantage of the characteristics of the 80386. I expect that - it has been invented many times before I discovered it, but I have not - seen it. It is based upon one of those ideas which one carries around - for years without ever bothering to check it out. -(3) The sqrt function has been tuned to get good performance. It is based - upon Newton's classic method. Performance was improved by capitalizing - upon the properties of Newton's method, and the code is once again - structured taking account of the 80386 characteristics. -(4) The trig, log, and exp functions are based in each case upon quasi- - "optimal" polynomial approximations. My definition of "optimal" was - based upon getting good accuracy with reasonable speed. - -The code of the emulator is complicated slightly by the need to -account for a limited form of re-entrancy. Normally, the emulator will -emulate each FPU instruction to completion without interruption. -However, it may happen that when the emulator is accessing the user -memory space, swapping may be needed. In this case the emulator may be -temporarily suspended while disk i/o takes place. During this time -another process may use the emulator, thereby changing some static -variables (eg FPU_st0_ptr, etc). The code which accesses user memory -is confined to five files: - fpu_entry.c - reg_ld_str.c - load_store.c - get_address.c - errors.c - ------------------------ Limitations of wm-FPU-emu ----------------------- - -There are a number of differences between the current wm-FPU-emu -(version beta 1.4) and the 80486 FPU (apart from bugs). Some of the -more important differences are listed below: - -All internal computations are performed at 64 bit or higher precision -and rounded etc as required by the PC bits of the FPU control word. -Under the crt0 version for Linux current at March 1993, the FPU PC -bits specify 53 bits precision. - -The precision flag (PE of the FPU status word) and the Roundup flag -(C1 of the status word) are now partially implemented. Does anyone -write code which uses these features? - -The functions which load/store the FPU state are partially implemented, -but the implementation should be sufficient for handling FPU errors etc -in 32 bit protected mode. - -The implementation of the exception mechanism is flawed for unmasked -interrupts. - -Detection of certain conditions, such as denormal operands, is not yet -complete. - ------------------------ Performance of wm-FPU-emu ----------------------- - -Speed. ------ - -The speed of floating point computation with the emulator will depend -upon instruction mix. Relative performance is best for the instructions -which require most computation. The simple instructions are adversely -affected by the fpu instruction trap overhead. - - -Timing: Some simple timing tests have been made on the emulator functions. -The times include load/store instructions. All times are in microseconds -measured on a 33MHz 386 with 64k cache. The Turbo C tests were under -ms-dos, the next two columns are for emulators running with the djgpp -ms-dos extender. The final column is for wm-FPU-emu in Linux 0.97, -using libm4.0 (hard). - -function Turbo C djgpp 1.06 WM-emu387 wm-FPU-emu - - + 60.5 154.8 76.5 139.4 - - 61.1-65.5 157.3-160.8 76.2-79.5 142.9-144.7 - * 71.0 190.8 79.6 146.6 - / 61.2-75.0 261.4-266.9 75.3-91.6 142.2-158.1 - - sin() 310.8 4692.0 319.0 398.5 - cos() 284.4 4855.2 308.0 388.7 - tan() 495.0 8807.1 394.9 504.7 - atan() 328.9 4866.4 601.1 419.5-491.9 - - sqrt() 128.7 crashed 145.2 227.0 - log() 413.1-419.1 5103.4-5354.21 254.7-282.2 409.4-437.1 - exp() 479.1 6619.2 469.1 850.8 - - -The performance under Linux is improved by the use of look-ahead code. -The following results show the improvement which is obtained under -Linux due to the look-ahead code. Also given are the times for the -original Linux emulator with the 4.1 'soft' lib. - - [ Linus' note: I changed look-ahead to be the default under linux, as - there was no reason not to use it after I had edited it to be - disabled during tracing ] - - wm-FPU-emu w original w - look-ahead 'soft' lib - + 106.4 190.2 - - 108.6-111.6 192.4-216.2 - * 113.4 193.1 - / 108.8-124.4 700.1-706.2 - - sin() 390.5 2642.0 - cos() 381.5 2767.4 - tan() 496.5 3153.3 - atan() 367.2-435.5 2439.4-3396.8 - - sqrt() 195.1 4732.5 - log() 358.0-387.5 3359.2-3390.3 - exp() 619.3 4046.4 - - -These figures are now somewhat out-of-date. The emulator has become -progressively slower for most functions as more of the 80486 features -have been implemented. - - ------------------------ Accuracy of wm-FPU-emu ----------------------- - - -Accuracy: The following table gives the accuracy of the sqrt(), trig -and log functions. Each function was tested at about 400 points. Ideal -results would be 64 bits. The reduced accuracy of cos() and tan() for -arguments greater than pi/4 can be thought of as being due to the -precision of the argument x; e.g. an argument of pi/2-(1e-10) which is -accurate to 64 bits can result in a relative accuracy in cos() of about -64 + log2(cos(x)) = 31 bits. Results for the Turbo C emulator are given -in the last column. - - -Function Tested x range Worst result (bits) Turbo C - -sqrt(x) 1 .. 2 64.1 63.2 -atan(x) 1e-10 .. 200 62.6 62.8 -cos(x) 0 .. pi/2-(1e-10) 63.2 (x <= pi/4) 62.4 - 35.2 (x = pi/2-(1e-10)) 31.9 -sin(x) 1e-10 .. pi/2 63.0 62.8 -tan(x) 1e-10 .. pi/2-(1e-10) 62.4 (x <= pi/4) 62.1 - 35.2 (x = pi/2-(1e-10)) 31.9 -exp(x) 0 .. 1 63.1 62.9 -log(x) 1+1e-6 .. 2 62.4 62.1 - - -As of version 1.3 of the emulator, the accuracy of the basic -arithmetic has been improved (by a small fraction of a bit). Care has -been taken to ensure full accuracy of the rounding of the basic -arithmetic functions (+,-,*,/,and fsqrt), and they all now produce -results which are exact to the 64th bit (unless there are any bugs -left). To ensure this, it was necessary to effectively get information -of up to about 128 bits precision. The emulator now passes the -"paranoia" tests (compiled with gcc 2.3.3) for 'float' variables (24 -bit precision numbers) when precision control is set to 24, 53 or 64 -bits, and for 'double' variables (53 bit precision numbers) when -precision control is set to 53 bits (a properly performing FPU cannot -pass the 'paranoia' tests for 'double' variables when precision -control is set to 64 bits). - -------------------------- Contributors ------------------------------- - -A number of people have contributed to the development of the -emulator, often by just reporting bugs, sometimes with a suggested -fix, and a few kind people have provided me with access in one way or -another to an 80486 machine. Contributors include (to those people who -I have forgotten, please excuse me): - -Linus Torvalds -Tommy.Thorn@daimi.aau.dk -Andrew.Tridgell@anu.edu.au -Nick Holloway alfie@dcs.warwick.ac.uk -Hermano Moura moura@dcs.gla.ac.uk -Jon Jagger J.Jagger@scp.ac.uk -Lennart Benschop -Brian Gallew geek+@CMU.EDU -Thomas Staniszewski ts3v+@andrew.cmu.edu -Martin Howell mph@plasma.apana.org.au -M Saggaf alsaggaf@athena.mit.edu -Peter Barker PETER@socpsy.sci.fau.edu -tom@vlsivie.tuwien.ac.at -Dan Russel russed@rpi.edu -Daniel Carosone danielce@ee.mu.oz.au -cae@jpmorgan.com -Hamish Coleman t933093@minyos.xx.rmit.oz.au - -...and numerous others who responded to my request for help with -a real 80486. - diff --git a/sys/gnu/i386/fpemul/bde_trapinfo.mail b/sys/gnu/i386/fpemul/bde_trapinfo.mail deleted file mode 100644 index 2749e04..0000000 --- a/sys/gnu/i386/fpemul/bde_trapinfo.mail +++ /dev/null @@ -1,35 +0,0 @@ -From bde@kralizec.zeta.org.au Sun Jun 27 01:18:32 1993 -Received: from ultima.socs.uts.EDU.AU by bsd.coe.montana.edu (5.67/KAOS-1) - id AA11952; Sun, 27 Jun 93 01:18:32 -0600 -Received: by ultima.socs.uts.EDU.AU (5.65+/SMI-3.3) - id AA03033; Sun, 27 Jun 93 17:10:22 +1000 -Received: by kralizec.zeta.org.au (4.0/SMI-4.0) - id AA15074; Sat, 26 Jun 93 02:32:58 EST -Date: Sat, 26 Jun 93 02:32:58 EST -From: bde@kralizec.zeta.org.au (Bruce Evans) -Message-Id: <9306251632.AA15074@kralizec.zeta.org.au> -To: nate@bsd.coe.montana.edu -Subject: Re: Trapframe information -Status: OR - -tf_isp original esp (probably spare - popal ignores it) -tf_trapno s/w trap no (may be spare - trap.c has already looked at it) -tf_err h/w error code (probably spare - gets discarded before iret) - -___fs not stored in 386BSD pcb. Constant anyway unless user has - screwed with it (?). -___gs ditto -___orig_eip in linux, this is on the stack just before the call to the - emulator. The reason that it's not a local variable is to - avoid passing around pointers to it - current->frame (or - whatever) points to everything in the stack frame. The - macros hide a lot of slow memory references - current->frame->var. - ->(And I need to see if I can map orig_eip to one of the three that I'm unsure of ->in the BSD sources) - -tf_isp is the least evil. - -Bruce - diff --git a/sys/gnu/i386/fpemul/control_w.h b/sys/gnu/i386/fpemul/control_w.h deleted file mode 100644 index 0e799c5..0000000 --- a/sys/gnu/i386/fpemul/control_w.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * control_w.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: control_w.h,v 1.3 1994/06/10 07:44:07 rich Exp $ - * - */ - -#ifndef _CONTROLW_H_ -#define _CONTROLW_H_ - -#ifdef LOCORE -#define _Const_(x) $/**/x -#else -#define _Const_(x) x -#endif - -#define CW_RC _Const_(0x0C00) /* rounding control */ -#define CW_PC _Const_(0x0300) /* precision control */ - -#define CW_Precision Const_(0x0020) /* loss of precision mask */ -#define CW_Underflow Const_(0x0010) /* underflow mask */ -#define CW_Overflow Const_(0x0008) /* overflow mask */ -#define CW_ZeroDiv Const_(0x0004) /* divide by zero mask */ -#define CW_Denormal Const_(0x0002) /* denormalized operand mask */ -#define CW_Invalid Const_(0x0001) /* invalid operation mask */ - -#define CW_Exceptions _Const_(0x003f) /* all masks */ - -#define RC_RND _Const_(0x0000) -#define RC_DOWN _Const_(0x0400) -#define RC_UP _Const_(0x0800) -#define RC_CHOP _Const_(0x0C00) - -/* p 15-5: Precision control bits affect only the following: - ADD, SUB(R), MUL, DIV(R), and SQRT */ -#define PR_24_BITS _Const_(0x000) -#define PR_53_BITS _Const_(0x200) -#define PR_64_BITS _Const_(0x300) -/* FULL_PRECISION simulates all exceptions masked */ -#define FULL_PRECISION (PR_64_BITS | RC_RND | 0x3f) - -#endif /* _CONTROLW_H_ */ diff --git a/sys/gnu/i386/fpemul/div_small.s b/sys/gnu/i386/fpemul/div_small.s deleted file mode 100644 index d25313b..0000000 --- a/sys/gnu/i386/fpemul/div_small.s +++ /dev/null @@ -1,101 +0,0 @@ - .file "div_small.S" -/* - * div_small.S - * - * Divide a 64 bit integer by a 32 bit integer & return remainder. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: div_small.s,v 1.2 1994/04/29 21:07:11 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | unsigned long div_small(unsigned long long *x, unsigned long y) | - +---------------------------------------------------------------------------*/ - -#include "fpu_asm.h" - -.text - .align 2,144 - -.globl _div_small - -_div_small: - pushl %ebp - movl %esp,%ebp - - pushl %esi - - movl PARAM1,%esi /* pointer to num */ - movl PARAM2,%ecx /* The denominator */ - - movl 4(%esi),%eax /* Get the current num msw */ - xorl %edx,%edx - divl %ecx - - movl %eax,4(%esi) - - movl (%esi),%eax /* Get the num lsw */ - divl %ecx - - movl %eax,(%esi) - - movl %edx,%eax /* Return the remainder in eax */ - - popl %esi - - leave - ret - diff --git a/sys/gnu/i386/fpemul/errors.c b/sys/gnu/i386/fpemul/errors.c deleted file mode 100644 index a303b34..0000000 --- a/sys/gnu/i386/fpemul/errors.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * errors.c - * - * The error handling functions for wm-FPU-emu - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: errors.c,v 1.3 1994/06/10 07:44:10 rich Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Note: | - | The file contains code which accesses user memory. | - | Emulator static data may change when user memory is accessed, due to | - | other processes using the emulator while swapping is in progress. | - +---------------------------------------------------------------------------*/ - - - - - -#include "param.h" -#include "systm.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "status_w.h" -#include "control_w.h" -#include "reg_constant.h" -#include "version.h" - -/* */ -#undef PRINT_MESSAGES -/* */ - - -void -Un_impl(void) -{ - unsigned char byte1, FPU_modrm; - - REENTRANT_CHECK(OFF); - byte1 = fubyte((unsigned char *) FPU_ORIG_EIP); - FPU_modrm = fubyte(1 + (unsigned char *) FPU_ORIG_EIP); - - printf("Unimplemented FPU Opcode at eip=%p : %02x ", - FPU_ORIG_EIP, byte1); - - if (FPU_modrm >= 0300) - printf("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7); - else - printf("/%d\n", (FPU_modrm >> 3) & 7); - REENTRANT_CHECK(ON); - - EXCEPTION(EX_Invalid); - -} - - - - -void -emu_printall() -{ - int i; - static char *tag_desc[] = {"Valid", "Zero", "ERROR", "ERROR", - "DeNorm", "Inf", "NaN", "Empty"}; - unsigned char byte1, FPU_modrm; - - REENTRANT_CHECK(OFF); - byte1 = fubyte((unsigned char *) FPU_ORIG_EIP); - FPU_modrm = fubyte(1 + (unsigned char *) FPU_ORIG_EIP); - -#ifdef DEBUGGING - if (status_word & SW_Backward) - printf("SW: backward compatibility\n"); - if (status_word & SW_C3) - printf("SW: condition bit 3\n"); - if (status_word & SW_C2) - printf("SW: condition bit 2\n"); - if (status_word & SW_C1) - printf("SW: condition bit 1\n"); - if (status_word & SW_C0) - printf("SW: condition bit 0\n"); - if (status_word & SW_Summary) - printf("SW: exception summary\n"); - if (status_word & SW_Stack_Fault) - printf("SW: stack fault\n"); - if (status_word & SW_Precision) - printf("SW: loss of precision\n"); - if (status_word & SW_Underflow) - printf("SW: underflow\n"); - if (status_word & SW_Overflow) - printf("SW: overflow\n"); - if (status_word & SW_Zero_Div) - printf("SW: divide by zero\n"); - if (status_word & SW_Denorm_Op) - printf("SW: denormalized operand\n"); - if (status_word & SW_Invalid) - printf("SW: invalid operation\n"); -#endif /* DEBUGGING */ - - status_word = status_word & ~SW_Top; - status_word |= (top & 7) << SW_Top_Shift; - - printf("At %p: %02x ", FPU_ORIG_EIP, byte1); - if (FPU_modrm >= 0300) - printf("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7); - else - printf("/%d, mod=%d rm=%d\n", - (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7); - - printf(" SW: b=%d st=%d es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n", - status_word & 0x8000 ? 1 : 0, /* busy */ - (status_word & 0x3800) >> 11, /* stack top pointer */ - status_word & 0x80 ? 1 : 0, /* Error summary status */ - status_word & 0x40 ? 1 : 0, /* Stack flag */ - status_word & SW_C3 ? 1 : 0, status_word & SW_C2 ? 1 : 0, /* cc */ - status_word & SW_C1 ? 1 : 0, status_word & SW_C0 ? 1 : 0, /* cc */ - status_word & SW_Precision ? 1 : 0, status_word & SW_Underflow ? 1 : 0, - status_word & SW_Overflow ? 1 : 0, status_word & SW_Zero_Div ? 1 : 0, - status_word & SW_Denorm_Op ? 1 : 0, status_word & SW_Invalid ? 1 : 0); - - printf(" CW: ic=%d rc=%d%d pc=%d%d iem=%d ef=%d%d%d%d%d%d\n", - control_word & 0x1000 ? 1 : 0, - (control_word & 0x800) >> 11, (control_word & 0x400) >> 10, - (control_word & 0x200) >> 9, (control_word & 0x100) >> 8, - control_word & 0x80 ? 1 : 0, - control_word & SW_Precision ? 1 : 0, control_word & SW_Underflow ? 1 : 0, - control_word & SW_Overflow ? 1 : 0, control_word & SW_Zero_Div ? 1 : 0, - control_word & SW_Denorm_Op ? 1 : 0, control_word & SW_Invalid ? 1 : 0); - - for (i = 0; i < 8; i++) { - FPU_REG *r = &st(i); - switch (r->tag) { - case TW_Empty: - continue; - break; - case TW_Zero: - printf("st(%d) %c .0000 0000 0000 0000 ", - i, r->sign ? '-' : '+'); - break; - case TW_Valid: - case TW_NaN: - case TW_Denormal: - case TW_Infinity: - printf("st(%d) %c .%04x %04x %04x %04x e%+-6d ", i, - r->sign ? '-' : '+', - (long) (r->sigh >> 16), - (long) (r->sigh & 0xFFFF), - (long) (r->sigl >> 16), - (long) (r->sigl & 0xFFFF), - r->exp - EXP_BIAS + 1); - break; - default: - printf("Whoops! Error in errors.c "); - break; - } - printf("%s\n", tag_desc[(int) (unsigned) r->tag]); - } - - printf("[data] %c .%04x %04x %04x %04x e%+-6d ", - FPU_loaded_data.sign ? '-' : '+', - (long) (FPU_loaded_data.sigh >> 16), - (long) (FPU_loaded_data.sigh & 0xFFFF), - (long) (FPU_loaded_data.sigl >> 16), - (long) (FPU_loaded_data.sigl & 0xFFFF), - FPU_loaded_data.exp - EXP_BIAS + 1); - printf("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]); - REENTRANT_CHECK(ON); - -} - -static struct { - int type; - char *name; -} exception_names[] = { - { - EX_StackOver, "stack overflow" - }, - { - EX_StackUnder, "stack underflow" - }, - { - EX_Precision, "loss of precision" - }, - { - EX_Underflow, "underflow" - }, - { - EX_Overflow, "overflow" - }, - { - EX_ZeroDiv, "divide by zero" - }, - { - EX_Denormal, "denormalized operand" - }, - { - EX_Invalid, "invalid operation" - }, - { - EX_INTERNAL, "INTERNAL BUG in " FPU_VERSION - }, - { - 0, NULL - } -}; -/* - EX_INTERNAL is always given with a code which indicates where the - error was detected. - - Internal error types: - 0x14 in e14.c - 0x1nn in a *.c file: - 0x101 in reg_add_sub.c - 0x102 in reg_mul.c - 0x103 in poly_sin.c - 0x104 in poly_tan.c - 0x105 in reg_mul.c - 0x106 in reg_mov.c - 0x107 in fpu_trig.c - 0x108 in reg_compare.c - 0x109 in reg_compare.c - 0x110 in reg_add_sub.c - 0x111 in interface.c - 0x112 in fpu_trig.c - 0x113 in reg_add_sub.c - 0x114 in reg_ld_str.c - 0x115 in fpu_trig.c - 0x116 in fpu_trig.c - 0x117 in fpu_trig.c - 0x118 in fpu_trig.c - 0x119 in fpu_trig.c - 0x120 in poly_atan.c - 0x121 in reg_compare.c - 0x122 in reg_compare.c - 0x123 in reg_compare.c - 0x2nn in an *.s file: - 0x201 in reg_u_add.S - 0x202 in reg_u_div.S - 0x203 in reg_u_div.S - 0x204 in reg_u_div.S - 0x205 in reg_u_mul.S - 0x206 in reg_u_sub.S - 0x207 in wm_sqrt.S - 0x208 in reg_div.S - 0x209 in reg_u_sub.S - 0x210 in reg_u_sub.S - 0x211 in reg_u_sub.S - 0x212 in reg_u_sub.S - 0x213 in wm_sqrt.S - 0x214 in wm_sqrt.S - 0x215 in wm_sqrt.S - 0x216 in reg_round.S - 0x217 in reg_round.S - 0x218 in reg_round.S - */ - -void -exception(int n) -{ - int i, int_type; - - int_type = 0; /* Needed only to stop compiler warnings */ - if (n & EX_INTERNAL) { - int_type = n - EX_INTERNAL; - n = EX_INTERNAL; - /* Set lots of exception bits! */ - status_word |= (SW_Exc_Mask | SW_Summary | FPU_BUSY); - } else { - /* Extract only the bits which we use to set the status word */ - n &= (SW_Exc_Mask); - /* Set the corresponding exception bit */ - status_word |= n; - if (status_word & ~control_word & CW_Exceptions) - status_word |= SW_Summary; - if (n & (SW_Stack_Fault | EX_Precision)) { - if (!(n & SW_C1)) - /* This bit distinguishes over- from underflow - * for a stack fault, and roundup from - * round-down for precision loss. */ - status_word &= ~SW_C1; - } - } - - REENTRANT_CHECK(OFF); - if ((~control_word & n & CW_Exceptions) || (n == EX_INTERNAL)) { -#ifdef PRINT_MESSAGES - /* My message from the sponsor */ - printf(FPU_VERSION " " __DATE__ " (C) W. Metzenthen.\n"); -#endif /* PRINT_MESSAGES */ - - /* Get a name string for error reporting */ - for (i = 0; exception_names[i].type; i++) - if ((exception_names[i].type & n) == exception_names[i].type) - break; - - if (exception_names[i].type) { -#ifdef PRINT_MESSAGES - printf("FP Exception: %s!\n", exception_names[i].name); -#endif /* PRINT_MESSAGES */ - } else - printf("FP emulator: Unknown Exception: 0x%04x!\n", n); - - if (n == EX_INTERNAL) { - printf("FP emulator: Internal error type 0x%04x\n", int_type); - emu_printall(); - } -#ifdef PRINT_MESSAGES - else - emu_printall(); -#endif /* PRINT_MESSAGES */ - - /* The 80486 generates an interrupt on the next non-control - * FPU instruction. So we need some means of flagging it. We - * use the ES (Error Summary) bit for this, assuming that this - * is the way a real FPU does it (until I can check it out), - * if not, then some method such as the following kludge might - * be needed. */ -/* regs[0].tag |= TW_FPU_Interrupt; */ - } - REENTRANT_CHECK(ON); - -#ifdef __DEBUG__ - math_abort(SIGFPE); -#endif /* __DEBUG__ */ - -} - - -/* Real operation attempted on two operands, one a NaN */ -void -real_2op_NaN(FPU_REG * a, FPU_REG * b, FPU_REG * dest) -{ - FPU_REG *x; - int signalling; - - x = a; - if (a->tag == TW_NaN) { - if (b->tag == TW_NaN) { - signalling = !(a->sigh & b->sigh & 0x40000000); - /* find the "larger" */ - if (*(long long *) &(a->sigl) < *(long long *) &(b->sigl)) - x = b; - } else { - /* return the quiet version of the NaN in a */ - signalling = !(a->sigh & 0x40000000); - } - } else -#ifdef PARANOID - if (b->tag == TW_NaN) -#endif /* PARANOID */ - { - signalling = !(b->sigh & 0x40000000); - x = b; - } -#ifdef PARANOID - else { - signalling = 0; - EXCEPTION(EX_INTERNAL | 0x113); - x = &CONST_QNaN; - } -#endif /* PARANOID */ - - if (!signalling) { - if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */ - x = &CONST_QNaN; - reg_move(x, dest); - return; - } - if (control_word & CW_Invalid) { - /* The masked response */ - if (!(x->sigh & 0x80000000)) /* pseudo-NaN ? */ - x = &CONST_QNaN; - reg_move(x, dest); - /* ensure a Quiet NaN */ - dest->sigh |= 0x40000000; - } - EXCEPTION(EX_Invalid); - - return; -} -/* Invalid arith operation on Valid registers */ -void -arith_invalid(FPU_REG * dest) -{ - - if (control_word & CW_Invalid) { - /* The masked response */ - reg_move(&CONST_QNaN, dest); - } - EXCEPTION(EX_Invalid); - - return; - -} - - -/* Divide a finite number by zero */ -void -divide_by_zero(int sign, FPU_REG * dest) -{ - - if (control_word & CW_ZeroDiv) { - /* The masked response */ - reg_move(&CONST_INF, dest); - dest->sign = (unsigned char) sign; - } - EXCEPTION(EX_ZeroDiv); - - return; - -} - - -/* This may be called often, so keep it lean */ -void -set_precision_flag_up(void) -{ - if (control_word & CW_Precision) - status_word |= (SW_Precision | SW_C1); /* The masked response */ - else - exception(EX_Precision | SW_C1); - -} - - -/* This may be called often, so keep it lean */ -void -set_precision_flag_down(void) -{ - if (control_word & CW_Precision) { /* The masked response */ - status_word &= ~SW_C1; - status_word |= SW_Precision; - } else - exception(EX_Precision); -} - - -int -denormal_operand(void) -{ - if (control_word & CW_Denormal) { /* The masked response */ - status_word |= SW_Denorm_Op; - return 0; - } else { - exception(EX_Denormal); - return 1; - } -} - - -void -arith_overflow(FPU_REG * dest) -{ - - if (control_word & CW_Overflow) { - char sign; - /* The masked response */ -/* **** The response here depends upon the rounding mode */ - sign = dest->sign; - reg_move(&CONST_INF, dest); - dest->sign = sign; - } else { - /* Subtract the magic number from the exponent */ - dest->exp -= (3 * (1 << 13)); - } - - /* By definition, precision is lost. It appears that the roundup bit - * (C1) is also set by convention. */ - EXCEPTION(EX_Overflow | EX_Precision | SW_C1); - - return; - -} - - -void -arith_underflow(FPU_REG * dest) -{ - - if (control_word & CW_Underflow) { - /* The masked response */ - if (dest->exp <= EXP_UNDER - 63) - reg_move(&CONST_Z, dest); - } else { - /* Add the magic number to the exponent */ - dest->exp += (3 * (1 << 13)); - } - - EXCEPTION(EX_Underflow); - - return; -} - - -void -stack_overflow(void) -{ - - if (control_word & CW_Invalid) { - /* The masked response */ - top--; - reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0)); - } - EXCEPTION(EX_StackOver); - - return; - -} - - -void -stack_underflow(void) -{ - - if (control_word & CW_Invalid) { - /* The masked response */ - reg_move(&CONST_QNaN, FPU_st0_ptr); - } - EXCEPTION(EX_StackUnder); - - return; - -} - - -void -stack_underflow_i(int i) -{ - - if (control_word & CW_Invalid) { - /* The masked response */ - reg_move(&CONST_QNaN, &(st(i))); - } - EXCEPTION(EX_StackUnder); - - return; - -} - - -void -stack_underflow_pop(int i) -{ - - if (control_word & CW_Invalid) { - /* The masked response */ - reg_move(&CONST_QNaN, &(st(i))); - pop(); - } - EXCEPTION(EX_StackUnder); - - return; - -} diff --git a/sys/gnu/i386/fpemul/exception.h b/sys/gnu/i386/fpemul/exception.h deleted file mode 100644 index 11f9d02..0000000 --- a/sys/gnu/i386/fpemul/exception.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * exception.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: exception.h,v 1.2 1994/04/29 21:07:13 gclarkii Exp $ - * - * - */ - -#ifndef _EXCEPTION_H_ -#define _EXCEPTION_H_ - - -#ifdef LOCORE -#define Const_(x) $/**/x -#else -#define Const_(x) x -#endif - -#ifndef SW_C1 -#include "fpu_emu.h" -#endif /* SW_C1 */ - -#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */ -#define EX_ErrorSummary Const_(0x0080) /* Error summary status */ -/* Special exceptions: */ -#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */ -#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */ -#define EX_StackUnder Const_(0x0041) /* stack underflow */ -/* Exception flags: */ -#define EX_Precision Const_(0x0020) /* loss of precision */ -#define EX_Underflow Const_(0x0010) /* underflow */ -#define EX_Overflow Const_(0x0008) /* overflow */ -#define EX_ZeroDiv Const_(0x0004) /* divide by zero */ -#define EX_Denormal Const_(0x0002) /* denormalized operand */ -#define EX_Invalid Const_(0x0001) /* invalid operation */ - - -#ifndef LOCORE - -#ifdef DEBUG -#define EXCEPTION(x) { printf("exception in %s at line %d\n", \ - __FILE__, __LINE__); exception(x); } -#else -#define EXCEPTION(x) exception(x) -#endif - -#endif /* LOCORE */ - -#endif /* _EXCEPTION_H_ */ diff --git a/sys/gnu/i386/fpemul/fpu_arith.c b/sys/gnu/i386/fpemul/fpu_arith.c deleted file mode 100644 index 5745e1b..0000000 --- a/sys/gnu/i386/fpemul/fpu_arith.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * fpu_arith.c - * - * Code to implement the FPU register/register arithmetic instructions - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_arith.c,v 1.3 1994/06/10 07:44:14 rich Exp $ - * - */ - - - - -#include "param.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "control_w.h" - - -void -fadd__() -{ - /* fadd st,st(i) */ - reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); -} - - -void -fmul__() -{ - /* fmul st,st(i) */ - reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); -} - - - -void -fsub__() -{ - /* fsub st,st(i) */ - reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); -} - - -void -fsubr_() -{ - /* fsubr st,st(i) */ - reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word); -} - - -void -fdiv__() -{ - /* fdiv st,st(i) */ - reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word); -} - - -void -fdivr_() -{ - /* fdivr st,st(i) */ - reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word); -} - - - -void -fadd_i() -{ - /* fadd st(i),st */ - reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); -} - - -void -fmul_i() -{ - /* fmul st(i),st */ - reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); -} - - -void -fsubri() -{ - /* fsubr st(i),st */ - /* This is the sense of the 80486 manual reg_sub(&st(FPU_rm), - * FPU_st0_ptr, &st(FPU_rm), control_word); */ - reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); -} - - -void -fsub_i() -{ - /* fsub st(i),st */ - /* This is the sense of the 80486 manual reg_sub(FPU_st0_ptr, - * &st(FPU_rm), &st(FPU_rm), control_word); */ - reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); -} - - -void -fdivri() -{ - /* fdivr st(i),st */ - reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); -} - - -void -fdiv_i() -{ - /* fdiv st(i),st */ - reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); -} - - - -void -faddp_() -{ - /* faddp st(i),st */ - reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); - pop(); -} - - -void -fmulp_() -{ - /* fmulp st(i),st */ - reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); - pop(); -} - - - -void -fsubrp() -{ - /* fsubrp st(i),st */ - /* This is the sense of the 80486 manual reg_sub(&st(FPU_rm), - * FPU_st0_ptr, &st(FPU_rm), control_word); */ - reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); - pop(); -} - - -void -fsubp_() -{ - /* fsubp st(i),st */ - /* This is the sense of the 80486 manual reg_sub(FPU_st0_ptr, - * &st(FPU_rm), &st(FPU_rm), control_word); */ - reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); - pop(); -} - - -void -fdivrp() -{ - /* fdivrp st(i),st */ - reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); - pop(); -} - - -void -fdivp_() -{ - /* fdivp st(i),st */ - reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); - pop(); -} diff --git a/sys/gnu/i386/fpemul/fpu_asm.h b/sys/gnu/i386/fpemul/fpu_asm.h deleted file mode 100644 index e618c04..0000000 --- a/sys/gnu/i386/fpemul/fpu_asm.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * fpu_asm.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_asm.h,v 1.2 1994/04/29 21:07:14 gclarkii Exp $ - * - */ - -#ifndef _FPU_ASM_H_ -#define _FPU_ASM_H_ - -#include "fpu_emu.h" - -#define EXCEPTION _exception - - -#define PARAM1 8(%ebp) -#define PARAM2 12(%ebp) -#define PARAM3 16(%ebp) -#define PARAM4 20(%ebp) - -#define SIGL_OFFSET 8 -#define SIGN(x) (x) -#define TAG(x) 1(x) -#define EXP(x) 4(x) -#define SIG(x) SIGL_OFFSET/**/(x) -#define SIGL(x) SIGL_OFFSET/**/(x) -#define SIGH(x) 12(x) - -#endif /* _FPU_ASM_H_ */ diff --git a/sys/gnu/i386/fpemul/fpu_aux.c b/sys/gnu/i386/fpemul/fpu_aux.c deleted file mode 100644 index 629e45a..0000000 --- a/sys/gnu/i386/fpemul/fpu_aux.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * fpu_aux.c - * - * Code to implement some of the FPU auxiliary instructions. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_aux.c,v 1.2 1994/04/29 21:16:19 gclarkii Exp $ - * - */ - - -#include "param.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "status_w.h" - - - -void -fclex(void) -{ - status_word &= ~(SW_Backward | SW_Summary | SW_Stack_Fault | SW_Precision | - SW_Underflow | SW_Overflow | SW_Zero_Div | SW_Denorm_Op | - SW_Invalid); - FPU_entry_eip = ip_offset; /* We want no net effect */ -} -/* Needs to be externally visible */ -void -finit() -{ - int r; - control_word = 0x037f; - status_word = 0; - top = 0; /* We don't keep top in the status word - * internally. */ - for (r = 0; r < 8; r++) { - regs[r].tag = TW_Empty; - } - FPU_entry_eip = ip_offset = 0; -} - -static FUNC finit_table[] = { - Un_impl, Un_impl, fclex, finit, Un_impl, Un_impl, Un_impl, Un_impl -}; - -void -finit_() -{ - (finit_table[FPU_rm]) (); -} - - -static void -fstsw_ax(void) -{ - - status_word &= ~SW_Top; - status_word |= (top & 7) << SW_Top_Shift; - - *(short *) &FPU_EAX = status_word; - -} - -static FUNC fstsw_table[] = { - fstsw_ax, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl -}; - -void -fstsw_() -{ - (fstsw_table[FPU_rm]) (); -} - - - -static void -fnop(void) -{ -} - -FUNC fp_nop_table[] = { - fnop, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl -}; - -void -fp_nop() -{ - (fp_nop_table[FPU_rm]) (); -} - - -void -fld_i_() -{ - FPU_REG *st_new_ptr; - - if (STACK_OVERFLOW) { - stack_overflow(); - return; - } - /* fld st(i) */ - if (NOT_EMPTY(FPU_rm)) { - reg_move(&st(FPU_rm), st_new_ptr); - push(); - } else { - if (control_word & EX_Invalid) { - /* The masked response */ - push(); - stack_underflow(); - } else - EXCEPTION(EX_StackUnder); - } - -} - - -void -fxch_i() -{ - /* fxch st(i) */ - FPU_REG t; - register FPU_REG *sti_ptr = &st(FPU_rm); - - if (FPU_st0_tag == TW_Empty) { - if (sti_ptr->tag == TW_Empty) { - stack_underflow(); - stack_underflow_i(FPU_rm); - return; - } - reg_move(sti_ptr, FPU_st0_ptr); - stack_underflow_i(FPU_rm); - return; - } - if (sti_ptr->tag == TW_Empty) { - reg_move(FPU_st0_ptr, sti_ptr); - stack_underflow(); - return; - } - reg_move(FPU_st0_ptr, &t); - reg_move(sti_ptr, FPU_st0_ptr); - reg_move(&t, sti_ptr); -} - - -void -ffree_() -{ - /* ffree st(i) */ - st(FPU_rm).tag = TW_Empty; -} - - -void -ffreep() -{ - /* ffree st(i) + pop - unofficial code */ - st(FPU_rm).tag = TW_Empty; - pop(); -} - - -void -fst_i_() -{ - /* fst st(i) */ - reg_move(FPU_st0_ptr, &st(FPU_rm)); -} - - -void -fstp_i() -{ - /* fstp st(i) */ - reg_move(FPU_st0_ptr, &st(FPU_rm)); - pop(); -} diff --git a/sys/gnu/i386/fpemul/fpu_emu.h b/sys/gnu/i386/fpemul/fpu_emu.h deleted file mode 100644 index b62a9cf..0000000 --- a/sys/gnu/i386/fpemul/fpu_emu.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * fpu_emu.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_emu.h,v 1.2 1994/04/29 21:16:20 gclarkii Exp $ - * - */ - - -#ifndef _FPU_EMU_H_ -#define _FPU_EMU_H_ - -/* - * Define DENORM_OPERAND to make the emulator detect denormals - * and use the denormal flag of the status word. Note: this only - * affects the flag and corresponding interrupt, the emulator - * will always generate denormals and operate upon them as required. - */ -#define DENORM_OPERAND - -/* - * Define PECULIAR_486 to get a closer approximation to 80486 behaviour, - * rather than behaviour which appears to be cleaner. - * This is a matter of opinion: for all I know, the 80486 may simply - * be complying with the IEEE spec. Maybe one day I'll get to see the - * spec... - */ -#define PECULIAR_486 - -#ifdef LOCORE -#include "fpu_asm.h" -#define Const(x) $/**/x -#else -#define Const(x) x -#endif - -#define EXP_BIAS Const(0) -#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */ -#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */ - -#define SIGN_POS Const(0) -#define SIGN_NEG Const(1) - -/* Keep the order TW_Valid, TW_Zero, TW_Denormal */ -#define TW_Valid Const(0)/* valid */ -#define TW_Zero Const(1)/* zero */ -/* The following fold to 2 (Special) in the Tag Word */ -#define TW_Denormal Const(4)/* De-normal */ -#define TW_Infinity Const(5)/* + or - infinity */ -#define TW_NaN Const(6)/* Not a Number */ - -#define TW_Empty Const(7)/* empty */ - - /* #define TW_FPU_Interrupt Const(0x80) *//* Signals an interrupt */ - - -#ifndef LOCORE - -#include "types.h" -#include "math_emu.h" - -#ifdef PARANOID -extern char emulating; -#define REENTRANT_CHECK(state) emulating = (state) -#define ON 1 -#define OFF 0 -#else -#define REENTRANT_CHECK(state) -#endif /* PARANOID */ - -typedef void (*FUNC) (void); -typedef struct fpu_reg FPU_REG; - -#define st(x) ( regs[((top+x) &7 )] ) - -#define STACK_OVERFLOW (st_new_ptr = &st(-1), st_new_ptr->tag != TW_Empty) -#define NOT_EMPTY(i) (st(i).tag != TW_Empty) -#define NOT_EMPTY_0 (FPU_st0_tag ^ TW_Empty) - -extern unsigned char FPU_rm; - -extern char FPU_st0_tag; -extern FPU_REG *FPU_st0_ptr; - -extern void *FPU_data_address; - -extern FPU_REG FPU_loaded_data; - -#define pop() { FPU_st0_ptr->tag = TW_Empty; top++; } - -/* push() does not affect the tags */ -#define push() { top--; FPU_st0_ptr = st_new_ptr; } - - -#define reg_move(x, y) { \ - *(short *)&((y)->sign) = *(short *)&((x)->sign); \ - *(long *)&((y)->exp) = *(long *)&((x)->exp); \ - *(long long *)&((y)->sigl) = *(long long *)&((x)->sigl); } - - -/*----- Prototypes for functions written in assembler -----*/ -/* extern void reg_move(FPU_REG *a, FPU_REG *b); */ - -extern void mul64(long long *a, long long *b, long long *result); -extern void poly_div2(long long *x); -extern void poly_div4(long long *x); -extern void poly_div16(long long *x); -extern void -polynomial(unsigned accum[], unsigned x[], - unsigned short terms[][4], int n); - extern void normalize(FPU_REG * x); - extern void normalize_nuo(FPU_REG * x); - extern void reg_div(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ, - unsigned int control_w); - extern void reg_u_sub(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ, - unsigned int control_w); - extern void reg_u_mul(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ, - unsigned int control_w); - extern void reg_u_div(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ, - unsigned int control_w); - extern void reg_u_add(FPU_REG * arg1, FPU_REG * arg2, FPU_REG * answ, - unsigned int control_w); - extern void wm_sqrt(FPU_REG * n, unsigned int control_w); - extern unsigned shrx(void *l, unsigned x); - extern unsigned shrxs(void *v, unsigned x); - extern unsigned long div_small(unsigned long long *x, unsigned long y); - extern void round_reg(FPU_REG * arg, unsigned int extent, - unsigned int control_w); - -#ifndef MAKING_PROTO -#include "fpu_proto.h" -#endif - -#endif /* LOCORE */ - -#endif /* _FPU_EMU_H_ */ diff --git a/sys/gnu/i386/fpemul/fpu_entry.c b/sys/gnu/i386/fpemul/fpu_entry.c deleted file mode 100644 index edbe94d..0000000 --- a/sys/gnu/i386/fpemul/fpu_entry.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * fpu_entry.c - * - * The entry function for wm-FPU-emu - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * $Id: fpu_entry.c,v 1.5 1994/08/30 20:18:52 davidg Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Note: | - | The file contains code which accesses user memory. | - | Emulator static data may change when user memory is accessed, due to | - | other processes using the emulator while swapping is in progress. | - +---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------+ - | math_emulate() is the sole entry point for wm-FPU-emu | - +---------------------------------------------------------------------------*/ - - -#include "param.h" -#include "systm.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "control_w.h" -#include "status_w.h" - - -#define __BAD__ Un_impl /* Not implemented */ - -#define FPU_LOOKAHEAD 1 /* For performance boost */ - -#if FPU_LOOKAHEAD != 0 /* I think thet we have to limit the */ -#define LOOKAHEAD_LIMIT 7 /* Max number of lookahead instructions*/ -#endif /* Or else a prog consisting of a million */ - /* fnops will spend all its time in kernel*/ - -#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by - * default. */ - -/* WARNING: These codes are not documented by Intel in their 80486 manual - and may not work on FPU clones or later Intel FPUs. */ - -/* Changes to support the un-doc codes provided by Linus Torvalds. */ - -#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_, _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__, - fdivr_, trig_b, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__, -}; -#else /* Support only documented FPU op-codes */ - -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__, - 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__, - fdivr_, trig_b, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__, -}; -#endif /* NO_UNDOC_CODE */ - - -#define _NONE_ 0 /* Take no special action */ -#define _REG0_ 1 /* Need to check for not empty st(0) */ -#define _REGI_ 2 /* Need to check for not empty st(0) and - * st(rm) */ -#define _REGi_ 0 /* Uses st(rm) */ -#define _PUSH_ 3 /* Need to check for space to push onto stack */ -#define _null_ 4 /* Function illegal or not implemented */ -#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */ -#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) - * then pop */ -#define _REGIc 0 /* Compare st(0) and st(rm) */ -#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks - * later */ - -#ifndef NO_UNDOC_CODE - -/* Un-documented FPU op-codes supported by default. (see above) */ - -static unsigned char type_table[64] = { - _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_, - _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_, - _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_, - _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_, - _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_, - _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_, - _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_, - _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_ -}; -#else /* Support only documented FPU op-codes */ - -static unsigned char type_table[64] = { - _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_, - _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_, - _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_, - _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_, - _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_, - _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_, - _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_, - _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_ -}; -#endif /* NO_UNDOC_CODE */ - -/* Be careful when using any of these global variables... - they might change if swapping is triggered */ -unsigned char FPU_rm; -char FPU_st0_tag; -FPU_REG *FPU_st0_ptr; - -#ifdef PARANOID -char emulating = 0; -#endif /* PARANOID */ - -#define bswapw(x) __asm__("xchgb %%al,%%ah":"=a" (x):"0" ((short)x)) -#define math_abort(signo) \ - FPU_EIP = FPU_ORIG_EIP;REENTRANT_CHECK(OFF);return(signo); - -int -math_emulate(struct trapframe * tframe) -{ - - unsigned char FPU_modrm; - unsigned short code; -#ifdef LOOKAHEAD_LIMIT - int lookahead_limit = LOOKAHEAD_LIMIT; -#endif -#ifdef PARANOID - if (emulating) { - printf("ERROR: wm-FPU-emu is not RE-ENTRANT!\n"); - } - REENTRANT_CHECK(ON); -#endif /* PARANOID */ - - if ((((struct pcb *) curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) { - finit(); - control_word = __INITIAL_NPXCW__; - ((struct pcb *) curproc->p_addr)->pcb_flags |= FP_SOFTFP; - } - FPU_info = tframe; - FPU_ORIG_EIP = FPU_EIP; /* --pink-- */ - - if (FPU_CS != 0x001f) { - printf("math_emulate: %x : %x\n", FPU_CS, FPU_EIP); - panic("FPU emulation in kernel"); - } -#ifdef notyet - /* We cannot handle emulation in v86-mode */ - if (FPU_EFLAGS & 0x00020000) { - FPU_ORIG_EIP = FPU_EIP; - math_abort(FPU_info, SIGILL); - } -#endif - - FPU_lookahead = FPU_LOOKAHEAD; - if (curproc->p_flag & P_TRACED) - FPU_lookahead = 0; - -do_another_FPU_instruction: - - REENTRANT_CHECK(OFF); - code = fuword((u_int *) FPU_EIP); - REENTRANT_CHECK(ON); - if ((code & 0xff) == 0x9b) { /* fwait */ - if (status_word & SW_Summary) - goto do_the_FPU_interrupt; - else { - FPU_EIP++; - goto FPU_instruction_done; - } - } - if (status_word & SW_Summary) { - /* Ignore the error for now if the current instruction is a - * no-wait control instruction */ - /* The 80486 manual contradicts itself on this topic, so I use - * the following list of such instructions until I can check - * on a real 80486: fninit, fnstenv, fnsave, fnstsw, fnstenv, - * fnclex. */ - if (!((((code & 0xf803) == 0xe003) || /* fnclex, fninit, - * fnstsw */ - (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, - * fnstenv, fnstsw */ - ((code & 0xc000) != 0xc000))))) { - /* This is a guess about what a real FPU might do to - * this bit: */ -/* status_word &= ~SW_Summary; ****/ - - /* We need to simulate the action of the kernel to FPU - * interrupts here. Currently, the "real FPU" part of - * the kernel (0.99.10) clears the exception flags, - * sets the registers to empty, and passes information - * back to the interrupted process via the cs selector - * and operand selector, so we do the same. */ - do_the_FPU_interrupt: - cs_selector &= 0xffff0000; - cs_selector |= (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift); - operand_selector = tag_word(); - status_word = 0; - top = 0; - { - int r; - for (r = 0; r < 8; r++) { - regs[r].tag = TW_Empty; - } - } - REENTRANT_CHECK(OFF); - math_abort(SIGFPE); - } - } - FPU_entry_eip = FPU_ORIG_EIP = FPU_EIP; - - if ((code & 0xff) == 0x66) { /* size prefix */ - FPU_EIP++; - REENTRANT_CHECK(OFF); - code = fuword((u_int *) FPU_EIP); - REENTRANT_CHECK(ON); - } - FPU_EIP += 2; - - FPU_modrm = code >> 8; - FPU_rm = FPU_modrm & 7; - - if (FPU_modrm < 0300) { - /* All of these instructions use the mod/rm byte to get a data - * address */ - get_address(FPU_modrm); - if (!(code & 1)) { - unsigned short status1 = status_word; - FPU_st0_ptr = &st(0); - FPU_st0_tag = FPU_st0_ptr->tag; - - /* Stack underflow has priority */ - if (NOT_EMPTY_0) { - switch ((code >> 1) & 3) { - case 0: - reg_load_single(); - break; - case 1: - reg_load_int32(); - break; - case 2: - reg_load_double(); - break; - case 3: - reg_load_int16(); - break; - } - - /* No more access to user memory, it is safe - * to use static data now */ - FPU_st0_ptr = &st(0); - FPU_st0_tag = FPU_st0_ptr->tag; - - /* NaN operands have the next priority. */ - /* We have to delay looking at st(0) until - * after loading the data, because that data - * might contain an SNaN */ - if ((FPU_st0_tag == TW_NaN) || - (FPU_loaded_data.tag == TW_NaN)) { - /* Restore the status word; we might - * have loaded a denormal. */ - status_word = status1; - if ((FPU_modrm & 0x30) == 0x10) { - /* fcom or fcomp */ - EXCEPTION(EX_Invalid); - setcc(SW_C3 | SW_C2 | SW_C0); - if (FPU_modrm & 0x08) - pop(); /* fcomp, so we pop. */ - } else - real_2op_NaN(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr); - goto reg_mem_instr_done; - } - switch ((FPU_modrm >> 3) & 7) { - case 0: /* fadd */ - reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); - break; - case 1: /* fmul */ - reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); - break; - case 2: /* fcom */ - compare_st_data(); - break; - case 3: /* fcomp */ - compare_st_data(); - pop(); - break; - case 4: /* fsub */ - reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); - break; - case 5: /* fsubr */ - reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word); - break; - case 6: /* fdiv */ - reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr, control_word); - break; - case 7: /* fdivr */ - if (FPU_st0_tag == TW_Zero) - status_word = status1; /* Undo any denorm tag, - * zero-divide has - * priority. */ - reg_div(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr, control_word); - break; - } - } else { - if ((FPU_modrm & 0x30) == 0x10) { - /* The instruction is fcom or fcomp */ - EXCEPTION(EX_StackUnder); - setcc(SW_C3 | SW_C2 | SW_C0); - if (FPU_modrm & 0x08) - pop(); /* fcomp, Empty or not, - * we pop. */ - } else - stack_underflow(); - } - } else { - load_store_instr(((FPU_modrm & 0x38) | (code & 6)) >> 1); - } - -reg_mem_instr_done: - - data_operand_offset = (unsigned long) FPU_data_address; - } else { - /* None of these instructions access user memory */ - unsigned char instr_index = (FPU_modrm & 0x38) | (code & 7); - - FPU_st0_ptr = &st(0); - FPU_st0_tag = FPU_st0_ptr->tag; - switch (type_table[(int) instr_index]) { - case _NONE_: /* also _REGIc: _REGIn */ - break; - case _REG0_: - if (!NOT_EMPTY_0) { - stack_underflow(); - goto FPU_instruction_done; - } - break; - case _REGIi: - if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) { - stack_underflow_i(FPU_rm); - goto FPU_instruction_done; - } - break; - case _REGIp: - if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) { - stack_underflow_i(FPU_rm); - pop(); - goto FPU_instruction_done; - } - break; - case _REGI_: - if (!NOT_EMPTY_0 || !NOT_EMPTY(FPU_rm)) { - stack_underflow(); - goto FPU_instruction_done; - } - break; - case _PUSH_: /* Only used by the fld st(i) instruction */ - break; - case _null_: - Un_impl(); - goto FPU_instruction_done; - default: - EXCEPTION(EX_INTERNAL | 0x111); - goto FPU_instruction_done; - } - (*st_instr_table[(int) instr_index]) (); - } - -FPU_instruction_done: - - ip_offset = FPU_entry_eip; - bswapw(code); - *(1 + (unsigned short *) &cs_selector) = code & 0x7ff; - -#ifdef DEBUG - REENTRANT_CHECK(OFF); - emu_printall(); - REENTRANT_CHECK(ON); -#endif /* DEBUG */ -#ifdef LOOKAHEAD_LIMIT -if (--lookahead_limit) -#endif - if (FPU_lookahead) { - unsigned char next; - - /* (This test should generate no machine code) */ - while (1) { - REENTRANT_CHECK(OFF); - next = fubyte((u_char *) FPU_EIP); - REENTRANT_CHECK(ON); - if (((next & 0xf8) == 0xd8) || (next == 0x9b)) { /* fwait */ - goto do_another_FPU_instruction; - } else - if (next == 0x66) { /* size prefix */ - REENTRANT_CHECK(OFF); - next = fubyte((u_char *) (FPU_EIP + 1)); - REENTRANT_CHECK(ON); - if ((next & 0xf8) == 0xd8) { - FPU_EIP++; - goto do_another_FPU_instruction; - } - } - break; - } - } - REENTRANT_CHECK(OFF); - return (0); /* --pink-- */ -} diff --git a/sys/gnu/i386/fpemul/fpu_etc.c b/sys/gnu/i386/fpemul/fpu_etc.c deleted file mode 100644 index 936e39a..0000000 --- a/sys/gnu/i386/fpemul/fpu_etc.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * fpu_etc.c - * - * Implement a few FPU instructions. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_etc.c,v 1.2 1994/04/29 21:16:22 gclarkii Exp $ - * - */ - -#include "param.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "status_w.h" -#include "reg_constant.h" - - -static void -fchs(void) -{ - if (NOT_EMPTY_0) { - FPU_st0_ptr->sign ^= SIGN_POS ^ SIGN_NEG; - status_word &= ~SW_C1; - } else - stack_underflow(); -} - -static void -fabs(void) -{ - if (FPU_st0_tag ^ TW_Empty) { - FPU_st0_ptr->sign = SIGN_POS; - status_word &= ~SW_C1; - } else - stack_underflow(); -} - - -static void -ftst_(void) -{ - switch (FPU_st0_tag) { - case TW_Zero: - setcc(SW_C3); - break; - case TW_Valid: - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (FPU_st0_ptr->sign == SIGN_POS) - setcc(0); - else - setcc(SW_C0); - break; - case TW_NaN: - setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */ - EXCEPTION(EX_Invalid); - break; - case TW_Infinity: - if (FPU_st0_ptr->sign == SIGN_POS) - setcc(0); - else - setcc(SW_C0); - EXCEPTION(EX_Invalid); - break; - case TW_Empty: - setcc(SW_C0 | SW_C2 | SW_C3); - EXCEPTION(EX_StackUnder); - break; - default: - setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */ - EXCEPTION(EX_INTERNAL | 0x14); - break; - } -} - -static void -fxam(void) -{ - int c = 0; - switch (FPU_st0_tag) { - case TW_Empty: - c = SW_C3 | SW_C0; - break; - case TW_Zero: - c = SW_C3; - break; - case TW_Valid: - /* This will need to be changed if TW_Denormal is ever used. */ - if (FPU_st0_ptr->exp <= EXP_UNDER) - c = SW_C2 | SW_C3; /* Denormal */ - else - c = SW_C3; - break; - case TW_NaN: - c = SW_C0; - break; - case TW_Infinity: - c = SW_C2 | SW_C0; - break; - } - if (FPU_st0_ptr->sign == SIGN_NEG) - c |= SW_C1; - setcc(c); -} - -static FUNC fp_etc_table[] = { - fchs, fabs, Un_impl, Un_impl, ftst_, fxam, Un_impl, Un_impl -}; - -void -fp_etc() -{ - (fp_etc_table[FPU_rm]) (); -} diff --git a/sys/gnu/i386/fpemul/fpu_proto.h b/sys/gnu/i386/fpemul/fpu_proto.h deleted file mode 100644 index c15c913..0000000 --- a/sys/gnu/i386/fpemul/fpu_proto.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * $Id: fpu_proto.h,v 1.2 1994/04/29 21:16:23 gclarkii Exp $ - * - */ - - -/* errors.c */ -extern void Un_impl(void); -extern void emu_printall(void); -extern void exception(int n); -extern void real_2op_NaN(FPU_REG * a, FPU_REG * b, FPU_REG * dest); -extern void arith_invalid(FPU_REG * dest); -extern void divide_by_zero(int sign, FPU_REG * dest); -extern void set_precision_flag_up(void); -extern void set_precision_flag_down(void); -extern int denormal_operand(void); -extern void arith_overflow(FPU_REG * dest); -extern void arith_underflow(FPU_REG * dest); -extern void stack_overflow(void); -extern void stack_underflow(void); -extern void stack_underflow_i(int i); -extern void stack_underflow_pop(int i); -/* fpu_arith.c */ -extern void fadd__(void); -extern void fmul__(void); -extern void fsub__(void); -extern void fsubr_(void); -extern void fdiv__(void); -extern void fdivr_(void); -extern void fadd_i(void); -extern void fmul_i(void); -extern void fsubri(void); -extern void fsub_i(void); -extern void fdivri(void); -extern void fdiv_i(void); -extern void faddp_(void); -extern void fmulp_(void); -extern void fsubrp(void); -extern void fsubp_(void); -extern void fdivrp(void); -extern void fdivp_(void); -/* fpu_aux.c */ -extern void fclex(void); -extern void finit(void); -extern void finit_(void); -extern void fstsw_(void); -extern void fp_nop(void); -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 */ -#if 0 -extern int math_emulate(struct trapframe * info); -#endif -/* fpu_etc.c */ -extern void fp_etc(void); -/* fpu_trig.c */ -extern void convert_l2reg(long *arg, FPU_REG * dest); -extern void trig_a(void); -extern void trig_b(void); -/* get_address.c */ -extern void get_address(unsigned char FPU_modrm); -/* load_store.c */ -extern void load_store_instr(char type); -/* poly_2xm1.c */ -extern int poly_2xm1(FPU_REG * arg, FPU_REG * result); -/* poly_atan.c */ -extern void poly_atan(FPU_REG * arg); -extern void poly_add_1(FPU_REG * src); -/* poly_l2.c */ -extern void poly_l2(FPU_REG * arg, FPU_REG * result); -extern int poly_l2p1(FPU_REG * arg, FPU_REG * result); -/* poly_sin.c */ -extern void poly_sine(FPU_REG * arg, FPU_REG * result); -/* poly_tan.c */ -extern void poly_tan(FPU_REG * arg, FPU_REG * y_reg); -/* reg_add_sub.c */ -extern void reg_add(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w); -extern void reg_sub(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w); -/* reg_compare.c */ -extern int compare(FPU_REG * b); -extern int compare_st_data(void); -extern void fcom_st(void); -extern void fcompst(void); -extern void fcompp(void); -extern void fucom_(void); -extern void fucomp(void); -extern void fucompp(void); -/* reg_constant.c */ -extern void fconst(void); -/* reg_ld_str.c */ -extern void reg_load_extended(void); -extern void reg_load_double(void); -extern void reg_load_single(void); -extern void reg_load_int64(void); -extern void reg_load_int32(void); -extern void reg_load_int16(void); -extern void reg_load_bcd(void); -extern int reg_store_extended(void); -extern int reg_store_double(void); -extern int reg_store_single(void); -extern int reg_store_int64(void); -extern int reg_store_int32(void); -extern int reg_store_int16(void); -extern int reg_store_bcd(void); -extern int round_to_int(FPU_REG * r); -extern char *fldenv(void); -extern void frstor(void); -extern unsigned short tag_word(void); -extern char *fstenv(void); -extern void fsave(void); -/* reg_mul.c */ -extern void reg_mul(FPU_REG * a, FPU_REG * b, FPU_REG * dest, unsigned int control_w); diff --git a/sys/gnu/i386/fpemul/fpu_system.h b/sys/gnu/i386/fpemul/fpu_system.h deleted file mode 100644 index bb9e5d0..0000000 --- a/sys/gnu/i386/fpemul/fpu_system.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * fpu_system.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_system.h,v 1.3 1994/06/10 07:44:25 rich Exp $ - * - */ - - -#ifndef _FPU_SYSTEM_H -#define _FPU_SYSTEM_H - -/* system dependent definitions */ - -/* -#include <linux/sched.h> -#include <linux/kernel.h> -*/ - -#define I387 (*(union i387_union *)&(((struct pcb *)curproc->p_addr)->pcb_savefpu)) -#define FPU_info (I387.soft.frame) - -#define FPU_CS (*(unsigned short *) &(FPU_info->tf_cs)) -#define FPU_DS (*(unsigned short *) &(FPU_info->tf_ds)) -#define FPU_EAX (FPU_info->tf_eax) -#define FPU_EFLAGS (FPU_info->tf_eflags) -#define FPU_EIP (FPU_info->tf_eip) -/*#define FPU_ORIG_EIP (FPU_info->___orig_eip) */ -/*#define FPU_ORIG_EIP (FPU_info->tf_isp)*/ -#define FPU_ORIG_EIP (I387.soft.orig_eip) - -#define FPU_lookahead (I387.soft.lookahead) -#define FPU_entry_eip (I387.soft.entry_eip) - -#define status_word (I387.soft.swd) -#define control_word (I387.soft.cwd) -#define regs (I387.soft.regs) -#define top (I387.soft.top) - -#define ip_offset (I387.soft.fip) -#define cs_selector (I387.soft.fcs) -#define data_operand_offset (I387.soft.foo) -#define operand_selector (I387.soft.fos) - -#endif diff --git a/sys/gnu/i386/fpemul/fpu_trig.c b/sys/gnu/i386/fpemul/fpu_trig.c deleted file mode 100644 index ca32f91..0000000 --- a/sys/gnu/i386/fpemul/fpu_trig.c +++ /dev/null @@ -1,1367 +0,0 @@ -/* - * fpu_trig.c - * - * Implementation of the FPU "transcendental" functions. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: fpu_trig.c,v 1.3 1994/04/29 21:16:25 gclarkii Exp $ - * - */ - - -#include "param.h" -#include "proc.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "status_w.h" -#include "reg_constant.h" -#include "control_w.h" - -static int -trig_arg(FPU_REG * X) -{ - FPU_REG tmp, quot; - int rv; - long long q; - int old_cw = control_word; - - control_word &= ~CW_RC; - control_word |= RC_CHOP; - - reg_move(X, "); - reg_div(", &CONST_PI2, ", FULL_PRECISION); - - reg_move(", &tmp); - round_to_int(&tmp); - if (tmp.sigh & 0x80000000) - return -1; /* |Arg| is >= 2^63 */ - tmp.exp = EXP_BIAS + 63; - q = *(long long *) &(tmp.sigl); - normalize(&tmp); - - reg_sub(", &tmp, X, FULL_PRECISION); - rv = q & 7; - - control_word = old_cw; - return rv;; -} - - -/* Convert a long to register */ -void -convert_l2reg(long *arg, FPU_REG * dest) -{ - long num = *arg; - - if (num == 0) { - reg_move(&CONST_Z, dest); - return; - } - if (num > 0) - dest->sign = SIGN_POS; - else { - num = -num; - dest->sign = SIGN_NEG; - } - - dest->sigh = num; - dest->sigl = 0; - dest->exp = EXP_BIAS + 31; - dest->tag = TW_Valid; - normalize(dest); -} - - -static void -single_arg_error(void) -{ - switch (FPU_st0_tag) { - case TW_NaN: - if (!(FPU_st0_ptr->sigh & 0x40000000)) { /* Signaling ? */ - EXCEPTION(EX_Invalid); - /* Convert to a QNaN */ - FPU_st0_ptr->sigh |= 0x40000000; - } - break; /* return with a NaN in st(0) */ - case TW_Empty: - stack_underflow(); /* Puts a QNaN in st(0) */ - break; -#ifdef PARANOID - default: - EXCEPTION(EX_INTERNAL | 0x0112); -#endif /* PARANOID */ - } -} - - -/*---------------------------------------------------------------------------*/ - -static void -f2xm1(void) -{ - switch (FPU_st0_tag) { - case TW_Valid: - { - FPU_REG rv, tmp; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (FPU_st0_ptr->sign == SIGN_POS) { - /* poly_2xm1(x) requires 0 < x < 1. */ - if (poly_2xm1(FPU_st0_ptr, &rv)) - return; /* error */ - reg_mul(&rv, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION); - } else { -/* **** Should change poly_2xm1() to at least handle numbers near 0 */ - /* poly_2xm1(x) doesn't handle negative - * numbers. */ - /* So we compute (poly_2xm1(x+1)-1)/2, for -1 - * < x < 0 */ - reg_add(FPU_st0_ptr, &CONST_1, &tmp, FULL_PRECISION); - poly_2xm1(&tmp, &rv); - reg_mul(&rv, &tmp, &tmp, FULL_PRECISION); - reg_sub(&tmp, &CONST_1, FPU_st0_ptr, FULL_PRECISION); - FPU_st0_ptr->exp--; - if (FPU_st0_ptr->exp <= EXP_UNDER) - arith_underflow(FPU_st0_ptr); - } - return; - } - case TW_Zero: - return; - case TW_Infinity: - if (FPU_st0_ptr->sign == SIGN_NEG) { - /* -infinity gives -1 (p16-10) */ - reg_move(&CONST_1, FPU_st0_ptr); - FPU_st0_ptr->sign = SIGN_NEG; - } - return; - default: - single_arg_error(); - } -} - -static void -fptan(void) -{ - FPU_REG *st_new_ptr; - int q; - char arg_sign = FPU_st0_ptr->sign; - - if (STACK_OVERFLOW) { - stack_overflow(); - return; - } - switch (FPU_st0_tag) { - case TW_Valid: - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - FPU_st0_ptr->sign = SIGN_POS; - if ((q = trig_arg(FPU_st0_ptr)) != -1) { - if (q & 1) - reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION); - - poly_tan(FPU_st0_ptr, FPU_st0_ptr); - - FPU_st0_ptr->sign = (q & 1) ^ arg_sign; - - if (FPU_st0_ptr->exp <= EXP_UNDER) - arith_underflow(FPU_st0_ptr); - - push(); - reg_move(&CONST_1, FPU_st0_ptr); - setcc(0); - } else { - /* Operand is out of range */ - setcc(SW_C2); - FPU_st0_ptr->sign = arg_sign; /* restore st(0) */ - return; - } - break; - case TW_Infinity: - /* Operand is out of range */ - setcc(SW_C2); - FPU_st0_ptr->sign = arg_sign; /* restore st(0) */ - return; - case TW_Zero: - push(); - reg_move(&CONST_1, FPU_st0_ptr); - setcc(0); - break; - default: - single_arg_error(); - break; - } -} - - -static void -fxtract(void) -{ - FPU_REG *st_new_ptr; - register FPU_REG *st1_ptr = FPU_st0_ptr; /* anticipate */ - - if (STACK_OVERFLOW) { - stack_overflow(); - return; - } - if (!(FPU_st0_tag ^ TW_Valid)) { - long e; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - push(); - reg_move(st1_ptr, FPU_st0_ptr); - FPU_st0_ptr->exp = EXP_BIAS; - e = st1_ptr->exp - EXP_BIAS; - convert_l2reg(&e, st1_ptr); - return; - } else - if (FPU_st0_tag == TW_Zero) { - char sign = FPU_st0_ptr->sign; - divide_by_zero(SIGN_NEG, FPU_st0_ptr); - push(); - reg_move(&CONST_Z, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - return; - } else - if (FPU_st0_tag == TW_Infinity) { - char sign = FPU_st0_ptr->sign; - FPU_st0_ptr->sign = SIGN_POS; - push(); - reg_move(&CONST_INF, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - return; - } else - if (FPU_st0_tag == TW_NaN) { - if (!(FPU_st0_ptr->sigh & 0x40000000)) { /* Signaling ? */ - EXCEPTION(EX_Invalid); - /* Convert to a QNaN */ - FPU_st0_ptr->sigh |= 0x40000000; - } - push(); - reg_move(st1_ptr, FPU_st0_ptr); - return; - } else - if (FPU_st0_tag == TW_Empty) { - /* Is this the correct - * behaviour? */ - if (control_word & EX_Invalid) { - stack_underflow(); - push(); - stack_underflow(); - } else - EXCEPTION(EX_StackUnder); - } -#ifdef PARANOID - else - EXCEPTION(EX_INTERNAL | 0x119); -#endif /* PARANOID */ -} - - -static void -fdecstp(void) -{ - top--; /* FPU_st0_ptr will be fixed in math_emulate() - * before the next instr */ -} - -static void -fincstp(void) -{ - top++; /* FPU_st0_ptr will be fixed in math_emulate() - * before the next instr */ -} - - -static void -fsqrt_(void) -{ - if (!(FPU_st0_tag ^ TW_Valid)) { - int expon; - - if (FPU_st0_ptr->sign == SIGN_NEG) { - arith_invalid(FPU_st0_ptr); /* sqrt(negative) is - * invalid */ - return; - } -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - expon = FPU_st0_ptr->exp - EXP_BIAS; - FPU_st0_ptr->exp = EXP_BIAS + (expon & 1); /* make st(0) in [1.0 - * .. 4.0) */ - - wm_sqrt(FPU_st0_ptr, control_word); /* Do the computation */ - - FPU_st0_ptr->exp += expon >> 1; - FPU_st0_ptr->sign = SIGN_POS; - } else - if (FPU_st0_tag == TW_Zero) - return; - else - if (FPU_st0_tag == TW_Infinity) { - if (FPU_st0_ptr->sign == SIGN_NEG) - arith_invalid(FPU_st0_ptr); /* sqrt(-Infinity) is - * invalid */ - return; - } else { - single_arg_error(); - return; - } - -} - - -static void -frndint_(void) -{ - if (!(FPU_st0_tag ^ TW_Valid)) { - if (FPU_st0_ptr->exp > EXP_BIAS + 63) - return; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - round_to_int(FPU_st0_ptr); /* Fortunately, this can't - * overflow to 2^64 */ - FPU_st0_ptr->exp = EXP_BIAS + 63; - normalize(FPU_st0_ptr); - return; - } else - if ((FPU_st0_tag == TW_Zero) || (FPU_st0_tag == TW_Infinity)) - return; - else - single_arg_error(); -} - - -static void -fsin(void) -{ - char arg_sign = FPU_st0_ptr->sign; - - if (FPU_st0_tag == TW_Valid) { - int q; - FPU_st0_ptr->sign = SIGN_POS; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if ((q = trig_arg(FPU_st0_ptr)) != -1) { - FPU_REG rv; - - if (q & 1) - reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr, FULL_PRECISION); - - poly_sine(FPU_st0_ptr, &rv); - - setcc(0); - if (q & 2) - rv.sign ^= SIGN_POS ^ SIGN_NEG; - rv.sign ^= arg_sign; - reg_move(&rv, FPU_st0_ptr); - - if (FPU_st0_ptr->exp <= EXP_UNDER) - arith_underflow(FPU_st0_ptr); - - set_precision_flag_up(); /* We do not really know - * if up or down */ - - return; - } else { - /* Operand is out of range */ - setcc(SW_C2); - FPU_st0_ptr->sign = arg_sign; /* restore st(0) */ - return; - } - } else - if (FPU_st0_tag == TW_Zero) { - setcc(0); - return; - } else - if (FPU_st0_tag == TW_Infinity) { - /* Operand is out of range */ - setcc(SW_C2); - FPU_st0_ptr->sign = arg_sign; /* restore st(0) */ - return; - } else - single_arg_error(); -} - - -static int -f_cos(FPU_REG * arg) -{ - char arg_sign = arg->sign; - - if (arg->tag == TW_Valid) { - int q; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return 1; -#endif /* DENORM_OPERAND */ - - arg->sign = SIGN_POS; - if ((q = trig_arg(arg)) != -1) { - FPU_REG rv; - - if (!(q & 1)) - reg_sub(&CONST_1, arg, arg, FULL_PRECISION); - - poly_sine(arg, &rv); - - setcc(0); - if ((q + 1) & 2) - rv.sign ^= SIGN_POS ^ SIGN_NEG; - reg_move(&rv, arg); - - set_precision_flag_up(); /* We do not really know - * if up or down */ - - return 0; - } else { - /* Operand is out of range */ - setcc(SW_C2); - arg->sign = arg_sign; /* restore st(0) */ - return 1; - } - } else - if (arg->tag == TW_Zero) { - reg_move(&CONST_1, arg); - setcc(0); - return 0; - } else - if (FPU_st0_tag == TW_Infinity) { - /* Operand is out of range */ - setcc(SW_C2); - arg->sign = arg_sign; /* restore st(0) */ - return 1; - } else { - single_arg_error(); /* requires arg == - * &st(0) */ - return 1; - } -} - - -static void -fcos(void) -{ - f_cos(FPU_st0_ptr); -} - - -static void -fsincos(void) -{ - FPU_REG *st_new_ptr; - FPU_REG arg; - - if (STACK_OVERFLOW) { - stack_overflow(); - return; - } - reg_move(FPU_st0_ptr, &arg); - if (!f_cos(&arg)) { - fsin(); - push(); - reg_move(&arg, FPU_st0_ptr); - } -} - - -/*---------------------------------------------------------------------------*/ -/* The following all require two arguments: st(0) and st(1) */ - -/* remainder of st(0) / st(1) */ -/* Assumes that st(0) and st(1) are both TW_Valid */ -static void -fprem_kernel(int round) -{ - FPU_REG *st1_ptr = &st(1); - char st1_tag = st1_ptr->tag; - - if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) { - FPU_REG tmp; - int old_cw = control_word; - int expdif = FPU_st0_ptr->exp - (st1_ptr)->exp; - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - control_word &= ~CW_RC; - control_word |= round; - - if (expdif < 64) { - /* This should be the most common case */ - long long q; - int c = 0; - - reg_div(FPU_st0_ptr, st1_ptr, &tmp, FULL_PRECISION); - - round_to_int(&tmp); /* Fortunately, this can't - * overflow to 2^64 */ - tmp.exp = EXP_BIAS + 63; - q = *(long long *) &(tmp.sigl); - normalize(&tmp); - - reg_mul(st1_ptr, &tmp, &tmp, FULL_PRECISION); - reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr, FULL_PRECISION); - - if (q & 4) - c |= SW_C3; - if (q & 2) - c |= SW_C1; - if (q & 1) - c |= SW_C0; - - setcc(c); - } else { - /* There is a large exponent difference ( >= 64 ) */ - int N_exp; - - reg_div(FPU_st0_ptr, st1_ptr, &tmp, FULL_PRECISION); - /* N is 'a number between 32 and 63' (p26-113) */ - N_exp = (tmp.exp & 31) + 32; - tmp.exp = EXP_BIAS + N_exp; - - round_to_int(&tmp); /* Fortunately, this can't - * overflow to 2^64 */ - tmp.exp = EXP_BIAS + 63; - normalize(&tmp); - - tmp.exp = EXP_BIAS + expdif - N_exp; - - reg_mul(st1_ptr, &tmp, &tmp, FULL_PRECISION); - reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr, FULL_PRECISION); - - setcc(SW_C2); - } - control_word = old_cw; - - if (FPU_st0_ptr->exp <= EXP_UNDER) - arith_underflow(FPU_st0_ptr); - return; - } else - if ((FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty)) { - stack_underflow(); - return; - } else - if (FPU_st0_tag == TW_Zero) { - if (st1_tag == TW_Valid) { - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - setcc(0); - return; - } else - if (st1_tag == TW_Zero) { - arith_invalid(FPU_st0_ptr); - return; - } - /* fprem(?,0) always invalid */ - else - if (st1_tag == TW_Infinity) { - setcc(0); - return; - } - } else - if (FPU_st0_tag == TW_Valid) { - if (st1_tag == TW_Zero) { - arith_invalid(FPU_st0_ptr); /* fprem(Valid,Zero) is - * invalid */ - return; - } else - if (st1_tag != TW_NaN) { -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (st1_tag == TW_Infinity) { - /* fprem(Valid, - * Infinity) - * is o.k. */ - setcc(0); - return; - } - } - } else - if (FPU_st0_tag == TW_Infinity) { - if (st1_tag != TW_NaN) { - arith_invalid(FPU_st0_ptr); /* fprem(Infinity,?) is - * invalid */ - return; - } - } - /* One of the registers must contain a NaN is we got here. */ - -#ifdef PARANOID - if ((FPU_st0_tag != TW_NaN) && (st1_tag != TW_NaN)) - EXCEPTION(EX_INTERNAL | 0x118); -#endif /* PARANOID */ - - real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); - -} - - -/* ST(1) <- ST(1) * log ST; pop ST */ -static void -fyl2x(void) -{ - FPU_REG *st1_ptr = &st(1); - char st1_tag = st1_ptr->tag; - - if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) { - if (FPU_st0_ptr->sign == SIGN_POS) { - int saved_control, saved_status; - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - /* We use the general purpose arithmetic, so we need - * to save these. */ - saved_status = status_word; - saved_control = control_word; - control_word = FULL_PRECISION; - - poly_l2(FPU_st0_ptr, FPU_st0_ptr); - - /* Enough of the basic arithmetic is done now */ - control_word = saved_control; - status_word = saved_status; - - /* Let the multiply set the flags */ - reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr, FULL_PRECISION); - - pop(); - FPU_st0_ptr = &st(0); - } else { - /* negative */ - pop(); - FPU_st0_ptr = &st(0); - arith_invalid(FPU_st0_ptr); /* st(0) cannot be - * negative */ - return; - } - } else - if ((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) { - stack_underflow_pop(1); - return; - } else - if ((FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN)) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } else - if ((FPU_st0_tag <= TW_Zero) && (st1_tag <= TW_Zero)) { - /* one of the args is zero, the other - * valid, or both zero */ - if (FPU_st0_tag == TW_Zero) { - pop(); - FPU_st0_ptr = &st(0); - if (FPU_st0_ptr->tag == TW_Zero) - arith_invalid(FPU_st0_ptr); /* Both args zero is - * invalid */ -#ifdef PECULIAR_486 - /* This case is not - * specifically covered in the - * manual, but divide-by-zero - * would seem to be the best - * response. However, a real - * 80486 does it this way... */ - else - if (FPU_st0_ptr->tag == TW_Infinity) { - reg_move(&CONST_INF, FPU_st0_ptr); - return; - } -#endif /* PECULIAR_486 */ - else - divide_by_zero(st1_ptr->sign ^ SIGN_NEG ^ SIGN_POS, FPU_st0_ptr); - return; - } else { - /* st(1) contains zero, st(0) - * valid <> 0 */ - /* Zero is the valid answer */ - char sign = st1_ptr->sign; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - if (FPU_st0_ptr->sign == SIGN_NEG) { - pop(); - FPU_st0_ptr = &st(0); - arith_invalid(FPU_st0_ptr); /* log(negative) */ - return; - } - if (FPU_st0_ptr->exp < EXP_BIAS) - sign ^= SIGN_NEG ^ SIGN_POS; - pop(); - FPU_st0_ptr = &st(0); - reg_move(&CONST_Z, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - return; - } - } - /* One or both arg must be an infinity */ - else - if (FPU_st0_tag == TW_Infinity) { - if ((FPU_st0_ptr->sign == SIGN_NEG) || (st1_tag == TW_Zero)) { - pop(); - FPU_st0_ptr = &st(0); - arith_invalid(FPU_st0_ptr); /* log(-infinity) or - * 0*log(infinity) */ - return; - } else { - char sign = st1_ptr->sign; - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - pop(); - FPU_st0_ptr = &st(0); - reg_move(&CONST_INF, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - return; - } - } - /* st(1) must be infinity here */ - else - if ((FPU_st0_tag == TW_Valid) && (FPU_st0_ptr->sign == SIGN_POS)) { - if (FPU_st0_ptr->exp >= EXP_BIAS) { - if ((FPU_st0_ptr->exp == EXP_BIAS) && - (FPU_st0_ptr->sigh == 0x80000000) && - (FPU_st0_ptr->sigl == 0)) { - /* st(0 - * ) - * hold - * s - * 1.0 */ - pop(); - FPU_st0_ptr = &st(0); - arith_invalid(FPU_st0_ptr); /* infinity*log(1) */ - return; - } - /* st(0) is - * positive - * and > 1.0 */ - pop(); - } else { - /* st(0) is - * positive - * and < 1.0 */ - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - st1_ptr->sign ^= SIGN_NEG; - pop(); - } - return; - } else { - /* st(0) must be zero - * or negative */ - if (FPU_st0_ptr->tag == TW_Zero) { - pop(); - FPU_st0_ptr = st1_ptr; - st1_ptr->sign ^= SIGN_NEG ^ SIGN_POS; - /* This should - * be invalid, - * but a real - * 80486 is - * happy with - * it. */ -#ifndef PECULIAR_486 - divide_by_zero(st1_ptr->sign, FPU_st0_ptr); -#endif /* PECULIAR_486 */ - } else { - pop(); - FPU_st0_ptr = st1_ptr; - arith_invalid(FPU_st0_ptr); /* log(negative) */ - } - return; - } -} - - -static void -fpatan(void) -{ - FPU_REG *st1_ptr = &st(1); - char st1_tag = st1_ptr->tag; - - if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) { - int saved_control, saved_status; - FPU_REG sum; - int quadrant = st1_ptr->sign | ((FPU_st0_ptr->sign) << 1); - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - /* We use the general purpose arithmetic so we need to save - * these. */ - saved_status = status_word; - saved_control = control_word; - control_word = FULL_PRECISION; - - st1_ptr->sign = FPU_st0_ptr->sign = SIGN_POS; - if (compare(st1_ptr) == COMP_A_lt_B) { - quadrant |= 4; - reg_div(FPU_st0_ptr, st1_ptr, &sum, FULL_PRECISION); - } else - reg_div(st1_ptr, FPU_st0_ptr, &sum, FULL_PRECISION); - - poly_atan(&sum); - - if (quadrant & 4) { - reg_sub(&CONST_PI2, &sum, &sum, FULL_PRECISION); - } - if (quadrant & 2) { - reg_sub(&CONST_PI, &sum, &sum, FULL_PRECISION); - } - if (quadrant & 1) - sum.sign ^= SIGN_POS ^ SIGN_NEG; - - /* All of the basic arithmetic is done now */ - control_word = saved_control; - status_word = saved_status; - - reg_move(&sum, st1_ptr); - } else - if ((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) { - stack_underflow_pop(1); - return; - } else - if ((FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN)) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } else - if ((FPU_st0_tag == TW_Infinity) || (st1_tag == TW_Infinity)) { - char sign = st1_ptr->sign; - if (FPU_st0_tag == TW_Infinity) { - if (st1_tag == TW_Infinity) { - if (FPU_st0_ptr->sign == SIGN_POS) { - reg_move(&CONST_PI4, st1_ptr); - } else - reg_add(&CONST_PI4, &CONST_PI2, st1_ptr, FULL_PRECISION); - } else { - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (FPU_st0_ptr->sign == SIGN_POS) { - reg_move(&CONST_Z, st1_ptr); - pop(); - return; - } else - reg_move(&CONST_PI, st1_ptr); - } - } else { - /* st(1) is infinity, st(0) - * not infinity */ -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - reg_move(&CONST_PI2, st1_ptr); - } - st1_ptr->sign = sign; - } else - if (st1_tag == TW_Zero) { - /* st(0) must be valid or zero */ - char sign = st1_ptr->sign; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (FPU_st0_ptr->sign == SIGN_POS) { - reg_move(&CONST_Z, st1_ptr); - pop(); - return; - } else - reg_move(&CONST_PI, st1_ptr); - st1_ptr->sign = sign; - } else - if (FPU_st0_tag == TW_Zero) { - /* st(1) must be - * TW_Valid here */ - char sign = st1_ptr->sign; - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - reg_move(&CONST_PI2, st1_ptr); - st1_ptr->sign = sign; - } -#ifdef PARANOID - else - EXCEPTION(EX_INTERNAL | 0x220); -#endif /* PARANOID */ - - pop(); - set_precision_flag_up();/* We do not really know if up or down */ -} - - -static void -fprem(void) -{ - fprem_kernel(RC_CHOP); -} - - -static void -fprem1(void) -{ - fprem_kernel(RC_RND); -} - - -static void -fyl2xp1(void) -{ - FPU_REG *st1_ptr = &st(1); - char st1_tag = st1_ptr->tag; - - if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) { - int saved_control, saved_status; - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - /* We use the general purpose arithmetic so we need to save - * these. */ - saved_status = status_word; - saved_control = control_word; - control_word = FULL_PRECISION; - - if (poly_l2p1(FPU_st0_ptr, FPU_st0_ptr)) { - arith_invalid(st1_ptr); /* poly_l2p1() returned - * invalid */ - pop(); - return; - } - /* Enough of the basic arithmetic is done now */ - control_word = saved_control; - status_word = saved_status; - - /* Let the multiply set the flags */ - reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr, FULL_PRECISION); - - pop(); - } else - if ((FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty)) { - stack_underflow_pop(1); - return; - } else - if (FPU_st0_tag == TW_Zero) { - if (st1_tag <= TW_Zero) { - -#ifdef DENORM_OPERAND - if ((st1_tag == TW_Valid) && (st1_ptr->exp <= EXP_UNDER) && - (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - st1_ptr->sign ^= FPU_st0_ptr->sign; - reg_move(FPU_st0_ptr, st1_ptr); - } else - if (st1_tag == TW_Infinity) { - arith_invalid(st1_ptr); /* Infinity*log(1) */ - pop(); - return; - } else - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } -#ifdef PARANOID - else { - EXCEPTION(EX_INTERNAL | 0x116); - return; - } -#endif /* PARANOID */ - pop(); - return; - } else - if (FPU_st0_tag == TW_Valid) { - if (st1_tag == TW_Zero) { - if (FPU_st0_ptr->sign == SIGN_NEG) { - if (FPU_st0_ptr->exp >= EXP_BIAS) { - /* st(0) holds - * <= -1.0 */ - arith_invalid(st1_ptr); /* infinity*log(1) */ - pop(); - return; - } -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - st1_ptr->sign ^= SIGN_POS ^ SIGN_NEG; - pop(); - return; - } -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - pop(); - return; - } - if (st1_tag == TW_Infinity) { - if (FPU_st0_ptr->sign == SIGN_NEG) { - if ((FPU_st0_ptr->exp >= EXP_BIAS) && - !((FPU_st0_ptr->sigh == 0x80000000) && - (FPU_st0_ptr->sigl == 0))) { - /* st(0) holds - * < -1.0 */ - arith_invalid(st1_ptr); - pop(); - return; - } -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - st1_ptr->sign ^= SIGN_POS ^ SIGN_NEG; - pop(); - return; - } -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - pop(); - return; - } - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } - } else - if (FPU_st0_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } else - if (FPU_st0_tag == TW_Infinity) { - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr); - pop(); - return; - } else - if ((FPU_st0_ptr->sign == SIGN_NEG) || - (st1_tag == TW_Zero)) { - arith_invalid(st1_ptr); /* log(infinity) */ - pop(); - return; - } - /* st(1) must be valid - * here. */ - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - /* The Manual says - * that log(Infinity) - * is invalid, but a - * real 80486 sensibly - * says that it is - * o.k. */ - { - char sign = st1_ptr->sign; - reg_move(&CONST_INF, st1_ptr); - st1_ptr->sign = sign; - } - pop(); - return; - } -#ifdef PARANOID - else { - EXCEPTION(EX_INTERNAL | 0x117); - } -#endif /* PARANOID */ -} - - -static void -emu_fscale(void) -{ - FPU_REG *st1_ptr = &st(1); - char st1_tag = st1_ptr->tag; - int old_cw = control_word; - - if (!((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid))) { - long scale; - FPU_REG tmp; - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (st1_ptr->exp <= EXP_UNDER)) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (st1_ptr->exp > EXP_BIAS + 30) { - /* 2^31 is far too large, would require 2^(2^30) or - * 2^(-2^30) */ - char sign; - - if (st1_ptr->sign == SIGN_POS) { - EXCEPTION(EX_Overflow); - sign = FPU_st0_ptr->sign; - reg_move(&CONST_INF, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - } else { - EXCEPTION(EX_Underflow); - sign = FPU_st0_ptr->sign; - reg_move(&CONST_Z, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - } - return; - } - control_word &= ~CW_RC; - control_word |= RC_CHOP; - reg_move(st1_ptr, &tmp); - round_to_int(&tmp); /* This can never overflow here */ - control_word = old_cw; - scale = st1_ptr->sign ? -tmp.sigl : tmp.sigl; - scale += FPU_st0_ptr->exp; - FPU_st0_ptr->exp = scale; - - /* Use round_reg() to properly detect under/overflow etc */ - round_reg(FPU_st0_ptr, 0, control_word); - - return; - } else - if (FPU_st0_tag == TW_Valid) { - if (st1_tag == TW_Zero) { - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - return; - } - if (st1_tag == TW_Infinity) { - char sign = st1_ptr->sign; - -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - if (sign == SIGN_POS) { - reg_move(&CONST_INF, FPU_st0_ptr); - } else - reg_move(&CONST_Z, FPU_st0_ptr); - FPU_st0_ptr->sign = sign; - return; - } - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); - return; - } - } else - if (FPU_st0_tag == TW_Zero) { - if (st1_tag == TW_Valid) { - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - return; - } else - if (st1_tag == TW_Zero) { - return; - } else - if (st1_tag == TW_Infinity) { - if (st1_ptr->sign == SIGN_NEG) - return; - else { - arith_invalid(FPU_st0_ptr); /* Zero scaled by - * +Infinity */ - return; - } - } else - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); - return; - } - } else - if (FPU_st0_tag == TW_Infinity) { - if (st1_tag == TW_Valid) { - -#ifdef DENORM_OPERAND - if ((st1_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return; -#endif /* DENORM_OPERAND */ - - return; - } - if (((st1_tag == TW_Infinity) && (st1_ptr->sign == SIGN_POS)) - || (st1_tag == TW_Zero)) - return; - else - if (st1_tag == TW_Infinity) { - arith_invalid(FPU_st0_ptr); /* Infinity scaled by - * -Infinity */ - return; - } else - if (st1_tag == TW_NaN) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); - return; - } - } else - if (FPU_st0_tag == TW_NaN) { - if (st1_tag != TW_Empty) { - real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); - return; - } - } -#ifdef PARANOID - if (!((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty))) { - EXCEPTION(EX_INTERNAL | 0x115); - return; - } -#endif - - /* At least one of st(0), st(1) must be empty */ - stack_underflow(); - -} - - -/*---------------------------------------------------------------------------*/ - -static FUNC trig_table_a[] = { - f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp -}; - -void -trig_a(void) -{ - (trig_table_a[FPU_rm]) (); -} - - -static FUNC trig_table_b[] = -{ - fprem, fyl2xp1, fsqrt_, fsincos, frndint_, emu_fscale, fsin, fcos -}; - -void -trig_b(void) -{ - (trig_table_b[FPU_rm]) (); -} diff --git a/sys/gnu/i386/fpemul/get_address.c b/sys/gnu/i386/fpemul/get_address.c deleted file mode 100644 index 5839e57..0000000 --- a/sys/gnu/i386/fpemul/get_address.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * get_address.c - * - * Get the effective address from an FPU instruction. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: get_address.c,v 1.2 1994/04/29 21:16:26 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Note: | - | The file contains code which accesses user memory. | - | Emulator static data may change when user memory is accessed, due to | - | other processes using the emulator while swapping is in progress. | - +---------------------------------------------------------------------------*/ - -#include "param.h" -#include "proc.h" -#include "systm.h" -#include "machine/cpu.h" -#include "machine/pcb.h" -#include "machine/reg.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" - -static int reg_offset[] = { -tEAX, tECX, tEDX, tEBX, tESP, tEBP, tESI, tEDI}; -#define REG_(x) (*(((int*)FPU_info) + reg_offset[(x)])) - -void *FPU_data_address; - - -/* Decode the SIB byte. This function assumes mod != 0 */ -static void * -sib(int mod) -{ - unsigned char ss, index, base; - long offset; - - REENTRANT_CHECK(OFF); - base = fubyte((char *) FPU_EIP); /* The SIB byte */ - REENTRANT_CHECK(ON); - FPU_EIP++; - ss = base >> 6; - index = (base >> 3) & 7; - base &= 7; - - if ((mod == 0) && (base == 5)) - offset = 0; /* No base register */ - else - offset = REG_(base); - - if (index == 4) { - /* No index register */ - /* A non-zero ss is illegal */ - if (ss) - EXCEPTION(EX_Invalid); - } else { - offset += (REG_(index)) << ss; - } - - if (mod == 1) { - /* 8 bit signed displacement */ - REENTRANT_CHECK(OFF); - offset += (signed char) fubyte((char *) FPU_EIP); - REENTRANT_CHECK(ON); - FPU_EIP++; - } else - if (mod == 2 || base == 5) { /* The second condition also - * has mod==0 */ - /* 32 bit displacment */ - REENTRANT_CHECK(OFF); - offset += (signed) fuword((unsigned long *) FPU_EIP); - REENTRANT_CHECK(ON); - FPU_EIP += 4; - } - return (void *) offset; -} - - -/* - MOD R/M byte: MOD == 3 has a special use for the FPU - SIB byte used iff R/M = 100b - - 7 6 5 4 3 2 1 0 - ..... ......... ......... - MOD OPCODE(2) R/M - - - SIB byte - - 7 6 5 4 3 2 1 0 - ..... ......... ......... - SS INDEX BASE - -*/ - -void -get_address(unsigned char FPU_modrm) -{ - unsigned char mod; - long *cpu_reg_ptr; - int offset = 0; /* Initialized just to stop compiler warnings. */ - - mod = (FPU_modrm >> 6) & 3; - - if (FPU_rm == 4 && mod != 3) { - FPU_data_address = sib(mod); - return; - } - cpu_reg_ptr = (long *) ®_(FPU_rm); - switch (mod) { - case 0: - if (FPU_rm == 5) { - /* Special case: disp32 */ - REENTRANT_CHECK(OFF); - offset = fuword((unsigned long *) FPU_EIP); - REENTRANT_CHECK(ON); - FPU_EIP += 4; - FPU_data_address = (void *) offset; - return; - } else { - FPU_data_address = (void *) *cpu_reg_ptr; /* Just return the - * contents of the cpu - * register */ - return; - } - case 1: - /* 8 bit signed displacement */ - REENTRANT_CHECK(OFF); - offset = (signed char) fubyte((char *) FPU_EIP); - REENTRANT_CHECK(ON); - FPU_EIP++; - break; - case 2: - /* 32 bit displacement */ - REENTRANT_CHECK(OFF); - offset = (signed) fuword((unsigned long *) FPU_EIP); - REENTRANT_CHECK(ON); - FPU_EIP += 4; - break; - case 3: - /* Not legal for the FPU */ - EXCEPTION(EX_Invalid); - } - - FPU_data_address = offset + (char *) *cpu_reg_ptr; -} diff --git a/sys/gnu/i386/fpemul/load_store.c b/sys/gnu/i386/fpemul/load_store.c deleted file mode 100644 index e45b67e..0000000 --- a/sys/gnu/i386/fpemul/load_store.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * load_store.c - * - * This file contains most of the code to interpret the FPU instructions - * which load and store from user memory. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: load_store.c,v 1.3 1994/06/10 07:44:30 rich Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Note: | - | The file contains code which accesses user memory. | - | Emulator static data may change when user memory is accessed, due to | - | other processes using the emulator while swapping is in progress. | - +---------------------------------------------------------------------------*/ - -#include "param.h" -#include "proc.h" -#include "systm.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "status_w.h" - - -#define _NONE_ 0 /* FPU_st0_ptr etc not needed */ -#define _REG0_ 1 /* Will be storing st(0) */ -#define _PUSH_ 3 /* Need to check for space to push onto stack */ -#define _null_ 4 /* Function illegal or not implemented */ - -#define pop_0() { pop_ptr->tag = TW_Empty; top++; } - - -static unsigned char type_table[32] = { - _PUSH_, _PUSH_, _PUSH_, _PUSH_, - _null_, _null_, _null_, _null_, - _REG0_, _REG0_, _REG0_, _REG0_, - _REG0_, _REG0_, _REG0_, _REG0_, - _NONE_, _null_, _NONE_, _PUSH_, - _NONE_, _PUSH_, _null_, _PUSH_, - _NONE_, _null_, _NONE_, _REG0_, - _NONE_, _REG0_, _NONE_, _REG0_ -}; - -void -load_store_instr(char type) -{ - FPU_REG *pop_ptr; /* We need a version of FPU_st0_ptr which - * won't change. */ - - pop_ptr = NULL; /* Initialized just to stop compiler warnings. */ - - - switch (type_table[(int) (unsigned) type]) { - case _NONE_: - break; - case _REG0_: - pop_ptr = &st(0); /* Some of these instructions pop - * after storing */ - - FPU_st0_ptr = pop_ptr; /* Set the global variables. */ - FPU_st0_tag = FPU_st0_ptr->tag; - break; - case _PUSH_: - { - pop_ptr = &st(-1); - if (pop_ptr->tag != TW_Empty) { - stack_overflow(); - return; - } - top--; - } - break; - case _null_: - return Un_impl(); -#ifdef PARANOID - default: - return EXCEPTION(EX_INTERNAL); -#endif /* PARANOID */ - } - - switch (type) { - case 000: /* fld m32real */ - reg_load_single(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 001: /* fild m32int */ - reg_load_int32(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 002: /* fld m64real */ - reg_load_double(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 003: /* fild m16int */ - reg_load_int16(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 010: /* fst m32real */ - reg_store_single(); - break; - case 011: /* fist m32int */ - reg_store_int32(); - break; - case 012: /* fst m64real */ - reg_store_double(); - break; - case 013: /* fist m16int */ - reg_store_int16(); - break; - case 014: /* fstp m32real */ - if (reg_store_single()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 015: /* fistp m32int */ - if (reg_store_int32()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 016: /* fstp m64real */ - if (reg_store_double()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 017: /* fistp m16int */ - if (reg_store_int16()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 020: /* fldenv m14/28byte */ - fldenv(); - break; - case 022: /* frstor m94/108byte */ - frstor(); - break; - case 023: /* fbld m80dec */ - reg_load_bcd(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 024: /* fldcw */ - REENTRANT_CHECK(OFF); - control_word = fusword((unsigned short *) FPU_data_address); - REENTRANT_CHECK(ON); -#ifdef NO_UNDERFLOW_TRAP - if (!(control_word & EX_Underflow)) { - control_word |= EX_Underflow; - } -#endif - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - break; - case 025: /* fld m80real */ - reg_load_extended(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 027: /* fild m64int */ - reg_load_int64(); - setcc(0); /* Clear the SW_C1 bit, "other bits undefined" */ - reg_move(&FPU_loaded_data, pop_ptr); - break; - case 030: /* fstenv m14/28byte */ - fstenv(); - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - break; - case 032: /* fsave */ - fsave(); - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - break; - case 033: /* fbstp m80dec */ - if (reg_store_bcd()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 034: /* fstcw m16int */ - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, FPU_data_address, 2);*/ - susword( (short *) FPU_data_address,control_word); - REENTRANT_CHECK(ON); - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - break; - case 035: /* fstp m80real */ - if (reg_store_extended()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - case 036: /* fstsw m2byte */ - status_word &= ~SW_Top; - status_word |= (top & 7) << SW_Top_Shift; - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, FPU_data_address, 2);*/ - susword( (short *) FPU_data_address,status_word); - REENTRANT_CHECK(ON); - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - break; - case 037: /* fistp m64int */ - if (reg_store_int64()) - pop_0();/* pop only if the number was actually stored - * (see the 80486 manual p16-28) */ - break; - } -} diff --git a/sys/gnu/i386/fpemul/math_emu.h b/sys/gnu/i386/fpemul/math_emu.h deleted file mode 100644 index 4dc90b8..0000000 --- a/sys/gnu/i386/fpemul/math_emu.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * $Id:$ - * - */ - -#ifndef _MATH_EMU_H -#define _MATH_EMU_H - -struct fpu_reg { - char sign; - char tag; - long exp; - u_long sigl; - u_long sigh; -}; - -union i387_union { - struct i387_hard_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 - * bytes */ - } hard; - struct i387_soft_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long top; - struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 - * bytes */ - unsigned char lookahead; - struct trapframe *frame; - unsigned long entry_eip; - int orig_eip; - } soft; -}; -#endif diff --git a/sys/gnu/i386/fpemul/poly_2xm1.c b/sys/gnu/i386/fpemul/poly_2xm1.c deleted file mode 100644 index b7e81f2..0000000 --- a/sys/gnu/i386/fpemul/poly_2xm1.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * poly_2xm1.c - * - * Function to compute 2^x-1 by a polynomial approximation. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_2xm1.c,v 1.2 1994/04/29 21:23:25 gclarkii Exp $ - * - */ - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" - - - -#define HIPOWER 13 -static unsigned short lterms[HIPOWER][4] = -{ - {0x79b5, 0xd1cf, 0x17f7, 0xb172}, - {0x1b56, 0x058b, 0x7bff, 0x3d7f}, - {0x8bb0, 0x8250, 0x846b, 0x0e35}, - {0xbc65, 0xf747, 0x556d, 0x0276}, - {0x17cb, 0x9e39, 0x61ff, 0x0057}, - {0xe018, 0x9776, 0x1848, 0x000a}, - {0x66f2, 0xff30, 0xffe5, 0x0000}, - {0x682f, 0xffb6, 0x162b, 0x0000}, - {0xb7ca, 0x2956, 0x01b5, 0x0000}, - {0xcd3e, 0x4817, 0x001e, 0x0000}, - {0xb7e2, 0xecbe, 0x0001, 0x0000}, - {0x0ed5, 0x1a27, 0x0000, 0x0000}, - {0x101d, 0x0222, 0x0000, 0x0000}, -}; - - -/*--- poly_2xm1() -----------------------------------------------------------+ - | | - +---------------------------------------------------------------------------*/ -int -poly_2xm1(FPU_REG * arg, FPU_REG * result) -{ - short exponent; - long long Xll; - FPU_REG accum; - - - exponent = arg->exp - EXP_BIAS; - - if (arg->tag == TW_Zero) { - /* Return 0.0 */ - reg_move(&CONST_Z, result); - return 0; - } - if (exponent >= 0) { /* Can't hack a number >= 1.0 */ - arith_invalid(result); /* Number too large */ - return 1; - } - if (arg->sign != SIGN_POS) { /* Can't hack a number < 0.0 */ - arith_invalid(result); /* Number negative */ - return 1; - } - if (exponent < -64) { - reg_move(&CONST_LN2, result); - return 0; - } - *(unsigned *) &Xll = arg->sigl; - *(((unsigned *) &Xll) + 1) = arg->sigh; - if (exponent < -1) { - /* shift the argument right by the required places */ - if (shrx(&Xll, -1 - exponent) >= (unsigned)0x80000000) - Xll++; /* round up */ - } - *(short *) &(accum.sign) = 0; /* will be a valid positive nr with - * expon = 0 */ - accum.exp = 0; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((unsigned *) &accum.sigl, (unsigned *) &Xll, lterms, HIPOWER - 1); - - /* Convert to 64 bit signed-compatible */ - accum.exp += EXP_BIAS - 1; - - reg_move(&accum, result); - - normalize(result); - - return 0; - -} diff --git a/sys/gnu/i386/fpemul/poly_atan.c b/sys/gnu/i386/fpemul/poly_atan.c deleted file mode 100644 index 179049f..0000000 --- a/sys/gnu/i386/fpemul/poly_atan.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * p_atan.c - * - * Compute the tan of a FPU_REG, using a polynomial approximation. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_atan.c,v 1.3 1994/04/29 21:23:26 gclarkii Exp $ - * - */ - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "control_w.h" - - -#define HIPOWERon 6 /* odd poly, negative terms */ -static unsigned oddnegterms[HIPOWERon][2] = -{ - {0x00000000, 0x00000000}, /* for + 1.0 */ - {0x763b6f3d, 0x1adc4428}, - {0x20f0630b, 0x0502909d}, - {0x4e825578, 0x0198ce38}, - {0x22b7cb87, 0x008da6e3}, - {0x9b30ca03, 0x00239c79} -}; -#define HIPOWERop 6 /* odd poly, positive terms */ -static unsigned oddplterms[HIPOWERop][2] = -{ - {0xa6f67cb8, 0x94d910bd}, - {0xa02ffab4, 0x0a43cb45}, - {0x04265e6b, 0x02bf5655}, - {0x0a728914, 0x00f280f7}, - {0x6d640e01, 0x004d6556}, - {0xf1dd2dbf, 0x000a530a} -}; - - -static unsigned denomterm[2] = -{0xfc4bd208, 0xea2e6612}; - - - -/*--- poly_atan() -----------------------------------------------------------+ - | | - +---------------------------------------------------------------------------*/ -void -poly_atan(FPU_REG * arg) -{ - char recursions = 0; - short exponent; - FPU_REG odd_poly, even_poly, pos_poly, neg_poly; - FPU_REG argSq; - long long arg_signif, argSqSq; - - -#ifdef PARANOID - if (arg->sign != 0) { /* Can't hack a number < 0.0 */ - arith_invalid(arg); - return; - } /* Need a positive number */ -#endif /* PARANOID */ - - exponent = arg->exp - EXP_BIAS; - - if (arg->tag == TW_Zero) { - /* Return 0.0 */ - reg_move(&CONST_Z, arg); - return; - } - if (exponent >= -2) { - /* argument is in the range [0.25 .. 1.0] */ - if (exponent >= 0) { -#ifdef PARANOID - if ((exponent == 0) && - (arg->sigl == 0) && (arg->sigh == 0x80000000)) -#endif /* PARANOID */ - { - reg_move(&CONST_PI4, arg); - return; - } -#ifdef PARANOID - EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic - * error */ -#endif /* PARANOID */ - } - /* If the argument is greater than sqrt(2)-1 (=0.414213562...) */ - /* convert the argument by an identity for atan */ - if ((exponent >= -1) || (arg->sigh > 0xd413ccd0)) { - FPU_REG numerator, denom; - - recursions++; - - arg_signif = *(long long *) &(arg->sigl); - if (exponent < -1) { - if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) - arg_signif++; /* round up */ - } - *(long long *) &(numerator.sigl) = -arg_signif; - numerator.exp = EXP_BIAS - 1; - normalize(&numerator); /* 1 - arg */ - - arg_signif = *(long long *) &(arg->sigl); - if (shrx(&arg_signif, -exponent) >= (unsigned)0x80000000) - arg_signif++; /* round up */ - *(long long *) &(denom.sigl) = arg_signif; - denom.sigh |= 0x80000000; /* 1 + arg */ - - arg->exp = numerator.exp; - reg_u_div(&numerator, &denom, arg, FULL_PRECISION); - - exponent = arg->exp - EXP_BIAS; - } - } - *(long long *) &arg_signif = *(long long *) &(arg->sigl); - -#ifdef PARANOID - /* This must always be true */ - if (exponent >= -1) { - EXCEPTION(EX_INTERNAL | 0x120); /* There must be a logic error */ - } -#endif /* PARANOID */ - - /* shift the argument right by the required places */ - if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) - arg_signif++; /* round up */ - - /* Now have arg_signif with binary point at the left .1xxxxxxxx */ - mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl)); - mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(pos_poly.sign) = 0; - pos_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, - (unsigned short (*)[4]) oddplterms, HIPOWERop - 1); - mul64((long long *) (&argSq.sigl), (long long *) (&pos_poly.sigl), - (long long *) (&pos_poly.sigl)); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(neg_poly.sign) = 0; - neg_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, - (unsigned short (*)[4]) oddnegterms, HIPOWERon - 1); - - /* Subtract the mantissas */ - *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl)); - - reg_move(&pos_poly, &odd_poly); - poly_add_1(&odd_poly); - - /* The complete odd polynomial */ - reg_u_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(even_poly.sign) = 0; - - mul64((long long *) (&argSq.sigl), - (long long *) (&denomterm), (long long *) (&even_poly.sigl)); - - poly_add_1(&even_poly); - - reg_div(&odd_poly, &even_poly, arg, FULL_PRECISION); - - if (recursions) - reg_sub(&CONST_PI4, arg, arg, FULL_PRECISION); -} - - -/* The argument to this function must be polynomial() compatible, - i.e. have an exponent (not checked) of EXP_BIAS-1 but need not - be normalized. - This function adds 1.0 to the (assumed positive) argument. */ -void -poly_add_1(FPU_REG * src) -{ -/* Rounding in a consistent direction produces better results - for the use of this function in poly_atan. Simple truncation - is used here instead of round-to-nearest. */ - -#ifdef OBSOLETE - char round = (src->sigl & 3) == 3; -#endif /* OBSOLETE */ - - shrx(&src->sigl, 1); - -#ifdef OBSOLETE - if (round) - (*(long long *) &src->sigl)++; /* Round to even */ -#endif /* OBSOLETE */ - - src->sigh |= 0x80000000; - - src->exp = EXP_BIAS; - -} diff --git a/sys/gnu/i386/fpemul/poly_div.s b/sys/gnu/i386/fpemul/poly_div.s deleted file mode 100644 index 3ac5bf0..0000000 --- a/sys/gnu/i386/fpemul/poly_div.s +++ /dev/null @@ -1,144 +0,0 @@ - .file "poly_div.S" -/* - * poly_div.S - * - * A set of functions to divide 64 bit integers by fixed numbers. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_div.s,v 1.2 1994/04/29 21:23:27 gclarkii Exp $ - * - */ - -#include "fpu_asm.h" - -.text - -/*---------------------------------------------------------------------------*/ - .align 2,144 -.globl _poly_div2 -_poly_div2: - pushl %ebp - movl %esp,%ebp - - movl PARAM1,%ecx - movw (%ecx),%ax - - shrl $1,4(%ecx) - rcrl $1,(%ecx) - - testw $1,%ax - je poly_div2_exit - - addl $1,(%ecx) - adcl $0,4(%ecx) -poly_div2_exit: - - leave - ret -/*---------------------------------------------------------------------------*/ - .align 2,144 -.globl _poly_div4 -_poly_div4: - pushl %ebp - movl %esp,%ebp - - movl PARAM1,%ecx - movw (%ecx),%ax - - movl 4(%ecx),%edx - shll $30,%edx - - shrl $2,4(%ecx) - shrl $2,(%ecx) - - orl %edx,(%ecx) - - testw $2,%ax - je poly_div4_exit - - addl $1,(%ecx) - adcl $0,4(%ecx) -poly_div4_exit: - - leave - ret -/*---------------------------------------------------------------------------*/ - .align 2,144 -.globl _poly_div16 -_poly_div16: - pushl %ebp - movl %esp,%ebp - - movl PARAM1,%ecx - movw (%ecx),%ax - - movl 4(%ecx),%edx - shll $28,%edx - - shrl $4,4(%ecx) - shrl $4,(%ecx) - - orl %edx,(%ecx) - - testw $8,%ax - je poly_div16_exit - - addl $1,(%ecx) - adcl $0,4(%ecx) -poly_div16_exit: - - leave - ret -/*---------------------------------------------------------------------------*/ diff --git a/sys/gnu/i386/fpemul/poly_l2.c b/sys/gnu/i386/fpemul/poly_l2.c deleted file mode 100644 index 0607c16..0000000 --- a/sys/gnu/i386/fpemul/poly_l2.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * poly_l2.c - * - * Compute the base 2 log of a FPU_REG, using a polynomial approximation. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_l2.c,v 1.4 1994/04/30 16:47:08 gclarkii Exp $ - * - */ - - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "control_w.h" - - - -#define HIPOWER 9 -static unsigned short lterms[HIPOWER][4] = -{ - /* Ideal computation with these coeffs gives about 64.6 bit rel - * accuracy. */ - {0xe177, 0xb82f, 0x7652, 0x7154}, - {0xee0f, 0xe80f, 0x2770, 0x7b1c}, - {0x0fc0, 0xbe87, 0xb143, 0x49dd}, - {0x78b9, 0xdadd, 0xec54, 0x34c2}, - {0x003a, 0x5de9, 0x628b, 0x2909}, - {0x5588, 0xed16, 0x4abf, 0x2193}, - {0xb461, 0x85f7, 0x347a, 0x1c6a}, - {0x0975, 0x87b3, 0xd5bf, 0x1876}, - {0xe85c, 0xcec9, 0x84e7, 0x187d} -}; - - - - -/*--- poly_l2() -------------------------------------------------------------+ - | Base 2 logarithm by a polynomial approximation. | - +---------------------------------------------------------------------------*/ -void -poly_l2(FPU_REG * arg, FPU_REG * result) -{ - short exponent; - char zero; /* flag for an Xx == 0 */ - unsigned short bits, shift; - long long Xsq; - FPU_REG accum, denom, num, Xx; - - - exponent = arg->exp - EXP_BIAS; - - accum.tag = TW_Valid; /* set the tags to Valid */ - - if (arg->sigh > (unsigned) 0xb504f334) { - /* This is good enough for the computation of the polynomial - * sum, but actually results in a loss of precision for the - * computation of Xx. This will matter only if exponent - * becomes zero. */ - exponent++; - accum.sign = 1; /* sign to negative */ - num.exp = EXP_BIAS; /* needed to prevent errors in div - * routine */ - reg_u_div(&CONST_1, arg, &num, FULL_PRECISION); - } else { - accum.sign = 0; /* set the sign to positive */ - num.sigl = arg->sigl; /* copy the mantissa */ - num.sigh = arg->sigh; - } - - - /* shift num left, lose the ms bit */ - num.sigh <<= 1; - if (num.sigl & 0x80000000) - num.sigh |= 1; - num.sigl <<= 1; - - denom.sigl = num.sigl; - denom.sigh = num.sigh; - poly_div4((long long *) &(denom.sigl)); - denom.sigh += 0x80000000; /* set the msb */ - Xx.exp = EXP_BIAS; /* needed to prevent errors in div routine */ - reg_u_div(&num, &denom, &Xx, FULL_PRECISION); - - zero = !(Xx.sigh | Xx.sigl); - - mul64((long long *) &Xx.sigl, (long long *) &Xx.sigl, &Xsq); - poly_div16(&Xsq); - - accum.exp = -1; /* exponent of accum */ - - /* Do the basic fixed point polynomial evaluation */ - polynomial((unsigned *) &accum.sigl, (unsigned *) &Xsq, lterms, HIPOWER - 1); - - if (!exponent) { - /* If the exponent is zero, then we would lose precision by - * sticking to fixed point computation here */ - /* We need to re-compute Xx because of loss of precision. */ - FPU_REG lXx; - char sign; - - sign = accum.sign; - accum.sign = 0; - - /* make accum compatible and normalize */ - accum.exp = EXP_BIAS + accum.exp; - normalize(&accum); - - if (zero) { - reg_move(&CONST_Z, result); - } else { - /* we need to re-compute lXx to better accuracy */ - num.tag = TW_Valid; /* set the tags to Vaild */ - num.sign = 0; /* set the sign to positive */ - num.exp = EXP_BIAS - 1; - if (sign) { - /* The argument is of the form 1-x */ - /* Use 1-1/(1-x) = x/(1-x) */ - *((long long *) &num.sigl) = -*((long long *) &(arg->sigl)); - normalize(&num); - reg_div(&num, arg, &num, FULL_PRECISION); - } else { - normalize(&num); - } - - denom.tag = TW_Valid; /* set the tags to Valid */ - denom.sign = SIGN_POS; /* set the sign to positive */ - denom.exp = EXP_BIAS; - - reg_div(&num, &denom, &lXx, FULL_PRECISION); - - reg_u_mul(&lXx, &accum, &accum, FULL_PRECISION); - - reg_u_add(&lXx, &accum, result, FULL_PRECISION); - - normalize(result); - } - - result->sign = sign; - return; - } - mul64((long long *) &accum.sigl, - (long long *) &Xx.sigl, (long long *) &accum.sigl); - - *((long long *) (&accum.sigl)) += *((long long *) (&Xx.sigl)); - - if (Xx.sigh > accum.sigh) { - /* There was an overflow */ - - poly_div2((long long *) &accum.sigl); - accum.sigh |= 0x80000000; - accum.exp++; - } - /* When we add the exponent to the accum result later, we will require - * that their signs are the same. Here we ensure that this is so. */ - if (exponent && ((exponent < 0) ^ (accum.sign))) { - /* signs are different */ - - accum.sign = !accum.sign; - - /* An exceptional case is when accum is zero */ - if (accum.sigl | accum.sigh) { - /* find 1-accum */ - /* Shift to get exponent == 0 */ - if (accum.exp < 0) { - poly_div2((long long *) &accum.sigl); - accum.exp++; - } - /* Just negate, but throw away the sign */ - *((long long *) &(accum.sigl)) = -*((long long *) &(accum.sigl)); - if (exponent < 0) - exponent++; - else - exponent--; - } - } - shift = exponent >= 0 ? exponent : -exponent; - bits = 0; - if (shift) { - if (accum.exp) { - accum.exp++; - poly_div2((long long *) &accum.sigl); - } - while (shift) { - poly_div2((long long *) &accum.sigl); - if (shift & 1) - accum.sigh |= 0x80000000; - shift >>= 1; - bits++; - } - } - /* Convert to 64 bit signed-compatible */ - accum.exp += bits + EXP_BIAS - 1; - - reg_move(&accum, result); - normalize(result); - - return; -} - - -/*--- poly_l2p1() -----------------------------------------------------------+ - | Base 2 logarithm by a polynomial approximation. | - | log2(x+1) | - +---------------------------------------------------------------------------*/ -int -poly_l2p1(FPU_REG * arg, FPU_REG * result) -{ - char sign = 0; - long long Xsq; - FPU_REG arg_pl1, denom, accum, local_arg, poly_arg; - - - sign = arg->sign; - - reg_add(arg, &CONST_1, &arg_pl1, FULL_PRECISION); - - if ((arg_pl1.sign) | (arg_pl1.tag)) { /* We need a valid positive - * number! */ - return 1; - } - reg_add(&CONST_1, &arg_pl1, &denom, FULL_PRECISION); - reg_div(arg, &denom, &local_arg, FULL_PRECISION); - local_arg.sign = 0; /* Make the sign positive */ - - /* Now we need to check that |local_arg| is less than 3-2*sqrt(2) = - * 0.17157.. = .0xafb0ccc0 * 2^-2 */ - - if (local_arg.exp >= EXP_BIAS - 3) { - if ((local_arg.exp > EXP_BIAS - 3) || - (local_arg.sigh > (unsigned) 0xafb0ccc0)) { - /* The argument is large */ - poly_l2(&arg_pl1, result); - return 0; - } - } - /* Make a copy of local_arg */ - reg_move(&local_arg, &poly_arg); - - /* Get poly_arg bits aligned as required */ - shrx((unsigned *) &(poly_arg.sigl), -(poly_arg.exp - EXP_BIAS + 3)); - - mul64((long long *) &(poly_arg.sigl), (long long *) &(poly_arg.sigl), &Xsq); - poly_div16(&Xsq); - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &accum.sigl, (unsigned *) &Xsq, lterms, HIPOWER - 1); - - accum.tag = TW_Valid; /* set the tags to Valid */ - accum.sign = SIGN_POS; /* and make accum positive */ - - /* make accum compatible and normalize */ - accum.exp = EXP_BIAS - 1; - normalize(&accum); - - reg_u_mul(&local_arg, &accum, &accum, FULL_PRECISION); - - reg_u_add(&local_arg, &accum, result, FULL_PRECISION); - - /* Multiply the result by 2 */ - result->exp++; - - result->sign = sign; - - return 0; -} diff --git a/sys/gnu/i386/fpemul/poly_mul64.s b/sys/gnu/i386/fpemul/poly_mul64.s deleted file mode 100644 index c0f5d0f..0000000 --- a/sys/gnu/i386/fpemul/poly_mul64.s +++ /dev/null @@ -1,124 +0,0 @@ -/* - * poly_mul64.S - * - * Multiply two 64 bit integers. - * - * Call from C as: - * void mul64(long long *a, long long *b, long long *result) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_mul64.s,v 1.2 1994/04/29 21:23:29 gclarkii Exp $ - * - */ - - -#include "fpu_asm.h" - -.text - .align 2,144 -.globl _mul64 -_mul64: - pushl %ebp - movl %esp,%ebp - subl $16,%esp - pushl %esi - pushl %ebx - - movl PARAM1,%esi - movl PARAM2,%ecx - movl PARAM3,%ebx - - xor %eax,%eax - movl %eax,-4(%ebp) - movl %eax,-8(%ebp) - - movl (%esi),%eax - mull (%ecx) - movl %eax,-16(%ebp) /* Not used */ - movl %edx,-12(%ebp) - - movl (%esi),%eax - mull 4(%ecx) - addl %eax,-12(%ebp) - adcl %edx,-8(%ebp) - adcl $0,-4(%ebp) - - movl 4(%esi),%eax - mull (%ecx) - addl %eax,-12(%ebp) - adcl %edx,-8(%ebp) - adcl $0,-4(%ebp) - - movl 4(%esi),%eax - mull 4(%ecx) - addl %eax,-8(%ebp) - adcl %edx,-4(%ebp) - - testb $128,-9(%ebp) - je L_no_round - - addl $1,-8(%ebp) - adcl $0,-4(%ebp) - -L_no_round: - movl -8(%ebp),%esi - movl %esi,(%ebx) - movl -4(%ebp),%esi - movl %esi,4(%ebx) - - popl %ebx - popl %esi - leave - ret diff --git a/sys/gnu/i386/fpemul/poly_sin.c b/sys/gnu/i386/fpemul/poly_sin.c deleted file mode 100644 index a1aa11c..0000000 --- a/sys/gnu/i386/fpemul/poly_sin.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * poly_sin.c - * - * Computation of an approximation of the sin function by a polynomial - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_sin.c,v 1.4 1994/06/10 07:44:41 rich Exp $ - * - */ - - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "control_w.h" - - -#define HIPOWER 5 -static unsigned short lterms[HIPOWER][4] = -{ - {0x846a, 0x42d1, 0xb544, 0x921f}, - {0xe110, 0x75aa, 0xbc67, 0x1466}, - {0x503d, 0xa43f, 0x83c1, 0x000a}, - {0x8f9d, 0x7a19, 0x00f4, 0x0000}, - {0xda03, 0x06aa, 0x0000, 0x0000}, -}; - -static unsigned short negterms[HIPOWER][4] = -{ - {0x95ed, 0x2df2, 0xe731, 0xa55d}, - {0xd159, 0xe62b, 0xd2cc, 0x0132}, - {0x6342, 0xe9fb, 0x3c60, 0x0000}, - {0x6256, 0xdf5a, 0x0002, 0x0000}, - {0xf279, 0x000b, 0x0000, 0x0000}, -}; - - -/*--- poly_sine() -----------------------------------------------------------+ - | | - +---------------------------------------------------------------------------*/ -void -poly_sine(FPU_REG * arg, FPU_REG * result) -{ - short exponent; - FPU_REG Xx, Xx2, Xx4, accum, negaccum; - - - exponent = arg->exp - EXP_BIAS; - - if (arg->tag == TW_Zero) { - /* Return 0.0 */ - reg_move(&CONST_Z, result); - return; - } -#ifdef PARANOID - if (arg->sign != 0) { /* Can't hack a number < 0.0 */ - EXCEPTION(EX_Invalid); - reg_move(&CONST_QNaN, result); - return; - } - if (exponent >= 0) { /* Can't hack a number > 1.0 */ - if ((exponent == 0) && (arg->sigl == 0) && (arg->sigh == 0x80000000)) { - reg_move(&CONST_1, result); - return; - } - EXCEPTION(EX_Invalid); - reg_move(&CONST_QNaN, result); - return; - } -#endif /* PARANOID */ - - Xx.sigl = arg->sigl; - Xx.sigh = arg->sigh; - if (exponent < -1) { - /* shift the argument right by the required places */ - if (shrx(&(Xx.sigl), -1 - exponent) >= (unsigned)0x80000000) - (*((long long *) (&(Xx.sigl))))++; /* round up */ - } - mul64((long long *) &(Xx.sigl), (long long *) &(Xx.sigl), - (long long *) &(Xx2.sigl)); - mul64((long long *) &(Xx2.sigl), (long long *) &(Xx2.sigl), - (long long *) &(Xx4.sigl)); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(accum.sign) = 0; - accum.exp = 0; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &(accum.sigl), (u_int *)&(Xx4.sigl), lterms, HIPOWER - 1); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(negaccum.sign) = 0; - negaccum.exp = 0; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &(negaccum.sigl), (u_int *)&(Xx4.sigl), negterms, HIPOWER - 1); - mul64((long long *) &(Xx2.sigl), (long long *) &(negaccum.sigl), - (long long *) &(negaccum.sigl)); - - /* Subtract the mantissas */ - *((long long *) (&(accum.sigl))) -= *((long long *) (&(negaccum.sigl))); - - /* Convert to 64 bit signed-compatible */ - accum.exp = EXP_BIAS - 1 + accum.exp; - - *(short *) &(result->sign) = *(short *) &(accum.sign); - result->exp = accum.exp; - result->sigl = accum.sigl; - result->sigh = accum.sigh; - - normalize(result); - - reg_mul(result, arg, result, FULL_PRECISION); - reg_u_add(result, arg, result, FULL_PRECISION); - - /* A small overflow may be possible... but an illegal result. */ - if (result->exp >= EXP_BIAS) { - if ((result->exp > EXP_BIAS) /* Larger or equal 2.0 */ - ||(result->sigl > 1) /* Larger than 1.0+msb */ - ||(result->sigh != 0x80000000) /* Much > 1.0 */ - ) { -#ifdef DEBUGGING - RE_ENTRANT_CHECK_OFF - printk("\nEXP=%d, MS=%08x, LS=%08x\n", result->exp, - result->sigh, result->sigl); - RE_ENTRANT_CHECK_ON -#endif /* DEBUGGING */ - EXCEPTION(EX_INTERNAL | 0x103); - } -#ifdef DEBUGGING - RE_ENTRANT_CHECK_OFF - printk("\n***CORRECTING ILLEGAL RESULT*** in poly_sin() computation\n"); - printk("EXP=%d, MS=%08x, LS=%08x\n", result->exp, - result->sigh, result->sigl); - RE_ENTRANT_CHECK_ON -#endif /* DEBUGGING */ - - result->sigl = 0; /* Truncate the result to 1.00 */ - } -} diff --git a/sys/gnu/i386/fpemul/poly_tan.c b/sys/gnu/i386/fpemul/poly_tan.c deleted file mode 100644 index 6098c81..0000000 --- a/sys/gnu/i386/fpemul/poly_tan.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * poly_tan.c - * - * Compute the tan of a FPU_REG, using a polynomial approximation. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: poly_tan.c,v 1.4 1994/06/10 07:44:42 rich Exp $ - * - */ - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "control_w.h" - - -#define HIPOWERop 3 /* odd poly, positive terms */ -static unsigned short oddplterms[HIPOWERop][4] = -{ - {0x846a, 0x42d1, 0xb544, 0x921f}, - {0x6fb2, 0x0215, 0x95c0, 0x099c}, - {0xfce6, 0x0cc8, 0x1c9a, 0x0000} -}; -#define HIPOWERon 2 /* odd poly, negative terms */ -static unsigned short oddnegterms[HIPOWERon][4] = -{ - {0x6906, 0xe205, 0x25c8, 0x8838}, - {0x1dd7, 0x3fe3, 0x944e, 0x002c} -}; -#define HIPOWERep 2 /* even poly, positive terms */ -static unsigned short evenplterms[HIPOWERep][4] = -{ - {0xdb8f, 0x3761, 0x1432, 0x2acf}, - {0x16eb, 0x13c1, 0x3099, 0x0003} -}; -#define HIPOWERen 2 /* even poly, negative terms */ -static unsigned short evennegterms[HIPOWERen][4] = -{ - {0x3a7c, 0xe4c5, 0x7f87, 0x2945}, - {0x572b, 0x664c, 0xc543, 0x018c} -}; - - -/*--- poly_tan() ------------------------------------------------------------+ - | | - +---------------------------------------------------------------------------*/ -void -poly_tan(FPU_REG * arg, FPU_REG * y_reg) -{ - char invert = 0; - short exponent; - FPU_REG odd_poly, even_poly, pos_poly, neg_poly; - FPU_REG argSq; - long long arg_signif, argSqSq; - - - exponent = arg->exp - EXP_BIAS; - - if (arg->tag == TW_Zero) { - /* Return 0.0 */ - reg_move(&CONST_Z, y_reg); - return; - } - if (exponent >= -1) { - /* argument is in the range [0.5 .. 1.0] */ - if (exponent >= 0) { -#ifdef PARANOID - if ((exponent == 0) && - (arg->sigl == 0) && (arg->sigh == 0x80000000)) -#endif /* PARANOID */ - { - arith_overflow(y_reg); - return; - } -#ifdef PARANOID - EXCEPTION(EX_INTERNAL | 0x104); /* There must be a logic - * error */ - return; -#endif /* PARANOID */ - } - /* The argument is in the range [0.5 .. 1.0) */ - /* Convert the argument to a number in the range (0.0 .. 0.5] */ - *((long long *) (&arg->sigl)) = -*((long long *) (&arg->sigl)); - normalize(arg); /* Needed later */ - exponent = arg->exp - EXP_BIAS; - invert = 1; - } -#ifdef PARANOID - if (arg->sign != 0) { /* Can't hack a number < 0.0 */ - arith_invalid(y_reg); - return; - } /* Need a positive number */ -#endif /* PARANOID */ - - *(long long *) &arg_signif = *(long long *) &(arg->sigl); - if (exponent < -1) { - /* shift the argument right by the required places */ - if (shrx(&arg_signif, -1 - exponent) >= (unsigned)0x80000000) - arg_signif++; /* round up */ - } - mul64(&arg_signif, &arg_signif, (long long *) (&argSq.sigl)); - mul64((long long *) (&argSq.sigl), (long long *) (&argSq.sigl), &argSqSq); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(pos_poly.sign) = 0; - pos_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, oddplterms, HIPOWERop - 1); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(neg_poly.sign) = 0; - neg_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, oddnegterms, HIPOWERon - 1); - mul64((long long *) (&argSq.sigl), (long long *) (&neg_poly.sigl), - (long long *) (&neg_poly.sigl)); - - /* Subtract the mantissas */ - *((long long *) (&pos_poly.sigl)) -= *((long long *) (&neg_poly.sigl)); - - /* Convert to 64 bit signed-compatible */ - pos_poly.exp -= 1; - - reg_move(&pos_poly, &odd_poly); - normalize(&odd_poly); - - reg_mul(&odd_poly, arg, &odd_poly, FULL_PRECISION); - reg_u_add(&odd_poly, arg, &odd_poly, FULL_PRECISION); /* This is just the odd - * polynomial */ - - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(pos_poly.sign) = 0; - pos_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &pos_poly.sigl, (unsigned *) &argSqSq, evenplterms, HIPOWERep - 1); - mul64((long long *) (&argSq.sigl), - (long long *) (&pos_poly.sigl), (long long *) (&pos_poly.sigl)); - - /* will be a valid positive nr with expon = 0 */ - *(short *) &(neg_poly.sign) = 0; - neg_poly.exp = EXP_BIAS; - - /* Do the basic fixed point polynomial evaluation */ - polynomial((u_int *) &neg_poly.sigl, (unsigned *) &argSqSq, evennegterms, HIPOWERen - 1); - - /* Subtract the mantissas */ - *((long long *) (&neg_poly.sigl)) -= *((long long *) (&pos_poly.sigl)); - /* and multiply by argSq */ - - /* Convert argSq to a valid reg number */ - *(short *) &(argSq.sign) = 0; - argSq.exp = EXP_BIAS - 1; - normalize(&argSq); - - /* Convert to 64 bit signed-compatible */ - neg_poly.exp -= 1; - - reg_move(&neg_poly, &even_poly); - normalize(&even_poly); - - reg_mul(&even_poly, &argSq, &even_poly, FULL_PRECISION); - reg_add(&even_poly, &argSq, &even_poly, FULL_PRECISION); - reg_sub(&CONST_1, &even_poly, &even_poly, FULL_PRECISION); /* This is just the even - * polynomial */ - - /* Now ready to copy the results */ - if (invert) { - reg_div(&even_poly, &odd_poly, y_reg, FULL_PRECISION); - } else { - reg_div(&odd_poly, &even_poly, y_reg, FULL_PRECISION); - } - -} diff --git a/sys/gnu/i386/fpemul/polynomial.s b/sys/gnu/i386/fpemul/polynomial.s deleted file mode 100644 index f54c729..0000000 --- a/sys/gnu/i386/fpemul/polynomial.s +++ /dev/null @@ -1,192 +0,0 @@ -/* - * polynomial.S - * - * Fixed point arithmetic polynomial evaluation. - * - * Call from C as: - * void polynomial(unsigned accum[], unsigned x[], unsigned terms[][2], - * int n) - * - * Computes: - * terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x - * The result is returned in accum. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: polynomial.s,v 1.2 1994/04/29 21:23:31 gclarkii Exp $ - * - */ - - .file "fpolynom.s" - -#include "fpu_asm.h" - - -/* #define EXTRA_PRECISE*/ - -#define TERM_SIZE $8 - - -.text - .align 2,144 -.globl _polynomial -_polynomial: - pushl %ebp - movl %esp,%ebp - subl $32,%esp - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi /* accum */ - movl PARAM2,%edi /* x */ - movl PARAM3,%ebx /* terms */ - movl PARAM4,%ecx /* n */ - - movl TERM_SIZE,%eax - mull %ecx - movl %eax,%ecx - - movl 4(%ebx,%ecx,1),%edx /* terms[n] */ - movl %edx,-20(%ebp) - movl (%ebx,%ecx,1),%edx /* terms[n] */ - movl %edx,-24(%ebp) - xor %eax,%eax - movl %eax,-28(%ebp) - - subl TERM_SIZE,%ecx - js L_accum_done - -L_accum_loop: - xor %eax,%eax - movl %eax,-4(%ebp) - movl %eax,-8(%ebp) - -#ifdef EXTRA_PRECISE - movl -28(%ebp),%eax - mull 4(%edi) /* x ms long */ - movl %edx,-12(%ebp) -#endif EXTRA_PRECISE - - movl -24(%ebp),%eax - mull (%edi) /* x ls long */ -/* movl %eax,-16(%ebp) */ /* Not needed */ - addl %edx,-12(%ebp) - adcl $0,-8(%ebp) - - movl -24(%ebp),%eax - mull 4(%edi) /* x ms long */ - addl %eax,-12(%ebp) - adcl %edx,-8(%ebp) - adcl $0,-4(%ebp) - - movl -20(%ebp),%eax - mull (%edi) - addl %eax,-12(%ebp) - adcl %edx,-8(%ebp) - adcl $0,-4(%ebp) - - movl -20(%ebp),%eax - mull 4(%edi) - addl %eax,-8(%ebp) - adcl %edx,-4(%ebp) - -/* Now add the next term */ - movl (%ebx,%ecx,1),%eax - addl %eax,-8(%ebp) - movl 4(%ebx,%ecx,1),%eax - adcl %eax,-4(%ebp) - -/* And put into the second register */ - movl -4(%ebp),%eax - movl %eax,-20(%ebp) - movl -8(%ebp),%eax - movl %eax,-24(%ebp) - -#ifdef EXTRA_PRECISE - movl -12(%ebp),%eax - movl %eax,-28(%ebp) -#else - testb $128,-25(%ebp) - je L_no_poly_round - - addl $1,-24(%ebp) - adcl $0,-20(%ebp) -L_no_poly_round: -#endif EXTRA_PRECISE - - subl TERM_SIZE,%ecx - jns L_accum_loop - -L_accum_done: -#ifdef EXTRA_PRECISE -/* And round the result */ - testb $128,-25(%ebp) - je L_poly_done - - addl $1,-24(%ebp) - adcl $0,-20(%ebp) -#endif EXTRA_PRECISE - -L_poly_done: - movl -24(%ebp),%eax - movl %eax,(%esi) - movl -20(%ebp),%eax - movl %eax,4(%esi) - - popl %ebx - popl %edi - popl %esi - leave - ret diff --git a/sys/gnu/i386/fpemul/reg_add_sub.c b/sys/gnu/i386/fpemul/reg_add_sub.c deleted file mode 100644 index a122452..0000000 --- a/sys/gnu/i386/fpemul/reg_add_sub.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * reg_add_sub.c - * - * Functions to add or subtract two registers and put the result in a third. - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_add_sub.c,v 1.2 1994/04/29 21:30:15 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | For each function, the destination may be any FPU_REG, including one of | - | the source FPU_REGs. | - +---------------------------------------------------------------------------*/ - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "control_w.h" -#include "fpu_system.h" - - -void -reg_add(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w) -{ - int diff; - - if (!(a->tag | b->tag)) { - /* Both registers are valid */ - if (!(a->sign ^ b->sign)) { - /* signs are the same */ - reg_u_add(a, b, dest, control_w); - dest->sign = a->sign; - return; - } - /* The signs are different, so do a subtraction */ - diff = a->exp - b->exp; - if (!diff) { - diff = a->sigh - b->sigh; /* Works only if ms bits - * are identical */ - if (!diff) { - diff = a->sigl > b->sigl; - if (!diff) - diff = -(a->sigl < b->sigl); - } - } - if (diff > 0) { - reg_u_sub(a, b, dest, control_w); - dest->sign = a->sign; - } else - if (diff == 0) { - reg_move(&CONST_Z, dest); - /* sign depends upon rounding mode */ - dest->sign = ((control_w & CW_RC) != RC_DOWN) - ? SIGN_POS : SIGN_NEG; - } else { - reg_u_sub(b, a, dest, control_w); - dest->sign = b->sign; - } - return; - } else { - if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) { - real_2op_NaN(a, b, dest); - return; - } else - if (a->tag == TW_Zero) { - if (b->tag == TW_Zero) { - char different_signs = a->sign ^ b->sign; - /* Both are zero, result will be zero. */ - reg_move(a, dest); - if (different_signs) { - /* Signs are different. */ - /* Sign of answer depends upon - * rounding mode. */ - dest->sign = ((control_w & CW_RC) != RC_DOWN) - ? SIGN_POS : SIGN_NEG; - } - } else { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(b, dest); - } - return; - } else - if (b->tag == TW_Zero) { -#ifdef DENORM_OPERAND - if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(a, dest); - return; - } else - if (a->tag == TW_Infinity) { - if (b->tag != TW_Infinity) { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(a, dest); - return; - } - if (a->sign == b->sign) { - /* They are both + or - * - infinity */ - reg_move(a, dest); - return; - } - arith_invalid(dest); /* Infinity-Infinity is - * undefined. */ - return; - } else - if (b->tag == TW_Infinity) { -#ifdef DENORM_OPERAND - if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(b, dest); - return; - } - } -#ifdef PARANOID - EXCEPTION(EX_INTERNAL | 0x101); -#endif -} - - -/* Subtract b from a. (a-b) -> dest */ -void -reg_sub(FPU_REG * a, FPU_REG * b, FPU_REG * dest, int control_w) -{ - int diff; - - if (!(a->tag | b->tag)) { - /* Both registers are valid */ - diff = a->exp - b->exp; - if (!diff) { - diff = a->sigh - b->sigh; /* Works only if ms bits - * are identical */ - if (!diff) { - diff = a->sigl > b->sigl; - if (!diff) - diff = -(a->sigl < b->sigl); - } - } - switch (a->sign * 2 + b->sign) { - case 0: /* P - P */ - case 3: /* N - N */ - if (diff > 0) { - reg_u_sub(a, b, dest, control_w); - dest->sign = a->sign; - } else - if (diff == 0) { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(&CONST_Z, dest); - /* sign depends upon rounding mode */ - dest->sign = ((control_w & CW_RC) != RC_DOWN) - ? SIGN_POS : SIGN_NEG; - } else { - reg_u_sub(b, a, dest, control_w); - dest->sign = a->sign ^ SIGN_POS ^ SIGN_NEG; - } - return; - case 1: /* P - N */ - reg_u_add(a, b, dest, control_w); - dest->sign = SIGN_POS; - return; - case 2: /* N - P */ - reg_u_add(a, b, dest, control_w); - dest->sign = SIGN_NEG; - return; - } - } else { - if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) { - real_2op_NaN(a, b, dest); - return; - } else - if (b->tag == TW_Zero) { - if (a->tag == TW_Zero) { - char same_signs = !(a->sign ^ b->sign); - /* Both are zero, result will be zero. */ - reg_move(a, dest); /* Answer for different - * signs. */ - if (same_signs) { - /* Sign depends upon rounding - * mode */ - dest->sign = ((control_w & CW_RC) != RC_DOWN) - ? SIGN_POS : SIGN_NEG; - } - } else { -#ifdef DENORM_OPERAND - if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(a, dest); - } - return; - } else - if (a->tag == TW_Zero) { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(b, dest); - dest->sign ^= SIGN_POS ^ SIGN_NEG; - return; - } else - if (a->tag == TW_Infinity) { - if (b->tag != TW_Infinity) { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(a, dest); - return; - } - /* Both args are Infinity */ - if (a->sign == b->sign) { - arith_invalid(dest); /* Infinity-Infinity is - * undefined. */ - return; - } - reg_move(a, dest); - return; - } else - if (b->tag == TW_Infinity) { -#ifdef DENORM_OPERAND - if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(b, dest); - dest->sign ^= SIGN_POS ^ SIGN_NEG; - return; - } - } -#ifdef PARANOID - EXCEPTION(EX_INTERNAL | 0x110); -#endif -} diff --git a/sys/gnu/i386/fpemul/reg_compare.c b/sys/gnu/i386/fpemul/reg_compare.c deleted file mode 100644 index 52623f7..0000000 --- a/sys/gnu/i386/fpemul/reg_compare.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * reg_compare.c - * - * Compare two floating point registers - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_compare.c,v 1.4 1994/08/31 04:45:23 davidg Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | compare() is the core FPU_REG comparison function | - +---------------------------------------------------------------------------*/ -#include "param.h" -#include "proc.h" -#include "systm.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "control_w.h" -#include "status_w.h" - - -int -compare(FPU_REG * b) -{ - int diff; - - if (FPU_st0_ptr->tag | b->tag) { - if (FPU_st0_ptr->tag == TW_Zero) { - if (b->tag == TW_Zero) - return COMP_A_eq_B; - if (b->tag == TW_Valid) { -#ifdef DENORM_OPERAND - if ((b->exp <= EXP_UNDER) && (denormal_operand())) - return COMP_Denormal; -#endif /* DENORM_OPERAND */ - return (b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B; - } - } else - if (b->tag == TW_Zero) { - if (FPU_st0_ptr->tag == TW_Valid) { -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand())) - return COMP_Denormal; -#endif /* DENORM_OPERAND */ - return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B; - } - } - if (FPU_st0_ptr->tag == TW_Infinity) { - if ((b->tag == TW_Valid) || (b->tag == TW_Zero)) { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) - && (denormal_operand())) - return COMP_Denormal; -#endif /* DENORM_OPERAND */ - return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B; - } else - if (b->tag == TW_Infinity) { - /* The 80486 book says that infinities - * can be equal! */ - return (FPU_st0_ptr->sign == b->sign) ? COMP_A_eq_B : - ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); - } - /* Fall through to the NaN code */ - } else - if (b->tag == TW_Infinity) { - if ((FPU_st0_ptr->tag == TW_Valid) || (FPU_st0_ptr->tag == TW_Zero)) { -#ifdef DENORM_OPERAND - if ((FPU_st0_ptr->tag == TW_Valid) - && (FPU_st0_ptr->exp <= EXP_UNDER) - && (denormal_operand())) - return COMP_Denormal; -#endif /* DENORM_OPERAND */ - return (b->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B; - } - /* Fall through to the NaN code */ - } - /* The only possibility now should be that one of the - * arguments is a NaN */ - if ((FPU_st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN)) { - if (((FPU_st0_ptr->tag == TW_NaN) && !(FPU_st0_ptr->sigh & 0x40000000)) - || ((b->tag == TW_NaN) && !(b->sigh & 0x40000000))) - /* At least one arg is a signaling NaN */ - return COMP_No_Comp | COMP_SNaN | COMP_NaN; - else - /* Neither is a signaling NaN */ - return COMP_No_Comp | COMP_NaN; - } - EXCEPTION(EX_Invalid); - } -#ifdef PARANOID - if (!(FPU_st0_ptr->sigh & 0x80000000)) - EXCEPTION(EX_Invalid); - if (!(b->sigh & 0x80000000)) - EXCEPTION(EX_Invalid); -#endif /* PARANOID */ - -#ifdef DENORM_OPERAND - if (((FPU_st0_ptr->exp <= EXP_UNDER) || - (b->exp <= EXP_UNDER)) && (denormal_operand())) - return COMP_Denormal; -#endif /* DENORM_OPERAND */ - - if (FPU_st0_ptr->sign != b->sign) - return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B; - - diff = FPU_st0_ptr->exp - b->exp; - if (diff == 0) { - diff = FPU_st0_ptr->sigh - b->sigh; /* Works only if ms bits - * are identical */ - if (diff == 0) { - diff = FPU_st0_ptr->sigl > b->sigl; - if (diff == 0) - diff = -(FPU_st0_ptr->sigl < b->sigl); - } - } - if (diff > 0) - return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B; - if (diff < 0) - return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B; - return COMP_A_eq_B; - -} - - -/* This function requires that st(0) is not empty */ -int -compare_st_data(void) -{ - int f = 0, c; - - c = compare(&FPU_loaded_data); - - if (c & (COMP_NaN | COMP_Denormal)) { - if (c & COMP_NaN) { - EXCEPTION(EX_Invalid); - f = SW_C3 | SW_C2 | SW_C0; - } else { - /* One of the operands is a de-normal */ - return 0; - } - } else - switch (c) { - case COMP_A_lt_B: - f = SW_C0; - break; - case COMP_A_eq_B: - f = SW_C3; - break; - case COMP_A_gt_B: - f = 0; - break; - case COMP_No_Comp: - f = SW_C3 | SW_C2 | SW_C0; - break; -#ifdef PARANOID - default: - EXCEPTION(EX_INTERNAL | 0x121); - f = SW_C3 | SW_C2 | SW_C0; - break; -#endif /* PARANOID */ - } - setcc(f); - return 1; -} - - -static int -compare_st_st(int nr) -{ - int f = 0, c; - - if (!NOT_EMPTY_0 || !NOT_EMPTY(nr)) { - setcc(SW_C3 | SW_C2 | SW_C0); - /* Stack fault */ - EXCEPTION(EX_StackUnder); - return control_word & CW_Invalid; - } - c = compare(&st(nr)); - if (c & (COMP_NaN | COMP_Denormal)) { - if (c & COMP_NaN) { - setcc(SW_C3 | SW_C2 | SW_C0); - EXCEPTION(EX_Invalid); - return control_word & CW_Invalid; - } else { - /* One of the operands is a de-normal */ - return control_word & CW_Denormal; - } - } else - switch (c) { - case COMP_A_lt_B: - f = SW_C0; - break; - case COMP_A_eq_B: - f = SW_C3; - break; - case COMP_A_gt_B: - f = 0; - break; - case COMP_No_Comp: - f = SW_C3 | SW_C2 | SW_C0; - break; -#ifdef PARANOID - default: - EXCEPTION(EX_INTERNAL | 0x122); - f = SW_C3 | SW_C2 | SW_C0; - break; -#endif /* PARANOID */ - } - setcc(f); - return 1; -} - - -static int -compare_u_st_st(int nr) -{ - int f = 0, c; - - if (!NOT_EMPTY_0 || !NOT_EMPTY(nr)) { - setcc(SW_C3 | SW_C2 | SW_C0); - /* Stack fault */ - EXCEPTION(EX_StackUnder); - return control_word & CW_Invalid; - } - c = compare(&st(nr)); - if (c & (COMP_NaN | COMP_Denormal)) { - if (c & COMP_NaN) { - setcc(SW_C3 | SW_C2 | SW_C0); - if (c & COMP_SNaN) { /* This is the only difference - * between un-ordered and - * ordinary comparisons */ - EXCEPTION(EX_Invalid); - return control_word & CW_Invalid; - } - return 1; - } else { - /* One of the operands is a de-normal */ - return control_word & CW_Denormal; - } - } else - switch (c) { - case COMP_A_lt_B: - f = SW_C0; - break; - case COMP_A_eq_B: - f = SW_C3; - break; - case COMP_A_gt_B: - f = 0; - break; - case COMP_No_Comp: - f = SW_C3 | SW_C2 | SW_C0; - break; -#ifdef PARANOID - default: - EXCEPTION(EX_INTERNAL | 0x123); - f = SW_C3 | SW_C2 | SW_C0; - break; -#endif /* PARANOID */ - } - setcc(f); - return 1; -} -/*---------------------------------------------------------------------------*/ - -void -fcom_st() -{ - /* fcom st(i) */ - compare_st_st(FPU_rm); -} - - -void -fcompst() -{ - /* fcomp st(i) */ - if (compare_st_st(FPU_rm)) - pop(); -} - - -void -fcompp() -{ - /* fcompp */ - if (FPU_rm != 1) - return Un_impl(); - if (compare_st_st(1)) { - pop(); - FPU_st0_ptr = &st(0); - pop(); - } -} - - -void -fucom_() -{ - /* fucom st(i) */ - compare_u_st_st(FPU_rm); - -} - - -void -fucomp() -{ - /* fucomp st(i) */ - if (compare_u_st_st(FPU_rm)) - pop(); -} - - -void -fucompp() -{ - /* fucompp */ - if (FPU_rm == 1) { - if (compare_u_st_st(1)) { - pop(); - FPU_st0_ptr = &st(0); - pop(); - } - } else - Un_impl(); -} diff --git a/sys/gnu/i386/fpemul/reg_constant.c b/sys/gnu/i386/fpemul/reg_constant.c deleted file mode 100644 index f334273..0000000 --- a/sys/gnu/i386/fpemul/reg_constant.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * reg_constant.c - * - * All of the constant FPU_REGs - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $id:$ - * - */ - - - -#include "param.h" -#include "proc.h" -#include "systm.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "status_w.h" -#include "reg_constant.h" - - -FPU_REG CONST_1 = {SIGN_POS, TW_Valid, EXP_BIAS, -0x00000000, 0x80000000}; -FPU_REG CONST_2 = {SIGN_POS, TW_Valid, EXP_BIAS + 1, -0x00000000, 0x80000000}; -FPU_REG CONST_HALF = {SIGN_POS, TW_Valid, EXP_BIAS - 1, -0x00000000, 0x80000000}; -FPU_REG CONST_L2T = {SIGN_POS, TW_Valid, EXP_BIAS + 1, -0xcd1b8afe, 0xd49a784b}; -FPU_REG CONST_L2E = {SIGN_POS, TW_Valid, EXP_BIAS, -0x5c17f0bc, 0xb8aa3b29}; -FPU_REG CONST_PI = {SIGN_POS, TW_Valid, EXP_BIAS + 1, -0x2168c235, 0xc90fdaa2}; -FPU_REG CONST_PI2 = {SIGN_POS, TW_Valid, EXP_BIAS, -0x2168c235, 0xc90fdaa2}; -FPU_REG CONST_PI4 = {SIGN_POS, TW_Valid, EXP_BIAS - 1, -0x2168c235, 0xc90fdaa2}; -FPU_REG CONST_LG2 = {SIGN_POS, TW_Valid, EXP_BIAS - 2, -0xfbcff799, 0x9a209a84}; -FPU_REG CONST_LN2 = {SIGN_POS, TW_Valid, EXP_BIAS - 1, -0xd1cf79ac, 0xb17217f7}; -/* Only the sign (and tag) is used in internal zeroes */ -FPU_REG CONST_Z = {SIGN_POS, TW_Zero, 0, 0x0, 0x0}; -/* Only the sign and significand (and tag) are used in internal NaNs */ -/* The 80486 never generates one of these -FPU_REG CONST_SNAN = { SIGN_POS, TW_NaN, EXP_OVER, 0x00000001, 0x80000000 }; - */ -/* This is the real indefinite QNaN */ -FPU_REG CONST_QNaN = {SIGN_NEG, TW_NaN, EXP_OVER, 0x00000000, 0xC0000000}; -/* Only the sign (and tag) is used in internal infinities */ -FPU_REG CONST_INF = {SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x80000000}; - - - -static void -fld_const(FPU_REG * c) -{ - FPU_REG *st_new_ptr; - - if (STACK_OVERFLOW) { - stack_overflow(); - return; - } - push(); - reg_move(c, FPU_st0_ptr); - status_word &= ~SW_C1; -} - - -static void -fld1(void) -{ - fld_const(&CONST_1); -} - -static void -fldl2t(void) -{ - fld_const(&CONST_L2T); -} - -static void -fldl2e(void) -{ - fld_const(&CONST_L2E); -} - -static void -fldpi(void) -{ - fld_const(&CONST_PI); -} - -static void -fldlg2(void) -{ - fld_const(&CONST_LG2); -} - -static void -fldln2(void) -{ - fld_const(&CONST_LN2); -} - -static void -fldz(void) -{ - fld_const(&CONST_Z); -} - -static FUNC constants_table[] = { - fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, Un_impl -}; - -void -fconst(void) -{ - (constants_table[FPU_rm]) (); -} diff --git a/sys/gnu/i386/fpemul/reg_constant.h b/sys/gnu/i386/fpemul/reg_constant.h deleted file mode 100644 index 6e4ffa8..0000000 --- a/sys/gnu/i386/fpemul/reg_constant.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * reg_constant.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_constant.h,v 1.2 1994/04/29 21:30:18 gclarkii Exp $ - * - */ - -#ifndef _REG_CONSTANT_H_ -#define _REG_CONSTANT_H_ - -#include "fpu_emu.h" - -extern FPU_REG CONST_1; -extern FPU_REG CONST_2; -extern FPU_REG CONST_HALF; -extern FPU_REG CONST_L2T; -extern FPU_REG CONST_L2E; -extern FPU_REG CONST_PI; -extern FPU_REG CONST_PI2; -extern FPU_REG CONST_PI4; -extern FPU_REG CONST_LG2; -extern FPU_REG CONST_LN2; -extern FPU_REG CONST_Z; -extern FPU_REG CONST_PINF; -extern FPU_REG CONST_INF; -extern FPU_REG CONST_MINF; -extern FPU_REG CONST_QNaN; - -#endif /* _REG_CONSTANT_H_ */ diff --git a/sys/gnu/i386/fpemul/reg_div.s b/sys/gnu/i386/fpemul/reg_div.s deleted file mode 100644 index 5de5a46..0000000 --- a/sys/gnu/i386/fpemul/reg_div.s +++ /dev/null @@ -1,295 +0,0 @@ - .file "reg_div.S" -/* - * reg_div.S - * - * Divide one FPU_REG by another and put the result in a destination FPU_REG. - * - * Call from C as: - * void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest, - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_div.s,v 1.2 1994/04/29 21:30:19 gclarkii Exp $ - * - */ - -#include "exception.h" -#include "fpu_asm.h" -#include "control_w.h" - -.text - .align 2 - -.globl _reg_div -_reg_div: - pushl %ebp - movl %esp,%ebp - - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi - movl PARAM2,%ebx - movl PARAM3,%edi - - movb TAG(%esi),%al - orb TAG(%ebx),%al - - jne L_div_special /* Not (both numbers TW_Valid) */ - -#ifdef DENORM_OPERAND -/* Check for denormals */ - cmpl EXP_UNDER,EXP(%esi) - jg xL_arg1_not_denormal - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xL_arg1_not_denormal: - cmpl EXP_UNDER,EXP(%ebx) - jg xL_arg2_not_denormal - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xL_arg2_not_denormal: -#endif DENORM_OPERAND - -/* Both arguments are TW_Valid */ - movb TW_Valid,TAG(%edi) - - movb SIGN(%esi),%cl - cmpb %cl,SIGN(%ebx) - setne (%edi) /* Set the sign, requires SIGN_NEG=1, SIGN_POS=0 */ - - movl EXP(%esi),%edx - movl EXP(%ebx),%eax - subl %eax,%edx - addl EXP_BIAS,%edx - movl %edx,EXP(%edi) - - jmp _divide_kernel - - -/*-----------------------------------------------------------------------*/ -L_div_special: - cmpb TW_NaN,TAG(%esi) /* A NaN with anything to give NaN */ - je L_arg1_NaN - - cmpb TW_NaN,TAG(%ebx) /* A NaN with anything to give NaN */ - jne L_no_NaN_arg - -/* Operations on NaNs */ -L_arg1_NaN: -L_arg2_NaN: - pushl %edi /* Destination */ - pushl %ebx - pushl %esi - call _real_2op_NaN - jmp LDiv_exit - -/* Invalid operations */ -L_zero_zero: -L_inf_inf: - pushl %edi /* Destination */ - call _arith_invalid /* 0/0 or Infinity/Infinity */ - jmp LDiv_exit - -L_no_NaN_arg: - cmpb TW_Infinity,TAG(%esi) - jne L_arg1_not_inf - - cmpb TW_Infinity,TAG(%ebx) - je L_inf_inf /* invalid operation */ - - cmpb TW_Valid,TAG(%ebx) - je L_inf_valid - -#ifdef PARANOID - /* arg2 must be zero or valid */ - cmpb TW_Zero,TAG(%ebx) - ja L_unknown_tags -#endif PARANOID - - /* Note that p16-9 says that infinity/0 returns infinity */ - jmp L_copy_arg1 /* Answer is Inf */ - -L_inf_valid: -#ifdef DENORM_OPERAND - cmpl EXP_UNDER,EXP(%ebx) - jg L_copy_arg1 /* Answer is Inf */ - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit -#endif DENORM_OPERAND - - jmp L_copy_arg1 /* Answer is Inf */ - -L_arg1_not_inf: - cmpb TW_Zero,TAG(%ebx) /* Priority to div-by-zero error */ - jne L_arg2_not_zero - - cmpb TW_Zero,TAG(%esi) - je L_zero_zero /* invalid operation */ - -#ifdef PARANOID - /* arg1 must be valid */ - cmpb TW_Valid,TAG(%esi) - ja L_unknown_tags -#endif PARANOID - -/* Division by zero error */ - pushl %edi /* destination */ - movb SIGN(%esi),%al - xorb SIGN(%ebx),%al - pushl %eax /* lower 8 bits have the sign */ - call _divide_by_zero - jmp LDiv_exit - -L_arg2_not_zero: - cmpb TW_Infinity,TAG(%ebx) - jne L_arg2_not_inf - -#ifdef DENORM_OPERAND - cmpb TW_Valid,TAG(%esi) - jne L_return_zero - - cmpl EXP_UNDER,EXP(%esi) - jg L_return_zero /* Answer is zero */ - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit -#endif DENORM_OPERAND - - jmp L_return_zero /* Answer is zero */ - -L_arg2_not_inf: - -#ifdef PARANOID - cmpb TW_Zero,TAG(%esi) - jne L_unknown_tags -#endif PARANOID - - /* arg1 is zero, arg2 is not Infinity or a NaN */ - -#ifdef DENORM_OPERAND - cmpl EXP_UNDER,EXP(%ebx) - jg L_copy_arg1 /* Answer is zero */ - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit -#endif DENORM_OPERAND - -L_copy_arg1: - movb TAG(%esi),%ax - movb %ax,TAG(%edi) - movl EXP(%esi),%eax - movl %eax,EXP(%edi) - movl SIGL(%esi),%eax - movl %eax,SIGL(%edi) - movl SIGH(%esi),%eax - movl %eax,SIGH(%edi) - - movb SIGN(%esi),%cl - cmpb %cl,SIGN(%ebx) - jne LDiv_negative_result - - movb SIGN_POS,SIGN(%edi) - jmp LDiv_exit - -LDiv_set_result_sign: - movb SIGN(%esi),%cl - cmpb %cl,SIGN(%edi) - jne LDiv_negative_result - - movb SIGN_POS,SIGN(%ebx) - jmp LDiv_exit - -LDiv_negative_result: - movb SIGN_NEG,SIGN(%edi) - -LDiv_exit: - leal -12(%ebp),%esp - - popl %ebx - popl %edi - popl %esi - leave - ret - - -L_return_zero: - movb TW_Zero,TAG(%edi) - jmp LDiv_set_result_sign - -#ifdef PARANOID -L_unknown_tags: - push EX_INTERNAL | 0x208 - call EXCEPTION - - /* Generate a NaN for unknown tags */ - movl _CONST_QNaN,%eax - movl %eax,(%edi) - movl _CONST_QNaN+4,%eax - movl %eax,SIGL(%edi) - movl _CONST_QNaN+8,%eax - movl %eax,SIGH(%edi) - jmp LDiv_exit -#endif PARANOID diff --git a/sys/gnu/i386/fpemul/reg_ld_str.c b/sys/gnu/i386/fpemul/reg_ld_str.c deleted file mode 100644 index 8fde12f..0000000 --- a/sys/gnu/i386/fpemul/reg_ld_str.c +++ /dev/null @@ -1,1387 +0,0 @@ -/* - * reg_ld_str.c - * - * All of the functions which transfer data between user memory and FPU_REGs. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_ld_str.c,v 1.4 1994/08/31 04:45:24 davidg Exp $ - * - */ - - -/*---------------------------------------------------------------------------+ - | Note: | - | The file contains code which accesses user memory. | - | Emulator static data may change when user memory is accessed, due to | - | other processes using the emulator while swapping is in progress. | - +---------------------------------------------------------------------------*/ -#include "param.h" -#include "proc.h" -#include "systm.h" -#include "machine/cpu.h" -#include "machine/pcb.h" - -#include "fpu_emu.h" -#include "fpu_system.h" -#include "exception.h" -#include "reg_constant.h" -#include "control_w.h" -#include "status_w.h" - - -#define EXTENDED_Emax 0x3fff /* largest valid exponent */ -#define EXTENDED_Ebias 0x3fff -#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */ - -#define DOUBLE_Emax 1023 /* largest valid exponent */ -#define DOUBLE_Ebias 1023 -#define DOUBLE_Emin (-1022) /* smallest valid exponent */ - -#define SINGLE_Emax 127 /* largest valid exponent */ -#define SINGLE_Ebias 127 -#define SINGLE_Emin (-126) /* smallest valid exponent */ - -#define LOST_UP (EX_Precision | SW_C1) -#define LOST_DOWN EX_Precision - -FPU_REG FPU_loaded_data; - - -/* Get a long double from user memory */ -void -reg_load_extended(void) -{ - long double *s = (long double *) FPU_data_address; - unsigned long sigl, sigh, exp; - - REENTRANT_CHECK(OFF); - /* Use temporary variables here because FPU_loaded data is static and - * hence re-entrancy problems can arise */ - sigl = fuword((unsigned long *) s); - sigh = fuword(1 + (unsigned long *) s); - exp = fusword(4 + (unsigned short *) s); - REENTRANT_CHECK(ON); - - FPU_loaded_data.sigl = sigl; - FPU_loaded_data.sigh = sigh; - FPU_loaded_data.exp = exp; - - if (FPU_loaded_data.exp & 0x8000) - FPU_loaded_data.sign = SIGN_NEG; - else - FPU_loaded_data.sign = SIGN_POS; - if ((FPU_loaded_data.exp &= 0x7fff) == 0) { - if (!(FPU_loaded_data.sigl | FPU_loaded_data.sigh)) { - FPU_loaded_data.tag = TW_Zero; - return; - } - /* The number is a de-normal or pseudodenormal. */ - /* The 80486 doesn't regard pseudodenormals as denormals here. */ - if (!(FPU_loaded_data.sigh & 0x80000000)) - EXCEPTION(EX_Denormal); - FPU_loaded_data.exp++; - - /* The default behaviour will now take care of it. */ - } else - if (FPU_loaded_data.exp == 0x7fff) { - FPU_loaded_data.exp = EXTENDED_Emax; - if ((FPU_loaded_data.sigh == 0x80000000) - && (FPU_loaded_data.sigl == 0)) { - FPU_loaded_data.tag = TW_Infinity; - return; - } else - if (!(FPU_loaded_data.sigh & 0x80000000)) { - /* Unsupported NaN data type */ - EXCEPTION(EX_Invalid); - FPU_loaded_data.tag = TW_NaN; - return; - } - FPU_loaded_data.tag = TW_NaN; - return; - } - FPU_loaded_data.exp = (FPU_loaded_data.exp & 0x7fff) - EXTENDED_Ebias - + EXP_BIAS; - FPU_loaded_data.tag = TW_Valid; - - if (!(sigh & 0x80000000)) { - /* Unsupported data type */ - EXCEPTION(EX_Invalid); - normalize_nuo(&FPU_loaded_data); - } -} - - -/* Get a double from user memory */ -void -reg_load_double(void) -{ - double *dfloat = (double *) FPU_data_address; - int exp; - unsigned m64, l64; - - REENTRANT_CHECK(OFF); - m64 = fuword(1 + (unsigned long *) dfloat); - l64 = fuword((unsigned long *) dfloat); - REENTRANT_CHECK(ON); - - if (m64 & 0x80000000) - FPU_loaded_data.sign = SIGN_NEG; - else - FPU_loaded_data.sign = SIGN_POS; - exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias; - m64 &= 0xfffff; - if (exp > DOUBLE_Emax) { - /* Infinity or NaN */ - if ((m64 == 0) && (l64 == 0)) { - /* +- infinity */ - FPU_loaded_data.exp = EXTENDED_Emax; - FPU_loaded_data.tag = TW_Infinity; - return; - } else { - /* Must be a signaling or quiet NaN */ - FPU_loaded_data.exp = EXTENDED_Emax; - FPU_loaded_data.tag = TW_NaN; - FPU_loaded_data.sigh = (m64 << 11) | 0x80000000; - FPU_loaded_data.sigh |= l64 >> 21; - FPU_loaded_data.sigl = l64 << 11; - return; - } - } else - if (exp < DOUBLE_Emin) { - /* Zero or de-normal */ - if ((m64 == 0) && (l64 == 0)) { - /* Zero */ - int c = FPU_loaded_data.sign; - reg_move(&CONST_Z, &FPU_loaded_data); - FPU_loaded_data.sign = c; - return; - } else { - /* De-normal */ - EXCEPTION(EX_Denormal); - FPU_loaded_data.exp = DOUBLE_Emin + EXP_BIAS; - FPU_loaded_data.tag = TW_Valid; - FPU_loaded_data.sigh = m64 << 11; - FPU_loaded_data.sigh |= l64 >> 21; - FPU_loaded_data.sigl = l64 << 11; - normalize_nuo(&FPU_loaded_data); - return; - } - } else { - FPU_loaded_data.exp = exp + EXP_BIAS; - FPU_loaded_data.tag = TW_Valid; - FPU_loaded_data.sigh = (m64 << 11) | 0x80000000; - FPU_loaded_data.sigh |= l64 >> 21; - FPU_loaded_data.sigl = l64 << 11; - - return; - } -} - - -/* Get a float from user memory */ -void -reg_load_single(void) -{ - float *single = (float *) FPU_data_address; - unsigned m32; - int exp; - - REENTRANT_CHECK(OFF); - m32 = fuword((unsigned long *) single); - REENTRANT_CHECK(ON); - - if (m32 & 0x80000000) - FPU_loaded_data.sign = SIGN_NEG; - else - FPU_loaded_data.sign = SIGN_POS; - if (!(m32 & 0x7fffffff)) { - /* Zero */ - int c = FPU_loaded_data.sign; - reg_move(&CONST_Z, &FPU_loaded_data); - FPU_loaded_data.sign = c; - return; - } - exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias; - m32 = (m32 & 0x7fffff) << 8; - if (exp < SINGLE_Emin) { - /* De-normals */ - EXCEPTION(EX_Denormal); - FPU_loaded_data.exp = SINGLE_Emin + EXP_BIAS; - FPU_loaded_data.tag = TW_Valid; - FPU_loaded_data.sigh = m32; - FPU_loaded_data.sigl = 0; - normalize_nuo(&FPU_loaded_data); - return; - } else - if (exp > SINGLE_Emax) { - /* Infinity or NaN */ - if (m32 == 0) { - /* +- infinity */ - FPU_loaded_data.exp = EXTENDED_Emax; - FPU_loaded_data.tag = TW_Infinity; - return; - } else { - /* Must be a signaling or quiet NaN */ - FPU_loaded_data.exp = EXTENDED_Emax; - FPU_loaded_data.tag = TW_NaN; - FPU_loaded_data.sigh = m32 | 0x80000000; - FPU_loaded_data.sigl = 0; - return; - } - } else { - FPU_loaded_data.exp = exp + EXP_BIAS; - FPU_loaded_data.sigh = m32 | 0x80000000; - FPU_loaded_data.sigl = 0; - FPU_loaded_data.tag = TW_Valid; - } -} - - -/* Get a long long from user memory */ -void -reg_load_int64(void) -{ - long long *_s = (long long *) FPU_data_address; - int e; - long long s; - - REENTRANT_CHECK(OFF); - ((unsigned long *) &s)[0] = fuword((unsigned long *) _s); - ((unsigned long *) &s)[1] = fuword(1 + (unsigned long *) _s); - REENTRANT_CHECK(ON); - - if (s == 0) { - reg_move(&CONST_Z, &FPU_loaded_data); - return; - } - if (s > 0) - FPU_loaded_data.sign = SIGN_POS; - else { - s = -s; - FPU_loaded_data.sign = SIGN_NEG; - } - - e = EXP_BIAS + 63; - *((long long *) &FPU_loaded_data.sigl) = s; - FPU_loaded_data.exp = e; - FPU_loaded_data.tag = TW_Valid; - normalize_nuo(&FPU_loaded_data); -} - - -/* Get a long from user memory */ -void -reg_load_int32(void) -{ - long *_s = (long *) FPU_data_address; - long s; - int e; - - REENTRANT_CHECK(OFF); - s = (long) fuword((unsigned long *) _s); - REENTRANT_CHECK(ON); - - if (s == 0) { - reg_move(&CONST_Z, &FPU_loaded_data); - return; - } - if (s > 0) - FPU_loaded_data.sign = SIGN_POS; - else { - s = -s; - FPU_loaded_data.sign = SIGN_NEG; - } - - e = EXP_BIAS + 31; - FPU_loaded_data.sigh = s; - FPU_loaded_data.sigl = 0; - FPU_loaded_data.exp = e; - FPU_loaded_data.tag = TW_Valid; - normalize_nuo(&FPU_loaded_data); -} - - -/* Get a short from user memory */ -void -reg_load_int16(void) -{ - short *_s = (short *) FPU_data_address; - int s, e; - - REENTRANT_CHECK(OFF); - /* Cast as short to get the sign extended. */ - s = (short) fusword((unsigned short *) _s); - REENTRANT_CHECK(ON); - - if (s == 0) { - reg_move(&CONST_Z, &FPU_loaded_data); - return; - } - if (s > 0) - FPU_loaded_data.sign = SIGN_POS; - else { - s = -s; - FPU_loaded_data.sign = SIGN_NEG; - } - - e = EXP_BIAS + 15; - FPU_loaded_data.sigh = s << 16; - - FPU_loaded_data.sigl = 0; - FPU_loaded_data.exp = e; - FPU_loaded_data.tag = TW_Valid; - normalize_nuo(&FPU_loaded_data); -} - - -/* Get a packed bcd array from user memory */ -void -reg_load_bcd(void) -{ - char *s = (char *) FPU_data_address; - int pos; - unsigned char bcd; - long long l = 0; - - for (pos = 8; pos >= 0; pos--) { - l *= 10; - REENTRANT_CHECK(OFF); - bcd = (unsigned char) fubyte((unsigned char *) s + pos); - REENTRANT_CHECK(ON); - l += bcd >> 4; - l *= 10; - l += bcd & 0x0f; - } - - /* Finish all access to user memory before putting stuff into the - * static FPU_loaded_data */ - REENTRANT_CHECK(OFF); - FPU_loaded_data.sign = - ((unsigned char) fubyte((unsigned char *) s + 9)) & 0x80 ? - SIGN_NEG : SIGN_POS; - REENTRANT_CHECK(ON); - - if (l == 0) { - char sign = FPU_loaded_data.sign; - reg_move(&CONST_Z, &FPU_loaded_data); - FPU_loaded_data.sign = sign; - } else { - *((long long *) &FPU_loaded_data.sigl) = l; - FPU_loaded_data.exp = EXP_BIAS + 63; - FPU_loaded_data.tag = TW_Valid; - normalize_nuo(&FPU_loaded_data); - } -} -/*===========================================================================*/ - -/* Put a long double into user memory */ -int -reg_store_extended(void) -{ - long double *d = (long double *) FPU_data_address; - long e = FPU_st0_ptr->exp - EXP_BIAS + EXTENDED_Ebias; - unsigned short sign = FPU_st0_ptr->sign * 0x8000; - unsigned long ls, ms; - - - if (FPU_st0_tag == TW_Valid) { - if (e >= 0x7fff) { - EXCEPTION(EX_Overflow); /* Overflow */ - /* This is a special case: see sec 16.2.5.1 of the - * 80486 book */ - if (control_word & EX_Overflow) { - /* Overflow to infinity */ - ls = 0; - ms = 0x80000000; - e = 0x7fff; - } else - return 0; - } else - if (e <= 0) { - if (e > -63) { - /* Correctly format the de-normal */ - int precision_loss; - FPU_REG tmp; - - EXCEPTION(EX_Denormal); - reg_move(FPU_st0_ptr, &tmp); - tmp.exp += -EXTENDED_Emin + 63; /* largest exp to be 62 */ - if ((precision_loss = round_to_int(&tmp))) { - EXCEPTION(EX_Underflow | precision_loss); - /* This is a special case: see - * sec 16.2.5.1 of the 80486 - * book */ - if (!(control_word & EX_Underflow)) - return 0; - } - e = 0; - ls = tmp.sigl; - ms = tmp.sigh; - } else { - /* ****** ??? This should not be - * possible */ - EXCEPTION(EX_Underflow); /* Underflow */ - /* This is a special case: see sec - * 16.2.5.1 of the 80486 book */ - if (control_word & EX_Underflow) { - /* Underflow to zero */ - ls = 0; - ms = 0; - e = FPU_st0_ptr->sign == SIGN_POS ? 0x7fff : 0xffff; - } else - return 0; - } - } else { - ls = FPU_st0_ptr->sigl; - ms = FPU_st0_ptr->sigh; - } - } else - if (FPU_st0_tag == TW_Zero) { - ls = ms = 0; - e = 0; - } else - if (FPU_st0_tag == TW_Infinity) { - ls = 0; - ms = 0x80000000; - e = 0x7fff; - } else - if (FPU_st0_tag == TW_NaN) { - ls = FPU_st0_ptr->sigl; - ms = FPU_st0_ptr->sigh; - e = 0x7fff; - } else - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack - * underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN - * indefinite */ - ls = 0; - ms = 0xc0000000; - e = 0xffff; - } else - return 0; - } else { - /* We don't use TW_Denormal - * yet ... perhaps never! */ - EXCEPTION(EX_Invalid); - /* Store a NaN */ - e = 0x7fff; - ls = 1; - ms = 0x80000000; - } - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 10); */ - suword((unsigned long *) d, ls); - suword(1 + (unsigned long *) d, ms); - susword(4 + (short *) d, (unsigned short) e | sign); - REENTRANT_CHECK(ON); - - return 1; - -} - - -/* Put a double into user memory */ -int -reg_store_double(void) -{ - double *dfloat = (double *) FPU_data_address; - unsigned long l[2]; - if (FPU_st0_tag == TW_Valid) { - int exp; - FPU_REG tmp; - - reg_move(FPU_st0_ptr, &tmp); - exp = tmp.exp - EXP_BIAS; - - if (exp < DOUBLE_Emin) { /* It may be a denormal */ - /* Make a de-normal */ - int precision_loss; - - if (exp <= -EXTENDED_Ebias) - EXCEPTION(EX_Denormal); - - tmp.exp += -DOUBLE_Emin + 52; /* largest exp to be 51 */ - - if ((precision_loss = round_to_int(&tmp))) { -#ifdef PECULIAR_486 - /* Did it round to a non-denormal ? */ - /* This behaviour might be regarded as - * peculiar, it appears that the 80486 rounds - * to the dest precision, then converts to - * decide underflow. */ - if ((tmp.sigh == 0x00100000) && (tmp.sigl == 0) && - (FPU_st0_ptr->sigl & 0x000007ff)) - EXCEPTION(precision_loss); - else -#endif /* PECULIAR_486 */ - { - EXCEPTION(EX_Underflow | precision_loss); - /* This is a special case: see sec - * 16.2.5.1 of the 80486 book */ - if (!(control_word & EX_Underflow)) - return 0; - } - } - l[0] = tmp.sigl; - l[1] = tmp.sigh; - } else { - if (tmp.sigl & 0x000007ff) { - unsigned long increment = 0; /* avoid gcc warnings */ - - switch (control_word & CW_RC) { - case RC_RND: - /* Rounding can get a little messy.. */ - increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */ - ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */ - break; - case RC_DOWN: /* towards -infinity */ - increment = (tmp.sign == SIGN_POS) ? 0 : tmp.sigl & 0x7ff; - break; - case RC_UP: /* towards +infinity */ - increment = (tmp.sign == SIGN_POS) ? tmp.sigl & 0x7ff : 0; - break; - case RC_CHOP: - increment = 0; - break; - } - - /* Truncate the mantissa */ - tmp.sigl &= 0xfffff800; - - if (increment) { - set_precision_flag_up(); - - if (tmp.sigl >= 0xfffff800) { - /* the sigl part overflows */ - if (tmp.sigh == 0xffffffff) { - /* The sigh part - * overflows */ - tmp.sigh = 0x80000000; - exp++; - if (exp >= EXP_OVER) - goto overflow; - } else { - tmp.sigh++; - } - tmp.sigl = 0x00000000; - } else { - /* We only need to increment - * sigl */ - tmp.sigl += 0x00000800; - } - } else - set_precision_flag_down(); - } - l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21); - l[1] = ((tmp.sigh >> 11) & 0xfffff); - - if (exp > DOUBLE_Emax) { - overflow: - EXCEPTION(EX_Overflow); - /* This is a special case: see sec 16.2.5.1 of - * the 80486 book */ - if (control_word & EX_Overflow) { - /* Overflow to infinity */ - l[0] = 0x00000000; /* Set to */ - l[1] = 0x7ff00000; /* + INF */ - } else - return 0; - } else { - /* Add the exponent */ - l[1] |= (((exp + DOUBLE_Ebias) & 0x7ff) << 20); - } - } - } else - if (FPU_st0_tag == TW_Zero) { - /* Number is zero */ - l[0] = 0; - l[1] = 0; - } else - if (FPU_st0_tag == TW_Infinity) { - l[0] = 0; - l[1] = 0x7ff00000; - } else - if (FPU_st0_tag == TW_NaN) { - /* See if we can get a valid NaN from - * the FPU_REG */ - l[0] = (FPU_st0_ptr->sigl >> 11) | (FPU_st0_ptr->sigh << 21); - l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff); - if (!(l[0] | l[1])) { - /* This case does not seem to - * be handled by the 80486 - * specs */ - EXCEPTION(EX_Invalid); - /* Make the quiet NaN "real - * indefinite" */ - goto put_indefinite; - } - l[1] |= 0x7ff00000; - } else - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack - * underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN - * indefinite */ - put_indefinite: - REENTRANT_CHECK(OFF); - /* verify_area(VERIFY_W - * RITE, (void *) - * dfloat, 8); */ - suword((unsigned long *) dfloat, 0); - suword(1 + (unsigned long *) dfloat, 0xfff80000); - REENTRANT_CHECK(ON); - return 1; - } else - return 0; - } -#if 0 /* TW_Denormal is not used yet, and probably - * won't be */ - else - if (FPU_st0_tag == TW_Denormal) { - /* Extended real -> - * double real will - * always underflow */ - l[0] = l[1] = 0; - EXCEPTION(EX_Underflow); - } -#endif - if (FPU_st0_ptr->sign) - l[1] |= 0x80000000; - - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, (void *) dfloat, 8);*/ - suword((u_long *) dfloat, l[0]); - suword((u_long *) dfloat + 1, l[1]); -/* - suword(l[0], (unsigned long *) dfloat); - suword(l[1], 1 + (unsigned long *) dfloat);*/ - REENTRANT_CHECK(ON); - - return 1; -} - - -/* Put a float into user memory */ -int -reg_store_single(void) -{ - float *single = (float *) FPU_data_address; - long templ = 0; - - if (FPU_st0_tag == TW_Valid) { - int exp; - FPU_REG tmp; - - reg_move(FPU_st0_ptr, &tmp); - exp = tmp.exp - EXP_BIAS; - - if (exp < SINGLE_Emin) { - /* Make a de-normal */ - int precision_loss; - - if (exp <= -EXTENDED_Ebias) - EXCEPTION(EX_Denormal); - - tmp.exp += -SINGLE_Emin + 23; /* largest exp to be 22 */ - - if ((precision_loss = round_to_int(&tmp))) { -#ifdef PECULIAR_486 - /* Did it round to a non-denormal ? */ - /* This behaviour might be regarded as - * peculiar, it appears that the 80486 rounds - * to the dest precision, then converts to - * decide underflow. */ - if ((tmp.sigl == 0x00800000) && - ((FPU_st0_ptr->sigh & 0x000000ff) || FPU_st0_ptr->sigl)) - EXCEPTION(precision_loss); - else -#endif /* PECULIAR_486 */ - { - EXCEPTION(EX_Underflow | precision_loss); - /* This is a special case: see sec - * 16.2.5.1 of the 80486 book */ - if (!(control_word & EX_Underflow)) - return 0; - } - } - templ = tmp.sigl; - } else { - if (tmp.sigl | (tmp.sigh & 0x000000ff)) { - unsigned long increment = 0; /* avoid gcc warnings */ - unsigned long sigh = tmp.sigh; - unsigned long sigl = tmp.sigl; - - switch (control_word & CW_RC) { - case RC_RND: - increment = ((sigh & 0xff) > 0x80) /* more than half */ - ||(((sigh & 0xff) == 0x80) && sigl) /* more than half */ - ||((sigh & 0x180) == 0x180); /* round to even */ - break; - case RC_DOWN: /* towards -infinity */ - increment = (tmp.sign == SIGN_POS) - ? 0 : (sigl | (sigh & 0xff)); - break; - case RC_UP: /* towards +infinity */ - increment = (tmp.sign == SIGN_POS) - ? (sigl | (sigh & 0xff)) : 0; - break; - case RC_CHOP: - increment = 0; - break; - } - - /* Truncate part of the mantissa */ - tmp.sigl = 0; - - if (increment) { - set_precision_flag_up(); - - if (sigh >= 0xffffff00) { - /* The sigh part overflows */ - tmp.sigh = 0x80000000; - exp++; - if (exp >= EXP_OVER) - goto overflow; - } else { - tmp.sigh &= 0xffffff00; - tmp.sigh += 0x100; - } - } else { - set_precision_flag_down(); - tmp.sigh &= 0xffffff00; /* Finish the truncation */ - } - } - templ = (tmp.sigh >> 8) & 0x007fffff; - - if (exp > SINGLE_Emax) { - overflow: - EXCEPTION(EX_Overflow); - /* This is a special case: see sec 16.2.5.1 of - * the 80486 book */ - if (control_word & EX_Overflow) { - /* Overflow to infinity */ - templ = 0x7f800000; - } else - return 0; - } else - templ |= ((exp + SINGLE_Ebias) & 0xff) << 23; - } - } else - if (FPU_st0_tag == TW_Zero) { - templ = 0; - } else - if (FPU_st0_tag == TW_Infinity) { - templ = 0x7f800000; - } else - if (FPU_st0_tag == TW_NaN) { - /* See if we can get a valid NaN from - * the FPU_REG */ - templ = FPU_st0_ptr->sigh >> 8; - if (!(templ & 0x3fffff)) { - /* This case does not seem to - * be handled by the 80486 - * specs */ - EXCEPTION(EX_Invalid); - /* Make the quiet NaN "real - * indefinite" */ - goto put_indefinite; - } - templ |= 0x7f800000; - } else - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack - * underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN - * indefinite */ - put_indefinite: - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, (void *) single, 4); */ - suword((unsigned long *) single, 0xffc00000); - REENTRANT_CHECK(ON); - return 1; - } else - return 0; - } -#if 0 /* TW_Denormal is not used yet, and probably - * won't be */ - else - if (FPU_st0_tag == TW_Denormal) { - /* Extended real -> - * real will always - * underflow */ - templ = 0; - EXCEPTION(EX_Underflow); - } -#endif -#ifdef PARANOID - else { - EXCEPTION(EX_INTERNAL | 0x106); - return 0; - } -#endif - if (FPU_st0_ptr->sign) - templ |= 0x80000000; - - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, (void *) single, 4); */ - suword((unsigned long *) single, templ); - REENTRANT_CHECK(ON); - - return 1; -} - - -/* Put a long long into user memory */ -int -reg_store_int64(void) -{ - long long *d = (long long *) FPU_data_address; - FPU_REG t; - long long tll; - - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN indefinite */ - goto put_indefinite; - } else - return 0; - } - reg_move(FPU_st0_ptr, &t); - round_to_int(&t); - ((long *) &tll)[0] = t.sigl; - ((long *) &tll)[1] = t.sigh; - if ((t.sigh & 0x80000000) && - !((t.sigh == 0x80000000) && (t.sigl == 0) && (t.sign == SIGN_NEG))) { - EXCEPTION(EX_Invalid); - /* This is a special case: see sec 16.2.5.1 of the 80486 book */ - if (control_word & EX_Invalid) { - /* Produce "indefinite" */ - put_indefinite: - ((long *) &tll)[1] = 0x80000000; - ((long *) &tll)[0] = 0; - } else - return 0; - } else - if (t.sign) - tll = -tll; - - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, (void *) d, 8); */ - suword((unsigned long *) d, ((long *) &tll)[0]); - suword(1 + (unsigned long *) d, ((long *) &tll)[1]); - REENTRANT_CHECK(ON); - - return 1; -} - - -/* Put a long into user memory */ -int -reg_store_int32(void) -{ - long *d = (long *) FPU_data_address; - FPU_REG t; - - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN indefinite */ - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 4);*/ - suword((unsigned long *) d, 0x80000000); - REENTRANT_CHECK(ON); - return 1; - } else - return 0; - } - reg_move(FPU_st0_ptr, &t); - round_to_int(&t); - if (t.sigh || - ((t.sigl & 0x80000000) && - !((t.sigl == 0x80000000) && (t.sign == SIGN_NEG)))) { - EXCEPTION(EX_Invalid); - /* This is a special case: see sec 16.2.5.1 of the 80486 book */ - if (control_word & EX_Invalid) { - /* Produce "indefinite" */ - t.sigl = 0x80000000; - } else - return 0; - } else - if (t.sign) - t.sigl = -(long) t.sigl; - - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 4); */ - suword((unsigned long *) d, t.sigl); - REENTRANT_CHECK(ON); - - return 1; -} - - -/* Put a short into user memory */ -int -reg_store_int16(void) -{ - short *d = (short *) FPU_data_address; - FPU_REG t; - short ts; - - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN indefinite */ - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 2);*/ - susword((unsigned short *) d, 0x8000); - REENTRANT_CHECK(ON); - return 1; - } else - return 0; - } - reg_move(FPU_st0_ptr, &t); - round_to_int(&t); - if (t.sigh || - ((t.sigl & 0xffff8000) && - !((t.sigl == 0x8000) && (t.sign == SIGN_NEG)))) { - EXCEPTION(EX_Invalid); - /* This is a special case: see sec 16.2.5.1 of the 80486 book */ - if (control_word & EX_Invalid) { - /* Produce "indefinite" */ - ts = 0x8000; - } else - return 0; - } else - if (t.sign) - t.sigl = -t.sigl; - - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 2); */ - susword((short *) d, (short) t.sigl); - REENTRANT_CHECK(ON); - - return 1; -} - - -/* Put a packed bcd array into user memory */ -int -reg_store_bcd(void) -{ - char *d = (char *) FPU_data_address; - FPU_REG t; - long long ll; - unsigned char b; - int i; - unsigned char sign = (FPU_st0_ptr->sign == SIGN_NEG) ? 0x80 : 0; - - if (FPU_st0_tag == TW_Empty) { - /* Empty register (stack underflow) */ - EXCEPTION(EX_StackUnder); - if (control_word & EX_Invalid) { - /* The masked response */ - /* Put out the QNaN indefinite */ - goto put_indefinite; - } else - return 0; - } - reg_move(FPU_st0_ptr, &t); - round_to_int(&t); - ll = *(long long *) (&t.sigl); - - /* Check for overflow, by comparing with 999999999999999999 decimal. */ - if ((t.sigh > 0x0de0b6b3) || - ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff))) { - EXCEPTION(EX_Invalid); - /* This is a special case: see sec 16.2.5.1 of the 80486 book */ - if (control_word & EX_Invalid) { - put_indefinite: - /* Produce "indefinite" */ - REENTRANT_CHECK(OFF); -/* verify_area(VERIFY_WRITE, d, 10);*/ - subyte((unsigned char *) d + 7, 0xff); - subyte((unsigned char *) d + 8, 0xff); - subyte((unsigned char *) d + 9, 0xff); - REENTRANT_CHECK(ON); - return 1; - } else - return 0; - } -/* verify_area(VERIFY_WRITE, d, 10);*/ - for (i = 0; i < 9; i++) { - b = div_small(&ll, 10); - b |= (div_small(&ll, 10)) << 4; - REENTRANT_CHECK(OFF); - subyte((unsigned char *) d + i, b); - REENTRANT_CHECK(ON); - } - REENTRANT_CHECK(OFF); - subyte((unsigned char *) d + 9, sign); - REENTRANT_CHECK(ON); - - return 1; -} -/*===========================================================================*/ - -/* r gets mangled such that sig is int, sign: - it is NOT normalized */ -/* The return value (in eax) is zero if the result is exact, - if bits are changed due to rounding, truncation, etc, then - a non-zero value is returned */ -/* Overflow is signalled by a non-zero return value (in eax). - In the case of overflow, the returned significand always has the - the largest possible value */ -/* The value returned in eax is never actually needed :-) */ -int -round_to_int(FPU_REG * r) -{ - char very_big; - unsigned eax; - - if (r->tag == TW_Zero) { - /* Make sure that zero is returned */ - *(long long *) &r->sigl = 0; - return 0; /* o.k. */ - } - if (r->exp > EXP_BIAS + 63) { - r->sigl = r->sigh = ~0; /* The largest representable number */ - return 1; /* overflow */ - } - eax = shrxs(&r->sigl, EXP_BIAS + 63 - r->exp); - very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */ -#define half_or_more (eax & 0x80000000) -#define frac_part (eax) -#define more_than_half ((eax & 0x80000001) == 0x80000001) - switch (control_word & CW_RC) { - case RC_RND: - if (more_than_half /* nearest */ - || (half_or_more && (r->sigl & 1))) { /* odd -> even */ - if (very_big) - return 1; /* overflow */ - (*(long long *) (&r->sigl))++; - return LOST_UP; - } - break; - case RC_DOWN: - if (frac_part && r->sign) { - if (very_big) - return 1; /* overflow */ - (*(long long *) (&r->sigl))++; - return LOST_UP; - } - break; - case RC_UP: - if (frac_part && !r->sign) { - if (very_big) - return 1; /* overflow */ - (*(long long *) (&r->sigl))++; - return LOST_UP; - } - break; - case RC_CHOP: - break; - } - - return eax ? LOST_DOWN : 0; - -} -/*===========================================================================*/ - -char * -fldenv(void) -{ - char *s = (char *) FPU_data_address; - unsigned short tag_word = 0; - unsigned char tag; - int i; - - REENTRANT_CHECK(OFF); - control_word = fusword((unsigned short *) s); - status_word = fusword((unsigned short *) (s + 4)); - tag_word = fusword((unsigned short *) (s + 8)); - ip_offset = fuword((unsigned long *) (s + 0x0c)); - cs_selector = fuword((unsigned long *) (s + 0x10)); - data_operand_offset = fuword((unsigned long *) (s + 0x14)); - operand_selector = fuword((unsigned long *) (s + 0x18)); - REENTRANT_CHECK(ON); - - top = (status_word >> SW_Top_Shift) & 7; - - for (i = 0; i < 8; i++) { - tag = tag_word & 3; - tag_word >>= 2; - - switch (tag) { - case 0: - regs[i].tag = TW_Valid; - break; - case 1: - regs[i].tag = TW_Zero; - break; - case 2: - regs[i].tag = TW_NaN; - break; - case 3: - regs[i].tag = TW_Empty; - break; - } - } - - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ - FPU_entry_eip = ip_offset; /* We want no net effect */ - - return s + 0x1c; -} - - -void -frstor(void) -{ - int i, stnr; - unsigned char tag; - unsigned short saved_status, saved_control; - char *s = (char *) fldenv(); - - saved_status = status_word; - saved_control = control_word; - control_word = 0x037f; /* Mask all interrupts while we load. */ - for (i = 0; i < 8; i++) { - /* load each register */ - FPU_data_address = (void *) (s + i * 10); - reg_load_extended(); - stnr = (i + top) & 7; - tag = regs[stnr].tag; /* derived from the loaded tag word */ - reg_move(&FPU_loaded_data, ®s[stnr]); - if (tag == TW_NaN) { - /* The current data is a special, i.e. NaN, - * unsupported, infinity, or denormal */ - unsigned char t = regs[stnr].tag; /* derived from the new - * data */ - if ( /* (t == TW_Valid) || *** */ (t == TW_Zero)) - regs[stnr].tag = TW_NaN; - } else - regs[stnr].tag = tag; - } - control_word = saved_control; - status_word = saved_status; - - FPU_data_address = (void *) data_operand_offset; /* We want no net effect */ -} - - -unsigned short -tag_word(void) -{ - unsigned short word = 0; - unsigned char tag; - int i; - - for (i = 7; i >= 0; i--) { - switch (tag = regs[i].tag) { -#if 0 /* TW_Denormal is not used yet, and probably - * won't be */ - case TW_Denormal: -#endif - case TW_Valid: - if (regs[i].exp <= (EXP_BIAS - EXTENDED_Ebias)) - tag = 2; - break; - case TW_Infinity: - case TW_NaN: - tag = 2; - break; - case TW_Empty: - tag = 3; - break; - /* TW_Valid and TW_Zero already have the correct value */ - } - word <<= 2; - word |= tag; - } - return word; -} - - -char * -fstenv(void) -{ - char *d = (char *) FPU_data_address; - -/* verify_area(VERIFY_WRITE, d, 28);*/ - -#if 0 /****/ - *(unsigned short *) &cs_selector = fpu_cs; - *(unsigned short *) &operand_selector = fpu_os; -#endif /****/ - - REENTRANT_CHECK(OFF); - susword((unsigned short *) d, control_word); - susword((unsigned short *) (d + 4), (status_word & ~SW_Top) | ((top & 7) << SW_Top_Shift)); - susword((unsigned short *) (d + 8), tag_word()); - suword((unsigned long *) (d + 0x0c), ip_offset); - suword((unsigned long *) (d + 0x10), cs_selector); - suword((unsigned long *) (d + 0x14), data_operand_offset); - suword((unsigned long *) (d + 0x18), operand_selector); - REENTRANT_CHECK(ON); - - return d + 0x1c; -} - - -void -fsave(void) -{ - char *d; - FPU_REG tmp, *rp; - int i; - short e; - - d = fstenv(); -/* verify_area(VERIFY_WRITE, d, 80);*/ - for (i = 0; i < 8; i++) { - /* Store each register in the order: st(0), st(1), ... */ - rp = ®s[(top + i) & 7]; - - e = rp->exp - EXP_BIAS + EXTENDED_Ebias; - - if (rp->tag == TW_Valid) { - if (e >= 0x7fff) { - /* Overflow to infinity */ - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); - REENTRANT_CHECK(ON); - e = 0x7fff; - } else - if (e <= 0) { - if (e > -63) { - /* Make a de-normal */ - reg_move(rp, &tmp); - tmp.exp += -EXTENDED_Emin + 63; /* largest exp to be 62 */ - round_to_int(&tmp); - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), tmp.sigl); - suword((unsigned long *) (d + i * 10 + 4), tmp.sigh); - REENTRANT_CHECK(ON); - } else { - /* Underflow to zero */ - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); - REENTRANT_CHECK(ON); - } - e = 0; - } else { - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); - REENTRANT_CHECK(ON); - } - } else - if (rp->tag == TW_Zero) { - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0); - REENTRANT_CHECK(ON); - e = 0; - } else - if (rp->tag == TW_Infinity) { - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), 0); - suword((unsigned long *) (d + i * 10 + 4), 0x80000000); - REENTRANT_CHECK(ON); - e = 0x7fff; - } else - if (rp->tag == TW_NaN) { - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); - REENTRANT_CHECK(ON); - e = 0x7fff; - } else - if (rp->tag == TW_Empty) { - /* just copy the reg */ - REENTRANT_CHECK(OFF); - suword((unsigned long *) (d + i * 10), rp->sigl); - suword((unsigned long *) (d + i * 10 + 4), rp->sigh); - REENTRANT_CHECK(ON); - } - e |= rp->sign == SIGN_POS ? 0 : 0x8000; - REENTRANT_CHECK(OFF); - susword((unsigned short *) (d + i * 10 + 8), e); - REENTRANT_CHECK(ON); - } - - finit(); - -} -/*===========================================================================*/ diff --git a/sys/gnu/i386/fpemul/reg_mul.c b/sys/gnu/i386/fpemul/reg_mul.c deleted file mode 100644 index b51e9fc..0000000 --- a/sys/gnu/i386/fpemul/reg_mul.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * reg_mul.c - * - * Multiply one FPU_REG by another, put the result in a destination FPU_REG. - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_mul.c,v 1.2 1994/04/29 21:30:21 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | The destination may be any FPU_REG, including one of the source FPU_REGs. | - +---------------------------------------------------------------------------*/ - -#include "exception.h" -#include "reg_constant.h" -#include "fpu_emu.h" -#include "fpu_system.h" - - -/* This routine must be called with non-empty source registers */ -void -reg_mul(FPU_REG * a, FPU_REG * b, FPU_REG * dest, unsigned int control_w) -{ - char sign = (a->sign ^ b->sign); - - if (!(a->tag | b->tag)) { - /* This should be the most common case */ - reg_u_mul(a, b, dest, control_w); - dest->sign = sign; - return; - } else - if ((a->tag <= TW_Zero) && (b->tag <= TW_Zero)) { -#ifdef DENORM_OPERAND - if (((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) || - ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER))) { - if (denormal_operand()) - return; - } -#endif /* DENORM_OPERAND */ - /* Must have either both arguments == zero, or one - * valid and the other zero. The result is therefore - * zero. */ - reg_move(&CONST_Z, dest); -#ifdef PECULIAR_486 - /* The 80486 book says that the answer is +0, but a - * real 80486 appears to behave this way... */ - dest->sign = sign; -#endif /* PECULIAR_486 */ - return; - } -#if 0 /* TW_Denormal is not used yet... perhaps - * never will be. */ - else - if ((a->tag <= TW_Denormal) && (b->tag <= TW_Denormal)) { - /* One or both arguments are de-normalized */ - /* Internal de-normalized numbers are not - * supported yet */ - EXCEPTION(EX_INTERNAL | 0x105); - reg_move(&CONST_Z, dest); - } -#endif - else { - /* Must have infinities, NaNs, etc */ - if ((a->tag == TW_NaN) || (b->tag == TW_NaN)) { - real_2op_NaN(a, b, dest); - return; - } else - if (a->tag == TW_Infinity) { - if (b->tag == TW_Zero) { - arith_invalid(dest); - return; - } - /* Zero*Infinity is invalid */ - else { -#ifdef DENORM_OPERAND - if ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(a, dest); - dest->sign = sign; - } - return; - } else - if (b->tag == TW_Infinity) { - if (a->tag == TW_Zero) { - arith_invalid(dest); - return; - } - /* Zero*Infinity is - * invalid */ - else { -#ifdef DENORM_OPERAND - if ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER) && - denormal_operand()) - return; -#endif /* DENORM_OPERAND */ - reg_move(b, dest); - dest->sign = sign; - } - return; - } -#ifdef PARANOID - else { - EXCEPTION(EX_INTERNAL | 0x102); - } -#endif /* PARANOID */ - } -} diff --git a/sys/gnu/i386/fpemul/reg_norm.s b/sys/gnu/i386/fpemul/reg_norm.s deleted file mode 100644 index 6f9dd7c..0000000 --- a/sys/gnu/i386/fpemul/reg_norm.s +++ /dev/null @@ -1,182 +0,0 @@ -/* - * reg_norm.s - * - * Normalize the value in a FPU_REG. - * - * Call from C as: - * void normalize(FPU_REG *n) - * - * void normalize_nuo(FPU_REG *n) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_norm.s,v 1.2 1994/04/29 21:30:22 gclarkii Exp $ - * - */ - - -#include "fpu_asm.h" - - -.text - - .align 2,144 -.globl _normalize - -_normalize: - pushl %ebp - movl %esp,%ebp - pushl %ebx - - movl PARAM1,%ebx - - movl SIGH(%ebx),%edx - movl SIGL(%ebx),%eax - - orl %edx,%edx /* ms bits */ - js L_done /* Already normalized */ - jnz L_shift_1 /* Shift left 1 - 31 bits */ - - orl %eax,%eax - jz L_zero /* The contents are zero */ - -/* L_shift_32: */ - movl %eax,%edx - xorl %eax,%eax - subl $32,EXP(%ebx) /* This can cause an underflow */ - -/* We need to shift left by 1 - 31 bits */ -L_shift_1: - bsrl %edx,%ecx /* get the required shift in %ecx */ - subl $31,%ecx - negl %ecx - shld %cl,%eax,%edx - shl %cl,%eax - subl %ecx,EXP(%ebx) /* This can cause an underflow */ - - movl %edx,SIGH(%ebx) - movl %eax,SIGL(%ebx) - -L_done: - cmpl EXP_OVER,EXP(%ebx) - jge L_overflow - - cmpl EXP_UNDER,EXP(%ebx) - jle L_underflow - -L_exit: - popl %ebx - leave - ret - - -L_zero: - movl EXP_UNDER,EXP(%ebx) - movb TW_Zero,TAG(%ebx) - jmp L_exit - -L_underflow: - push %ebx - call _arith_underflow - pop %ebx - jmp L_exit - -L_overflow: - push %ebx - call _arith_overflow - pop %ebx - jmp L_exit - - - -/* Normalise without reporting underflow or overflow */ - .align 2,144 -.globl _normalize_nuo - -_normalize_nuo: - pushl %ebp - movl %esp,%ebp - pushl %ebx - - movl PARAM1,%ebx - - movl SIGH(%ebx),%edx - movl SIGL(%ebx),%eax - - orl %edx,%edx /* ms bits */ - js L_exit /* Already normalized */ - jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */ - - orl %eax,%eax - jz L_zero /* The contents are zero */ - -/* L_nuo_shift_32: */ - movl %eax,%edx - xorl %eax,%eax - subl $32,EXP(%ebx) /* This can cause an underflow */ - -/* We need to shift left by 1 - 31 bits */ -L_nuo_shift_1: - bsrl %edx,%ecx /* get the required shift in %ecx */ - subl $31,%ecx - negl %ecx - shld %cl,%eax,%edx - shl %cl,%eax - subl %ecx,EXP(%ebx) /* This can cause an underflow */ - - movl %edx,SIGH(%ebx) - movl %eax,SIGL(%ebx) - jmp L_exit - - diff --git a/sys/gnu/i386/fpemul/reg_round.s b/sys/gnu/i386/fpemul/reg_round.s deleted file mode 100644 index 99a2a8a..0000000 --- a/sys/gnu/i386/fpemul/reg_round.s +++ /dev/null @@ -1,653 +0,0 @@ - .file "reg_round.S" -/* - * reg_round.S - * - * Rounding/truncation/etc for FPU basic arithmetic functions. - * - * This code has four possible entry points. - * The following must be entered by a jmp intruction: - * FPU_round, FPU_round_sqrt, and FPU_Arith_exit. - * - * The _round_reg entry point is intended to be used by C code. - * From C, call as: - * void round_reg(FPU_REG *arg, unsigned int extent, unsigned int control_w) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_round.s,v 1.2 1994/04/29 21:30:23 gclarkii Exp $ - * - */ - - -/*---------------------------------------------------------------------------+ - | Four entry points. | - | | - | Needed by both the FPU_round and FPU_round_sqrt entry points: | - | %eax:%ebx 64 bit significand | - | %edx 32 bit extension of the significand | - | %edi pointer to an FPU_REG for the result to be stored | - | stack calling function must have set up a C stack frame and | - | pushed %esi, %edi, and %ebx | - | | - | Needed just for the FPU_round_sqrt entry point: | - | %cx A control word in the same format as the FPU control word. | - | Otherwise, PARAM4 must give such a value. | - | | - | | - | The significand and its extension are assumed to be exact in the | - | following sense: | - | If the significand by itself is the exact result then the significand | - | extension (%edx) must contain 0, otherwise the significand extension | - | must be non-zero. | - | If the significand extension is non-zero then the significand is | - | smaller than the magnitude of the correct exact result by an amount | - | greater than zero and less than one ls bit of the significand. | - | The significand extension is only required to have three possible | - | non-zero values: | - | less than 0x80000000 <=> the significand is less than 1/2 an ls | - | bit smaller than the magnitude of the | - | true exact result. | - | exactly 0x80000000 <=> the significand is exactly 1/2 an ls bit | - | smaller than the magnitude of the true | - | exact result. | - | greater than 0x80000000 <=> the significand is more than 1/2 an ls | - | bit smaller than the magnitude of the | - | true exact result. | - | | - +---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------+ - | The code in this module has become quite complex, but it should handle | - | all of the FPU flags which are set at this stage of the basic arithmetic | - | computations. | - | There are a few rare cases where the results are not set identically to | - | a real FPU. These require a bit more thought because at this stage the | - | results of the code here appear to be more consistent... | - | This may be changed in a future version. | - +---------------------------------------------------------------------------*/ - - -#include "fpu_asm.h" -#include "exception.h" -#include "control_w.h" - -#define LOST_DOWN $1 -#define LOST_UP $2 -#define DENORMAL $1 -#define UNMASKED_UNDERFLOW $2 - -.data - .align 2,0 -FPU_bits_lost: - .byte 0 -FPU_denormal: - .byte 0 - -.text - .align 2,144 -.globl FPU_round -.globl FPU_round_sqrt -.globl FPU_Arith_exit -.globl _round_reg - -/* Entry point when called from C */ -_round_reg: - pushl %ebp - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%edi - movl SIGH(%edi),%eax - movl SIGL(%edi),%ebx - movl PARAM2,%edx - movl PARAM3,%ecx - jmp FPU_round_sqrt - -FPU_round: /* Normal entry point */ - movl PARAM4,%ecx - -FPU_round_sqrt: /* Entry point from wm_sqrt.S */ - -#ifdef PARANOID -/* Cannot use this here yet */ -/* orl %eax,%eax */ -/* jns L_entry_bugged */ -#endif PARANOID - - cmpl EXP_UNDER,EXP(%edi) - jle xMake_denorm /* The number is a de-normal*/ - - movb $0,FPU_denormal /* 0 -> not a de-normal*/ - -xDenorm_done: - movb $0,FPU_bits_lost /*No bits yet lost in rounding*/ - - movl %ecx,%esi - andl CW_PC,%ecx - cmpl PR_64_BITS,%ecx - je LRound_To_64 - - cmpl PR_53_BITS,%ecx - je LRound_To_53 - - cmpl PR_24_BITS,%ecx - je LRound_To_24 - -#ifdef PARANOID - jmp L_bugged /* There is no bug, just a bad control word */ -#endif PARANOID - - -/* Round etc to 24 bit precision */ -LRound_To_24: - movl %esi,%ecx - andl CW_RC,%ecx - cmpl RC_RND,%ecx - je LRound_nearest_24 - - cmpl RC_CHOP,%ecx - je LCheck_truncate_24 - - cmpl RC_UP,%ecx /* Towards +infinity */ - je LUp_24 - - cmpl RC_DOWN,%ecx /* Towards -infinity */ - je LDown_24 - -#ifdef PARANOID - jmp L_bugged -#endif PARANOID - -LUp_24: - cmpb SIGN_POS,SIGN(%edi) - jne LCheck_truncate_24 /* If negative then up==truncate */ - - jmp LCheck_24_round_up - -LDown_24: - cmpb SIGN_POS,SIGN(%edi) - je LCheck_truncate_24 /* If positive then down==truncate */ - -LCheck_24_round_up: - movl %eax,%ecx - andl $0x000000ff,%ecx - orl %ebx,%ecx - orl %edx,%ecx - jnz LDo_24_round_up - jmp LRe_normalise - -LRound_nearest_24: - /* Do rounding of the 24th bit if needed (nearest or even) */ - movl %eax,%ecx - andl $0x000000ff,%ecx - cmpl $0x00000080,%ecx - jc LCheck_truncate_24 /*less than half, no increment needed*/ - - jne LGreater_Half_24 /* greater than half, increment needed*/ - - /* Possibly half, we need to check the ls bits */ - orl %ebx,%ebx - jnz LGreater_Half_24 /* greater than half, increment needed*/ - - orl %edx,%edx - jnz LGreater_Half_24 /* greater than half, increment needed*/ - - /* Exactly half, increment only if 24th bit is 1 (round to even)*/ - testl $0x00000100,%eax - jz LDo_truncate_24 - -LGreater_Half_24: /*Rounding: increment at the 24th bit*/ -LDo_24_round_up: - andl $0xffffff00,%eax /*Truncate to 24 bits*/ - xorl %ebx,%ebx - movb LOST_UP,FPU_bits_lost - addl $0x00000100,%eax - jmp LCheck_Round_Overflow - -LCheck_truncate_24: - movl %eax,%ecx - andl $0x000000ff,%ecx - orl %ebx,%ecx - orl %edx,%ecx - jz LRe_normalise /* No truncation needed*/ - -LDo_truncate_24: - andl $0xffffff00,%eax /* Truncate to 24 bits*/ - xorl %ebx,%ebx - movb LOST_DOWN,FPU_bits_lost - jmp LRe_normalise - - -/* Round etc to 53 bit precision */ -LRound_To_53: - movl %esi,%ecx - andl CW_RC,%ecx - cmpl RC_RND,%ecx - je LRound_nearest_53 - - cmpl RC_CHOP,%ecx - je LCheck_truncate_53 - - cmpl RC_UP,%ecx /* Towards +infinity*/ - je LUp_53 - - cmpl RC_DOWN,%ecx /* Towards -infinity*/ - je LDown_53 - -#ifdef PARANOID - jmp L_bugged -#endif PARANOID - -LUp_53: - cmpb SIGN_POS,SIGN(%edi) - jne LCheck_truncate_53 /* If negative then up==truncate*/ - - jmp LCheck_53_round_up - -LDown_53: - cmpb SIGN_POS,SIGN(%edi) - je LCheck_truncate_53 /* If positive then down==truncate*/ - -LCheck_53_round_up: - movl %ebx,%ecx - andl $0x000007ff,%ecx - orl %edx,%ecx - jnz LDo_53_round_up - jmp LRe_normalise - -LRound_nearest_53: - /*Do rounding of the 53rd bit if needed (nearest or even)*/ - movl %ebx,%ecx - andl $0x000007ff,%ecx - cmpl $0x00000400,%ecx - jc LCheck_truncate_53 /* less than half, no increment needed*/ - - jnz LGreater_Half_53 /* greater than half, increment needed*/ - - /*Possibly half, we need to check the ls bits*/ - orl %edx,%edx - jnz LGreater_Half_53 /* greater than half, increment needed*/ - - /* Exactly half, increment only if 53rd bit is 1 (round to even)*/ - testl $0x00000800,%ebx - jz LTruncate_53 - -LGreater_Half_53: /*Rounding: increment at the 53rd bit*/ -LDo_53_round_up: - movb LOST_UP,FPU_bits_lost - andl $0xfffff800,%ebx /* Truncate to 53 bits*/ - addl $0x00000800,%ebx - adcl $0,%eax - jmp LCheck_Round_Overflow - -LCheck_truncate_53: - movl %ebx,%ecx - andl $0x000007ff,%ecx - orl %edx,%ecx - jz LRe_normalise - -LTruncate_53: - movb LOST_DOWN,FPU_bits_lost - andl $0xfffff800,%ebx /* Truncate to 53 bits*/ - jmp LRe_normalise - - -/* Round etc to 64 bit precision*/ -LRound_To_64: - movl %esi,%ecx - andl CW_RC,%ecx - cmpl RC_RND,%ecx - je LRound_nearest_64 - - cmpl RC_CHOP,%ecx - je LCheck_truncate_64 - - cmpl RC_UP,%ecx /* Towards +infinity*/ - je LUp_64 - - cmpl RC_DOWN,%ecx /* Towards -infinity*/ - je LDown_64 - -#ifdef PARANOID - jmp L_bugged -#endif PARANOID - -LUp_64: - cmpb SIGN_POS,SIGN(%edi) - jne LCheck_truncate_64 /* If negative then up==truncate*/ - - orl %edx,%edx - jnz LDo_64_round_up - jmp LRe_normalise - -LDown_64: - cmpb SIGN_POS,SIGN(%edi) - je LCheck_truncate_64 /*If positive then down==truncate*/ - - orl %edx,%edx - jnz LDo_64_round_up - jmp LRe_normalise - -LRound_nearest_64: - cmpl $0x80000000,%edx - jc LCheck_truncate_64 - - jne LDo_64_round_up - - /* Now test for round-to-even */ - testb $1,%ebx - jz LCheck_truncate_64 - -LDo_64_round_up: - movb LOST_UP,FPU_bits_lost - addl $1,%ebx - adcl $0,%eax - -LCheck_Round_Overflow: - jnc LRe_normalise /* Rounding done, no overflow */ - - /* Overflow, adjust the result (to 1.0) */ - rcrl $1,%eax - rcrl $1,%ebx - incl EXP(%edi) - jmp LRe_normalise - -LCheck_truncate_64: - orl %edx,%edx - jz LRe_normalise - -LTruncate_64: - movb LOST_DOWN,FPU_bits_lost - -LRe_normalise: - testb $0xff,FPU_denormal - jnz xNormalise_result - -xL_Normalised: - cmpb LOST_UP,FPU_bits_lost - je xL_precision_lost_up - - cmpb LOST_DOWN,FPU_bits_lost - je xL_precision_lost_down - -xL_no_precision_loss: - cmpl EXP_OVER,EXP(%edi) - jge L_overflow - - /* store the result */ - movb TW_Valid,TAG(%edi) - -xL_Store_significand: - movl %eax,SIGH(%edi) - movl %ebx,SIGL(%edi) - -FPU_Arith_exit: - popl %ebx - popl %edi - popl %esi - leave - ret - - -/* Set the FPU status flags to represent precision loss due to*/ -/* round-up.*/ -xL_precision_lost_up: - push %eax - call _set_precision_flag_up - popl %eax - jmp xL_no_precision_loss - -/* Set the FPU status flags to represent precision loss due to*/ -/* truncation.*/ -xL_precision_lost_down: - push %eax - call _set_precision_flag_down - popl %eax - jmp xL_no_precision_loss - - -/* The number is a denormal (which might get rounded up to a normal) -// Shift the number right the required number of bits, which will -// have to be undone later...*/ -xMake_denorm: - /* The action to be taken depends upon whether the underflow - // exception is masked*/ - testb CW_Underflow,%cl /* Underflow mask.*/ - jz xUnmasked_underflow /* Do not make a denormal.*/ - - movb DENORMAL,FPU_denormal - - pushl %ecx /* Save*/ - movl EXP(%edi),%ecx - subl EXP_UNDER+1,%ecx - negl %ecx - - cmpl $64,%ecx /* shrd only works for 0..31 bits */ - jnc xDenorm_shift_more_than_63 - - cmpl $32,%ecx /* shrd only works for 0..31 bits */ - jnc xDenorm_shift_more_than_32 - -/* We got here without jumps by assuming that the most common requirement -// is for a small de-normalising shift. -// Shift by [1..31] bits */ - addl %ecx,EXP(%edi) - orl %edx,%edx /* extension*/ - setne %ch - xorl %edx,%edx - shrd %cl,%ebx,%edx - shrd %cl,%eax,%ebx - shr %cl,%eax - orb %ch,%dl - popl %ecx - jmp xDenorm_done - -/* Shift by [32..63] bits*/ -xDenorm_shift_more_than_32: - addl %ecx,EXP(%edi) - subb $32,%cl - orl %edx,%edx - setne %ch - orb %ch,%bl - xorl %edx,%edx - shrd %cl,%ebx,%edx - shrd %cl,%eax,%ebx - shr %cl,%eax - orl %edx,%edx /*test these 32 bits*/ - setne %cl - orb %ch,%bl - orb %cl,%bl - movl %ebx,%edx - movl %eax,%ebx - xorl %eax,%eax - popl %ecx - jmp xDenorm_done - -/* Shift by [64..) bits*/ -xDenorm_shift_more_than_63: - cmpl $64,%ecx - jne xDenorm_shift_more_than_64 - -/* Exactly 64 bit shift*/ - addl %ecx,EXP(%edi) - xorl %ecx,%ecx - orl %edx,%edx - setne %cl - orl %ebx,%ebx - setne %ch - orb %ch,%cl - orb %cl,%al - movl %eax,%edx - xorl %eax,%eax - xorl %ebx,%ebx - popl %ecx - jmp xDenorm_done - -xDenorm_shift_more_than_64: - movl EXP_UNDER+1,EXP(%edi) -/* This is easy, %eax must be non-zero, so..*/ - movl $1,%edx - xorl %eax,%eax - xorl %ebx,%ebx - popl %ecx - jmp xDenorm_done - - -xUnmasked_underflow: - /* Increase the exponent by the magic number*/ - addl $(3*(1<<13)),EXP(%edi) - movb UNMASKED_UNDERFLOW,FPU_denormal - jmp xDenorm_done - - -/* Undo the de-normalisation.*/ -xNormalise_result: - cmpb UNMASKED_UNDERFLOW,FPU_denormal - je xSignal_underflow - -/* The number must be a denormal if we got here.*/ -#ifdef PARANOID - /* But check it... just in case.*/ - cmpl EXP_UNDER+1,EXP(%edi) - jne L_norm_bugged -#endif PARANOID - - orl %eax,%eax /* ms bits*/ - jnz LNormalise_shift_up_to_31 /* Shift left 0 - 31 bits*/ - - orl %ebx,%ebx - jz L_underflow_to_zero /* The contents are zero*/ - -/* Shift left 32 - 63 bits*/ - movl %ebx,%eax - xorl %ebx,%ebx - subl $32,EXP(%edi) - -LNormalise_shift_up_to_31: - bsrl %eax,%ecx /* get the required shift in %ecx */ - subl $31,%ecx - negl %ecx - shld %cl,%ebx,%eax - shl %cl,%ebx - subl %ecx,EXP(%edi) - -LNormalise_shift_done: - testb $0xff,FPU_bits_lost /* bits lost == underflow*/ - jz xL_Normalised - - /* There must be a masked underflow*/ - push %eax - pushl EX_Underflow - call _exception - popl %eax - popl %eax - jmp xL_Normalised - - -/* The operations resulted in a number too small to represent. -// Masked response.*/ -L_underflow_to_zero: - push %eax - call _set_precision_flag_down - popl %eax - - push %eax - pushl EX_Underflow - call _exception - popl %eax - popl %eax - - movb TW_Zero,TAG(%edi) - jmp xL_Store_significand - - -/* The operations resulted in a number too large to represent.*/ -L_overflow: - push %edi - call _arith_overflow - pop %edi - jmp FPU_Arith_exit - - -xSignal_underflow: - push %eax - pushl EX_Underflow - call EXCEPTION - popl %eax - popl %eax - jmp xL_Normalised - - -#ifdef PARANOID -/* If we ever get here then we have problems! */ -L_bugged: - pushl EX_INTERNAL|0x201 - call EXCEPTION - popl %ebx - jmp FPU_Arith_exit - -L_norm_bugged: - pushl EX_INTERNAL|0x216 - call EXCEPTION - popl %ebx - jmp FPU_Arith_exit - -L_entry_bugged: - pushl EX_INTERNAL|0x217 - call EXCEPTION - popl %ebx - jmp FPU_Arith_exit -#endif PARANOID diff --git a/sys/gnu/i386/fpemul/reg_u_add.s b/sys/gnu/i386/fpemul/reg_u_add.s deleted file mode 100644 index 86c8475..0000000 --- a/sys/gnu/i386/fpemul/reg_u_add.s +++ /dev/null @@ -1,244 +0,0 @@ - .file "reg_u_add.S" -/* - * reg_u_add.S - * - * Add two valid (TW_Valid) FPU_REG numbers, of the same sign, and put the - * result in a destination FPU_REG. - * - * Call from C as: - * void reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, - * int control_w) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_u_add.s,v 1.2 1994/04/29 21:34:23 gclarkii Exp $ - * - */ - - -/* - | Kernel addition routine reg_u_add(reg *arg1, reg *arg2, reg *answ). - | Takes two valid reg f.p. numbers (TW_Valid), which are - | treated as unsigned numbers, - | and returns their sum as a TW_Valid or TW_S f.p. number. - | The returned number is normalized. - | Basic checks are performed if PARANOID is defined. - */ - -#include "exception.h" -#include "fpu_asm.h" -#include "control_w.h" - -.text - .align 2,144 -.globl _reg_u_add -_reg_u_add: - pushl %ebp - movl %esp,%ebp -/* subl $16,%esp*/ - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi /* source 1 */ - movl PARAM2,%edi /* source 2 */ - -#ifdef DENORM_OPERAND - cmpl EXP_UNDER,EXP(%esi) - jg xOp1_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp1_not_denorm: - cmpl EXP_UNDER,EXP(%edi) - jg xOp2_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp2_not_denorm: -#endif DENORM_OPERAND - -/* xorl %ecx,%ecx*/ - movl EXP(%esi),%ecx - subl EXP(%edi),%ecx /* exp1 - exp2 */ -/* jnc L_arg1_larger*/ - jge L_arg1_larger - - /* num1 is smaller */ - movl SIGL(%esi),%ebx - movl SIGH(%esi),%eax - - movl %edi,%esi - negw %cx - jmp L_accum_loaded - -L_arg1_larger: - /* num1 has larger or equal exponent */ - movl SIGL(%edi),%ebx - movl SIGH(%edi),%eax - -L_accum_loaded: - movl PARAM3,%edi /* destination */ - movb SIGN(%esi),%dl - movb %dl,SIGN(%edi) /* Copy the sign from the first arg */ - - - movl EXP(%esi),%edx - movl %edx,EXP(%edi) /* Copy exponent to destination */ - - xorl %edx,%edx /* clear the extension */ - -#ifdef PARANOID - testl $0x80000000,%eax - je L_bugged - - testl $0x80000000,SIGH(%esi) - je L_bugged -#endif PARANOID - -/* The number to be shifted is in %eax:%ebx:%edx*/ - cmpw $32,%cx /* shrd only works for 0..31 bits */ - jnc L_more_than_31 - -/* less than 32 bits */ - shrd %cl,%ebx,%edx - shrd %cl,%eax,%ebx - shr %cl,%eax - jmp L_shift_done - -L_more_than_31: - cmpw $64,%cx - jnc L_more_than_63 - - subb $32,%cl - jz L_exactly_32 - - shrd %cl,%eax,%edx - shr %cl,%eax - orl %ebx,%ebx - jz L_more_31_no_low /* none of the lowest bits is set*/ - - orl $1,%edx /* record the fact in the extension*/ - -L_more_31_no_low: - movl %eax,%ebx - xorl %eax,%eax - jmp L_shift_done - -L_exactly_32: - movl %ebx,%edx - movl %eax,%ebx - xorl %eax,%eax - jmp L_shift_done - -L_more_than_63: - cmpw $65,%cx - jnc L_more_than_64 - - movl %eax,%edx - orl %ebx,%ebx - jz L_more_63_no_low - - orl $1,%edx - jmp L_more_63_no_low - -L_more_than_64: - movl $1,%edx /* The shifted nr always at least one '1'*/ - -L_more_63_no_low: - xorl %ebx,%ebx - xorl %eax,%eax - -L_shift_done: - /* Now do the addition */ - addl SIGL(%esi),%ebx - adcl SIGH(%esi),%eax - jnc L_round_the_result - - /* Overflow, adjust the result */ - rcrl $1,%eax - rcrl $1,%ebx - rcrl $1,%edx - jnc L_no_bit_lost - - orl $1,%edx - -L_no_bit_lost: - incl EXP(%edi) - -L_round_the_result: - jmp FPU_round /* Round the result*/ - - - -#ifdef PARANOID -/* If we ever get here then we have problems! */ -L_bugged: - pushl EX_INTERNAL|0x201 - call EXCEPTION - pop %ebx - jmp L_exit -#endif PARANOID - - -L_exit: - popl %ebx - popl %edi - popl %esi - leave - ret diff --git a/sys/gnu/i386/fpemul/reg_u_div.s b/sys/gnu/i386/fpemul/reg_u_div.s deleted file mode 100644 index 4952923..0000000 --- a/sys/gnu/i386/fpemul/reg_u_div.s +++ /dev/null @@ -1,506 +0,0 @@ - .file "reg_u_div.S" -/* - * reg_u_div.S - * - * Core division routines - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_u_div.s,v 1.2 1994/04/29 21:34:24 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Kernel for the division routines. | - | | - | void reg_u_div(FPU_REG *a, FPU_REG *a, | - | FPU_REG *dest, unsigned int control_word) | - | | - | Does not compute the destination exponent, but does adjust it. | - +---------------------------------------------------------------------------*/ - -#include "exception.h" -#include "fpu_asm.h" -#include "control_w.h" - - -/* #define dSIGL(x) (x) */ -/* #define dSIGH(x) 4(x) */ - - -.data -/* - Local storage: - Result: accum_3:accum_2:accum_1:accum_0 - Overflow flag: ovfl_flag - */ - .align 2,0 -accum_3: - .long 0 -accum_2: - .long 0 -accum_1: - .long 0 -accum_0: - .long 0 -result_1: - .long 0 -result_2: - .long 0 -ovfl_flag: - .byte 0 - - -.text - .align 2,144 - -.globl _reg_u_div - -.globl _divide_kernel - -_reg_u_div: - pushl %ebp - movl %esp,%ebp - - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi /* pointer to num */ - movl PARAM2,%ebx /* pointer to denom */ - movl PARAM3,%edi /* pointer to answer */ - -#ifdef DENORM_OPERAND - movl EXP(%esi),%eax - cmpl EXP_UNDER,%eax - jg xOp1_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp1_not_denorm: - movl EXP(%ebx),%eax - cmpl EXP_UNDER,%eax - jg xOp2_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp2_not_denorm: -#endif DENORM_OPERAND - -_divide_kernel: -#ifdef PARANOID -/* testl $0x80000000, SIGH(%esi) *//* Dividend */ -/* je L_bugged */ - testl $0x80000000, SIGH(%ebx) /* Divisor*/ - je L_bugged -#endif PARANOID - -/* Check if the divisor can be treated as having just 32 bits */ - cmpl $0,SIGL(%ebx) - jnz L_Full_Division /* Can't do a quick divide */ - -/* We should be able to zip through the division here */ - movl SIGH(%ebx),%ecx /* The divisor */ - movl SIGH(%esi),%edx /* Dividend */ - movl SIGL(%esi),%eax /* Dividend */ - - cmpl %ecx,%edx - setaeb ovfl_flag /* Keep a record */ - jb L_no_adjust - - subl %ecx,%edx /* Prevent the overflow */ - -L_no_adjust: - /* Divide the 64 bit number by the 32 bit denominator */ - divl %ecx - movl %eax,result_2 - - /* Work on the remainder of the first division */ - xorl %eax,%eax - divl %ecx - movl %eax,result_1 - - /* Work on the remainder of the 64 bit division */ - xorl %eax,%eax - divl %ecx - - testb $255,ovfl_flag /* was the num > denom ? */ - je L_no_overflow - - /* Do the shifting here */ - /* increase the exponent */ - incl EXP(%edi) - - /* shift the mantissa right one bit */ - stc /* To set the ms bit */ - rcrl result_2 - rcrl result_1 - rcrl %eax - -L_no_overflow: - jmp LRound_precision /* Do the rounding as required*/ - - -/*---------------------------------------------------------------------------+ - | Divide: Return arg1/arg2 to arg3. | - | | - | This routine does not use the exponents of arg1 and arg2, but does | - | adjust the exponent of arg3. | - | | - | The maximum returned value is (ignoring exponents) | - | .ffffffff ffffffff | - | ------------------ = 1.ffffffff fffffffe | - | .80000000 00000000 | - | and the minimum is | - | .80000000 00000000 | - | ------------------ = .80000000 00000001 (rounded) | - | .ffffffff ffffffff | - | | - +---------------------------------------------------------------------------*/ - - -L_Full_Division: - /* Save extended dividend in local register*/ - movl SIGL(%esi),%eax - movl %eax,accum_2 - movl SIGH(%esi),%eax - movl %eax,accum_3 - xorl %eax,%eax - movl %eax,accum_1 /* zero the extension */ - movl %eax,accum_0 /* zero the extension */ - - movl SIGL(%esi),%eax /* Get the current num */ - movl SIGH(%esi),%edx - -/*----------------------------------------------------------------------*/ -/* Initialization done */ -/* Do the first 32 bits */ - - movb $0,ovfl_flag - cmpl SIGH(%ebx),%edx /* Test for imminent overflow */ - jb LLess_than_1 - ja LGreater_than_1 - - cmpl SIGL(%ebx),%eax - jb LLess_than_1 - -LGreater_than_1: -/* The dividend is greater or equal, would cause overflow */ - setaeb ovfl_flag /* Keep a record */ - - subl SIGL(%ebx),%eax - sbbl SIGH(%ebx),%edx /* Prevent the overflow */ - movl %eax,accum_2 - movl %edx,accum_3 - -LLess_than_1: -/* At this point, we have a dividend < divisor, with a record of - adjustment in ovfl_flag */ - - /* We will divide by a number which is too large */ - movl SIGH(%ebx),%ecx - addl $1,%ecx - jnc LFirst_div_not_1 - - /* here we need to divide by 100000000h, - i.e., no division at all.. */ - mov %edx,%eax - jmp LFirst_div_done - -LFirst_div_not_1: - divl %ecx /* Divide the numerator by the augmented - denom ms dw */ - -LFirst_div_done: - movl %eax,result_2 /* Put the result in the answer */ - - mull SIGH(%ebx) /* mul by the ms dw of the denom */ - - subl %eax,accum_2 /* Subtract from the num local reg */ - sbbl %edx,accum_3 - - movl result_2,%eax /* Get the result back */ - mull SIGL(%ebx) /* now mul the ls dw of the denom */ - - subl %eax,accum_1 /* Subtract from the num local reg */ - sbbl %edx,accum_2 - sbbl $0,accum_3 - je LDo_2nd_32_bits /* Must check for non-zero result here */ - -#ifdef PARANOID - jb L_bugged_1 -#endif PARANOID - - /* need to subtract another once of the denom */ - incl result_2 /* Correct the answer */ - - movl SIGL(%ebx),%eax - movl SIGH(%ebx),%edx - subl %eax,accum_1 /* Subtract from the num local reg */ - sbbl %edx,accum_2 - -#ifdef PARANOID - sbbl $0,accum_3 - jne L_bugged_1 /* Must check for non-zero result here */ -#endif PARANOID - -/*----------------------------------------------------------------------*/ -/* Half of the main problem is done, there is just a reduced numerator - to handle now */ -/* Work with the second 32 bits, accum_0 not used from now on */ -LDo_2nd_32_bits: - movl accum_2,%edx /* get the reduced num */ - movl accum_1,%eax - - /* need to check for possible subsequent overflow */ - cmpl SIGH(%ebx),%edx - jb LDo_2nd_div - ja LPrevent_2nd_overflow - - cmpl SIGL(%ebx),%eax - jb LDo_2nd_div - -LPrevent_2nd_overflow: -/* The numerator is greater or equal, would cause overflow */ - /* prevent overflow */ - subl SIGL(%ebx),%eax - sbbl SIGH(%ebx),%edx - movl %edx,accum_2 - movl %eax,accum_1 - - incl result_2 /* Reflect the subtraction in the answer */ - -#ifdef PARANOID - je L_bugged_2 /* Can't bump the result to 1.0 */ -#endif PARANOID - -LDo_2nd_div: - cmpl $0,%ecx /* augmented denom msw*/ - jnz LSecond_div_not_1 - - /* %ecx == 0, we are dividing by 1.0 */ - mov %edx,%eax - jmp LSecond_div_done - -LSecond_div_not_1: - divl %ecx /* Divide the numerator by the denom ms dw */ - -LSecond_div_done: - movl %eax,result_1 /* Put the result in the answer */ - - mull SIGH(%ebx) /* mul by the ms dw of the denom */ - - subl %eax,accum_1 /* Subtract from the num local reg */ - sbbl %edx,accum_2 - -#ifdef PARANOID - jc L_bugged_2 -#endif PARANOID - - movl result_1,%eax /* Get the result back */ - mull SIGL(%ebx) /* now mul the ls dw of the denom */ - - subl %eax,accum_0 /* Subtract from the num local reg */ - sbbl %edx,accum_1 /* Subtract from the num local reg */ - sbbl $0,accum_2 - -#ifdef PARANOID - jc L_bugged_2 -#endif PARANOID - - jz LDo_3rd_32_bits - -#ifdef PARANOID - cmpl $1,accum_2 - jne L_bugged_2 -#endif PARANOID - - /* need to subtract another once of the denom */ - movl SIGL(%ebx),%eax - movl SIGH(%ebx),%edx - subl %eax,accum_0 /* Subtract from the num local reg */ - sbbl %edx,accum_1 - sbbl $0,accum_2 - -#ifdef PARANOID - jc L_bugged_2 - jne L_bugged_2 -#endif PARANOID - - addl $1,result_1 /* Correct the answer */ - adcl $0,result_2 - -#ifdef PARANOID - jc L_bugged_2 /* Must check for non-zero result here */ -#endif PARANOID - -/*----------------------------------------------------------------------*/ -/* The division is essentially finished here, we just need to perform - tidying operations. */ -/* deal with the 3rd 32 bits */ -LDo_3rd_32_bits: - movl accum_1,%edx /* get the reduced num */ - movl accum_0,%eax - - /* need to check for possible subsequent overflow */ - cmpl SIGH(%ebx),%edx /* denom*/ - jb LRound_prep - ja LPrevent_3rd_overflow - - cmpl SIGL(%ebx),%eax /* denom */ - jb LRound_prep - -LPrevent_3rd_overflow: - /* prevent overflow */ - subl SIGL(%ebx),%eax - sbbl SIGH(%ebx),%edx - movl %edx,accum_1 - movl %eax,accum_0 - - addl $1,result_1 /* Reflect the subtraction in the answer */ - adcl $0,result_2 - jne LRound_prep - jnc LRound_prep - - /* This is a tricky spot, there is an overflow of the answer */ - movb $255,ovfl_flag /* Overflow -> 1.000 */ - -LRound_prep: -/* Prepare for rounding. -// To test for rounding, we just need to compare 2*accum with the -// denom. */ - movl accum_0,%ecx - movl accum_1,%edx - movl %ecx,%eax - orl %edx,%eax - jz LRound_ovfl /* The accumulator contains zero.*/ - - /* Multiply by 2 */ - clc - rcll $1,%ecx - rcll $1,%edx - jc LRound_large /* No need to compare, denom smaller */ - - subl SIGL(%ebx),%ecx - sbbl SIGH(%ebx),%edx - jnc LRound_not_small - - movl $0x70000000,%eax /* Denom was larger */ - jmp LRound_ovfl - -LRound_not_small: - jnz LRound_large - - movl $0x80000000,%eax /* Remainder was exactly 1/2 denom */ - jmp LRound_ovfl - -LRound_large: - movl $0xff000000,%eax /* Denom was smaller */ - -LRound_ovfl: -/* We are now ready to deal with rounding, but first we must get - the bits properly aligned */ - testb $255,ovfl_flag /* was the num > denom ? */ - je LRound_precision - - incl EXP(%edi) - - /* shift the mantissa right one bit */ - stc /* Will set the ms bit */ - rcrl result_2 - rcrl result_1 - rcrl %eax - -/* Round the result as required */ -LRound_precision: - decl EXP(%edi) /* binary point between 1st & 2nd bits */ - - movl %eax,%edx - movl result_1,%ebx - movl result_2,%eax - jmp FPU_round - - -#ifdef PARANOID -/* The logic is wrong if we got here */ -L_bugged: - pushl EX_INTERNAL|0x202 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged_1: - pushl EX_INTERNAL|0x203 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged_2: - pushl EX_INTERNAL|0x204 - call EXCEPTION - pop %ebx - jmp L_exit - -L_exit: - popl %ebx - popl %edi - popl %esi - - leave - ret -#endif PARANOID diff --git a/sys/gnu/i386/fpemul/reg_u_mul.s b/sys/gnu/i386/fpemul/reg_u_mul.s deleted file mode 100644 index 798f204..0000000 --- a/sys/gnu/i386/fpemul/reg_u_mul.s +++ /dev/null @@ -1,199 +0,0 @@ - .file "reg_u_mul.S" -/* - * reg_u_mul.S - * - * Core multiplication routine - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_u_mul.s,v 1.2 1994/04/29 21:34:25 gclarkii Exp $ - * - */ - -/*---------------------------------------------------------------------------+ - | Basic multiplication routine. | - | Does not check the resulting exponent for overflow/underflow | - | | - | reg_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); | - | | - | Internal working is at approx 128 bits. | - | Result is rounded to nearest 53 or 64 bits, using "nearest or even". | - +---------------------------------------------------------------------------*/ - -#include "exception.h" -#include "fpu_asm.h" -#include "control_w.h" - - -.data - .align 2,0 -accum_0: - .long 0 -accum_1: - .long 0 - - -.text - .align 2,144 - -.globl _reg_u_mul -_reg_u_mul: - pushl %ebp - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi - movl PARAM2,%edi - -#ifdef PARANOID - testl $0x80000000,SIGH(%esi) - jz L_bugged - testl $0x80000000,SIGH(%edi) - jz L_bugged -#endif PARANOID - -#ifdef DENORM_OPERAND - movl EXP(%esi),%eax - cmpl EXP_UNDER,%eax - jg xOp1_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp1_not_denorm: - movl EXP(%edi),%eax - cmpl EXP_UNDER,%eax - jg xOp2_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp2_not_denorm: -#endif DENORM_OPERAND - - xorl %ecx,%ecx - xorl %ebx,%ebx - - movl SIGL(%esi),%eax - mull SIGL(%edi) - movl %eax,accum_0 - movl %edx,accum_1 - - movl SIGL(%esi),%eax - mull SIGH(%edi) - addl %eax,accum_1 - adcl %edx,%ebx -/* adcl $0,%ecx *//* overflow here is not possible */ - - movl SIGH(%esi),%eax - mull SIGL(%edi) - addl %eax,accum_1 - adcl %edx,%ebx - adcl $0,%ecx - - movl SIGH(%esi),%eax - mull SIGH(%edi) - addl %eax,%ebx - adcl %edx,%ecx - - movl EXP(%esi),%eax /* Compute the exponent */ - addl EXP(%edi),%eax - subl EXP_BIAS-1,%eax -/* Have now finished with the sources */ - movl PARAM3,%edi /* Point to the destination */ - movl %eax,EXP(%edi) - -/* Now make sure that the result is normalized */ - testl $0x80000000,%ecx - jnz LResult_Normalised - - /* Normalize by shifting left one bit */ - shll $1,accum_0 - rcll $1,accum_1 - rcll $1,%ebx - rcll $1,%ecx - decl EXP(%edi) - -LResult_Normalised: - movl accum_0,%eax - movl accum_1,%edx - orl %eax,%eax - jz L_extent_zero - - orl $1,%edx - -L_extent_zero: - movl %ecx,%eax - jmp FPU_round - - -#ifdef PARANOID -L_bugged: - pushl EX_INTERNAL|0x205 - call EXCEPTION - pop %ebx - jmp L_exit - -L_exit: - popl %ebx - popl %edi - popl %esi - leave - ret -#endif PARANOID - diff --git a/sys/gnu/i386/fpemul/reg_u_sub.s b/sys/gnu/i386/fpemul/reg_u_sub.s deleted file mode 100644 index 3161e19..0000000 --- a/sys/gnu/i386/fpemul/reg_u_sub.s +++ /dev/null @@ -1,361 +0,0 @@ - .file "reg_u_sub.S" -/* - * reg_u_sub.S - * - * Core floating point subtraction routine. - * - * Call from C as: - * void reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, - * int control_w) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: reg_u_sub.s,v 1.2 1994/04/29 21:34:26 gclarkii Exp $ - * - */ - -/* - | Kernel subtraction routine reg_u_sub(reg *arg1, reg *arg2, reg *answ). - | Takes two valid reg f.p. numbers (TW_Valid), which are - | treated as unsigned numbers, - | and returns their difference as a TW_Valid or TW_Zero f.p. - | number. - | The first number (arg1) must be the larger. - | The returned number is normalized. - | Basic checks are performed if PARANOID is defined. - */ - -#include "exception.h" -#include "fpu_asm.h" -#include "control_w.h" - -.text - .align 2,144 -.globl _reg_u_sub -_reg_u_sub: - pushl %ebp - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi /* source 1 */ - movl PARAM2,%edi /* source 2 */ - -#ifdef DENORM_OPERAND - cmpl EXP_UNDER,EXP(%esi) - jg xOp1_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp1_not_denorm: - cmpl EXP_UNDER,EXP(%edi) - jg xOp2_not_denorm - - call _denormal_operand - orl %eax,%eax - jnz FPU_Arith_exit - -xOp2_not_denorm: -#endif DENORM_OPERAND - -/* xorl %ecx,%ecx */ - movl EXP(%esi),%ecx - subl EXP(%edi),%ecx /* exp1 - exp2 */ - -#ifdef PARANOID - /* source 2 is always smaller than source 1 */ -/* jc L_bugged */ - js L_bugged_1 - - testl $0x80000000,SIGH(%edi) /* The args are assumed to be be normalized */ - je L_bugged_2 - - testl $0x80000000,SIGH(%esi) - je L_bugged_2 -#endif PARANOID - -/*--------------------------------------+ - | Form a register holding the | - | smaller number | - +--------------------------------------*/ - movl SIGH(%edi),%eax /* register ms word */ - movl SIGL(%edi),%ebx /* register ls word */ - - movl PARAM3,%edi /* destination */ - movl EXP(%esi),%edx - movl %edx,EXP(%edi) /* Copy exponent to destination */ - movb SIGN(%esi),%dl - movb %dl,SIGN(%edi) /* Copy the sign from the first arg */ - - xorl %edx,%edx /* register extension */ - -/*--------------------------------------+ - | Shift the temporary register | - | right the required number of | - | places. | - +--------------------------------------*/ -L_shift_r: - cmpl $32,%ecx /* shrd only works for 0..31 bits */ - jnc L_more_than_31 - -/* less than 32 bits */ - shrd %cl,%ebx,%edx - shrd %cl,%eax,%ebx - shr %cl,%eax - jmp L_shift_done - -L_more_than_31: - cmpl $64,%ecx - jnc L_more_than_63 - - subb $32,%cl - jz L_exactly_32 - - shrd %cl,%eax,%edx - shr %cl,%eax - orl %ebx,%ebx - jz L_more_31_no_low /* none of the lowest bits is set */ - - orl $1,%edx /* record the fact in the extension */ - -L_more_31_no_low: - movl %eax,%ebx - xorl %eax,%eax - jmp L_shift_done - -L_exactly_32: - movl %ebx,%edx - movl %eax,%ebx - xorl %eax,%eax - jmp L_shift_done - -L_more_than_63: - cmpw $65,%cx - jnc L_more_than_64 - - /* Shift right by 64 bits */ - movl %eax,%edx - orl %ebx,%ebx - jz L_more_63_no_low - - orl $1,%edx - jmp L_more_63_no_low - -L_more_than_64: - jne L_more_than_65 - - /* Shift right by 65 bits */ - /* Carry is clear if we get here */ - movl %eax,%edx - rcrl %edx - jnc L_shift_65_nc - - orl $1,%edx - jmp L_more_63_no_low - -L_shift_65_nc: - orl %ebx,%ebx - jz L_more_63_no_low - - orl $1,%edx - jmp L_more_63_no_low - -L_more_than_65: - movl $1,%edx /* The shifted nr always at least one '1' */ - -L_more_63_no_low: - xorl %ebx,%ebx - xorl %eax,%eax - -L_shift_done: -L_subtr: -/*------------------------------+ - | Do the subtraction | - +------------------------------*/ - xorl %ecx,%ecx - subl %edx,%ecx - movl %ecx,%edx - movl SIGL(%esi),%ecx - sbbl %ebx,%ecx - movl %ecx,%ebx - movl SIGH(%esi),%ecx - sbbl %eax,%ecx - movl %ecx,%eax - -#ifdef PARANOID - /* We can never get a borrow */ - jc L_bugged -#endif PARANOID - -/*--------------------------------------+ - | Normalize the result | - +--------------------------------------*/ - testl $0x80000000,%eax - jnz L_round /* no shifting needed */ - - orl %eax,%eax - jnz L_shift_1 /* shift left 1 - 31 bits */ - - orl %ebx,%ebx - jnz L_shift_32 /* shift left 32 - 63 bits */ - -/* A rare case, the only one which is non-zero if we got here -// is: 1000000 .... 0000 -// -0111111 .... 1111 1 -// -------------------- -// 0000000 .... 0000 1 */ - - cmpl $0x80000000,%edx - jnz L_must_be_zero - - /* Shift left 64 bits */ - subl $64,EXP(%edi) - movl %edx,%eax - jmp L_store - -L_must_be_zero: -#ifdef PARANOID - orl %edx,%edx - jnz L_bugged_3 -#endif PARANOID - - /* The result is zero */ - movb TW_Zero,TAG(%edi) - movl $0,EXP(%edi) /* exponent */ - movl $0,SIGL(%edi) - movl $0,SIGH(%edi) - jmp L_exit /* Does not underflow */ - -L_shift_32: - movl %ebx,%eax - movl %edx,%ebx - movl $0,%edx - subl $32,EXP(%edi) /* Can get underflow here */ - -/* We need to shift left by 1 - 31 bits */ -L_shift_1: - bsrl %eax,%ecx /* get the required shift in %ecx */ - subl $31,%ecx - negl %ecx - shld %cl,%ebx,%eax - shld %cl,%edx,%ebx - shl %cl,%edx - subl %ecx,EXP(%edi) /* Can get underflow here */ - -L_round: - jmp FPU_round /* Round the result */ - - -#ifdef PARANOID -L_bugged_1: - pushl EX_INTERNAL|0x206 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged_2: - pushl EX_INTERNAL|0x209 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged_3: - pushl EX_INTERNAL|0x210 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged_4: - pushl EX_INTERNAL|0x211 - call EXCEPTION - pop %ebx - jmp L_exit - -L_bugged: - pushl EX_INTERNAL|0x212 - call EXCEPTION - pop %ebx - jmp L_exit -#endif PARANOID - - -L_store: -/*------------------------------+ - | Store the result | - +------------------------------*/ - movl %eax,SIGH(%edi) - movl %ebx,SIGL(%edi) - - movb TW_Valid,TAG(%edi) /* Set the tags to TW_Valid */ - - cmpl EXP_UNDER,EXP(%edi) - jle L_underflow - -L_exit: - popl %ebx - popl %edi - popl %esi - leave - ret - - -L_underflow: - push %edi - call _arith_underflow - pop %ebx - jmp L_exit - diff --git a/sys/gnu/i386/fpemul/status_w.h b/sys/gnu/i386/fpemul/status_w.h deleted file mode 100644 index 75b87b4..0000000 --- a/sys/gnu/i386/fpemul/status_w.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * status_w.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: status_w.h,v 1.2 1994/04/29 21:34:27 gclarkii Exp $ - * - */ - - -#ifndef _STATUS_H_ -#define _STATUS_H_ - - -#ifdef LOCORE -#define Const__(x) $/**/x -#else -#define Const__(x) x -#endif - -#define SW_Backward Const__(0x8000) /* backward compatibility */ -#define SW_C3 Const__(0x4000) /* condition bit 3 */ -#define SW_Top Const__(0x3800) /* top of stack */ -#define SW_Top_Shift Const__(11) /* shift for top of stack bits */ -#define SW_C2 Const__(0x0400) /* condition bit 2 */ -#define SW_C1 Const__(0x0200) /* condition bit 1 */ -#define SW_C0 Const__(0x0100) /* condition bit 0 */ -#define SW_Summary Const__(0x0080) /* exception summary */ -#define SW_Stack_Fault Const__(0x0040) /* stack fault */ -#define SW_Precision Const__(0x0020) /* loss of precision */ -#define SW_Underflow Const__(0x0010) /* underflow */ -#define SW_Overflow Const__(0x0008) /* overflow */ -#define SW_Zero_Div Const__(0x0004) /* divide by zero */ -#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */ -#define SW_Invalid Const__(0x0001) /* invalid operation */ - -#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */ - -#ifndef LOCORE - -#define COMP_A_gt_B 1 -#define COMP_A_eq_B 2 -#define COMP_A_lt_B 3 -#define COMP_No_Comp 4 -#define COMP_Denormal 0x20 -#define COMP_NaN 0x40 -#define COMP_SNaN 0x80 - -#define setcc(cc) ({ \ - status_word &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \ - status_word |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); }) - -#endif /* LOCORE */ - -#endif /* _STATUS_H_ */ diff --git a/sys/gnu/i386/fpemul/version.h b/sys/gnu/i386/fpemul/version.h deleted file mode 100644 index 9c08aed..0000000 --- a/sys/gnu/i386/fpemul/version.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * version.h - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: version.h,v 1.2 1994/04/29 21:34:28 gclarkii Exp $ - * - */ - -#define FPU_VERSION "wm-FPU-emu version BETA 1.4" diff --git a/sys/gnu/i386/fpemul/wm_shrx.s b/sys/gnu/i386/fpemul/wm_shrx.s deleted file mode 100644 index 9de9464..0000000 --- a/sys/gnu/i386/fpemul/wm_shrx.s +++ /dev/null @@ -1,261 +0,0 @@ - .file "wm_shrx.S" -/* - * wm_shrx.S - * - * 64 bit right shift functions - * - * Call from C as: - * unsigned shrx(void *arg1, unsigned arg2) - * and - * unsigned shrxs(void *arg1, unsigned arg2) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: wm_shrx.s,v 1.2 1994/04/29 21:34:29 gclarkii Exp $ - * - */ - - -#include "fpu_asm.h" - -.text - .align 2,144 - -/*---------------------------------------------------------------------------+ - | unsigned shrx(void *arg1, unsigned arg2) | - | | - | Extended shift right function. | - | Fastest for small shifts. | - | Shifts the 64 bit quantity pointed to by the first arg (arg1) | - | right by the number of bits specified by the second arg (arg2). | - | Forms a 96 bit quantity from the 64 bit arg and eax: | - | [ 64 bit arg ][ eax ] | - | shift right ---------> | - | The eax register is initialized to 0 before the shifting. | - | Results returned in the 64 bit arg and eax. | - +---------------------------------------------------------------------------*/ - - .globl _shrx - -_shrx: - push %ebp - movl %esp,%ebp - pushl %esi - movl PARAM2,%ecx - movl PARAM1,%esi - cmpl $32,%ecx /* shrd only works for 0..31 bits */ - jnc L_more_than_31 - -/* less than 32 bits */ - pushl %ebx - movl (%esi),%ebx /* lsl */ - movl 4(%esi),%edx /* msl */ - xorl %eax,%eax /* extension */ - shrd %cl,%ebx,%eax - shrd %cl,%edx,%ebx - shr %cl,%edx - movl %ebx,(%esi) - movl %edx,4(%esi) - popl %ebx - popl %esi - leave - ret - -L_more_than_31: - cmpl $64,%ecx - jnc L_more_than_63 - - subb $32,%cl - movl (%esi),%eax /* lsl */ - movl 4(%esi),%edx /* msl */ - shrd %cl,%edx,%eax - shr %cl,%edx - movl %edx,(%esi) - movl $0,4(%esi) - popl %esi - leave - ret - -L_more_than_63: - cmpl $96,%ecx - jnc L_more_than_95 - - subb $64,%cl - movl 4(%esi),%eax /* msl */ - shr %cl,%eax - xorl %edx,%edx - movl %edx,(%esi) - movl %edx,4(%esi) - popl %esi - leave - ret - -L_more_than_95: - xorl %eax,%eax - movl %eax,(%esi) - movl %eax,4(%esi) - popl %esi - leave - ret - - -/*---------------------------------------------------------------------------+ - | unsigned shrxs(void *arg1, unsigned arg2) | - | | - | Extended shift right function (optimized for small floating point | - | integers). | - | Shifts the 64 bit quantity pointed to by the first arg (arg1) | - | right by the number of bits specified by the second arg (arg2). | - | Forms a 96 bit quantity from the 64 bit arg and eax: | - | [ 64 bit arg ][ eax ] | - | shift right ---------> | - | The eax register is initialized to 0 before the shifting. | - | The lower 8 bits of eax are lost and replaced by a flag which is | - | set (to 0x01) if any bit, apart from the first one, is set in the | - | part which has been shifted out of the arg. | - | Results returned in the 64 bit arg and eax. | - +---------------------------------------------------------------------------*/ - .globl _shrxs -_shrxs: - push %ebp - movl %esp,%ebp - pushl %esi - pushl %ebx - movl PARAM2,%ecx - movl PARAM1,%esi - cmpl $64,%ecx /* shrd only works for 0..31 bits */ - jnc Ls_more_than_63 - - cmpl $32,%ecx /* shrd only works for 0..31 bits */ - jc Ls_less_than_32 - -/* We got here without jumps by assuming that the most common requirement - is for small integers */ -/* Shift by [32..63] bits */ - subb $32,%cl - movl (%esi),%eax /* lsl */ - movl 4(%esi),%edx /* msl */ - xorl %ebx,%ebx - shrd %cl,%eax,%ebx - shrd %cl,%edx,%eax - shr %cl,%edx - orl %ebx,%ebx /* test these 32 bits */ - setne %bl - test $0x7fffffff,%eax /* and 31 bits here */ - setne %bh - orw %bx,%bx /* Any of the 63 bit set ? */ - setne %al - movl %edx,(%esi) - movl $0,4(%esi) - popl %ebx - popl %esi - leave - ret - -/* Shift by [0..31] bits */ -Ls_less_than_32: - movl (%esi),%ebx /* lsl */ - movl 4(%esi),%edx /* msl */ - xorl %eax,%eax /* extension */ - shrd %cl,%ebx,%eax - shrd %cl,%edx,%ebx - shr %cl,%edx - test $0x7fffffff,%eax /* only need to look at eax here */ - setne %al - movl %ebx,(%esi) - movl %edx,4(%esi) - popl %ebx - popl %esi - leave - ret - -/* Shift by [64..95] bits */ -Ls_more_than_63: - cmpl $96,%ecx - jnc Ls_more_than_95 - - subb $64,%cl - movl (%esi),%ebx /* lsl */ - movl 4(%esi),%eax /* msl */ - xorl %edx,%edx /* extension */ - shrd %cl,%ebx,%edx - shrd %cl,%eax,%ebx - shr %cl,%eax - orl %ebx,%edx - setne %bl - test $0x7fffffff,%eax /* only need to look at eax here */ - setne %bh - orw %bx,%bx - setne %al - xorl %edx,%edx - movl %edx,(%esi) /* set to zero */ - movl %edx,4(%esi) /* set to zero */ - popl %ebx - popl %esi - leave - ret - -Ls_more_than_95: -/* Shift by [96..inf) bits */ - xorl %eax,%eax - movl (%esi),%ebx - orl 4(%esi),%ebx - setne %al - xorl %ebx,%ebx - movl %ebx,(%esi) - movl %ebx,4(%esi) - popl %ebx - popl %esi - leave - ret diff --git a/sys/gnu/i386/fpemul/wm_sqrt.s b/sys/gnu/i386/fpemul/wm_sqrt.s deleted file mode 100644 index b1bc03b..0000000 --- a/sys/gnu/i386/fpemul/wm_sqrt.s +++ /dev/null @@ -1,496 +0,0 @@ - .file "wm_sqrt.S" -/* - * wm_sqrt.S - * - * Fixed point arithmetic square root evaluation. - * - * Call from C as: - * void wm_sqrt(FPU_REG *n, unsigned int control_word) - * - * - * Copyright (C) 1992,1993,1994 - * W. Metzenthen, 22 Parker St, Ormond, Vic 3163, - * Australia. E-mail billm@vaxc.cc.monash.edu.au - * All rights reserved. - * - * This copyright notice covers the redistribution and use of the - * FPU emulator developed by W. Metzenthen. It covers only its use - * in the 386BSD, FreeBSD and NetBSD operating systems. Any other - * use is not permitted under this copyright. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must include information specifying - * that source code for the emulator is freely available and include - * either: - * a) an offer to provide the source code for a nominal distribution - * fee, or - * b) list at least two alternative methods whereby the source - * can be obtained, e.g. a publically accessible bulletin board - * and an anonymous ftp site from which the software can be - * downloaded. - * 3. All advertising materials specifically mentioning features or use of - * this emulator must acknowledge that it was developed by W. Metzenthen. - * 4. The name of W. Metzenthen may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * W. METZENTHEN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * The purpose of this copyright, based upon the Berkeley copyright, is to - * ensure that the covered software remains freely available to everyone. - * - * The software (with necessary differences) is also available, but under - * the terms of the GNU copyleft, for the Linux operating system and for - * the djgpp ms-dos extender. - * - * W. Metzenthen June 1994. - * - * - * $Id: wm_sqrt.s,v 1.2 1994/04/29 21:34:30 gclarkii Exp $ - * - */ - - -/*---------------------------------------------------------------------------+ - | wm_sqrt(FPU_REG *n, unsigned int control_word) | - | returns the square root of n in n. | - | | - | Use Newton's method to compute the square root of a number, which must | - | be in the range [1.0 .. 4.0), to 64 bits accuracy. | - | Does not check the sign or tag of the argument. | - | Sets the exponent, but not the sign or tag of the result. | - | | - | The guess is kept in %esi:%edi | - +---------------------------------------------------------------------------*/ - -#include "exception.h" -#include "fpu_asm.h" - - -.data -/* - Local storage: - */ - .align 4,0 -accum_3: - .long 0 /* ms word */ -accum_2: - .long 0 -accum_1: - .long 0 -accum_0: - .long 0 - -/* The de-normalised argument: -// sq_2 sq_1 sq_0 -// b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0 -// ^ binary point here */ -fsqrt_arg_2: - .long 0 /* ms word */ -fsqrt_arg_1: - .long 0 -fsqrt_arg_0: - .long 0 /* ls word, at most the ms bit is set */ - -.text - .align 2,144 - -.globl _wm_sqrt - -_wm_sqrt: - pushl %ebp - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - - movl PARAM1,%esi - - movl SIGH(%esi),%eax - movl SIGL(%esi),%ecx - xorl %edx,%edx - -/* We use a rough linear estimate for the first guess.. */ - - cmpl EXP_BIAS,EXP(%esi) - jnz sqrt_arg_ge_2 - - shrl $1,%eax /* arg is in the range [1.0 .. 2.0) */ - rcrl $1,%ecx - rcrl $1,%edx - -sqrt_arg_ge_2: -/* From here on, n is never accessed directly again until it is -// replaced by the answer. */ - - movl %eax,fsqrt_arg_2 /* ms word of n */ - movl %ecx,fsqrt_arg_1 - movl %edx,fsqrt_arg_0 - -/* Make a linear first estimate */ - shrl $1,%eax - addl $0x40000000,%eax - movl $0xaaaaaaaa,%ecx - mull %ecx - shll %edx /* max result was 7fff... */ - testl $0x80000000,%edx /* but min was 3fff... */ - jnz sqrt_prelim_no_adjust - - movl $0x80000000,%edx /* round up */ - -sqrt_prelim_no_adjust: - movl %edx,%esi /* Our first guess */ - -/* We have now computed (approx) (2 + x) / 3, which forms the basis - for a few iterations of Newton's method */ - - movl fsqrt_arg_2,%ecx /* ms word */ - -/* From our initial estimate, three iterations are enough to get us -// to 30 bits or so. This will then allow two iterations at better -// precision to complete the process. - -// Compute (g + n/g)/2 at each iteration (g is the guess). */ - shrl %ecx /* Doing this first will prevent a divide */ - /* overflow later. */ - - movl %ecx,%edx /* msw of the arg / 2 */ - divl %esi /* current estimate */ - shrl %esi /* divide by 2 */ - addl %eax,%esi /* the new estimate */ - - movl %ecx,%edx - divl %esi - shrl %esi - addl %eax,%esi - - movl %ecx,%edx - divl %esi - shrl %esi - addl %eax,%esi - -/* Now that an estimate accurate to about 30 bits has been obtained (in %esi), -// we improve it to 60 bits or so. - -// The strategy from now on is to compute new estimates from -// guess := guess + (n - guess^2) / (2 * guess) */ - -/* First, find the square of the guess */ - movl %esi,%eax - mull %esi -/* guess^2 now in %edx:%eax */ - - movl fsqrt_arg_1,%ecx - subl %ecx,%eax - movl fsqrt_arg_2,%ecx /* ms word of normalized n */ - sbbl %ecx,%edx - jnc sqrt_stage_2_positive -/* subtraction gives a negative result -// negate the result before division */ - notl %edx - notl %eax - addl $1,%eax - adcl $0,%edx - - divl %esi - movl %eax,%ecx - - movl %edx,%eax - divl %esi - jmp sqrt_stage_2_finish - -sqrt_stage_2_positive: - divl %esi - movl %eax,%ecx - - movl %edx,%eax - divl %esi - - notl %ecx - notl %eax - addl $1,%eax - adcl $0,%ecx - -sqrt_stage_2_finish: - sarl $1,%ecx /* divide by 2 */ - rcrl $1,%eax - - /* Form the new estimate in %esi:%edi */ - movl %eax,%edi - addl %ecx,%esi - - jnz sqrt_stage_2_done /* result should be [1..2) */ - -#ifdef PARANOID -/* It should be possible to get here only if the arg is ffff....ffff*/ - cmp $0xffffffff,fsqrt_arg_1 - jnz sqrt_stage_2_error -#endif PARANOID - -/* The best rounded result.*/ - xorl %eax,%eax - decl %eax - movl %eax,%edi - movl %eax,%esi - movl $0x7fffffff,%eax - jmp sqrt_round_result - -#ifdef PARANOID -sqrt_stage_2_error: - pushl EX_INTERNAL|0x213 - call EXCEPTION -#endif PARANOID - -sqrt_stage_2_done: - -/* Now the square root has been computed to better than 60 bits */ - -/* Find the square of the guess*/ - movl %edi,%eax /* ls word of guess*/ - mull %edi - movl %edx,accum_1 - - movl %esi,%eax - mull %esi - movl %edx,accum_3 - movl %eax,accum_2 - - movl %edi,%eax - mull %esi - addl %eax,accum_1 - adcl %edx,accum_2 - adcl $0,accum_3 - -/* movl %esi,%eax*/ -/* mull %edi*/ - addl %eax,accum_1 - adcl %edx,accum_2 - adcl $0,accum_3 - -/* guess^2 now in accum_3:accum_2:accum_1*/ - - movl fsqrt_arg_0,%eax /* get normalized n*/ - subl %eax,accum_1 - movl fsqrt_arg_1,%eax - sbbl %eax,accum_2 - movl fsqrt_arg_2,%eax /* ms word of normalized n*/ - sbbl %eax,accum_3 - jnc sqrt_stage_3_positive - -/* subtraction gives a negative result*/ -/* negate the result before division */ - notl accum_1 - notl accum_2 - notl accum_3 - addl $1,accum_1 - adcl $0,accum_2 - -#ifdef PARANOID - adcl $0,accum_3 /* This must be zero */ - jz sqrt_stage_3_no_error - -sqrt_stage_3_error: - pushl EX_INTERNAL|0x207 - call EXCEPTION - -sqrt_stage_3_no_error: -#endif PARANOID - - movl accum_2,%edx - movl accum_1,%eax - divl %esi - movl %eax,%ecx - - movl %edx,%eax - divl %esi - - sarl $1,%ecx / divide by 2*/ - rcrl $1,%eax - - /* prepare to round the result*/ - - addl %ecx,%edi - adcl $0,%esi - - jmp sqrt_stage_3_finished - -sqrt_stage_3_positive: - movl accum_2,%edx - movl accum_1,%eax - divl %esi - movl %eax,%ecx - - movl %edx,%eax - divl %esi - - sarl $1,%ecx /* divide by 2*/ - rcrl $1,%eax - - /* prepare to round the result*/ - - notl %eax /* Negate the correction term*/ - notl %ecx - addl $1,%eax - adcl $0,%ecx /* carry here ==> correction == 0*/ - adcl $0xffffffff,%esi - - addl %ecx,%edi - adcl $0,%esi - -sqrt_stage_3_finished: - -/* The result in %esi:%edi:%esi should be good to about 90 bits here, -// and the rounding information here does not have sufficient accuracy -// in a few rare cases. */ - cmpl $0xffffffe0,%eax - ja sqrt_near_exact_x - - cmpl $0x00000020,%eax - jb sqrt_near_exact - - cmpl $0x7fffffe0,%eax - jb sqrt_round_result - - cmpl $0x80000020,%eax - jb sqrt_get_more_precision - -sqrt_round_result: -/* Set up for rounding operations*/ - movl %eax,%edx - movl %esi,%eax - movl %edi,%ebx - movl PARAM1,%edi - movl EXP_BIAS,EXP(%edi) /* Result is in [1.0 .. 2.0)*/ - movl PARAM2,%ecx - jmp FPU_round_sqrt - - -sqrt_near_exact_x: -/* First, the estimate must be rounded up.*/ - addl $1,%edi - adcl $0,%esi - -sqrt_near_exact: -/* This is an easy case because x^1/2 is monotonic. -// We need just find the square of our estimate, compare it -// with the argument, and deduce whether our estimate is -// above, below, or exact. We use the fact that the estimate -// is known to be accurate to about 90 bits. */ - movl %edi,%eax /* ls word of guess*/ - mull %edi - movl %edx,%ebx /* 2nd ls word of square*/ - movl %eax,%ecx /* ls word of square*/ - - movl %edi,%eax - mull %esi - addl %eax,%ebx - addl %eax,%ebx - -#ifdef PARANOID - cmp $0xffffffb0,%ebx - jb sqrt_near_exact_ok - - cmp $0x00000050,%ebx - ja sqrt_near_exact_ok - - pushl EX_INTERNAL|0x214 - call EXCEPTION - -sqrt_near_exact_ok: -#endif PARANOID - - or %ebx,%ebx - js sqrt_near_exact_small - - jnz sqrt_near_exact_large - - or %ebx,%edx - jnz sqrt_near_exact_large - -/* Our estimate is exactly the right answer*/ - xorl %eax,%eax - jmp sqrt_round_result - -sqrt_near_exact_small: -/* Our estimate is too small*/ - movl $0x000000ff,%eax - jmp sqrt_round_result - -sqrt_near_exact_large: -/* Our estimate is too large, we need to decrement it*/ - subl $1,%edi - sbbl $0,%esi - movl $0xffffff00,%eax - jmp sqrt_round_result - - -sqrt_get_more_precision: -/* This case is almost the same as the above, except we start*/ -/* with an extra bit of precision in the estimate.*/ - stc /* The extra bit.*/ - rcll $1,%edi /* Shift the estimate left one bit*/ - rcll $1,%esi - - movl %edi,%eax /* ls word of guess*/ - mull %edi - movl %edx,%ebx /* 2nd ls word of square*/ - movl %eax,%ecx /* ls word of square*/ - - movl %edi,%eax - mull %esi - addl %eax,%ebx - addl %eax,%ebx - -/* Put our estimate back to its original value*/ - stc /* The ms bit.*/ - rcrl $1,%esi /* Shift the estimate left one bit*/ - rcrl $1,%edi - -#ifdef PARANOID - cmp $0xffffff60,%ebx - jb sqrt_more_prec_ok - - cmp $0x000000a0,%ebx - ja sqrt_more_prec_ok - - pushl EX_INTERNAL|0x215 - call EXCEPTION - -sqrt_more_prec_ok: -#endif PARANOID - - or %ebx,%ebx - js sqrt_more_prec_small - - jnz sqrt_more_prec_large - - or %ebx,%ecx - jnz sqrt_more_prec_large - -/* Our estimate is exactly the right answer*/ - movl $0x80000000,%eax - jmp sqrt_round_result - -sqrt_more_prec_small: -/* Our estimate is too small*/ - movl $0x800000ff,%eax - jmp sqrt_round_result - -sqrt_more_prec_large: -/* Our estimate is too large*/ - movl $0x7fffff00,%eax - jmp sqrt_round_result diff --git a/sys/gnu/i386/isa/dgb.c b/sys/gnu/i386/isa/dgb.c deleted file mode 100644 index 1e61971..0000000 --- a/sys/gnu/i386/isa/dgb.c +++ /dev/null @@ -1,1982 +0,0 @@ -/*- - * dgb.c $Id: dgb.c,v 1.4 1995/10/12 23:28:31 bde Exp $ - * - * Digiboard driver. - * - * Stage 1. "Better than nothing". - * - * Based on sio driver by Bruce Evans and on Linux driver by Troy - * De Jongh <troyd@digibd.com> or <troyd@skypoint.com> - * which is under GNU General Public License version 2 so this driver - * is forced to be under GPL 2 too. - * - * Written by Serge Babkin, - * Joint Stock Commercial Bank "Chelindbank" - * (Chelyabinsk, Russia) - * babkin@hq.icb.chel.su - */ - -#include "dgb.h" - -#if NDGB > 0 - -/* the overall number of ports controlled by this driver */ - -#ifndef NDGBPORTS -# define NDGBPORTS (NDGB*16) -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/reboot.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/proc.h> -#include <sys/user.h> -#include <sys/conf.h> -#include <sys/dkstat.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/syslog.h> -#include <sys/devconf.h> - -#include <machine/clock.h> - -#include <i386/isa/isa.h> -#include <i386/isa/isa_device.h> - -#include <gnu/i386/isa/dgbios.h> -#include <gnu/i386/isa/dgfep.h> -#include <gnu/i386/isa/dgreg.h> - -#define CALLOUT_MASK 0x80 -#define CONTROL_MASK 0x60 -#define CONTROL_INIT_STATE 0x20 -#define CONTROL_LOCK_STATE 0x40 -#define UNIT_MASK 0x30000 -#define PORT_MASK 0x1F -#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev))) -#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK) -#define MINOR_TO_UNIT(mynor) (((mynor) & UNIT_MASK)>>16) -#define MINOR_TO_PORT(mynor) ((mynor) & PORT_MASK) - -/* types. XXX - should be elsewhere */ -typedef u_char bool_t; /* boolean */ - -/* digiboard port structure */ -struct dgb_p { - bool_t status; - - u_char unit; /* board unit number */ - u_char pnum; /* port number */ - u_char omodem; /* FEP output modem status */ - u_char imodem; /* FEP input modem status */ - u_char modemfake; /* Modem values to be forced */ - u_char modem; /* Force values */ - u_char hflow; - u_char dsr; - u_char dcd; - u_char stopc; - u_char startc; - u_char stopca; - u_char startca; - u_char fepstopc; - u_char fepstartc; - u_char fepstopca; - u_char fepstartca; - u_char txwin; - u_char rxwin; - ushort fepiflag; - ushort fepcflag; - ushort fepoflag; - ushort txbufhead; - ushort txbufsize; - ushort rxbufhead; - ushort rxbufsize; - int close_delay; - int count; - int blocked_open; - int event; - int asyncflags; - u_long statusflags; - u_char *txptr; - u_char *rxptr; - struct board_chan *brdchan; - struct tty *tty; - - bool_t active_out; /* nonzero if the callout device is open */ - u_int wopeners; /* # processes waiting for DCD in open() */ - - /* Initial state. */ - struct termios it_in; /* should be in struct tty */ - struct termios it_out; - - /* Lock state. */ - struct termios lt_in; /* should be in struct tty */ - struct termios lt_out; - - /* flags of state, are used in sleep() too */ - u_char closing; /* port is being closed now */ - u_char draining; /* port is being drained now */ - u_char used; /* port is being used now */ - u_char mustdrain; /* data must be waited to drain in dgbparam() */ -}; - -/* Digiboard per-board structure */ -struct dgb_softc { - /* struct board_info */ - u_char status; /* status: DISABLED/ENABLED */ - u_char unit; /* unit number */ - u_char type; /* type of card: PCXE, PCXI, PCXEVE */ - u_char altpin; /* do we need alternate pin setting ? */ - ushort numports; /* number of ports on card */ - ushort port; /* I/O port */ - u_char *vmem; /* virtual memory address */ - long pmem; /* physical memory address */ - int mem_seg; /* internal memory segment */ - struct dgb_p *ports; /* pointer to array of port descriptors */ - struct tty *ttys; /* pointer to array of TTY structures */ - volatile struct global_data *mailbox; - }; - - -struct dgb_softc dgb_softc[NDGB]; -struct dgb_p dgb_ports[NDGBPORTS]; -struct tty dgb_tty[NDGBPORTS]; - -/* - * The public functions in the com module ought to be declared in a com-driver - * system header. - */ - -/* Interrupt handling entry points. */ -void dgbintr __P((int unit)); -void dgbpoll __P((void *unit_c)); - -/* Device switch entry points. */ -#define dgbreset noreset -#define dgbmmap nommap -#define dgbstrategy nostrategy - -static int dgbattach __P((struct isa_device *dev)); -static int dgbprobe __P((struct isa_device *dev)); -static void dgbregisterdev __P((struct isa_device *id)); - -static void fepcmd(struct dgb_p *port, int cmd, int op1, int op2, - int ncmds, int bytecmd); - -static void dgbstart __P((struct tty *tp)); -static int dgbparam __P((struct tty *tp, struct termios *t)); -static void dgbhardclose __P((struct dgb_p *port)); -static void dgb_drain_or_flush __P((struct dgb_p *port)); -static int dgbdrain __P((struct dgb_p *port)); -static void dgb_pause __P((void *chan)); -static void wakeflush __P((void *p)); - - -struct isa_driver dgbdriver = { - dgbprobe, dgbattach, "dgb",0 -}; - -static speed_t dgbdefaultrate = TTYDEF_SPEED; -static u_int dgb_events; /* input chars + weighted output completions */ -static int dgbmajor; - -static struct speedtab dgbspeedtab[] = { - 0, 0, /* old (sysV-like) Bx codes */ - 50, 1, - 75, 2, - 110, 3, - 134, 4, - 150, 5, - 200, 6, - 300, 7, - 600, 8, - 1200, 9, - 1800, 10, - 2400, 11, - 4800, 12, - 9600, 13, - 19200, 14, - 38400, 15, - 57600, (02000 | 1), /* B50 & fast baud table */ - 115200, (02000 | 2), /* B100 & fast baud table */ - -1, -1 -}; - -#ifdef DEBUG - int dgbdebug=1; -#else - int dgbdebug=0; -#endif - -static int polltimeout=0; - -static int setwin __P((struct dgb_softc *sc, unsigned addr)); -static int setinitwin __P((struct dgb_softc *sc, unsigned addr)); -static void hidewin __P((struct dgb_softc *sc)); -static void towin __P((struct dgb_softc *sc, int win)); - -static inline int -setwin(sc,addr) - struct dgb_softc *sc; - unsigned int addr; -{ - if(sc->type==PCXEVE) { - outb(sc->port+1, FEPWIN|(addr>>13)); - DPRINT3("dgb%d: switched to window 0x%x\n",sc->unit,addr>>13); - return (addr & 0x1FFF); - } else { - outb(sc->port,FEPMEM); - return addr; - } -} - -static inline int -setinitwin(sc,addr) - struct dgb_softc *sc; - unsigned int addr; -{ - if(sc->type==PCXEVE) { - outb(sc->port+1, FEPWIN|(addr>>13)); - DPRINT3("dgb%d: switched to window 0x%x\n",sc->unit,addr>>13); - return (addr & 0x1FFF); - } else { - outb(sc->port,inb(sc->port)|FEPMEM); - return addr; - } -} - -static inline void -hidewin(sc) - struct dgb_softc *sc; -{ - if(sc->type==PCXEVE) - outb(sc->port+1, 0); - else - outb(sc->port,0); -} - -static inline void -towin(sc,win) - struct dgb_softc *sc; - int win; -{ - if(sc->type==PCXEVE) { - outb(sc->port+1, win); - } else { - outb(sc->port,FEPMEM); - } -} - -static int -dgbprobe(dev) - struct isa_device *dev; -{ - struct dgb_softc *sc= &dgb_softc[dev->id_unit]; - int i, v, t; - u_long win_size; /* size of vizible memory window */ - u_char *mem; - int addr; - int unit=dev->id_unit; - - sc->unit=dev->id_unit; - sc->port=dev->id_iobase; - - if(dev->id_flags & DGBFLAG_ALTPIN) - sc->altpin=1; - else - sc->altpin=0; - - /* left 24 bits only (ISA address) */ - sc->pmem=((long)dev->id_maddr & 0xFFFFFF); - - DPRINT4("dgb%d: port 0x%x mem 0x%x\n",unit,sc->port,sc->pmem); - - outb(sc->port, FEPRST); - sc->status=DISABLED; - - for(i=0; i< 1000; i++) { - DELAY(1); - if( (inb(sc->port) & FEPMASK) == FEPRST ) { - sc->status=ENABLED; - DPRINT3("dgb%d: got reset after %d us\n",unit,i); - break; - } - } - - if(sc->status!=ENABLED) { - DPRINT2("dgb%d: failed to respond\n",dev->id_unit); - return 0; - } - - /* check type of card and get internal memory characteristics */ - - v=inb(sc->port); - - if( v & 0x1 ) { - switch( v&0x30 ) { - case 0: - sc->mem_seg=0xF000; - win_size=0x10000; - printf("dgb%d: PC/Xi 64K\n",dev->id_unit); - break; - case 0x10: - sc->mem_seg=0xE000; - win_size=0x20000; - printf("dgb%d: PC/Xi 128K\n",dev->id_unit); - break; - case 0x20: - sc->mem_seg=0xC000; - win_size=0x40000; - printf("dgb%d: PC/Xi 256K\n",dev->id_unit); - break; - default: /* case 0x30: */ - sc->mem_seg=0x8000; - win_size=0x80000; - printf("dgb%d: PC/Xi 512K\n",dev->id_unit); - break; - } - sc->type=PCXI; - } else { - outb(sc->port, 1); - v=inb(sc->port); - - if( v & 0x1 ) { - printf("dgb%d: PC/Xm isn't supported\n",dev->id_unit); - sc->status=DISABLED; - return 0; - } - - sc->mem_seg=0xF000; - - if(dev->id_flags==DGBFLAG_NOWIN || ( v&0xC0 )==0) { - win_size=0x10000; - printf("dgb%d: PC/Xe 64K\n",dev->id_unit); - sc->type=PCXE; - } else { - win_size=0x2000; - printf("dgb%d: PC/Xe 64/8K (windowed)\n",dev->id_unit); - sc->type=PCXEVE; - if((u_long)sc->pmem & ~0xFFE000) { - printf("dgb%d: warning: address 0x%x truncated to 0x%x\n", - dev->id_unit, sc->pmem, - (long)sc->pmem & 0xFFE000); - - dev->id_maddr= (u_char *)( (long)sc->pmem & 0xFFE000 ); - } - } - } - - /* save size of vizible memory segment */ - dev->id_msize=win_size; - - /* map memory */ - dev->id_maddr=sc->vmem=pmap_mapdev(sc->pmem,dev->id_msize); - - outb(sc->port, FEPCLR); /* drop RESET */ - - return 4; /* we need I/O space of 4 ports */ -} - -static struct kern_devconf kdc_dgb[NDGB] = { { - 0, 0, 0, /* filled in by dev_attach */ - "dgb", 0, { MDDT_ISA, 0, "tty" }, - isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, - &kdc_isa0, /* parent */ - 0, /* parentdata */ - DC_UNCONFIGURED, - "DigiBoard multiport card" -} }; - -static void -dgbregisterdev(id) - struct isa_device *id; -{ - int unit; - - unit = id->id_unit; - if (unit != 0) - kdc_dgb[unit] = kdc_dgb[0]; - kdc_dgb[unit].kdc_unit = unit; - kdc_dgb[unit].kdc_isa = id; - - /* now we assume that multiport is always 'open' for simplicity */ - kdc_dgb[unit].kdc_state = DC_BUSY; - dev_attach(&kdc_dgb[unit]); -} - - -static int -dgbattach(dev) - struct isa_device *dev; -{ - int unit=dev->id_unit; - struct dgb_softc *sc= &dgb_softc[dev->id_unit]; - int i, t; - u_char *mem; - u_char *ptr; - int addr; - struct dgb_p *port; - struct board_chan *bc; - struct global_data *gd; - int shrinkmem; - int nfails; - ushort *pstat; - int lowwater; - int nports=0; - - if(sc->status!=ENABLED) { - DPRINT2("dbg%d: try to attach a disabled card\n",unit); - return 0; - } - - mem=sc->vmem; - - DPRINT3("dgb%d: internal memory segment 0x%x\n",unit,sc->mem_seg); - - outb(sc->port, FEPRST); DELAY(1); - - for(i=0; (inb(sc->port) & FEPMASK) != FEPRST ; i++) { - if(i>10000) { - printf("dgb%d: 1st reset failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - DELAY(1); - } - - DPRINT3("dgb%d: got reset after %d us\n",unit,i); - - /* for PCXEVE set up interrupt and base address */ - - if(sc->type==PCXEVE) { - t=(((u_long)sc->pmem>>8) & 0xFFE0) | 0x10 /* enable windowing */; - - /* IRQ isn't used */ -#if 0 - switch(dev->id_irq) { - case IRQ3: - t|=0x1; - break; - case IRQ5: - t|=2; - break; - case IRQ7: - t|=3; - break; - case IRQ10: - t|=4; - break; - case IRQ11: - t|=5; - break; - case IRQ12: - t|=6; - break; - case IRQ15: - t|=7; - break; - default: - printf("dgb%d: wrong IRQ mask 0x%x\n",dev->id_unit,dev->id_irq); - sc->status=DISABLED; - return 0; - } -#endif - - outb(sc->port+2,t & 0xFF); - outb(sc->port+3,t>>8); - } else if(sc->type==PCXE) { - t=(((u_long)sc->pmem>>8) & 0xFFE0) /* disable windowing */; - outb(sc->port+2,t & 0xFF); - outb(sc->port+3,t>>8); - } - - - if(sc->type==PCXI || sc->type==PCXE) { - outb(sc->port, FEPRST|FEPMEM); DELAY(1); - - for(i=0; (inb(sc->port) & FEPMASK) != (FEPRST|FEPMEM) ; i++) { - if(i>10000) { - printf("dgb%d: 2nd reset failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - DELAY(1); - } - - DPRINT3("dgb%d: got memory after %d us\n",unit,i); - } - - mem=sc->vmem; - - /* very short memory test */ - - addr=setinitwin(sc,BOTWIN); - *(u_long *)(mem+addr) = 0xA55A3CC3; - if(*(u_long *)(mem+addr)!=0xA55A3CC3) { - printf("dgb%d: 1st memory test failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - - addr=setinitwin(sc,TOPWIN); - *(u_long *)(mem+addr) = 0x5AA5C33C; - if(*(u_long *)(mem+addr)!=0x5AA5C33C) { - printf("dgb%d: 2nd memory test failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - - addr=setinitwin(sc,BIOSCODE+((0xF000-sc->mem_seg)<<4)); - *(u_long *)(mem+addr) = 0x5AA5C33C; - if(*(u_long *)(mem+addr)!=0x5AA5C33C) { - printf("dgb%d: 3rd (BIOS) memory test failed\n",dev->id_unit); - } - - addr=setinitwin(sc,MISCGLOBAL); - for(i=0; i<16; i++) { - mem[addr+i]=0; - } - - if(sc->type==PCXI || sc->type==PCXE) { - - addr=BIOSCODE+((0xF000-sc->mem_seg)<<4); - - DPRINT3("dgb%d: BIOS local address=0x%x\n",unit,addr); - - ptr= mem+addr; - - for(i=0; i<pcxx_nbios; i++, ptr++) - *ptr = pcxx_bios[i]; - - ptr= mem+addr; - - nfails=0; - for(i=0; i<pcxx_nbios; i++, ptr++) - if( *ptr != pcxx_bios[i] ) { - DPRINT5("dgb%d: wrong code in BIOS at addr 0x%x : \ -0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] ); - - if(++nfails>=5) { - printf("dgb%d: 4th memory test (BIOS load) fails\n",unit); - break; - } - } - - outb(sc->port,FEPMEM); - - for(i=0; (inb(sc->port) & FEPMASK) != FEPMEM ; i++) { - if(i>10000) { - printf("dgb%d: BIOS start failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - DELAY(1); - } - - DPRINT3("dgb%d: reset dropped after %d us\n",unit,i); - - for(i=0; i<200000; i++) { - if( *((ushort *)(mem+MISCGLOBAL)) == *((ushort *)"GD") ) - goto load_fep; - DELAY(1); - } - printf("dgb%d: BIOS download failed\n",dev->id_unit); - DPRINT4("dgb%d: code=0x%x must be 0x%x\n", - dev->id_unit, - *((ushort *)(mem+MISCGLOBAL)), - *((ushort *)"GD")); - - sc->status=DISABLED; - hidewin(sc); - return 0; - } - - if(sc->type==PCXEVE) { - /* set window 7 */ - outb(sc->port+1,0xFF); - - ptr= mem+(BIOSCODE & 0x1FFF); - - for(i=0; i<pcxx_nbios; i++) - *ptr++ = pcxx_bios[i]; - - ptr= mem+(BIOSCODE & 0x1FFF); - - nfails=0; - for(i=0; i<pcxx_nbios; i++, ptr++) - if( *ptr != pcxx_bios[i] ) { - DPRINT5("dgb%d: wrong code in BIOS at addr 0x%x : \ -0x%x instead of 0x%x\n", unit, ptr-(mem+addr), *ptr, pcxx_bios[i] ); - - if(++nfails>=5) { - printf("dgb%d: 4th memory test (BIOS load) fails\n",unit); - break; - } - } - - outb(sc->port,FEPCLR); - - setwin(sc,0); - - for(i=0; (inb(sc->port) & FEPMASK) != FEPCLR ; i++) { - if(i>10000) { - printf("dgb%d: BIOS start failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - DELAY(1); - } - - DPRINT3("dgb%d: reset dropped after %d us\n",unit,i); - - addr=setwin(sc,MISCGLOBAL); - - for(i=0; i<200000; i++) { - if(*(ushort *)(mem+addr)== *(ushort *)"GD") - goto load_fep; - DELAY(1); - } - printf("dgb%d: BIOS download failed\n",dev->id_unit); - DPRINT5("dgb%d: Error#(0x%x,0x%x) code=0x%x\n", - dev->id_unit, - *(ushort *)(mem+0xC12), - *(ushort *)(mem+0xC14), - *(ushort *)(mem+MISCGLOBAL)); - - sc->status=DISABLED; - hidewin(sc); - return 0; - } - -load_fep: - DPRINT2("dgb%d: BIOS loaded\n",dev->id_unit); - - addr=setwin(sc,FEPCODE); - - ptr= mem+addr; - - for(i=0; i<pcxx_ncook; i++) - *ptr++ = pcxx_cook[i]; - - addr=setwin(sc,MBOX); - *(ushort *)(mem+addr+ 0)=2; - *(ushort *)(mem+addr+ 2)=sc->mem_seg+FEPCODESEG; - *(ushort *)(mem+addr+ 4)=0; - *(ushort *)(mem+addr+ 6)=FEPCODESEG; - *(ushort *)(mem+addr+ 8)=0; - *(ushort *)(mem+addr+10)=pcxx_ncook; - - outb(sc->port,FEPMEM|FEPINT); /* send interrupt to BIOS */ - outb(sc->port,FEPMEM); - - for(i=0; *(ushort *)(mem+addr)!=0; i++) { - if(i>200000) { - printf("dgb%d: FEP code download failed\n",unit); - DPRINT3("dgb%d: code=0x%x must be 0\n", unit, - *(ushort *)(mem+addr)); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - } - - DPRINT2("dgb%d: FEP code loaded\n",unit); - - *(ushort *)(mem+setwin(sc,FEPSTAT))=0; - addr=setwin(sc,MBOX); - *(ushort *)(mem+addr+0)=1; - *(ushort *)(mem+addr+2)=FEPCODESEG; - *(ushort *)(mem+addr+4)=0x4; - - outb(sc->port,FEPINT); /* send interrupt to BIOS */ - outb(sc->port,FEPCLR); - - addr=setwin(sc,FEPSTAT); - for(i=0; *(ushort *)(mem+addr)!= *(ushort *)"OS"; i++) { - if(i>200000) { - printf("dgb%d: FEP/OS start failed\n",dev->id_unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - } - - DPRINT2("dgb%d: FEP/OS started\n",dev->id_unit); - - sc->numports= *(ushort *)(mem+setwin(sc,NPORT)); - - printf("dgb%d: %d ports\n",unit,sc->numports); - - if(sc->numports > MAX_DGB_PORTS) { - printf("dgb%d: too many ports\n",unit); - sc->status=DISABLED; - hidewin(sc); - return 0; - } - - if(nports+sc->numports>NDGBPORTS) { - printf("dgb%d: only %d ports are usable\n", unit, NDGBPORTS-nports); - sc->numports=NDGBPORTS-nports; - } - - /* allocate port and tty structures */ - sc->ports=&dgb_ports[nports]; - sc->ttys=&dgb_tty[nports]; - nports+=sc->numports; - - addr=setwin(sc,PORTBASE); - pstat=(ushort *)(mem+addr); - - for(i=0; i<sc->numports && pstat[i]; i++) - if(pstat[i]) - sc->ports[i].status=ENABLED; - else { - sc->ports[i].status=DISABLED; - printf("dgb%d: port %d is broken\n", unit, i); - } - - /* We should now init per-port structures */ - bc=(struct board_chan *)(mem + CHANSTRUCT); - sc->mailbox=(struct global_data *)(mem + FEP_GLOBAL); - - if(sc->numports<3) - shrinkmem=1; - else - shrinkmem=0; - - for(i=0; i<sc->numports; i++, bc++) { - port= &sc->ports[i]; - - port->tty=&sc->ttys[i]; - port->unit=unit; - - port->brdchan=bc; - - if(sc->altpin) { - port->dsr=CD; - port->dcd=DSR; - } else { - port->dcd=CD; - port->dsr=DSR; - } - - port->pnum=i; - - if(shrinkmem) { - DPRINT2("dgb%d: shrinking memory\n",unit); - fepcmd(port, SETBUFFER, 32, 0, 0, 0); - shrinkmem=0; - } - - if(sc->type!=PCXEVE) { - port->txptr=mem+((bc->tseg-sc->mem_seg)<<4); - port->rxptr=mem+((bc->rseg-sc->mem_seg)<<4); - port->txwin=port->rxwin=0; - } else { - port->txptr=mem+( ((bc->tseg-sc->mem_seg)<<4) & 0x1FFF ); - port->rxptr=mem+( ((bc->rseg-sc->mem_seg)<<4) & 0x1FFF ); - port->txwin=FEPWIN | ((bc->tseg-sc->mem_seg)>>9); - port->rxwin=FEPWIN | ((bc->rseg-sc->mem_seg)>>9); - } - - port->txbufhead=0; - port->rxbufhead=0; - port->txbufsize=bc->tmax+1; - port->rxbufsize=bc->rmax+1; - - lowwater= (port->txbufsize>=2000) ? 1024 : (port->txbufsize/2); - fepcmd(port, STXLWATER, lowwater, 0, 10, 0); - fepcmd(port, SRXLWATER, port->rxbufsize/4, 0, 10, 0); - fepcmd(port, SRXHWATER, 3*port->rxbufsize/4, 0, 10, 0); - - bc->edelay=100; - bc->idata=1; - - port->startc=bc->startc; - port->startca=bc->startca; - port->stopc=bc->stopc; - port->stopca=bc->stopca; - - port->close_delay=50; - - /* - * We don't use all the flags from <sys/ttydefaults.h> since they - * are only relevant for logins. It's important to have echo off - * initially so that the line doesn't start blathering before the - * echo flag can be turned off. - */ - port->it_in.c_iflag = TTYDEF_IFLAG; - port->it_in.c_oflag = TTYDEF_OFLAG; - port->it_in.c_cflag = TTYDEF_CFLAG; - port->it_in.c_lflag = TTYDEF_LFLAG; - termioschars(&port->it_in); - port->it_in.c_ispeed = port->it_in.c_ospeed = dgbdefaultrate; - port->it_out = port->it_in; - } - - hidewin(sc); - - /* register the polling function */ - timeout(dgbpoll, (void *)unit, hz/25); - - return 1; -} - -/* ARGSUSED */ -int -dgbopen(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - struct dgb_softc *sc; - struct tty *tp; - int unit; - int mynor; - int pnum; - struct dgb_p *port; - int s; - int error; - struct board_chan *bc; - - error=0; - - mynor=minor(dev); - unit=MINOR_TO_UNIT(mynor); - pnum=MINOR_TO_PORT(mynor); - - if(unit >= NDGB) { - DPRINT2("dgb%d: try to open a nonexisting card\n",unit); - return ENXIO; - } - - sc=&dgb_softc[unit]; - - if(sc->status!=ENABLED) { - DPRINT2("dgb%d: try to open a disabled card\n",unit); - return ENXIO; - } - - if(pnum>=sc->numports) { - DPRINT3("dgb%d: try to open non-existing port %d\n",unit,pnum); - return ENXIO; - } - - if(mynor & CONTROL_MASK) - return 0; - - tp=&sc->ttys[pnum]; - port=&sc->ports[pnum]; - bc=port->brdchan; - -open_top: - - s=spltty(); - - while(port->closing) { - error=tsleep(&port->closing, TTOPRI|PCATCH, "dgocl", 0); - - if(error) { - DPRINT4("dgb%d: port %d: tsleep(dgocl) error=%d\n",unit,pnum,error); - goto out; - } - } - - if (tp->t_state & TS_ISOPEN) { - /* - * The device is open, so everything has been initialized. - * Handle conflicts. - */ - if (mynor & CALLOUT_MASK) { - if (!port->active_out) { - error = EBUSY; - DPRINT4("dgb%d: port %d: BUSY error=%d\n",unit,pnum,error); - goto out; - } - } else { - if (port->active_out) { - if (flag & O_NONBLOCK) { - error = EBUSY; - DPRINT4("dgb%d: port %d: BUSY error=%d\n",unit,pnum,error); - goto out; - } - error = tsleep(&port->active_out, - TTIPRI | PCATCH, "dgbi", 0); - if (error != 0) { - DPRINT4("dgb%d: port %d: tsleep(dgbi) error=%d\n", - unit,pnum,error); - goto out; - } - splx(s); - goto open_top; - } - } - if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { - error = EBUSY; - goto out; - } - } else { - /* - * The device isn't open, so there are no conflicts. - * Initialize it. Initialization is done twice in many - * cases: to preempt sleeping callin opens if we are - * callout, and to complete a callin open after DCD rises. - */ - tp->t_oproc=dgbstart; - tp->t_param=dgbparam; - tp->t_dev=dev; - tp->t_termios= (mynor & CALLOUT_MASK) ? - port->it_out : - port->it_in; - - setwin(sc,0); - port->imodem=bc->mstat; - bc->rout=bc->rin; /* clear input queue */ - bc->idata=1; - - hidewin(sc); - - port->wopeners++; - error=dgbparam(tp, &tp->t_termios); - port->wopeners--; - - if(error!=0) { - DPRINT4("dgb%d: port %d: dgbparam error=%d\n",unit,pnum,error); - goto out; - } - - ttsetwater(tp); - - /* handle fake DCD for callout devices */ - /* and initial DCD */ - - if( (port->imodem & port->dcd) || mynor & CALLOUT_MASK ) - linesw[tp->t_line].l_modem(tp,1); - - } - - /* - * Wait for DCD if necessary. - */ - if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK) - && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) { - ++port->wopeners; - error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "dgdcd", 0); - --port->wopeners; - if (error != 0) { - DPRINT4("dgb%d: port %d: tsleep(dgdcd) error=%d\n",unit,pnum,error); - goto out; - } - splx(s); - goto open_top; - } - error = linesw[tp->t_line].l_open(dev, tp); - DPRINT4("dgb%d: port %d: l_open error=%d\n",unit,pnum,error); - - if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK) - port->active_out = TRUE; - - port->used=1; - -out: - splx(s); - - if( !(tp->t_state & TS_ISOPEN) && port->wopeners==0 ) - dgbhardclose(port); - - DPRINT4("dgb%d: port %d: open() returns %d\n",unit,pnum,error); - - return error; -} - -/*ARGSUSED*/ -int -dgbclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - int mynor; - struct tty *tp; - int unit, pnum; - struct dgb_softc *sc; - struct dgb_p *port; - int s; - - mynor=minor(dev); - unit=MINOR_TO_UNIT(mynor); - pnum=MINOR_TO_PORT(mynor); - - sc=&dgb_softc[unit]; - tp=&sc->ttys[pnum]; - port=sc->ports+pnum; - - if(mynor & CONTROL_MASK) - return 0; - - DPRINT3("dgb%d: port %d: closing\n",unit,pnum); - - s=spltty(); - - port->closing=1; - linesw[tp->t_line].l_close(tp,flag); - dgb_drain_or_flush(port); - dgbhardclose(port); - ttyclose(tp); - port->closing=0; wakeup(&port->closing); - port->used=0; - - splx(s); - - wakeup(TSA_CARR_ON(tp)); - wakeup(&port->active_out); - port->active_out=0; - - return 0; -} - -static void -dgbhardclose(port) - struct dgb_p *port; -{ - struct dgb_softc *sc=&dgb_softc[port->unit]; - struct board_chan *bc=port->brdchan; - int s; - - setwin(sc,0); - - bc->idata=0; bc->iempty=0; bc->ilow=0; - if(port->tty->t_cflag & HUPCL) { - port->omodem &= ~(RTS|DTR); - fepcmd(port, SETMODEM, 0, DTR|RTS, 0, 1); - } - - hidewin(sc); - - timeout(dgb_pause, &port->brdchan, hz/2); - tsleep(&port->brdchan, TTIPRI | PCATCH, "dgclo", 0); -} - -static void -dgb_pause(chan) - void *chan; -{ -wakeup((caddr_t)chan); -} - - -int -dgbread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - int mynor; - struct tty *tp; - int error, unit, pnum; - - mynor=minor(dev); - if (mynor & CONTROL_MASK) - return (ENODEV); - unit=MINOR_TO_UNIT(mynor); - pnum=MINOR_TO_PORT(mynor); - - tp=&dgb_softc[unit].ttys[pnum]; - - error=linesw[tp->t_line].l_read(tp, uio, flag); - DPRINT4("dgb%d: port %d: read() returns %d\n",unit,pnum,error); - - return error; -} - -int -dgbwrite(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - int mynor; - struct tty *tp; - int error, unit, pnum; - - mynor=minor(dev); - if (mynor & CONTROL_MASK) - return (ENODEV); - - unit=MINOR_TO_UNIT(mynor); - pnum=MINOR_TO_PORT(mynor); - - tp=&dgb_softc[unit].ttys[pnum]; - - error=linesw[tp->t_line].l_write(tp, uio, flag); - DPRINT4("dgb%d: port %d: write() returns %d\n",unit,pnum,error); - - return error; -} - -void dgbpoll(unit_c) - void *unit_c; -{ - int unit=(int)unit_c; - int pnum; - struct dgb_p *port; - struct dgb_softc *sc=&dgb_softc[unit]; - int head, tail; - u_char *eventbuf; - int event, mstat, lstat; - struct board_chan *bc; - struct tty *tp; - int rhead, rtail; - int whead, wtail; - int wrapmask; - int size; - int c=0; - u_char *ptr; - int ocount; - - if(sc->status==DISABLED) { - printf("dgb%d: polling of disabled board stopped\n",unit); - return; - } - - setwin(sc,0); - - head=sc->mailbox->ein; - tail=sc->mailbox->eout; - - while(head!=tail) { - if(head >= FEP_IMAX-FEP_ISTART - || tail >= FEP_IMAX-FEP_ISTART - || (head|tail) & 03 ) { - printf("dgb%d: event queue's head or tail is wrong!\n", unit); - break; - } - - eventbuf=sc->vmem+tail+FEP_ISTART; - pnum=eventbuf[0]; - event=eventbuf[1]; - mstat=eventbuf[2]; - lstat=eventbuf[3]; - - port=&sc->ports[pnum]; - bc=port->brdchan; - tp=&sc->ttys[pnum]; - - if(pnum>=sc->numports || port->status==DISABLED) { - printf("dgb%d: port %d: got event on nonexisting port\n",unit,pnum); - } else if(port->used || port->wopeners>0 ) { - - if( !(event & ALL_IND) ) - printf("dgb%d: port%d: ? event 0x%x mstat 0x%x lstat 0x%x\n", - unit, pnum, event, mstat, lstat); - - if(event & DATA_IND) { - DPRINT3("dgb%d: port %d: DATA_IND\n",unit,pnum); - - wrapmask=port->rxbufsize-1; - - rhead=bc->rin & wrapmask; - rtail=bc->rout & wrapmask; - - if( !(tp->t_cflag & CREAD) || !port->used ) { - bc->rout=rhead; - goto end_of_data; - } - - if(bc->orun) { - printf("dgb%d: port%d: overrun\n", unit, pnum); - bc->orun=0; - } - - while(rhead!=rtail) { - DPRINT5("dgb%d: port %d: p rx head=%d tail=%d\n", - unit,pnum,rhead,rtail); - - if(rhead>rtail) - size=rhead-rtail; - else - size=port->rxbufsize-rtail; - - ptr=port->rxptr+rtail; - - for(c=0; c<size; c++) { - int chr; - - towin(sc,port->rxwin); - chr= *ptr++; - -#if 0 - if(chr>=' ' && chr<127) - DPRINT4("dgb%d: port %d: got char '%c'\n", - unit,pnum,chr); - else - DPRINT4("dgb%d: port %d: got char 0x%x\n", - unit,pnum,chr); -#endif - - hidewin(sc); - linesw[tp->t_line].l_rint(chr, tp); - } - - setwin(sc,0); - rtail= (rtail + size) & wrapmask; - bc->rout=rtail; - rhead=bc->rin & wrapmask; - } - - end_of_data: - } - - if(event & MODEMCHG_IND) { - DPRINT3("dgb%d: port %d: MODEMCHG_IND\n",unit,pnum); - port->imodem=mstat; - if(mstat & port->dcd) { - hidewin(sc); - linesw[tp->t_line].l_modem(tp,1); - setwin(sc,0); - wakeup(TSA_CARR_ON(tp)); - } else { - hidewin(sc); - linesw[tp->t_line].l_modem(tp,0); - setwin(sc,0); - if( port->draining) { - port->draining=0; - wakeup(&port->draining); - } - } - } - - if(event & BREAK_IND) { - DPRINT3("dgb%d: port %d: BREAK_IND\n",unit,pnum); - hidewin(sc); - linesw[tp->t_line].l_rint(TTY_BI, tp); - setwin(sc,0); - } - - if(event & (LOWTX_IND | EMPTYTX_IND) ) { - DPRINT3("dgb%d: port %d: LOWTX_IND or EMPTYTX_IND\n",unit,pnum); - - if( (event & EMPTYTX_IND ) && tp->t_outq.c_cc==0 - && port->draining) { - port->draining=0; - wakeup(&port->draining); - bc->ilow=0; bc->iempty=0; - } - - wrapmask=port->txbufsize; - - while( tp->t_outq.c_cc!=0 ) { -#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */ - ttwwakeup(tp); -#else - if(tp->t_outq.c_cc <= tp->t_lowat) { - if(tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup(TSA_OLOWAT(tp)); - } - selwakeup(&tp->t_wsel); - } -#endif - setwin(sc,0); - - whead=bc->tin & wrapmask; - wtail=bc->tout & wrapmask; - - DPRINT5("dgb%d: port%d: p tx head=%d tail=%d\n", - unit,pnum,whead,wtail); - - if(whead<wtail) - size=wtail-whead-1; - else { - size=port->txbufsize-whead; - if(wtail==0) - size--; - } - - if(size==0) { - bc->iempty=1; bc->ilow=1; - goto end_of_buffer; - } - - towin(sc,port->txwin); - - ocount=q_to_b(&tp->t_outq, port->txptr+whead, size); - whead+=ocount; - - setwin(sc,0); - bc->tin=whead; - } -#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */ - ttwwakeup(tp); -#else - if(tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup(TSA_OLOWAT(tp)); - } - tp->t_state &= ~TS_BUSY; -#endif - end_of_buffer: - } - } else { - DPRINT4("dgb%d: port %d: got event 0x%x on closed port\n", - unit,pnum,event); - bc->rout=bc->rin; - bc->idata=bc->iempty=bc->ilow=0; - } - - bc->idata=1; - - tail= (tail+4) & (FEP_IMAX-FEP_ISTART-4); - } - - sc->mailbox->eout=tail; - hidewin(sc); - - timeout(dgbpoll, unit_c, hz/25); -} - -void -dgbintr(unit) - int unit; -{ -} - -int -dgbioctl(dev, cmd, data, flag, p) - dev_t dev; - int cmd; - caddr_t data; - int flag; - struct proc *p; -{ - struct dgb_softc *sc; - int unit, pnum; - struct dgb_p *port; - int mynor; - struct tty *tp; - struct board_chan *bc; - int error; - int s; - int tiocm_xxx; - - mynor=minor(dev); - unit=MINOR_TO_UNIT(mynor); - pnum=MINOR_TO_PORT(mynor); - - sc=&dgb_softc[unit]; - port=&sc->ports[pnum]; - tp=&sc->ttys[pnum]; - bc=port->brdchan; - - if (mynor & CONTROL_MASK) { - struct termios *ct; - - switch (mynor & CONTROL_MASK) { - case CONTROL_INIT_STATE: - ct = mynor & CALLOUT_MASK ? &port->it_out : &port->it_in; - break; - case CONTROL_LOCK_STATE: - ct = mynor & CALLOUT_MASK ? &port->lt_out : &port->lt_in; - break; - default: - return (ENODEV); /* /dev/nodev */ - } - switch (cmd) { - case TIOCSETA: - error = suser(p->p_ucred, &p->p_acflag); - if (error != 0) - return (error); - *ct = *(struct termios *)data; - return (0); - case TIOCGETA: - *(struct termios *)data = *ct; - return (0); - case TIOCGETD: - *(int *)data = TTYDISC; - return (0); - case TIOCGWINSZ: - bzero(data, sizeof(struct winsize)); - return (0); - default: - return (ENOTTY); - } - } - - if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) { - int cc; - struct termios *dt = (struct termios *)data; - struct termios *lt = mynor & CALLOUT_MASK - ? &port->lt_out : &port->lt_in; - - dt->c_iflag = (tp->t_iflag & lt->c_iflag) - | (dt->c_iflag & ~lt->c_iflag); - dt->c_oflag = (tp->t_oflag & lt->c_oflag) - | (dt->c_oflag & ~lt->c_oflag); - dt->c_cflag = (tp->t_cflag & lt->c_cflag) - | (dt->c_cflag & ~lt->c_cflag); - dt->c_lflag = (tp->t_lflag & lt->c_lflag) - | (dt->c_lflag & ~lt->c_lflag); - for (cc = 0; cc < NCCS; ++cc) - if (lt->c_cc[cc] != 0) - dt->c_cc[cc] = tp->t_cc[cc]; - if (lt->c_ispeed != 0) - dt->c_ispeed = tp->t_ispeed; - if (lt->c_ospeed != 0) - dt->c_ospeed = tp->t_ospeed; - } - - if(cmd==TIOCSTOP) { - setwin(sc,0); - fepcmd(port, PAUSETX, 0, 0, 0, 0); - hidewin(sc); - return 0; - } else if(cmd==TIOCSTART) { - setwin(sc,0); - fepcmd(port, RESUMETX, 0, 0, 0, 0); - hidewin(sc); - return 0; - } - - if(cmd==TIOCSETAW || cmd==TIOCSETAF) - port->mustdrain=1; - - error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p); - - if (error >= 0) - return error; - error = ttioctl(tp, cmd, data, flag); - - port->mustdrain=0; - - if (error >= 0) - return error; - s = spltty(); - switch (cmd) { - case TIOCSBRK: - error=dgbdrain(port); - - if(error!=0) { - splx(s); - return error; - } - - setwin(sc,0); - - /* now it sends 250 millisecond break because I don't know */ - /* how to send an infinite break */ - - fepcmd(port, SENDBREAK, 250, 0, 10, 0); - hidewin(sc); - break; - case TIOCCBRK: - /* now it's empty */ - break; - case TIOCSDTR: - DPRINT3("dgb%d: port %d: set DTR\n",unit,pnum); - port->omodem |= DTR; - setwin(sc,0); - fepcmd(port, SETMODEM, port->omodem, RTS, 0, 1); - - if( !(bc->mstat & DTR) ) { - DPRINT3("dgb%d: port %d: DTR is off\n",unit,pnum); - } - - hidewin(sc); - break; - case TIOCCDTR: - DPRINT3("dgb%d: port %d: reset DTR\n",unit,pnum); - port->omodem &= ~DTR; - setwin(sc,0); - fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1); - - if( bc->mstat & DTR ) { - DPRINT3("dgb%d: port %d: DTR is on\n",unit,pnum); - } - - hidewin(sc); - break; - case TIOCMSET: - if(*(int *)data & TIOCM_DTR) - port->omodem |=DTR; - else - port->omodem &=~DTR; - - if(*(int *)data & TIOCM_RTS) - port->omodem |=RTS; - else - port->omodem &=~RTS; - - setwin(sc,0); - fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1); - hidewin(sc); - break; - case TIOCMBIS: - if(*(int *)data & TIOCM_DTR) - port->omodem |=DTR; - - if(*(int *)data & TIOCM_RTS) - port->omodem |=RTS; - - setwin(sc,0); - fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1); - hidewin(sc); - break; - case TIOCMBIC: - if(*(int *)data & TIOCM_DTR) - port->omodem &=~DTR; - - if(*(int *)data & TIOCM_RTS) - port->omodem &=~RTS; - - setwin(sc,0); - fepcmd(port, SETMODEM, port->omodem, RTS|DTR, 0, 1); - hidewin(sc); - break; - case TIOCMGET: - setwin(sc,0); - port->imodem=bc->mstat; - hidewin(sc); - - tiocm_xxx = TIOCM_LE; /* XXX - always enabled while open */ - - DPRINT3("dgb%d: port %d: modem stat -- ",unit,pnum); - - if (port->imodem & DTR) { - DPRINT1("DTR "); - tiocm_xxx |= TIOCM_DTR; - } - if (port->imodem & RTS) { - DPRINT1("RTS "); - tiocm_xxx |= TIOCM_RTS; - } - if (port->imodem & CTS) { - DPRINT1("CTS "); - tiocm_xxx |= TIOCM_CTS; - } - if (port->imodem & port->dcd) { - DPRINT1("DCD "); - tiocm_xxx |= TIOCM_CD; - } - if (port->imodem & port->dsr) { - DPRINT1("DSR "); - tiocm_xxx |= TIOCM_DSR; - } - if (port->imodem & RI) { - DPRINT1("RI "); - tiocm_xxx |= TIOCM_RI; - } - *(int *)data = tiocm_xxx; - DPRINT1("--\n"); - break; - default: - splx(s); - return ENOTTY; - } - splx(s); - return 0; -} - -static void -wakeflush(p) - void *p; -{ - struct dgb_p *port=p; - - wakeup(&port->draining); -} - -/* wait for the output to drain */ - -static int -dgbdrain(port) - struct dgb_p *port; -{ - struct tty *tp=port->tty; - struct dgb_softc *sc=&dgb_softc[port->unit]; - struct board_chan *bc=port->brdchan; - int error; - int head, tail; - - setwin(sc,0); - - bc->iempty=1; - tail=bc->tout; - head=bc->tin; - - while(tail!=head) { - DPRINT5("dgb%d: port %d: drain: head=%d tail=%d\n", - port->unit, port->pnum, head, tail); - - hidewin(sc); - port->draining=1; - timeout(wakeflush,port, hz); - error=tsleep(&port->draining, TTIPRI | PCATCH, "dgdrn", 0); - port->draining=0; - setwin(sc,0); - - if (error != 0) { - DPRINT4("dgb%d: port %d: tsleep(dgdrn) error=%d\n", - port->unit,port->pnum,error); - - bc->iempty=0; - hidewin(sc); - return error; - } - - tail=bc->tout; - head=bc->tin; - } - DPRINT5("dgb%d: port %d: drain: head=%d tail=%d\n", - port->unit, port->pnum, head, tail); - - return 0; -} - -/* wait for the output to drain */ -/* or simply clear the buffer it it's stopped */ - -static void -dgb_drain_or_flush(port) - struct dgb_p *port; -{ - struct tty *tp=port->tty; - struct dgb_softc *sc=&dgb_softc[port->unit]; - struct board_chan *bc=port->brdchan; - int error; - int lasttail; - int head, tail; - - setwin(sc,0); - - lasttail=-1; - bc->iempty=1; - tail=bc->tout; - head=bc->tin; - - while(tail!=head /* && tail!=lasttail */ ) { - DPRINT5("dgb%d: port %d: flush: head=%d tail=%d\n", - port->unit, port->pnum, head, tail); - - /* if there is no carrier simply clean the buffer */ - if( !(tp->t_state & TS_CARR_ON) ) { - bc->tout=bc->tin=0; - bc->iempty=0; - hidewin(sc); - return; - } - - hidewin(sc); - port->draining=1; - timeout(wakeflush,port, hz); - error=tsleep(&port->draining, TTIPRI | PCATCH, "dgfls", 0); - port->draining=0; - setwin(sc,0); - - if (error != 0) { - DPRINT4("dgb%d: port %d: tsleep(dgfls) error=%d\n", - port->unit,port->pnum,error); - - /* silently clean the buffer */ - - bc->tout=bc->tin=0; - bc->iempty=0; - hidewin(sc); - return; - } - - lasttail=tail; - tail=bc->tout; - head=bc->tin; - } - DPRINT5("dgb%d: port %d: flush: head=%d tail=%d\n", - port->unit, port->pnum, head, tail); -} - -static int -dgbparam(tp, t) - struct tty *tp; - struct termios *t; -{ - int dev=tp->t_dev; - int mynor=minor(dev); - int unit=MINOR_TO_UNIT(dev); - int pnum=MINOR_TO_PORT(dev); - struct dgb_softc *sc=&dgb_softc[unit]; - struct dgb_p *port=&sc->ports[pnum]; - struct board_chan *bc=port->brdchan; - int cflag; - int head; - int mval; - int iflag; - int hflow; - int s; - - DPRINT3("dgb%d: port%d: setting parameters\n",unit,pnum); - - if(port->mustdrain) { - DPRINT3("dgb%d: port%d: must call dgbdrain()\n",unit,pnum); - dgbdrain(port); - } - - cflag=ttspeedtab(t->c_ospeed, dgbspeedtab); - - if (t->c_ispeed == 0) - t->c_ispeed = t->c_ospeed; - - if (cflag < 0 || cflag > 0 && t->c_ispeed != t->c_ospeed) - return (EINVAL); - - s=spltty(); - - setwin(sc,0); - - if(cflag==0) { /* hangup */ - DPRINT3("dgb%d: port%d: hangup\n",unit,pnum); - head=bc->rin; - bc->rout=head; - head=bc->tin; - fepcmd(port, STOUT, head, 0, 0, 0); - mval= port->omodem & ~(DTR|RTS); - } else { - DPRINT4("dgb%d: port%d: CBAUD=%d\n",unit,pnum,cflag); - - /* convert flags to sysV-style values */ - if(t->c_cflag & PARODD) - cflag|=01000; - if(t->c_cflag & PARENB) - cflag|=00400; - if(t->c_cflag & CSTOPB) - cflag|=00100; - - cflag|= (t->c_cflag & CSIZE) >> 4; - DPRINT4("dgb%d: port%d: CFLAG=0x%x\n",unit,pnum,cflag); - - if(cflag!=port->fepcflag) { - DPRINT3("dgb%d: port%d: set cflag\n",unit,pnum); - port->fepcflag=cflag; - fepcmd(port, SETCTRLFLAGS, (unsigned)cflag, 0, 0, 0); - } - mval= port->omodem | (DTR|RTS) ; - } - - iflag=t->c_iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP); - if(t->c_cflag & IXON) - cflag|=002000; - if(t->c_cflag & IXANY) - cflag|=004000; - if(t->c_cflag & IXOFF) - cflag|=010000; - - if(iflag!=port->fepiflag) { - DPRINT3("dgb%d: port%d: set iflag\n",unit,pnum); - port->fepiflag=iflag; - fepcmd(port, SETIFLAGS, (unsigned)iflag, 0, 0, 0); - } - - bc->mint=port->dcd; - - if(t->c_cflag & CRTSCTS) - hflow=(CTS|RTS); - else - hflow=0; - - if(hflow!=port->hflow) { - DPRINT3("dgb%d: port%d: set hflow\n",unit,pnum); - port->hflow=hflow; - fepcmd(port, SETHFLOW, (unsigned)hflow, 0xff, 0, 1); - } - - if(port->omodem != mval) { - DPRINT4("dgb%d: port %d: setting modem parameters 0x%x\n", - unit,pnum,mval); - port->omodem=mval; - fepcmd(port, SETMODEM, (unsigned)mval, RTS|DTR, 0, 1); - } - - if(port->fepstartc!=t->c_cc[VSTART] || port->fepstopc!=t->c_cc[VSTOP]) { - DPRINT3("dgb%d: port%d: set startc, stopc\n",unit,pnum); - port->fepstartc=t->c_cc[VSTART]; - port->fepstopc=t->c_cc[VSTOP]; - fepcmd(port, SONOFFC, port->fepstartc, port->fepstopc, 0, 1); - } - - hidewin(sc); - splx(s); - - return 0; - -} - -static void -dgbstart(tp) - struct tty *tp; -{ - int unit; - int pnum; - struct dgb_p *port; - struct dgb_softc *sc; - struct board_chan *bc; - int head, tail; - int size, ocount; - int s; - int wmask; - - unit=MINOR_TO_UNIT(minor(tp->t_dev)); - pnum=MINOR_TO_PORT(minor(tp->t_dev)); - sc=&dgb_softc[unit]; - port=&sc->ports[pnum]; - bc=port->brdchan; - - wmask=port->txbufsize-1; - - s=spltty(); - - while( tp->t_outq.c_cc!=0 ) { -#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */ - ttwwakeup(tp); -#else - if(tp->t_outq.c_cc <= tp->t_lowat) { - if(tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup(TSA_OLOWAT(tp)); - } - selwakeup(&tp->t_wsel); - } -#endif - setwin(sc,0); - - head=bc->tin & wmask; - tail=bc->tout & wmask; - - DPRINT5("dgb%d: port%d: s tx head=%d tail=%d\n",unit,pnum,head,tail); - - if(tail>head) - size=tail-head-1; - else { - size=port->txbufsize-head; - if(tail==0) - size--; - } - - if(size==0) { - bc->iempty=1; bc->ilow=1; - hidewin(sc); - tp->t_state|=TS_BUSY; - splx(s); - return; - } - - towin(sc,port->txwin); - - ocount=q_to_b(&tp->t_outq, port->txptr+head, size); - head+=ocount; - - setwin(sc,0); - bc->tin=head; - } - -#ifndef TS_ASLEEP /* post 2.0.5 FreeBSD */ - ttwwakeup(tp); -#else - if(tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup(TSA_OLOWAT(tp)); - } - tp->t_state&=~TS_BUSY; -#endif - hidewin(sc); - splx(s); -} - -void -dgbstop(tp, rw) - struct tty *tp; - int rw; -{ -} - -struct tty * -dgbdevtotty(dev) - dev_t dev; -{ - int mynor, pnum, unit; - struct dgb_softc *sc; - - mynor = minor(dev); - if (mynor & CONTROL_MASK) - return (NULL); - unit = MINOR_TO_UNIT(mynor); - if ((u_int) unit >= NDGB) - return (NULL); - pnum = MINOR_TO_PORT(mynor); - sc = &dgb_softc[unit]; - if (pnum >= sc->numports) - return (NULL); - return (&sc->ttys[pnum]); -} - -static void -fepcmd(port, cmd, op1, op2, ncmds, bytecmd) - struct dgb_p *port; - int cmd, op1, op2, ncmds, bytecmd; -{ - struct dgb_softc *sc=&dgb_softc[port->unit]; - u_char *mem=sc->vmem; - unsigned tail, head; - int count, n; - - if(port->status==DISABLED) { - printf("dgb%d(%d): FEP command on disabled port\n", - port->unit, port->pnum); - return; - } - - setwin(sc,0); - head=sc->mailbox->cin; - - if(head>=(FEP_CMAX-FEP_CSTART) || (head & 3)) { - printf("dgb%d(%d): wrong pointer head of command queue : 0x%x\n", - port->unit, port->pnum, head); - return; - } - - if(bytecmd) { - mem[head+FEP_CSTART+0]=cmd; - mem[head+FEP_CSTART+1]=port->pnum; - mem[head+FEP_CSTART+2]=op1; - mem[head+FEP_CSTART+3]=op2; - } else { - mem[head+FEP_CSTART+0]=cmd; - mem[head+FEP_CSTART+1]=port->pnum; - *(ushort *)(mem+head+FEP_CSTART+2)=op1; - } - - head=(head+4) & (FEP_CMAX-FEP_CSTART-4); - sc->mailbox->cin=head; - - for(count=FEPTIMEOUT; count>0; count--) { - head=sc->mailbox->cin; - tail=sc->mailbox->cout; - n=(head-tail) & (FEP_CMAX-FEP_CSTART-4); - - if(n <= ncmds * 4) - return; - } - - printf("dgb%d(%d): timeout on FEP command\n", - port->unit, port->pnum); -} - -#endif /* NDGB > 0 */ diff --git a/sys/gnu/i386/isa/dgbios.h b/sys/gnu/i386/isa/dgbios.h deleted file mode 100644 index b6e916e..0000000 --- a/sys/gnu/i386/isa/dgbios.h +++ /dev/null @@ -1,175 +0,0 @@ -static unsigned char pcxx_bios[] = { - 0x28,0x43,0x29,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68, - 0x74,0x20,0x31,0x39,0x39,0x34,0x2C,0x20,0x44,0x69,0x67,0x69, - 0x42,0x6F,0x61,0x72,0x64,0x20,0x49,0x6E,0x63,0x2E,0x00,0x00, - 0x8A,0xF8,0x8A,0xF8,0x15,0xF9,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8, - 0x8A,0xF8,0x8A,0xF8,0xBC,0xF8,0x8A,0xF8,0x96,0xF8,0x96,0xF8, - 0x96,0xF8,0x96,0xF8,0x96,0xF8,0x96,0xF8,0x8A,0xF8,0x8A,0xF8, - 0x96,0xF8,0x96,0xF8,0x8A,0xF8,0xAD,0xF8,0xB0,0xF8,0x8A,0xF8, - 0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x8A,0xF8, - 0x8A,0xF8,0x8A,0xF8,0x8A,0xF8,0x04,0x02,0x00,0x02,0x14,0x02, - 0x10,0x02,0x24,0x02,0x20,0x02,0x34,0x02,0x30,0x02,0x44,0x02, - 0x40,0x02,0x54,0x02,0x50,0x02,0x64,0x02,0x60,0x02,0x74,0x02, - 0x70,0x02,0x04,0x01,0x00,0x01,0x1E,0x2E,0x8E,0x1E,0x22,0xF8, - 0xFE,0x06,0x70,0x00,0x1F,0xCF,0x1E,0x50,0x52,0x2E,0x8E,0x1E, - 0x22,0xF8,0xFE,0x06,0x71,0x00,0xB8,0x00,0x80,0xBA,0x22,0xFF, - 0xEF,0x5A,0x58,0x1F,0xCF,0xB4,0x80,0xCF,0x1E,0x2E,0x8E,0x1E, - 0x22,0xF8,0xFE,0x06,0x2B,0x00,0x1F,0xCF,0x1E,0x52,0x50,0x2E, - 0x8E,0x1E,0x22,0xF8,0xCD,0x16,0xFE,0x06,0x2A,0x00,0x80,0x3E, - 0x2A,0x00,0x12,0x72,0x39,0xC6,0x06,0x2A,0x00,0x00,0xFE,0x06, - 0x29,0x00,0x80,0x3E,0x29,0x00,0x3C,0x72,0x29,0xC6,0x06,0x29, - 0x00,0x00,0xFE,0x06,0x28,0x00,0x80,0x3E,0x28,0x00,0x3C,0x72, - 0x19,0xC6,0x06,0x28,0x00,0x00,0xFE,0x06,0x27,0x00,0x80,0x3E, - 0x27,0x00,0x18,0x72,0x09,0xC6,0x06,0x27,0x00,0x00,0xFF,0x06, - 0x25,0x00,0xBA,0x22,0xFF,0xB8,0x00,0x80,0xEF,0x58,0x5A,0x1F, - 0xCF,0x60,0x1E,0x06,0xFC,0x2E,0x8E,0x06,0x22,0xF8,0x2E,0x8E, - 0x1E,0x22,0xF8,0x8D,0x36,0x40,0x00,0xAD,0x3C,0x3F,0x7F,0x22, - 0x3C,0x1F,0x7F,0x22,0x32,0xE4,0xD1,0xE0,0x3D,0x16,0x00,0x90, - 0x73,0x14,0xBB,0x56,0xF9,0x03,0xD8,0x2E,0xFF,0x17,0x8D,0x36, - 0x40,0x00,0xB0,0x00,0x89,0x04,0x07,0x1F,0x61,0xCF,0xB4,0x80, - 0xEB,0xF0,0xCD,0x15,0xEB,0xEC,0x6C,0xF9,0x79,0xF9,0xB9,0xF9, - 0xD3,0xF9,0xD8,0xF9,0xE1,0xF9,0xE9,0xF9,0xF2,0xF9,0xFA,0xF9, - 0xFD,0xF9,0x2A,0xFA,0xE4,0x00,0x24,0xF7,0xE6,0x00,0x0C,0x08, - 0xE6,0x00,0xB4,0x00,0xC3,0x1E,0xAD,0x8B,0xD8,0xAD,0x8E,0xDB, - 0x8B,0xF0,0x33,0xDB,0x8B,0x07,0x3D,0x4F,0x53,0x75,0x2A,0x8A, - 0x47,0x02,0x32,0xE4,0x86,0xC4,0x8B,0xC8,0x32,0xC0,0x02,0x07, - 0x43,0xE2,0xFB,0x0A,0xC0,0x75,0x16,0x8C,0xD9,0x1F,0x89,0x0E, - 0x2E,0x00,0x89,0x36,0x2C,0x00,0x8D,0x1E,0x02,0x00,0xC7,0x07, - 0x45,0x4D,0x32,0xE4,0xC3,0x1F,0xB4,0x80,0xC3,0xAD,0x8B,0xD8, - 0xAD,0x8B,0xD0,0xAD,0x8E,0xC0,0xAD,0x8B,0xF8,0xAD,0x8B,0xC8, - 0x8B,0xF2,0x1E,0x8E,0xDB,0xF3,0xA4,0x1F,0x32,0xE4,0xC3,0xEA, - 0xF0,0xFF,0x00,0xF0,0xAD,0x8B,0xD0,0xEC,0x88,0x04,0x32,0xE4, - 0xC3,0xAD,0x8B,0xD0,0xAC,0xEE,0x32,0xE4,0xC3,0xAD,0x8B,0xD0, - 0xED,0x89,0x04,0x32,0xE4,0xC3,0xAD,0x8B,0xD0,0xAD,0xEF,0x32, - 0xE4,0xC3,0xB4,0x80,0xC3,0xAC,0x3C,0x12,0x7F,0x25,0xFE,0xC8, - 0x32,0xE4,0xD1,0xE0,0x8D,0x1E,0x66,0xF8,0x03,0xD8,0x2E,0x8B, - 0x17,0xEC,0xAC,0x3C,0x0F,0x7F,0x10,0x3C,0x00,0x74,0x03,0xEE, - 0x90,0x90,0xEC,0x8B,0xFE,0x1E,0x07,0xAA,0x32,0xE4,0xC3,0xB4, - 0x80,0xC3,0xAC,0x3C,0x12,0x7F,0x1F,0xFE,0xC8,0x32,0xE4,0xD1, - 0xE0,0x8D,0x1E,0x66,0xF8,0x03,0xD8,0x2E,0x8B,0x17,0xEC,0xAC, - 0x3C,0x0F,0x7F,0x0A,0x3C,0x00,0x74,0x01,0xEE,0xAC,0xEE,0x32, - 0xE4,0xC3,0xB4,0x80,0xC3,0xFC,0x8E,0xC0,0xB8,0xFF,0xFF,0x8B, - 0xCB,0x33,0xFF,0xF3,0xAB,0x8B,0xCB,0x33,0xFF,0xF3,0xAF,0xE3, - 0x01,0xC3,0x8B,0xCB,0xBF,0x00,0x00,0x26,0x89,0x3D,0x83,0xC7, - 0x02,0xE2,0xF8,0xBE,0x00,0x00,0x8B,0xCB,0x26,0x8B,0x3C,0x3B, - 0xFE,0x74,0x01,0xC3,0x83,0xC6,0x02,0x83,0xC7,0x02,0xE2,0xF0, - 0x33,0xC0,0x8B,0xCB,0x33,0xFF,0xF3,0xAB,0x8B,0xCB,0x33,0xFF, - 0xF3,0xAF,0xC3,0x32,0xC0,0x26,0x80,0x3E,0x23,0x00,0x00,0x74, - 0x02,0x0C,0x01,0x26,0xF7,0x06,0x20,0x00,0x0F,0x00,0x74,0x02, - 0x0C,0x02,0x26,0xF7,0x06,0x20,0x00,0xF0,0x00,0x74,0x02,0x0C, - 0x04,0x26,0xF7,0x06,0x20,0x00,0x00,0xFF,0x74,0x02,0x0C,0x08, - 0x26,0xA2,0x24,0x00,0xB8,0x00,0x40,0xBA,0x5E,0xFF,0xEF,0xBA, - 0x66,0xFF,0xEF,0xBA,0x52,0xFF,0xB8,0x63,0x0E,0xEF,0xBA,0x56, - 0xFF,0xB8,0x05,0xE0,0xEF,0xBA,0x28,0xFF,0xB8,0xFC,0x00,0xEF, - 0xB8,0x00,0x02,0x26,0xA3,0x2E,0x00,0xB8,0x04,0x00,0x26,0xA3, - 0x2C,0x00,0xB0,0xC3,0xE6,0x08,0x8A,0xD8,0xE4,0x08,0x3A,0xC3, - 0x75,0x06,0x26,0xC6,0x06,0xB4,0x00,0x01,0xFC,0x8D,0x3E,0x00, - 0x00,0xB8,0x47,0x44,0xAB,0xB8,0xFF,0xFF,0xAB,0xAB,0xAB,0xB8, - 0x42,0x49,0xAB,0xB8,0x4F,0x53,0xAB,0xB8,0x58,0x69,0x26,0x80, - 0x3E,0x10,0x00,0x04,0x74,0x0E,0xB8,0x58,0x65,0x26,0x80,0x3E, - 0x10,0x00,0x03,0x74,0x03,0xB8,0x58,0x74,0xAB,0x8D,0x36,0xFE, - 0xFF,0x8A,0x04,0x8D,0x36,0xFF,0xFF,0x8A,0x24,0xAB,0xFB,0x26, - 0x81,0x0E,0x12,0x00,0x00,0x08,0x06,0x1F,0xA1,0x00,0x00,0x8B, - 0x1E,0x02,0x00,0x3D,0x44,0x47,0x75,0x0B,0x26,0x81,0x0E,0x12, - 0x00,0x00,0x10,0xFF,0x2E,0x2C,0x00,0x81,0xFB,0x45,0x4D,0x75, - 0xE3,0x26,0x81,0x0E,0x12,0x00,0x00,0x20,0xFF,0x2E,0x2C,0x00, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFA,0xBA,0xA8,0xFF,0xB8,0xBA,0x81,0xEF, - 0xBA,0xA4,0xFF,0xB8,0x3A,0x00,0xEF,0x90,0xE4,0x00,0xA8,0x60, - 0x75,0x0C,0x24,0x06,0x74,0x14,0x3C,0x02,0x74,0x1C,0x3C,0x04, - 0x74,0x24,0xBB,0x38,0xC0,0xBE,0xF8,0x81,0xBF,0xBA,0xA0,0xEB, - 0x22,0x90,0xBB,0x38,0xF0,0xBE,0xF8,0x41,0xBF,0xBA,0x81,0xEB, - 0x16,0x90,0xBB,0x38,0xF0,0xBE,0xF8,0xE1,0xBF,0xBA,0x88,0xEB, - 0x0A,0x90,0xBB,0x38,0xC0,0xBE,0xF8,0x41,0xBF,0xBA,0x81,0xBA, - 0xA0,0xFF,0x8B,0xC3,0xEF,0xBA,0xA2,0xFF,0xB8,0xF8,0x0F,0xEF, - 0xBA,0xA6,0xFF,0x8B,0xC6,0xEF,0xBA,0xA8,0xFF,0x8B,0xC7,0xEF, - 0x8C,0xC8,0x8E,0xD8,0xE4,0x00,0x24,0x06,0x74,0x17,0xBB,0x00, - 0x80,0xBD,0xC0,0xE0,0x3C,0x02,0x74,0x5A,0xBD,0xC0,0xC0,0x3C, - 0x04,0x74,0x53,0xBD,0xC0,0x80,0xEB,0x4E,0x90,0xB9,0x08,0x00, - 0xB8,0x00,0x80,0x8E,0xC0,0x26,0xA3,0x00,0x00,0x05,0x00,0x10, - 0xE2,0xF5,0xBD,0xC0,0xF0,0xBB,0x00,0x7C,0xB8,0x00,0xE0,0x8E, - 0xC0,0x26,0x8B,0x0E,0x00,0x00,0x3B,0xC8,0x75,0x28,0xBB,0x00, - 0x80,0xBD,0xC0,0xE0,0xB8,0x00,0xC0,0x8E,0xC0,0x26,0x8B,0x0E, - 0x00,0x00,0x3B,0xC8,0x75,0x14,0xBD,0xC0,0xC0,0xB8,0x00,0x80, - 0x8E,0xC0,0x26,0x8B,0x0E,0x00,0x00,0x3B,0xC8,0x75,0x03,0xBD, - 0xC0,0x80,0x8C,0xC8,0x8E,0xD0,0xBC,0xED,0xFC,0x8B,0xC5,0x25, - 0x00,0xF0,0xE9,0x6C,0xFD,0xB4,0x00,0x74,0x06,0xB4,0xFF,0xEB, - 0x02,0xE5,0xFC,0x8E,0xC5,0x2E,0x89,0x2E,0x22,0xF8,0xE4,0x00, - 0x24,0x16,0x26,0xA2,0x11,0x00,0x26,0x83,0x0E,0x12,0x00,0x01, - 0x80,0xFC,0x00,0x74,0x06,0x26,0x83,0x0E,0x14,0x00,0x01,0x26, - 0xC7,0x06,0x18,0x00,0x40,0x00,0x26,0xC6,0x06,0x10,0x00,0x03, - 0xA8,0x10,0x74,0x06,0x26,0xC6,0x06,0x10,0x00,0x04,0xB8,0x00, - 0x00,0x8E,0xC0,0xB8,0xAA,0x55,0x26,0xA3,0x00,0x00,0x26,0xC7, - 0x06,0x02,0x00,0x00,0x00,0x26,0xC7,0x06,0x04,0x00,0x00,0x00, - 0x8B,0xCD,0x81,0xE1,0x00,0xF0,0x8E,0xC1,0x26,0x8B,0x1E,0x00, - 0x00,0x3B,0xC3,0x75,0x13,0x8E,0xC5,0x26,0xC6,0x06,0x10,0x00, - 0x05,0xB8,0x40,0x00,0x8E,0xD0,0xBC,0x00,0x04,0xE9,0x99,0x00, - 0x8C,0xC8,0x8E,0xD0,0xBC,0x7C,0xFD,0xB8,0x00,0x00,0xBB,0x00, - 0x20,0xE9,0xDD,0xFC,0xB4,0x00,0x74,0x06,0xB4,0xFF,0xEB,0x02, - 0x74,0xFD,0x8E,0xC5,0x80,0xFC,0x00,0x74,0x08,0x26,0x83,0x0E, - 0x14,0x00,0x02,0xEB,0x0D,0x26,0xC7,0x06,0x16,0x00,0x10,0x00, - 0x26,0x83,0x0E,0x12,0x00,0x02,0xB8,0x40,0x00,0x8E,0xD0,0xBC, - 0x00,0x04,0xE4,0x00,0xA8,0x60,0x75,0x07,0xBA,0xA2,0xFF,0xB8, - 0xFC,0x0F,0xEF,0xB8,0x00,0x04,0x8E,0xC0,0xB8,0xAA,0x55,0x26, - 0xA3,0x00,0x00,0x26,0xC7,0x06,0x02,0x00,0x00,0x00,0x26,0xC7, - 0x06,0x04,0x00,0x00,0x00,0xB9,0x00,0x00,0x8E,0xC1,0x26,0x8B, - 0x1E,0x00,0x00,0x3B,0xC3,0x75,0x02,0xEB,0x24,0x8E,0xC5,0x26, - 0x83,0x0E,0x12,0x00,0x04,0xB8,0x00,0x04,0xBB,0x00,0x60,0x06, - 0xE8,0x66,0xFC,0x07,0x75,0x09,0x26,0xC7,0x06,0x16,0x00,0x40, - 0x00,0xEB,0x06,0x26,0x83,0x0E,0x14,0x00,0x04,0x8E,0xC5,0x8C, - 0xC0,0x3D,0xC0,0xF0,0x75,0x03,0xE9,0x9F,0x00,0x3D,0xC0,0x80, - 0x74,0x62,0x3D,0xC0,0xC0,0x74,0x23,0x26,0x83,0x0E,0x12,0x00, - 0x08,0xB8,0x00,0xF0,0xBB,0x00,0x7C,0x06,0xE8,0x2E,0xFC,0x07, - 0x75,0x08,0x26,0x83,0x06,0x18,0x00,0x40,0xEB,0x06,0x26,0x83, - 0x0E,0x14,0x00,0x08,0xEB,0x72,0xB9,0x03,0x00,0xB8,0x00,0xD0, - 0xBA,0x08,0x00,0xBB,0x00,0x80,0x3D,0x00,0xF0,0x75,0x03,0xBB, - 0x00,0x7C,0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xE8,0xFC, - 0xFB,0x59,0x58,0x07,0x75,0x0F,0x26,0x83,0x06,0x18,0x00,0x40, - 0xD1,0xE2,0x05,0x00,0x10,0xE2,0xD8,0xEB,0x05,0x26,0x09,0x16, - 0x14,0x00,0xEB,0x38,0xB9,0x07,0x00,0xB8,0x00,0x90,0xBA,0x08, - 0x00,0xBB,0x00,0x80,0x3D,0x00,0xF0,0x75,0x03,0xBB,0x00,0x7C, - 0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xE8,0xC2,0xFB,0x59, - 0x58,0x07,0x75,0x0F,0x26,0x83,0x06,0x18,0x00,0x40,0xD1,0xE2, - 0x05,0x00,0x10,0xE2,0xD8,0xEB,0x05,0x26,0x09,0x16,0x14,0x00, - 0x26,0xA1,0x18,0x00,0x2D,0x10,0x00,0x26,0xA3,0x1A,0x00,0x06, - 0xFC,0x33,0xFF,0x8E,0xC7,0xB9,0x00,0x02,0xB8,0x00,0xF0,0xF3, - 0xAB,0x33,0xFF,0xBE,0x24,0xF8,0xB9,0x20,0x00,0xA5,0x47,0x47, - 0xE2,0xFB,0xBE,0x64,0xF8,0xB9,0xE0,0x00,0x8B,0x1C,0x26,0x89, - 0x1D,0x83,0xC7,0x04,0xE2,0xF8,0x07,0xBA,0x28,0xFF,0xB8,0xFD, - 0x00,0xEF,0xBA,0x32,0xFF,0xB8,0x0D,0x00,0xEF,0xBA,0x34,0xFF, - 0xB8,0x0F,0x00,0xEF,0xBA,0x36,0xFF,0xB8,0x0E,0x00,0xEF,0xBA, - 0x38,0xFF,0xB8,0x19,0x00,0xEF,0xBA,0x3A,0xFF,0xB8,0x18,0x00, - 0xEF,0xBA,0x3C,0xFF,0xB8,0x0B,0x00,0xEF,0xBA,0x3E,0xFF,0xB8, - 0x1A,0x00,0xEF,0x8D,0x3E,0x90,0x00,0x8D,0x36,0x66,0xF8,0xB9, - 0x10,0x00,0xF3,0xA5,0x8D,0x3E,0xB0,0x00,0x8D,0x36,0x86,0xF8, - 0xB9,0x02,0x00,0xF3,0xA5,0xB9,0x10,0x00,0x8D,0x36,0x90,0x00, - 0x83,0xC6,0x1E,0x26,0x8B,0x14,0xB3,0x10,0x32,0xC0,0xEC,0xB0, - 0x0C,0xEE,0x8A,0xC3,0x8A,0xC3,0xEE,0x83,0xEE,0x02,0x26,0x8B, - 0x14,0xFE,0xCB,0xE2,0xEB,0xB9,0x10,0x00,0x8D,0x36,0x90,0x00, - 0x26,0x8B,0x14,0xB3,0x01,0xBF,0x00,0x80,0xB0,0x0C,0xEE,0xF6, - 0xE8,0xEC,0x3A,0xC3,0x75,0x0E,0xD1,0xC7,0x26,0x09,0x3E,0x20, - 0x00,0x26,0xFE,0x06,0x22,0x00,0xEB,0x07,0x33,0xC0,0x26,0x89, - 0x04,0xD1,0xC7,0x83,0xC6,0x02,0x26,0x8B,0x14,0xFE,0xC3,0xE2, - 0xD7,0x26,0xC6,0x06,0x23,0x00,0x01,0x8D,0x36,0xB0,0x00,0x26, - 0x8B,0x14,0x32,0xC0,0xEE,0xB0,0x0C,0xEE,0xB0,0x5A,0xEE,0xB0, - 0x0C,0xEE,0xF6,0xE8,0xEC,0x3C,0x5A,0x74,0x14,0x26,0xC7,0x06, - 0xB0,0x00,0x00,0x00,0x26,0xC7,0x06,0xB2,0x00,0x00,0x00,0x26, - 0xC6,0x06,0x23,0x00,0x00,0xE9,0xD3,0xFA,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xEA,0x00,0xFC,0x00,0xF0,0x4D,0x2F,0x50, - 0x43,0x2F,0x58,0x2A,0x39,0x34,0x34,0x30 -}; - -static unsigned pcxx_nbios=sizeof(pcxx_bios); diff --git a/sys/gnu/i386/isa/dgfep.h b/sys/gnu/i386/isa/dgfep.h deleted file mode 100644 index c60c66a..0000000 --- a/sys/gnu/i386/isa/dgfep.h +++ /dev/null @@ -1,516 +0,0 @@ -static unsigned char pcxx_cook[] = { - 0x4F,0x53,0x18,0x85,0xE9,0xBF,0x15,0x00,0x40,0x28,0x23,0x29, - 0x46,0x45,0x50,0x4F,0x53,0x20,0x37,0x2E,0x30,0x37,0x20,0x31, - 0x2F,0x31,0x30,0x2F,0x39,0x35,0x00,0x40,0x28,0x23,0x29,0x28, - 0x43,0x29,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20, - 0x31,0x39,0x38,0x39,0x2D,0x31,0x39,0x39,0x35,0x20,0x44,0x69, - 0x67,0x69,0x42,0x6F,0x61,0x72,0x64,0x20,0x49,0x6E,0x63,0x2E, - 0x00,0xCB,0x0C,0xCB,0x0C,0xE2,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB, - 0x0C,0xCB,0x0C,0xCB,0x0C,0x57,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB, - 0x0C,0x53,0x0B,0xCB,0x0C,0xCB,0x0C,0x42,0x0B,0xCB,0x0C,0xCB, - 0x0C,0x12,0x0D,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB, - 0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB,0x0C,0xCB, - 0x0C,0xCB,0x0C,0xCB,0x0C,0x00,0x10,0x80,0x10,0x00,0x11,0x80, - 0x11,0x00,0x12,0x80,0x12,0x00,0x13,0x80,0x13,0x00,0x14,0x80, - 0x14,0x00,0x15,0x80,0x15,0x00,0x16,0x80,0x16,0x00,0x17,0x80, - 0x17,0x78,0x0B,0xB9,0x0B,0x50,0x0C,0xB9,0x0B,0x8D,0x0B,0x8D, - 0x0B,0x8D,0x0B,0x8D,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0, - 0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x50,0x0C,0xB9, - 0x0B,0x50,0x0C,0xB9,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D,0x0B,0x8D, - 0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0xC0,0x0B,0x8D,0x0B,0x8D, - 0x0B,0x8D,0x0B,0x8D,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94, - 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94, - 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94, - 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94, - 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94, - 0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x94,0x0B,0x16,0x00,0xFE, - 0x11,0xFE,0x0B,0x2C,0x08,0xB5,0x06,0xFE,0x05,0x7E,0x04,0xFE, - 0x02,0x7E,0x01,0xBE,0x00,0x7E,0x00,0x5E,0x00,0x2E,0x00,0x16, - 0x00,0x0A,0x00,0x04,0x00,0x16,0x00,0x02,0x00,0x01,0x00,0x00, - 0x00,0x0E,0x00,0x06,0x00,0x7E,0x04,0xFE,0x02,0x7E,0x01,0xBE, - 0x00,0x7E,0x00,0x5E,0x00,0x2E,0x00,0x16,0x00,0x0A,0x00,0x04, - 0x00,0x18,0x00,0x86,0x13,0x03,0x0D,0xDF,0x08,0x41,0x07,0x81, - 0x06,0xE0,0x04,0x3F,0x03,0x9F,0x01,0xCE,0x00,0x89,0x00,0x66, - 0x00,0x32,0x00,0x18,0x00,0x0B,0x00,0x0B,0x00,0x18,0x00,0x0B, - 0x00,0x0B,0x00,0x0B,0x00,0x41,0x07,0x81,0x06,0xE0,0x04,0x3F, - 0x03,0x9F,0x01,0xCE,0x00,0x89,0x00,0x66,0x00,0x32,0x00,0x18, - 0x00,0x0B,0x00,0x0B,0x00,0x00,0x80,0x40,0xC0,0x1F,0x3F,0x7F, - 0xFF,0x00,0x04,0x02,0x06,0x08,0x0C,0x0A,0x0E,0x00,0x04,0x02, - 0x06,0x08,0x0C,0x0A,0x0E,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0x1E,0x06,0x3E, - 0x06,0xEF,0x06,0xF8,0x05,0x0E,0x06,0x55,0x07,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1, - 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1, - 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1, - 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0xA1, - 0x05,0xA1,0x05,0xA1,0x05,0xA1,0x05,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x5B,0x05,0xEA,0x05,0xEA,0x05,0xEA, - 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA, - 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA, - 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA, - 0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0xEA,0x05,0x69, - 0x05,0x77,0x05,0x85,0x05,0x93,0x05,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0,0x08,0xA0, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D,0x08,0x9D, - 0x08,0x00,0x00,0xFA,0x8A,0x5C,0x50,0xF6,0xC3,0x0E,0x75,0x3C, - 0xF6,0xC3,0x40,0x75,0x16,0xF6,0xC3,0x10,0x74,0x26,0xF6,0xC3, - 0x01,0x75,0x13,0xF6,0xC3,0x20,0x75,0x15,0xC7,0x04,0xB6,0x04, - 0xE9,0xCF,0x00,0x8B,0x44,0x02,0x89,0x04,0xFF,0xE0,0xC7,0x04, - 0x03,0x05,0xE9,0x0E,0x01,0xC7,0x04,0x66,0x08,0xE9,0x6A,0x04, - 0xF6,0xC3,0x20,0x74,0x1A,0xC7,0x04,0xB3,0x08,0xE9,0xAB,0x04, - 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0xF6,0xC3,0x02,0x75,0x42,0xF6, - 0xC3,0x08,0x75,0x0E,0xEB,0x69,0x90,0xC7,0x04,0x20,0x04,0xFB, - 0x81,0xC6,0x80,0x00,0xFF,0x24,0xF6,0xC1,0x04,0x74,0x27,0x80, - 0x64,0x50,0xF7,0xF6,0x44,0x51,0x02,0x74,0x13,0xF6,0x44,0x29, - 0x10,0x74,0x0D,0x8A,0x44,0x5D,0x83,0xC2,0x02,0xEE,0x83,0xEA, - 0x02,0xE9,0x49,0x04,0x8A,0x44,0x5C,0x83,0xC2,0x02,0xEE,0x83, - 0xEA,0x02,0xE9,0x3C,0x04,0xF6,0x44,0x50,0x04,0x75,0x28,0x83, - 0x7C,0x24,0xFF,0x74,0x1F,0xA1,0x00,0x0E,0x2B,0x44,0x26,0x3D, - 0x64,0x00,0x77,0x14,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x24,0xEF, - 0x88,0x44,0x75,0xEE,0x80,0x64,0x50,0xFD,0x80,0x64,0x4B,0xFD, - 0xE9,0x0E,0x04,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01, - 0x74,0x25,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x0C,0x10,0x88,0x44, - 0x75,0xEE,0xA1,0x00,0x0E,0x03,0x44,0x24,0x89,0x44,0x26,0x80, - 0x64,0x50,0xFB,0x80,0x64,0x4B,0xFB,0x80,0x4C,0x50,0x02,0x80, - 0x4C,0x4B,0x02,0xE9,0xDB,0x03,0xFA,0x8B,0x54,0x20,0xEC,0x8A, - 0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,0x75,0x19,0x8B,0x7C,0x0C, - 0x3B,0x7C,0x0A,0x74,0x18,0x8E,0x44,0x08,0x26,0x8A,0x05,0x47, - 0x23,0x7C,0x0E,0x89,0x7C,0x0C,0x83,0xC2,0x02,0xEE,0xFB,0x81, - 0xC6,0x80,0x00,0xFF,0x24,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC, - 0xA8,0x01,0x74,0x0C,0x80,0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF, - 0xC7,0x04,0xC3,0x03,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFA, - 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53, - 0x75,0x3A,0x8B,0x7C,0x0C,0x3B,0x7C,0x0A,0x74,0x1B,0x8E,0x44, - 0x08,0x26,0x8A,0x05,0x47,0x23,0x7C,0x0E,0x89,0x7C,0x0C,0x8A, - 0xD8,0x22,0x5C,0x62,0x32,0xFF,0x03,0xDB,0x2E,0xFF,0xA7,0xC1, - 0x01,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,0x74,0x0C, - 0x80,0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF,0xC7,0x04,0xC3,0x03, - 0xF6,0xC1,0x01,0x75,0x07,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24, - 0xE9,0x61,0x03,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9,0x39,0x03, - 0xB0,0x27,0xEB,0x42,0x90,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9, - 0x2B,0x03,0xB0,0x28,0xEB,0x34,0x90,0xF6,0x44,0x2A,0x01,0x75, - 0x03,0xE9,0x1D,0x03,0xB0,0x21,0xEB,0x26,0x90,0xF6,0x44,0x2A, - 0x01,0x75,0x03,0xE9,0x0F,0x03,0xB0,0x29,0xEB,0x18,0x90,0xF6, - 0x44,0x2A,0x01,0x75,0x03,0xE9,0x01,0x03,0xB0,0x5E,0xEB,0x0A, - 0x90,0xF6,0x44,0x2A,0x01,0x75,0x03,0xE9,0xF3,0x02,0x88,0x44, - 0x61,0xB0,0x5C,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0x4C, - 0x50,0x40,0xC7,0x04,0xC6,0x05,0xC7,0x44,0x02,0xC6,0x05,0xE9, - 0xCB,0x02,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52, - 0x3A,0x44,0x53,0x75,0x12,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03, - 0x05,0x83,0x44,0x30,0x02,0x8A,0x44,0x61,0xE9,0xB9,0x02,0xE9, - 0xA7,0x02,0xF6,0x44,0x2A,0x02,0x75,0x03,0xE9,0xAA,0x02,0x2C, - 0x20,0xE9,0xA5,0x02,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6, - 0x44,0x2B,0x40,0x75,0x03,0xE9,0x89,0x02,0xB8,0x7F,0x00,0xE9, - 0x9B,0x01,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0x44,0x2B, - 0x80,0x75,0xED,0xE9,0x73,0x02,0x83,0xC2,0x02,0xEE,0x83,0xEA, - 0x02,0xF7,0x44,0x30,0xFF,0xFF,0x74,0x03,0xFF,0x4C,0x30,0xF6, - 0x44,0x2B,0x20,0x75,0x03,0xE9,0x59,0x02,0xB8,0x02,0x00,0xE9, - 0x6B,0x01,0xB3,0x18,0x22,0x5C,0x2B,0x75,0x16,0x83,0xC2,0x02, - 0xEE,0x83,0xEA,0x02,0x8B,0x44,0x30,0x05,0x08,0x00,0x25,0xF8, - 0xFF,0x89,0x44,0x30,0xE9,0x36,0x02,0x80,0xFB,0x18,0x75,0x57, - 0xB0,0x20,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x8B,0x44,0x30, - 0x8B,0xD8,0x05,0x08,0x00,0x25,0xF8,0xFF,0x89,0x44,0x30,0x2B, - 0xC3,0x48,0x74,0x38,0x89,0x44,0x32,0x80,0x4C,0x50,0x40,0xC7, - 0x44,0x02,0x8F,0x06,0xC7,0x04,0x8F,0x06,0xE9,0x02,0x02,0xFA, - 0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53, - 0x75,0x16,0xB0,0x20,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xFF, - 0x4C,0x32,0x75,0x08,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05, - 0xE9,0xDA,0x01,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0xFB, - 0x08,0x75,0x18,0x8B,0x44,0x30,0x8B,0xD8,0x05,0x08,0x00,0x25, - 0xF8,0xFF,0x89,0x44,0x30,0x2B,0xC3,0x3D,0x05,0x00,0x7C,0xDC, - 0xE9,0xCE,0x00,0x8B,0x44,0x30,0x8B,0xD8,0x05,0x08,0x00,0x25, - 0xF8,0xFF,0x89,0x44,0x30,0xB8,0x02,0x00,0xE9,0xBA,0x00,0xF6, - 0x44,0x2A,0x20,0x75,0x43,0xF6,0x44,0x2A,0x04,0x74,0x42,0xF6, - 0x44,0x2A,0x10,0x74,0x07,0xF7,0x44,0x30,0xFF,0xFF,0x74,0x30, - 0xB0,0x0D,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x80,0x4C,0x50, - 0x40,0xC7,0x04,0x21,0x07,0xC7,0x44,0x02,0x21,0x07,0xE9,0x70, - 0x01,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A, - 0x44,0x53,0x75,0x1C,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05, - 0xB0,0x0A,0xEB,0x2B,0x90,0xB0,0x0A,0x83,0xC2,0x02,0xEE,0x83, - 0xEA,0x02,0xF6,0x44,0x2B,0x01,0x75,0x03,0xE9,0x42,0x01,0xB8, - 0x05,0x00,0xEB,0x55,0x90,0xF6,0x44,0x2A,0x08,0x75,0xE2,0xF6, - 0x44,0x2A,0x10,0x74,0x06,0x83,0x7C,0x30,0x00,0x74,0x13,0x83, - 0xC2,0x02,0xEE,0x83,0xEA,0x02,0xB3,0x06,0x22,0x5C,0x2B,0x75, - 0x08,0xC7,0x44,0x30,0x00,0x00,0xE9,0x14,0x01,0x80,0xFB,0x02, - 0x75,0x14,0x8B,0x44,0x30,0xC1,0xE8,0x04,0x05,0x03,0x00,0x3D, - 0x06,0x00,0x72,0x14,0xB8,0x06,0x00,0xEB,0x0F,0x90,0x80,0xFB, - 0x04,0x75,0x06,0xB8,0x05,0x00,0xEB,0x04,0x90,0xB8,0x09,0x00, - 0xC7,0x44,0x30,0x00,0x00,0xF6,0x44,0x2A,0x40,0x74,0x45,0x3D, - 0x20,0x00,0x77,0x40,0xBB,0x01,0x00,0x3D,0x03,0x00,0x7E,0x03, - 0xBB,0x02,0x00,0x89,0x5C,0x32,0x80,0x4C,0x50,0x40,0xC7,0x44, - 0x02,0xD2,0x07,0xC7,0x04,0xD2,0x07,0xE9,0xBF,0x00,0xFA,0x8B, - 0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52,0x3A,0x44,0x53,0x75, - 0x10,0x8A,0x44,0x60,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0x83, - 0x6C,0x32,0x01,0x7E,0x50,0xE9,0x9D,0x00,0x05,0x06,0x00,0x03, - 0xC0,0x89,0x44,0x32,0x80,0x4C,0x50,0x40,0xC7,0x44,0x02,0x0C, - 0x08,0xC7,0x04,0x0C,0x08,0xE9,0x85,0x00,0xFA,0x8B,0x54,0x20, - 0xEC,0x8A,0xC8,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01, - 0x74,0x0F,0xA1,0x00,0x0E,0x01,0x44,0x32,0xC7,0x44,0x02,0x30, - 0x08,0xC7,0x04,0x30,0x08,0xEB,0x62,0x90,0x8B,0x54,0x20,0xEC, - 0x8A,0xC8,0xA1,0x00,0x0E,0x2B,0x44,0x32,0x3D,0xE8,0x03,0x77, - 0xEC,0x80,0x64,0x50,0xBF,0xC7,0x04,0x03,0x05,0xEB,0x46,0x90, - 0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0xA8,0x01,0x74,0x3A,0x80, - 0x64,0x50,0xEF,0x80,0x64,0x4B,0xEF,0xC7,0x04,0xB3,0x08,0xEB, - 0x2C,0x90,0xFA,0x8B,0x54,0x20,0xEC,0x8A,0xC8,0x22,0x44,0x52, - 0x3A,0x44,0x53,0x75,0x1C,0x8B,0x7C,0x0C,0x3B,0x7C,0x0A,0x74, - 0xCF,0x8E,0x44,0x08,0x26,0x8A,0x05,0x47,0x23,0x7C,0x0E,0x89, - 0x7C,0x0C,0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0xC1,0x01, - 0x75,0x26,0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFF,0x44,0x30, - 0x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xF6,0xC1,0x01,0x75,0x10, - 0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0xFA,0x8B,0x54,0x20,0xEC, - 0xA8,0x01,0x74,0xDA,0xC6,0x44,0x49,0x02,0x8B,0x7C,0x12,0x8E, - 0x44,0x10,0xB0,0x01,0xEE,0x90,0x90,0x90,0xEC,0x8A,0xE0,0x90, - 0xB0,0x30,0xEE,0x83,0xC2,0x02,0x90,0xEC,0x83,0xEA,0x02,0x23, - 0x44,0x34,0xFF,0x64,0x06,0xB3,0x1C,0x22,0x5C,0x51,0x75,0x1A, - 0xF6,0x44,0x29,0x04,0x74,0x21,0xF6,0x44,0x29,0x20,0x75,0x2B, - 0x80,0x7C,0x5E,0x00,0x75,0x1D,0xC7,0x44,0x06,0x58,0x0A,0xE9, - 0x56,0x01,0xF6,0xC3,0x10,0x75,0x2E,0xF6,0xC3,0x04,0x75,0x74, - 0xEB,0x6B,0x90,0xC7,0x44,0x06,0x62,0x0A,0xE9,0x4B,0x01,0xC7, - 0x44,0x06,0x53,0x0A,0xE9,0x34,0x01,0x80,0x7C,0x5E,0x00,0x75, - 0x08,0xC7,0x44,0x06,0xCA,0x09,0xE9,0x9D,0x00,0xC7,0x44,0x06, - 0xC5,0x09,0xE9,0x90,0x00,0x0A,0xC0,0x74,0x2A,0xFE,0x4C,0x63, - 0x74,0x1A,0x80,0xE3,0xEF,0x75,0xC4,0xF6,0x44,0x29,0x04,0x74, - 0x21,0xF6,0x44,0x29,0x20,0x75,0x21,0x80,0x7C,0x5E,0x00,0x75, - 0x18,0xE9,0x00,0x01,0x80,0x64,0x51,0xEF,0x80,0xE3,0xEF,0x75, - 0xA6,0xEB,0x85,0x80,0x64,0x51,0xEF,0xE9,0x06,0x01,0xE9,0xF5, - 0x00,0xE9,0xE3,0x00,0x80,0x7C,0x5E,0x00,0x75,0x4F,0xEB,0x52, - 0x90,0x80,0x64,0x51,0xF7,0xE9,0xE2,0x00,0x80,0x64,0x53,0x3F, - 0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0x80,0x64,0x51,0xFB, - 0xF6,0x44,0x29,0x40,0x75,0x2C,0x3A,0x44,0x5D,0x74,0x27,0x3A, - 0x44,0x5C,0x74,0x22,0xF6,0x44,0x29,0x20,0x74,0x0A,0x3A,0x44, - 0x5A,0x74,0x17,0x3A,0x44,0x5B,0x74,0x12,0xF6,0x44,0x5E,0xFF, - 0x74,0x09,0x3A,0x44,0x5E,0x75,0x04,0x80,0x4C,0x51,0x08,0xE9, - 0xA0,0x00,0xE9,0xAB,0x00,0x3A,0x44,0x5E,0x74,0x7D,0x3A,0x44, - 0x5C,0x74,0x3D,0x3A,0x44,0x5D,0x74,0x55,0x3A,0x44,0x5A,0x74, - 0x08,0x3A,0x44,0x5B,0x74,0x18,0xE9,0x81,0x00,0xF6,0x44,0x53, - 0x40,0x74,0x07,0x80,0x64,0x53,0xBF,0xE9,0x82,0x00,0x3A,0x44, - 0x5B,0x74,0x03,0xEB,0x7B,0x90,0x80,0x4C,0x53,0x40,0xF6,0x44, - 0x29,0x08,0x74,0x70,0x80,0x4C,0x51,0x04,0xC7,0x44,0x06,0xE1, - 0x08,0xEB,0x65,0x90,0xF6,0x44,0x53,0x80,0x74,0x0F,0x80,0x64, - 0x53,0x7F,0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0xEB,0x50, - 0x90,0x3A,0x44,0x5D,0x74,0x03,0xEB,0x48,0x90,0x80,0x4C,0x53, - 0x80,0x80,0x4C,0x54,0x01,0x80,0x4C,0x58,0x01,0xF6,0x44,0x29, - 0x08,0x74,0x35,0x80,0x4C,0x51,0x04,0xC7,0x44,0x06,0xE1,0x08, - 0xEB,0x2A,0x90,0x80,0x4C,0x51,0x08,0xC7,0x44,0x06,0xE1,0x08, - 0xEB,0x10,0x90,0x3A,0x44,0x5E,0x74,0xEF,0x3A,0x44,0x5C,0x74, - 0xAF,0x3A,0x44,0x5D,0x74,0xC7,0x3D,0xFF,0x00,0x73,0x26,0xAA, - 0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x4F,0xEC,0xA8,0x01,0x74, - 0x03,0xE9,0x4E,0xFE,0x89,0x7C,0x12,0x2B,0x7C,0x14,0x23,0x7C, - 0x16,0x3B,0x7C,0x1C,0x73,0x46,0xFB,0x81,0xC6,0x80,0x00,0xFF, - 0x24,0x0A,0xE4,0x75,0x1E,0xB3,0x0C,0x22,0x5C,0x28,0x80,0xFB, - 0x08,0x75,0xCC,0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x1B, - 0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x12,0xEB,0xC1,0xF6, - 0x44,0x28,0x04,0x75,0xBB,0xF6,0x44,0x28,0x08,0x75,0x50,0x32, - 0xC0,0xEB,0xA8,0x4F,0x23,0x7C,0x16,0x89,0x7C,0x12,0xC6,0x44, - 0x59,0x01,0xEB,0xA4,0xF6,0x44,0x51,0x02,0x74,0x07,0xFB,0x81, - 0xC6,0x80,0x00,0xFF,0x24,0x80,0x4C,0x51,0x02,0xB0,0x05,0xEE, - 0xB0,0x82,0x22,0x44,0x5F,0xF6,0xD0,0x22,0x44,0x75,0x88,0x44, - 0x75,0xEE,0xF6,0x44,0x29,0x10,0x74,0x10,0x80,0x4C,0x54,0x04, - 0x80,0x4C,0x58,0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03, - 0xFB,0x81,0xC6,0x80,0x00,0xFF,0x24,0x26,0xC6,0x05,0xFF,0x47, - 0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0xA7,0x32,0xFF,0xF6,0x44, - 0x29,0x80,0x74,0x0A,0x8A,0xDC,0xC0,0xEB,0x04,0x2E,0x8A,0xBF, - 0xB1,0x01,0x26,0x88,0x3D,0x47,0x23,0x7C,0x16,0x3B,0x7C,0x14, - 0x74,0x89,0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x80,0xE9, - 0x2E,0xFF,0x1E,0x2E,0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x1C,0x0E, - 0x60,0xBE,0x00,0x14,0xEB,0x0F,0x90,0x1E,0x2E,0x8E,0x1E,0xC1, - 0x03,0xFF,0x06,0x1A,0x0E,0x60,0xBE,0x00,0x10,0xB9,0x08,0x00, - 0x8B,0x54,0x20,0xB0,0x03,0xEE,0x90,0x90,0x32,0xFF,0xEC,0x8A, - 0xD8,0x02,0xD8,0x2E,0xFF,0xA7,0xA9,0x00,0x81,0xC6,0x00,0x01, - 0x8B,0x54,0x20,0x0B,0xD2,0xE0,0xE4,0xB8,0x00,0x80,0xBA,0x22, - 0xFF,0xEF,0x61,0x1F,0xCF,0x81,0xCE,0x80,0x00,0x8B,0x54,0x20, - 0xFF,0x06,0x20,0x0E,0xB0,0x01,0xEE,0x8A,0x44,0x71,0x24,0xE7, - 0x88,0x44,0x71,0xEE,0xC6,0x44,0x49,0x02,0x80,0x4C,0x50,0x20, - 0xC7,0x04,0xC3,0x03,0x81,0xE6,0x7F,0xFF,0x8B,0x54,0x20,0xEB, - 0xAE,0x81,0xCE,0x80,0x00,0x8B,0x54,0x20,0xFF,0x06,0x22,0x0E, - 0xEC,0x0A,0xC0,0x79,0x7A,0x80,0x4C,0x51,0x10,0xC7,0x44,0x06, - 0xE1,0x08,0xC6,0x44,0x63,0x04,0xF6,0x44,0x51,0x04,0x74,0x08, - 0x80,0x64,0x51,0xFB,0x80,0x64,0x53,0x3F,0xF6,0x44,0x28,0x01, - 0x75,0x59,0xF6,0x44,0x28,0x02,0x75,0x4F,0x8B,0x7C,0x12,0x8C, - 0xC3,0x8E,0x44,0x10,0xF6,0x44,0x28,0x08,0x74,0x1E,0xB0,0xFF, - 0xAA,0x23,0x7C,0x16,0x3B,0x7C,0x14,0x74,0x26,0x32,0xC0,0xF6, - 0x44,0x29,0x80,0x74,0x02,0xB0,0x10,0xAA,0x23,0x7C,0x16,0x3B, - 0x7C,0x14,0x74,0x13,0x32,0xC0,0xAA,0x23,0x7C,0x16,0x3B,0x7C, - 0x14,0x74,0x08,0x8E,0xC3,0x89,0x7C,0x12,0xEB,0x15,0x90,0x8E, - 0xC3,0x4F,0x23,0x7C,0x16,0x89,0x7C,0x12,0xC6,0x44,0x59,0x01, - 0xEB,0x05,0x90,0x80,0x4C,0x4F,0x01,0xB0,0x10,0xEE,0x81,0xE6, - 0x7F,0xFF,0x8B,0x54,0x20,0xE9,0x17,0xFF,0xFF,0x06,0x1E,0x0E, - 0xE9,0x10,0xFF,0x1E,0x2E,0x8E,0x1E,0xC1,0x03,0x50,0x52,0x55, - 0x8B,0xEC,0x8B,0x46,0x08,0xA3,0x12,0x0E,0x32,0xE4,0xA0,0x22, - 0x0C,0xA3,0x10,0x0E,0xFF,0x06,0x00,0x0E,0x83,0x06,0x0E,0x0E, - 0x0A,0x83,0x3E,0x04,0x0E,0x00,0x74,0x31,0x8B,0x16,0x00,0x0E, - 0x2B,0x16,0x02,0x0E,0x3B,0x16,0x04,0x0E,0x72,0x23,0x8B,0x16, - 0x00,0x0E,0x89,0x16,0x02,0x0E,0x8B,0x16,0x18,0x0D,0x3B,0x16, - 0x1A,0x0D,0x74,0x11,0x80,0x3E,0x10,0x0C,0x01,0x74,0x16,0xB0, - 0x00,0x90,0xE6,0x00,0x0C,0x08,0x90,0xE6,0x00,0xB8,0x00,0x80, - 0xBA,0x22,0xFF,0xEF,0x5D,0x5A,0x58,0x1F,0xCF,0xB0,0x80,0xE6, - 0x00,0xA0,0x11,0x0C,0x0C,0x10,0xA2,0x11,0x0C,0xEB,0xE6,0x1E, - 0x2E,0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x28,0x0E,0x55,0x8B,0xEC, - 0x8B,0x6E,0x02,0x89,0x2E,0x16,0x0E,0x5D,0x1F,0xCF,0x1E,0x2E, - 0x8E,0x1E,0xC1,0x03,0xFF,0x06,0x24,0x0E,0x55,0x8B,0xEC,0x8B, - 0x6E,0x02,0x89,0x2E,0x14,0x0E,0x5D,0x80,0x3E,0x10,0x0C,0x01, - 0x75,0x12,0x50,0xA0,0x11,0x0C,0x0C,0x01,0xA2,0x11,0x0C,0xE4, - 0x00,0x90,0x90,0x24,0x7F,0xE6,0x00,0x58,0x1F,0xCF,0x1E,0x06, - 0x60,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x2E,0x8E,0x1E,0xC1, - 0x03,0x2E,0x8E,0x06,0xC1,0x03,0x2E,0xFF,0x06,0x30,0x0D,0xFC, - 0xFF,0x26,0x2E,0x0E,0x00,0x00,0xFB,0x40,0x43,0x41,0x42,0x46, - 0x47,0x45,0xEB,0xF6,0xC3,0x00,0x00,0x8F,0x06,0x2E,0x0E,0x2E, - 0xFF,0x06,0x3D,0x0D,0xB8,0x00,0x00,0xBA,0x58,0xFF,0xEF,0xB8, - 0x00,0xE0,0xBA,0x5E,0xFF,0xEF,0x61,0x07,0x1F,0xCF,0xC2,0xFE, - 0xFF,0x8B,0x7C,0x0A,0x2B,0x7C,0x0C,0x23,0x7C,0x0E,0x3B,0x7C, - 0x18,0x77,0x2E,0xC6,0x44,0x4D,0x00,0x80,0x4C,0x4F,0x02,0xEB, - 0x5A,0x90,0x8B,0x7C,0x0A,0x3B,0x7C,0x0C,0x75,0x1B,0x8B,0x3E, - 0x10,0x0D,0x3B,0x3E,0x12,0x0D,0x75,0x53,0xF6,0x44,0x4B,0xFF, - 0x75,0x4D,0xC6,0x44,0x4C,0x00,0x80,0x4C,0x4F,0x04,0xEB,0x43, - 0x90,0xF6,0x44,0x50,0x10,0x75,0x3C,0xEB,0x09,0x90,0x8B,0x7C, - 0x0A,0x2B,0x7C,0x0C,0x74,0x31,0x80,0x4C,0x50,0x10,0x80,0x4C, - 0x4B,0x10,0xC7,0x04,0xC3,0x03,0xEB,0x23,0x90,0xFA,0x8B,0x36, - 0x08,0x0E,0x8B,0x54,0x20,0xEC,0x8A,0xF8,0x8A,0x5C,0x54,0x32, - 0xFB,0xF6,0x44,0x4D,0xFF,0x75,0x8E,0xF6,0x44,0x4C,0xFF,0x75, - 0xA1,0xF6,0x44,0x50,0x10,0x74,0xC7,0xEC,0x32,0xC3,0x22,0xF8, - 0x83,0x2E,0x10,0x0E,0x01,0x78,0x05,0xD0,0x6C,0x49,0x72,0x45, - 0x8B,0x7C,0x12,0x2B,0x7C,0x14,0x74,0x22,0x80,0x7C,0x4E,0x00, - 0x74,0x1C,0x23,0x7C,0x16,0x03,0xFF,0x3B,0x7C,0x16,0x73,0x43, - 0x8B,0x0E,0x0E,0x0E,0x2B,0x4C,0x6E,0x3B,0x4C,0x22,0x73,0x37, - 0x80,0x7C,0x49,0x00,0x74,0x31,0xF6,0x44,0x51,0x02,0x75,0x3C, - 0xEC,0x32,0xC3,0x22,0xF8,0x80,0xE7,0x38,0xFB,0x89,0x1E,0x30, - 0x0E,0xBE,0x00,0x10,0xFF,0x14,0xEB,0x61,0x90,0xB0,0x01,0xEE, - 0x8A,0x44,0x71,0x0C,0x10,0x88,0x44,0x71,0xEE,0x80,0x64,0x50, - 0xDF,0xC7,0x04,0xC3,0x03,0xEB,0xA5,0xC6,0x44,0x4E,0x00,0x8B, - 0x0E,0x0E,0x0E,0x89,0x4C,0x6E,0x80,0x4C,0x4F,0x08,0xEB,0xBE, - 0x8B,0x7C,0x12,0x2B,0x7C,0x14,0x23,0x7C,0x16,0x3B,0x7C,0x1A, - 0x73,0xB6,0x80,0x64,0x51,0xFD,0xF6,0x44,0x29,0x10,0x74,0x10, - 0x80,0x64,0x54,0xFB,0x80,0x4C,0x58,0x04,0x80,0x74,0x50,0x08, - 0xC7,0x04,0xC3,0x03,0xB0,0x05,0xEE,0xB0,0x82,0x22,0x44,0x5F, - 0x0A,0x44,0x75,0x88,0x44,0x75,0xEE,0xEB,0x8B,0xFA,0x8B,0x36, - 0x08,0x0E,0x8B,0x1E,0x30,0x0E,0x8A,0xCB,0xE5,0x80,0x23,0x44, - 0x2E,0x74,0x02,0xF6,0xD1,0x80,0xE1,0x40,0x0A,0xF9,0x8A,0xDF, - 0x22,0x5C,0x55,0x30,0x5C,0x54,0x32,0xFB,0x88,0x7C,0x55,0x0A, - 0x5C,0x58,0x88,0x5C,0x58,0x22,0x5C,0x56,0x75,0x24,0x80,0x7C, - 0x4F,0x00,0x75,0x22,0xFB,0x03,0x74,0x1E,0x89,0x36,0x08,0x0E, - 0xFF,0x06,0x26,0x0E,0x8B,0x3E,0x12,0x0D,0x3B,0x3E,0x10,0x0D, - 0x75,0x46,0xBE,0x00,0x10,0xFF,0x14,0xE9,0xD3,0xFE,0x80,0x4C, - 0x4F,0x20,0x8B,0x3E,0x18,0x0D,0x8A,0x44,0x48,0x8A,0x64,0x4F, - 0x89,0x85,0x00,0x08,0x8A,0x44,0x54,0x8A,0x64,0x57,0x89,0x85, - 0x02,0x08,0x83,0xC7,0x04,0x81,0xE7,0xFC,0x03,0x3B,0x3E,0x1A, - 0x0D,0x74,0x13,0x88,0x44,0x57,0xC6,0x44,0x4F,0x00,0x8A,0x44, - 0x56,0xF6,0xD0,0x20,0x44,0x58,0x89,0x3E,0x18,0x0D,0xEB,0xA4, - 0xFF,0x06,0x2C,0x0E,0xBE,0x00,0x10,0xFF,0x14,0xFA,0x8B,0x3E, - 0x12,0x0D,0x81,0xC7,0x00,0x04,0x8A,0x5D,0x01,0x83,0xE3,0x0F, - 0x03,0xDB,0x2E,0x8B,0xB7,0x89,0x00,0x8B,0x54,0x20,0x0B,0xD2, - 0x74,0x0D,0x8A,0x1D,0x83,0xE3,0x1F,0x03,0xDB,0xFA,0x2E,0xFF, - 0xA7,0x9C,0x0F,0xFF,0x06,0x2A,0x0E,0x8B,0x3E,0x12,0x0D,0x8B, - 0x36,0x18,0x0D,0x8B,0x9D,0x00,0x04,0x89,0x9C,0x00,0x08,0x8B, - 0x9D,0x02,0x04,0x89,0x9C,0x02,0x08,0x83,0xC6,0x04,0x81,0xE6, - 0xFC,0x03,0x3B,0x36,0x1A,0x0D,0x74,0x04,0x89,0x36,0x18,0x0D, - 0xFB,0x8B,0x3E,0x12,0x0D,0x83,0xC7,0x04,0x81,0xE7,0xFC,0x03, - 0x89,0x3E,0x12,0x0D,0xBE,0x00,0x10,0xFF,0x14,0xE9,0x1D,0xFE, - 0xDC,0x0F,0xE4,0x0F,0xEC,0x0F,0x0D,0x10,0x1C,0x10,0x57,0x0F, - 0x2F,0x10,0x57,0x0F,0x3B,0x10,0x54,0x10,0x83,0x10,0xCF,0x10, - 0xDB,0x10,0xE4,0x10,0xEB,0x10,0x35,0x11,0x7D,0x11,0x83,0x11, - 0xA1,0x11,0xB9,0x11,0xF2,0x11,0x38,0x12,0x03,0x13,0x0C,0x13, - 0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F,0x57,0x0F, - 0x57,0x0F,0x57,0x0F,0x8B,0x45,0x02,0x89,0x44,0x1A,0xEB,0xA0, - 0x8B,0x45,0x02,0x89,0x44,0x1C,0xEB,0x98,0x8B,0x45,0x02,0x8B, - 0x5C,0x0A,0x2B,0x5C,0x0C,0x23,0x5C,0x0E,0x8B,0x4C,0x0A,0x2B, - 0xC8,0x23,0x4C,0x0E,0x3B,0xD9,0x76,0x06,0x23,0x44,0x0E,0x89, - 0x44,0x0C,0xE9,0x77,0xFF,0x80,0x4C,0x53,0x80,0x80,0x4C,0x54, - 0x01,0x80,0x4C,0x58,0x01,0xE9,0x68,0xFF,0x80,0x64,0x53,0x3F, - 0x80,0x64,0x54,0xFE,0x80,0x4C,0x58,0x01,0x80,0x64,0x51,0xFB, - 0xE9,0x55,0xFF,0x8B,0x45,0x02,0x88,0x44,0x5A,0x88,0x64,0x5B, - 0xE9,0x49,0xFF,0x8B,0x45,0x02,0x0B,0xC0,0x74,0x03,0x89,0x44, - 0x24,0x80,0x4C,0x50,0x04,0x80,0x4C,0x4B,0x04,0xC7,0x04,0xC3, - 0x03,0xE9,0x30,0xFF,0x8B,0x5D,0x02,0xF6,0xD7,0x22,0x7C,0x54, - 0x0A,0xDF,0x8A,0x44,0x54,0x32,0xC3,0x24,0x82,0x30,0x44,0x54, - 0xB0,0x05,0xEE,0x8A,0x44,0x75,0x32,0xD8,0x8A,0x7C,0x5F,0xF6, - 0xD7,0x22,0xDF,0x80,0xE3,0x82,0x32,0xC3,0x88,0x44,0x75,0xEE, - 0xE9,0x01,0xFF,0x8B,0x5D,0x02,0xF6,0xC7,0x04,0x75,0x08,0x80, - 0x64,0x53,0x3F,0x80,0x64,0x51,0xFB,0x8A,0x44,0x29,0x32,0xC7, - 0xA8,0x10,0x74,0x0E,0xF6,0x44,0x51,0x02,0x74,0x08,0x80,0x74, - 0x50,0x08,0xC7,0x04,0xC3,0x03,0x88,0x5C,0x28,0x88,0x7C,0x29, - 0xB4,0x60,0xF6,0xC3,0x10,0x74,0x03,0x80,0xCC,0x10,0x8A,0x44, - 0x62,0xF6,0xC3,0x20,0x74,0x02,0x24,0x7F,0x89,0x44,0x34,0xC7, - 0x44,0x06,0xE1,0x08,0xE9,0xB5,0xFE,0x8B,0x45,0x02,0x88,0x44, - 0x5C,0x88,0x64,0x5D,0xE9,0xA9,0xFE,0x8B,0x45,0x02,0x89,0x44, - 0x18,0xE9,0xA0,0xFE,0xFF,0x1E,0x24,0x0D,0xE9,0x99,0xFE,0xF6, - 0x44,0x51,0x02,0x75,0x41,0x8B,0x44,0x12,0x2B,0x44,0x14,0x23, - 0x44,0x16,0x3B,0x44,0x1A,0x72,0x33,0x80,0x4C,0x51,0x02,0xF6, - 0x44,0x29,0x10,0x74,0x10,0x80,0x4C,0x54,0x04,0x80,0x4C,0x58, - 0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03,0xF6,0x44,0x5F, - 0x82,0x74,0x13,0xB0,0x05,0xEE,0x8A,0x44,0x75,0xB4,0x82,0x22, - 0x64,0x5F,0xF6,0xD4,0x22,0xC4,0x88,0x44,0x75,0xEE,0xE9,0x4F, - 0xFE,0xF6,0x44,0x51,0x02,0x74,0x3F,0x8B,0x44,0x12,0x2B,0x44, - 0x14,0x23,0x44,0x16,0x3B,0x44,0x1C,0x73,0xE9,0x80,0x64,0x51, - 0xFD,0xF6,0x44,0x29,0x10,0x74,0x10,0x80,0x64,0x54,0xFB,0x80, - 0x4C,0x58,0x04,0x80,0x74,0x50,0x08,0xC7,0x04,0xC3,0x03,0xF6, - 0x44,0x5F,0x02,0x74,0x11,0xB0,0x05,0xEE,0x8A,0x44,0x75,0xB4, - 0x82,0x22,0x64,0x5F,0x0A,0xC4,0x88,0x44,0x75,0xEE,0xE9,0x07, - 0xFE,0xE8,0x8A,0x02,0xE9,0x01,0xFE,0x8B,0x45,0x02,0xBB,0x10, - 0x27,0xF7,0xE3,0xBB,0x0F,0x00,0xF7,0xF3,0xA3,0x06,0x0E,0xBA, - 0x52,0xFF,0xEF,0xBA,0x50,0xFF,0xB8,0x00,0x00,0xEF,0xE9,0xE3, - 0xFD,0x8B,0x45,0x02,0x3A,0x06,0x22,0x0C,0x72,0x0C,0x3B,0x06, - 0x1A,0x0C,0x77,0x06,0xE8,0xAB,0x01,0xE9,0xCE,0xFD,0xE9,0x9E, - 0xFD,0x8B,0x45,0x02,0x88,0x44,0x2A,0x88,0x64,0x2B,0x0B,0xC0, - 0x75,0x07,0x80,0x64,0x50,0xFE,0xEB,0x10,0x90,0xF6,0x44,0x50, - 0x01,0x75,0x09,0x80,0x4C,0x50,0x01,0xC7,0x44,0x30,0x00,0x00, - 0xA8,0x80,0x75,0x07,0xC6,0x44,0x60,0x00,0xEB,0x05,0x90,0xC6, - 0x44,0x60,0x7F,0xC7,0x04,0xC3,0x03,0xE9,0x92,0xFD,0x8B,0x5D, - 0x02,0xF6,0xD7,0x22,0x7C,0x5F,0x0A,0xDF,0x8A,0xFB,0x88,0x5C, - 0x5F,0x8A,0x44,0x52,0x8A,0x64,0x53,0x8B,0xCB,0x33,0xC8,0x81, - 0xE1,0x38,0x38,0x33,0xC1,0x88,0x44,0x52,0x88,0x64,0x53,0xB0, - 0x05,0xEE,0xF6,0xD3,0x22,0x5C,0x54,0xF6,0x44,0x51,0x02,0x75, - 0x02,0x0A,0xDF,0x8A,0x44,0x75,0x32,0xD8,0x80,0xE3,0x82,0x32, - 0xC3,0x88,0x44,0x75,0xEE,0xE9,0x4C,0xFD,0x8B,0x5D,0x02,0x88, - 0x5C,0x2C,0x88,0x7C,0x2D,0x8B,0xCB,0x83,0xE3,0x0F,0x03,0xDB, - 0x80,0x3E,0x10,0x0C,0x01,0x75,0x1F,0xA1,0x0E,0x0C,0x86,0xE0, - 0x3D,0x32,0x31,0x73,0x15,0xF6,0xC5,0x04,0x75,0x08,0x2E,0x8B, - 0x9F,0x69,0x01,0xEB,0x1B,0x90,0x2E,0x8B,0x9F,0x89,0x01,0xEB, - 0x13,0x90,0xF6,0xC5,0x04,0x75,0x08,0x2E,0x8B,0x9F,0x29,0x01, - 0xEB,0x06,0x90,0x2E,0x8B,0x9F,0x49,0x01,0xB0,0x0C,0xEE,0x8A, - 0xC3,0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0x8A,0xC7, - 0x88,0x44,0x7D,0xEE,0xB0,0x04,0xEE,0xB0,0x44,0xF6,0xC1,0x40, - 0x74,0x0C,0xF6,0xC1,0x80,0x74,0x05,0x04,0x04,0xEB,0x03,0x90, - 0x0C,0x08,0xF6,0xC5,0x01,0x74,0x09,0x0C,0x01,0xF6,0xC5,0x02, - 0x75,0x02,0x0C,0x02,0x88,0x44,0x74,0xEE,0xB0,0x03,0x90,0x90, - 0xEE,0x8A,0xD9,0x80,0xE3,0x30,0xC0,0xEB,0x04,0x32,0xFF,0x2E, - 0x8A,0xA7,0xA9,0x01,0x8A,0x44,0x73,0x24,0x3F,0x0A,0xC4,0x88, - 0x44,0x73,0xEE,0x90,0x90,0xB0,0x05,0xEE,0xD0,0xEC,0x8A,0x44, - 0x75,0x24,0x9F,0x0A,0xC4,0x88,0x44,0x75,0xEE,0x2E,0x8A,0x87, - 0xAD,0x01,0x88,0x44,0x62,0xF6,0x44,0x28,0x20,0x74,0x02,0x24, - 0x7F,0x88,0x44,0x34,0xE9,0x81,0xFC,0x8A,0x45,0x02,0x88,0x44, - 0x5E,0xE9,0x78,0xFC,0x8B,0x45,0x02,0xBA,0x5A,0xFF,0xEF,0x9C, - 0xFF,0x36,0x26,0x0D,0xFF,0x36,0x24,0x0D,0x1E,0x06,0x60,0x8B, - 0x36,0x0A,0x0E,0xC7,0x04,0x3F,0x0D,0xE9,0x5A,0xFC,0xB8,0x00, - 0x00,0x8E,0xC0,0x8B,0xF0,0x8B,0xF8,0x2E,0x8B,0x9C,0x49,0x00, - 0x83,0xC6,0x02,0x26,0x89,0x1D,0x26,0x8C,0x4D,0x02,0x83,0xC7, - 0x04,0x81,0xFF,0x80,0x00,0x72,0xE8,0x26,0xC7,0x05,0xCB,0x0C, - 0x26,0x8C,0x4D,0x02,0x83,0xC7,0x04,0x81,0xFF,0x00,0x04,0x72, - 0xEE,0xC3,0xC1,0xE0,0x06,0x8B,0xD8,0x8C,0xDA,0x81,0xC2,0x00, - 0x04,0x8B,0xFA,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE,0x00,0x10, - 0x33,0xC0,0x89,0x44,0x0A,0x89,0x44,0x0C,0x89,0x44,0x12,0x89, - 0x44,0x14,0x81,0xC6,0x80,0x00,0xE2,0xEE,0x89,0x36,0x0A,0x0E, - 0xB8,0x01,0x00,0x8B,0xD0,0xB3,0x00,0x8A,0x0E,0x22,0x0C,0xB5, - 0x00,0xBE,0x00,0x10,0x2B,0xDA,0x72,0x29,0x89,0x44,0x16,0x81, - 0xC6,0x80,0x00,0xE2,0xF3,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE, - 0x00,0x10,0x2B,0xDA,0x72,0x13,0x89,0x44,0x0E,0x81,0xC6,0x80, - 0x00,0xE2,0xF3,0x8B,0xD0,0x03,0xC0,0x81,0xFA,0x00,0x02,0x72, - 0xCA,0x8A,0x0E,0x22,0x0C,0xB5,0x00,0xBE,0x00,0x10,0x89,0x7C, - 0x10,0x8B,0x44,0x16,0x03,0xF8,0x8B,0xD7,0xC1,0xE0,0x04,0x48, - 0x89,0x44,0x16,0x81,0xC6,0x80,0x00,0xE2,0xE9,0x8A,0x0E,0x22, - 0x0C,0xB5,0x00,0xBE,0x00,0x10,0x89,0x7C,0x08,0x8B,0x44,0x0E, - 0x03,0xF8,0x8B,0xD7,0xC1,0xE0,0x04,0x48,0x89,0x44,0x0E,0x81, - 0xC6,0x80,0x00,0xE2,0xE9,0xC3,0xC7,0x04,0x20,0x04,0xC7,0x44, - 0x06,0xE1,0x08,0x8B,0xC6,0x2D,0x00,0x10,0xB1,0x80,0xF6,0xF1, - 0x88,0x44,0x48,0xC7,0x44,0x0A,0x00,0x00,0xC7,0x44,0x0C,0x00, - 0x00,0xC7,0x44,0x12,0x00,0x00,0xC7,0x44,0x14,0x00,0x00,0xC7, - 0x44,0x18,0x00,0x00,0xC7,0x44,0x1A,0x00,0x00,0xC7,0x44,0x1C, - 0xFF,0xFF,0x8A,0x5C,0x48,0x83,0xE3,0x0F,0x03,0xDB,0x8B,0x97, - 0x90,0x0C,0x89,0x54,0x20,0xB8,0x01,0x00,0x8A,0x4C,0x48,0xD3, - 0xE0,0x89,0x44,0x2E,0xC7,0x44,0x24,0x19,0x00,0xC7,0x44,0x26, - 0x00,0x00,0xC6,0x44,0x4A,0x00,0xC7,0x44,0x30,0x00,0x00,0xC7, - 0x44,0x32,0x00,0x00,0xC6,0x44,0x4C,0x00,0xC6,0x44,0x4D,0x00, - 0xC6,0x44,0x4E,0x00,0xC6,0x44,0x4F,0x00,0xC6,0x44,0x50,0x00, - 0xC6,0x44,0x4B,0x00,0xC6,0x44,0x51,0x00,0xC6,0x44,0x28,0x00, - 0xC6,0x44,0x29,0x00,0xC6,0x44,0x2A,0x00,0xC6,0x44,0x2B,0x00, - 0xC6,0x44,0x54,0x00,0xC6,0x44,0x57,0x00,0xC6,0x44,0x55,0x00, - 0xC6,0x44,0x56,0x00,0xC6,0x44,0x58,0x00,0xC6,0x44,0x52,0x04, - 0xC6,0x44,0x53,0x04,0xC6,0x44,0x5F,0x00,0xC6,0x44,0x2C,0x3D, - 0xC6,0x44,0x2D,0x00,0xC7,0x44,0x34,0xFF,0x60,0xC6,0x44,0x62, - 0xFF,0xC6,0x44,0x5D,0x13,0xC6,0x44,0x5C,0x11,0xC6,0x44,0x5E, - 0x00,0xC6,0x44,0x60,0x23,0xC6,0x44,0x61,0x23,0x0B,0xD2,0x75, - 0x03,0xE9,0xD9,0x00,0xB0,0x09,0xEE,0x8A,0x4C,0x48,0xB0,0x80, - 0xD2,0xE8,0xEE,0xC6,0x44,0x70,0x00,0xB0,0x01,0xEE,0xB0,0x11, - 0x88,0x44,0x71,0xEE,0xB0,0x02,0x90,0x90,0xEE,0x8A,0x44,0x48, - 0xC0,0xE0,0x03,0x24,0xF0,0x88,0x44,0x72,0xEE,0xB0,0x03,0x90, - 0x90,0xEE,0xB0,0xC0,0x88,0x44,0x73,0xEE,0xB0,0x04,0x90,0x90, - 0xEE,0xB0,0x44,0x88,0x44,0x74,0xEE,0xB0,0x05,0x90,0xEE,0xB0, - 0x60,0x88,0x44,0x75,0xEE,0xC6,0x44,0x76,0x00,0xC6,0x44,0x77, - 0x00,0xC6,0x44,0x78,0x00,0xB0,0x09,0xEE,0xB0,0x09,0x88,0x44, - 0x79,0xEE,0xC6,0x44,0x7A,0x00,0xB0,0x0B,0xEE,0xB0,0x52,0x88, - 0x44,0x7B,0xEE,0x80,0x3E,0x10,0x0C,0x01,0x75,0x21,0xA1,0x0E, - 0x0C,0x86,0xE0,0x3D,0x32,0x31,0x73,0x17,0xB0,0x0C,0xEE,0xB0, - 0x18,0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0xB0,0x00, - 0x88,0x44,0x7D,0xEE,0xEB,0x15,0x90,0xB0,0x0C,0xEE,0xB0,0x16, - 0x88,0x44,0x7C,0xEE,0xB0,0x0D,0x90,0x90,0xEE,0xB0,0x00,0x88, - 0x44,0x7D,0xEE,0xB0,0x0E,0x90,0x90,0xEE,0xB0,0x03,0x88,0x44, - 0x7E,0xEE,0xB0,0x0F,0x90,0x90,0xEE,0xB0,0x80,0x88,0x44,0x7F, - 0xEE,0xB0,0x03,0x90,0x90,0xEE,0x8A,0x44,0x73,0x0C,0x01,0x88, - 0x44,0x73,0xEE,0x90,0x90,0xB0,0x05,0xEE,0x8A,0x44,0x75,0x0C, - 0x08,0x88,0x44,0x75,0xEE,0xC3,0xFA,0x8C,0xD8,0x25,0x00,0xF0, - 0x8E,0xD0,0xBC,0xFE,0x1F,0x8C,0xD8,0x25,0x00,0xF0,0x8E,0xD8, - 0x80,0x3E,0x40,0x0D,0x01,0x75,0x51,0xA1,0x0E,0x0C,0x86,0xE0, - 0x3D,0x30,0x32,0x73,0x47,0x8B,0x1E,0x20,0x0C,0x8A,0x16,0x23, - 0x0C,0xC6,0x06,0x23,0x0C,0x00,0x83,0xFB,0x00,0x74,0x07,0xFE, - 0xCA,0xC6,0x06,0x23,0x0C,0x01,0x88,0x16,0x22,0x0C,0xBE,0x10, - 0x0C,0xBF,0x90,0x0C,0xB9,0x08,0x00,0x1E,0x07,0xFC,0xF3,0xA5, - 0xBF,0xA0,0x0C,0xB8,0x00,0x00,0xB9,0x08,0x00,0xF3,0xAB,0xC7, - 0x06,0x1A,0x0C,0x70,0x00,0xA0,0x40,0x0D,0xA2,0x10,0x0C,0xC6, - 0x06,0x11,0x0C,0x00,0x2E,0x8C,0x1E,0xC1,0x03,0xC7,0x06,0x18, - 0x0E,0x02,0x00,0xE8,0xEC,0xFC,0xC7,0x06,0x24,0x0D,0x5A,0x0D, - 0x8C,0x0E,0x26,0x0D,0xC7,0x06,0x18,0x0E,0x06,0x00,0xA1,0x1A, - 0x0C,0xE8,0x0A,0xFD,0xC7,0x06,0x18,0x0E,0x0A,0x00,0xBE,0x00, - 0x10,0xC7,0x44,0x1E,0x80,0x00,0xE8,0xA5,0xFD,0x81,0xC6,0x80, - 0x00,0x81,0xFE,0x00,0x18,0x72,0xEE,0xA0,0x22,0x0C,0xB4,0x80, - 0xF6,0xE4,0xBE,0x00,0x10,0x03,0xF0,0x89,0x36,0x0A,0x0E,0x29, - 0x44,0x9E,0xC7,0x06,0x00,0x0E,0x00,0x00,0xC7,0x06,0x02,0x0E, - 0x00,0x00,0xC7,0x06,0x04,0x0E,0x00,0x00,0xC7,0x06,0x06,0x0E, - 0x9A,0x02,0xBA,0x52,0xFF,0xA1,0x06,0x0E,0xEF,0xBA,0x50,0xFF, - 0xB8,0x00,0x00,0xEF,0xBA,0x56,0xFF,0xB8,0x05,0xE0,0xEF,0xBA, - 0x5E,0xFF,0xB8,0x00,0x40,0xEF,0xBA,0x66,0xFF,0xB8,0x00,0x40, - 0xEF,0xC7,0x06,0x10,0x0D,0x00,0x00,0xC7,0x06,0x12,0x0D,0x00, - 0x00,0xC7,0x06,0x14,0x0D,0x00,0x04,0xC7,0x06,0x16,0x0D,0xFC, - 0x03,0xC7,0x06,0x18,0x0D,0x00,0x00,0xC7,0x06,0x1A,0x0D,0x00, - 0x00,0xC7,0x06,0x1C,0x0D,0x00,0x08,0xC7,0x06,0x1E,0x0D,0xFC, - 0x03,0xB0,0x00,0x90,0xE6,0x00,0xC7,0x06,0x18,0x0E,0x32,0x00, - 0xBA,0x38,0xFF,0xB8,0x11,0x00,0xEF,0xBA,0x3A,0xFF,0xB8,0x08, - 0x00,0xEF,0xBA,0x3C,0xFF,0xB8,0x08,0x00,0xEF,0xBA,0x3E,0xFF, - 0xB8,0x08,0x00,0x80,0x3E,0x22,0x0C,0x08,0x76,0x03,0xB8,0x12, - 0x00,0xEF,0xBA,0x32,0xFF,0xB8,0x05,0x00,0xEF,0xBA,0x28,0xFF, - 0xB8,0x6C,0x00,0xEF,0xBA,0x22,0xFF,0xB8,0x00,0x80,0xEF,0xC7, - 0x06,0x18,0x0E,0x33,0x00,0xC7,0x06,0x20,0x0D,0x4F,0x00,0xC7, - 0x06,0x21,0x0D,0x53,0x00,0x8B,0x36,0x0A,0x0E,0xC7,0x04,0x3C, - 0x0D,0xC7,0x06,0x08,0x0E,0x00,0x10,0xE9,0x63,0xF6,0x40,0x28, - 0x23,0x29,0x20,0x24,0x49,0x64,0x3A,0x20,0x78,0x61,0x63,0x6F, - 0x6F,0x6B,0x2E,0x61,0x73,0x6D,0x2C,0x76,0x20,0x37,0x2E,0x32, - 0x35,0x20,0x31,0x39,0x39,0x35,0x2F,0x30,0x31,0x2F,0x31,0x32, - 0x20,0x32,0x30,0x3A,0x35,0x39,0x3A,0x32,0x31,0x20,0x6D,0x69, - 0x6C,0x74,0x20,0x45,0x78,0x70,0x20,0x24,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -}; - -static unsigned pcxx_ncook=sizeof(pcxx_cook); diff --git a/sys/gnu/i386/isa/dgreg.h b/sys/gnu/i386/isa/dgreg.h deleted file mode 100644 index 8bf90f0..0000000 --- a/sys/gnu/i386/isa/dgreg.h +++ /dev/null @@ -1,360 +0,0 @@ -/*- - * dgreg.h $Id: dgreg.h,v 1.1 1995/09/03 19:52:55 jkh Exp $ - * - * Digiboard driver. - * - * Stage 1. "Better than nothing". - * - * Based on sio driver by Bruce Evans and on Linux driver by Troy - * De Jongh <troyd@digibd.com> or <troyd@skypoint.com> - * which is under GNU General Public License version 2 so this driver - * is forced to be under GPL 2 too. - * - * Written by Serge Babkin, - * Joint Stock Commercial Bank "Chelindbank" - * (Chelyabinsk, Russia) - * babkin@hq.icb.chel.su - */ - -#define DEBUG - -#define MAX_DGB_PORTS 32 - -/* digi.h */ -/* Definitions for DigiBoard ditty(1) command. */ - -#if !defined(TIOCMODG) -#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */ -#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */ -#endif - -#if !defined(TIOCMSET) -#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */ -#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */ -#endif - -#if !defined(TIOCMBIC) -#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */ -#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */ -#endif - -#if !defined(TIOCSDTR) -#define TIOCSDTR ('e'<<8) | 0 /* set DTR */ -#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */ -#endif - -/************************************************************************ - * Ioctl command arguments for DIGI parameters. - ************************************************************************/ -#define DIGI_GETA ('e'<<8) | 94 /* Read params */ - -#define DIGI_SETA ('e'<<8) | 95 /* Set params */ -#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */ -#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */ - -#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */ - /* control characters */ -#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */ - /* control characters */ -#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */ - /* flow control chars */ -#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */ - /* flow control chars */ - -struct digiflow_struct { - unsigned char startc; /* flow cntl start char */ - unsigned char stopc; /* flow cntl stop char */ -}; - -typedef struct digiflow_struct digiflow_t; - - -/************************************************************************ - * Values for digi_flags - ************************************************************************/ -#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ -#define DIGI_FAST 0x0002 /* Fast baud rates */ -#define RTSPACE 0x0004 /* RTS input flow control */ -#define CTSPACE 0x0008 /* CTS output flow control */ -#define DSRPACE 0x0010 /* DSR output flow control */ -#define DCDPACE 0x0020 /* DCD output flow control */ -#define DTRPACE 0x0040 /* DTR input flow control */ -#define DIGI_FORCEDCD 0x0100 /* Force carrier */ -#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ -#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ - - -/************************************************************************ - * Structure used with ioctl commands for DIGI parameters. - ************************************************************************/ -struct digi_struct { - unsigned short digi_flags; /* Flags (see above) */ -}; - -typedef struct digi_struct digi_t; - -/* fep.h */ - -#define FEP_CSTART 0x400L -#define FEP_CMAX 0x800L -#define FEP_ISTART 0x800L -#define FEP_IMAX 0xC00L -#define FEP_CIN 0xD10L -#define FEP_GLOBAL 0xD10L -#define FEP_EIN 0xD18L -#define FEPSTAT 0xD20L -#define CHANSTRUCT 0x1000L -#define RXTXBUF 0x4000L - - -struct global_data { - volatile ushort cin; - volatile ushort cout; - volatile ushort cstart; - volatile ushort cmax; - volatile ushort ein; - volatile ushort eout; - volatile ushort istart; - volatile ushort imax; -}; - - -struct board_chan { - int filler1; - int filler2; - volatile ushort tseg; - volatile ushort tin; - volatile ushort tout; - volatile ushort tmax; - - volatile ushort rseg; - volatile ushort rin; - volatile ushort rout; - volatile ushort rmax; - - volatile ushort tlow; - volatile ushort rlow; - volatile ushort rhigh; - volatile ushort incr; - - volatile ushort etime; - volatile ushort edelay; - volatile u_char *dev; - - volatile ushort iflag; - volatile ushort oflag; - volatile ushort cflag; - volatile ushort gmask; - - volatile ushort col; - volatile ushort delay; - volatile ushort imask; - volatile ushort tflush; - - int filler3; - int filler4; - int filler5; - int filler6; - - volatile u_char num; - volatile u_char ract; - volatile u_char bstat; - volatile u_char tbusy; - volatile u_char iempty; - volatile u_char ilow; - volatile u_char idata; - volatile u_char eflag; - - volatile u_char tflag; - volatile u_char rflag; - volatile u_char xmask; - volatile u_char xval; - volatile u_char mstat; - volatile u_char mchange; - volatile u_char mint; - volatile u_char lstat; - - volatile u_char mtran; - volatile u_char orun; - volatile u_char startca; - volatile u_char stopca; - volatile u_char startc; - volatile u_char stopc; - volatile u_char vnext; - volatile u_char hflow; - - volatile u_char fillc; - volatile u_char ochar; - volatile u_char omask; - - u_char filler7; - u_char filler8[28]; -}; - - -#define SRXLWATER 0xE0 -#define SRXHWATER 0xE1 -#define STOUT 0xE2 -#define PAUSETX 0xE3 -#define RESUMETX 0xE4 -#define SAUXONOFFC 0xE6 -#define SENDBREAK 0xE8 -#define SETMODEM 0xE9 -#define SETIFLAGS 0xEA -#define SONOFFC 0xEB -#define STXLWATER 0xEC -#define PAUSERX 0xEE -#define RESUMERX 0xEF -#define SETBUFFER 0xF2 -#define SETCOOKED 0xF3 -#define SETHFLOW 0xF4 -#define SETCTRLFLAGS 0xF5 -#define SETVNEXT 0xF6 - - - -#define BREAK_IND 0x01 -#define LOWTX_IND 0x02 -#define EMPTYTX_IND 0x04 -#define DATA_IND 0x08 -#define MODEMCHG_IND 0x20 - -#define ALL_IND (BREAK_IND|LOWTX_IND|EMPTYTX_IND|DATA_IND|MODEMCHG_IND) - - -#define RTS 0x02 -#define CD 0x08 -#define DSR 0x10 -#define CTS 0x20 -#define RI 0x40 -#define DTR 0x80 - -/* pcxx.h */ - -#define FEPCODESEG 0x0200L -#define FEPCODE 0x2000L -#define BIOSCODE 0xf800L - -#define MISCGLOBAL 0x0C00L -#define NPORT 0x0C22L -#define MBOX 0x0C40L -#define PORTBASE 0x0C90L -#define BOTWIN 0x100L -#define TOPWIN 0xFF00L - -#define FEPCLR 0x00 -#define FEPMEM 0x02 -#define FEPRST 0x04 -#define FEPINT 0x08 -#define FEPMASK 0x0e -#define FEPWIN 0x80 - -#define PCXI 0 -#define PCXE 1 -#define PCXEVE 2 - -static char *board_desc[] = { - "PC/Xi (64K)", - "PC/Xe (64K)", - "PC/Xe (8K) ", -}; - -#define STARTC 021 -#define STOPC 023 -#define IAIXON 0x2000 - - -struct board_info { - u_char status; - u_char type; - u_char altpin; - ushort numports; - ushort port; - u_long membase; -}; - - -#define TXSTOPPED 0x1 -#define LOWWAIT 0x2 -#define EMPTYWAIT 0x4 - -#define DISABLED 0 -#define ENABLED 1 -#define OFF 0 -#define ON 1 - -#define FEPTIMEOUT 200000 -#define SERIAL_TYPE_NORMAL 1 -#define SERIAL_TYPE_CALLOUT 2 -#define PCXE_EVENT_HANGUP 1 - -struct channel { - u_char unit; /* board unit number */ - u_char omodem; /* FEP output modem status */ - u_char imodem; /* FEP input modem status */ - u_char modemfake; /* Modem values to be forced */ - u_char modem; /* Force values */ - u_char hflow; - u_char dsr; - u_char dcd; - u_char stopc; - u_char startc; - u_char stopca; - u_char startca; - u_char fepstopc; - u_char fepstartc; - u_char fepstopca; - u_char fepstartca; - u_char txwin; - u_char rxwin; - ushort fepiflag; - ushort fepcflag; - ushort fepoflag; - ushort txbufhead; - ushort txbufsize; - ushort rxbufhead; - ushort rxbufsize; - int close_delay; - int count; - int blocked_open; - int event; - int asyncflags; - uint dev; - long session; - long pgrp; - u_long statusflags; - u_long c_iflag; - u_long c_cflag; - u_long c_lflag; - u_long c_oflag; - u_char *txptr; - u_char *rxptr; - struct board_info *board; - struct board_chan *brdchan; - struct digi_struct digiext; - struct tty *tty; - struct termios normal_termios; - struct termios callout_termios; - volatile struct global_data *mailbox; -}; - -/* flags for configuring */ - -#define DGBFLAG_ALTPIN 0x0001 /* chande DCD and DCD */ -#define DGBFLAG_NOWIN 0x0002 /* use windowed PC/Xe as non-windowed */ - -/* debugging printout */ - -#ifdef DEBUG -# define DPRINT1(a1) (dgbdebug ? printf(a1) : 0) -# define DPRINT2(a1,a2) (dgbdebug ? printf(a1,a2) : 0) -# define DPRINT3(a1,a2,a3) (dgbdebug ? printf(a1,a2,a3) : 0) -# define DPRINT4(a1,a2,a3,a4) (dgbdebug ? printf(a1,a2,a3,a4) : 0) -# define DPRINT5(a1,a2,a3,a4,a5) (dgbdebug ? printf(a1,a2,a3,a4,a5) : 0) -#else -# define DPRINT1(a1) -# define DPRINT2(a1,a2) -# define DPRINT3(a1,a2,a3) -# define DPRINT4(a1,a2,a3,a4) -# define DPRINT5(a1,a2,a3,a4,a5) -#endif diff --git a/sys/gnu/i386/isa/nic3008.c b/sys/gnu/i386/isa/nic3008.c deleted file mode 100644 index e329112..0000000 --- a/sys/gnu/i386/isa/nic3008.c +++ /dev/null @@ -1,1172 +0,0 @@ -static char nic38_id[] = "@(#)$Id: nic3008.c,v 1.6 1995/05/30 07:57:57 rgrimes Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.6 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: nic3008.c,v $ - * Revision 1.6 1995/05/30 07:57:57 rgrimes - * Remove trailing whitespace. - * - * Revision 1.5 1995/05/11 19:25:55 rgrimes - * Fix -Wformat warnings from LINT kernel. - * - * Revision 1.4 1995/03/28 07:54:31 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.3 1995/03/19 14:28:35 davidg - * Removed redundant newlines that were in some panic strings. - * - * Revision 1.2 1995/02/15 11:59:40 jkh - * Fix a few more nits. Should compile better now! :_) - * - * Revision 1.1 1995/02/14 15:00:10 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -/* - * Copyright (c) 1994 Dietmar Friede (dietmar@friede.de) All rights reserved. - * FSF/FSAG GNU Copyright applies - * - * A low level driver for the NICCY-3008 ISDN Card. - * - */ - -#include "nic.h" -#if NNIC > 0 - -#include "param.h" -#include "ioctl.h" -#include "kernel.h" -#include "systm.h" -#include <sys/proc.h> - -#include "i386/isa/isa_device.h" -#include "gnu/i386/isa/nic3008.h" -#include "gnu/i386/isa/niccyreg.h" -#include "gnu/isdn/isdn_ioctl.h" - -#define OPEN 1 -#define LOAD_HEAD 3 -#define LOAD_DATA 5 -#define IS_DIAL(p) (((p)&0x20)==0) -#define IS_LISTEN(p) ((p)&0x20) -#define CHAN(pl) (((pl)&7)-1) -#define C_CHAN(x) ((x)&1) -#define APPL(pl) ((((pl)>>6)&0x7f)-1) -#define CARD(pl) (((pl)>>13)&7) -#define MK_APPL(pl) (((pl)+1)<<6) - -#define con_act_resp(sc,pl) en_q_d(sc,DD_CONN_ACT_RSP, pl ,0,NULL) -#define discon_resp(sc,pl) en_q_d(sc,DD_DISC_RSP, pl ,0,NULL) -#define inf_resp(sc,pl) en_q_d(sc,DD_INFO_RSP, pl ,0,NULL) -#define listen_b3_req(sc,mb,pl) en_q_b(sc,mb,BD_LIST_B3_REQ,pl,0,NULL) -#define con_b3_req(sc,mb,pl) en_q_b(sc,mb,BD_CONN_B3_REQ,pl,0,NULL) -#define min(a,b) ((a)<(b)?(a):(b)) - -extern isdn_appl_t isdn_appl[]; -extern u_short isdn_state; -extern isdn_ctrl_t isdn_ctrl[]; -extern int ispy_applnr; -extern int Isdn_Appl, Isdn_Ctrl, Isdn_Typ; - -static old_spy= 0; - -int nicprobe(), nicattach(); -int nic_connect(), nic_listen(), nic_disconnect(), nic_accept(); -int nic_output(); -extern void isdn_start_out(); - -static void s_intr(), reset_req(), reset_card(); -static int cstrcmp(), discon_req(), reset_plci(), sel_b2_prot_req(); - -static short bsintr; - -struct isa_driver nicdriver = {nicprobe, nicattach, "nic"}; - -typedef enum -{ - DISCON, ISDISCON, DIAL, CALLED, CONNECT, IDLE, ACTIVE -} io_state; -typedef struct -{ - char ctrl; - u_char msg_nr; - u_char morenr; - short plci; - short ncci; - short state; - short i_len; - char i_buf[2048]; - char o_buf[2048]; - u_short more; - char *more_b; -} chan_t; - -struct nic_softc -{ - dpr_type *sc_dpr; /* card RAM virtual memory base */ - u_short sc_vector; /* interrupt vector */ - short sc_port; - u_char sc_flags; - u_char sc_unit; - u_char sc_ctrl; - short sc_stat; - chan_t sc_chan[2]; -} nic_sc[NNIC]; - - -int -nicprobe(struct isa_device * is) -{ - register struct nic_softc *sc = &nic_sc[is->id_unit & 127]; - dpr_type *dpr; - - sc->sc_vector = is->id_irq; - sc->sc_port = is->id_iobase; - sc->sc_unit = is->id_unit; - dpr = sc->sc_dpr = (dpr_type *) is->id_maddr; - - if (cstrcmp(dpr->niccy_ver, "NICCY V ") == 0) - { - printf("NICCY NICCY-Card %d not found at %p\n" - ,is->id_unit, is->id_maddr); - return (0); - } - while (dpr->card_state & 1); /* self test running */ - - if (dpr->card_state & 0x8A) - { - printf("Check Niccy Card, error state %d \n", dpr->card_state); - return (0); - } - dpr->card_number = is->id_unit; - is->id_msize = 8192; - reset_card(sc); - return (8); -} - -/* - * nicattach() Install device - */ -int -nicattach(struct isa_device * is) -{ - struct nic_softc *sc; - dpr_type *dpr; - int cn; - isdn_ctrl_t *ctrl0, *ctrl1; - - sc = &nic_sc[is->id_unit]; - dpr = sc->sc_dpr; - sc->sc_ctrl = -1; - if ((cn = isdn_ctrl_attach(2)) == -1) - { - return (0); - } - sc->sc_ctrl = cn; - - sc->sc_chan[0].plci = sc->sc_chan[1].plci = -1; - - ctrl0 = &isdn_ctrl[cn]; - ctrl1 = &isdn_ctrl[cn + 1]; - sc->sc_chan[0].ctrl = ctrl0->ctrl = cn; - sc->sc_chan[1].ctrl = ctrl1->ctrl = cn + 1; - ctrl0->o_buf = sc->sc_chan[0].o_buf; - ctrl1->o_buf = sc->sc_chan[1].o_buf; - ctrl0->listen = ctrl1->listen = nic_listen; - ctrl0->disconnect = ctrl1->disconnect = nic_disconnect; - ctrl0->accept = ctrl1->accept = nic_accept; - ctrl0->connect = ctrl1->connect = nic_connect; - ctrl0->output = ctrl1->output = nic_output; - ctrl0->unit = ctrl1->unit = is->id_unit; - ctrl0->appl = ctrl1->appl = -1; - ctrl0->o_len = ctrl1->o_len = -1; - - while (dpr->card_state & 1); /* self test running */ - dpr->card_number = is->id_unit; - dpr->int_flg_pc = 0xff; - reset_req(sc, MBX_MU, 4); - return (1); -} - -static int -cstrcmp(char *str1, char *str2) -{ - while (*str2 && (*str2 == *str1)) - { - str1++; - str2++; - } - if (!*str2) - return (1); - return (0); -} - -/* If the niccy card wants it: Interupt it. */ -static void -make_intr(int box, struct nic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - - dpr->watchdog_cnt = 0xFF; - if ((dpr->int_flg_nic & (1 << box)) == 0) - return; - if (dpr->ext_hw_config == 1) - { - u_char s; - s = inb(sc->sc_port + 4); - outb(sc->sc_port + 4, s & 0xfb); - outb(sc->sc_port + 4, s | 4); - outb(sc->sc_port + 4, s); - return; - } - outb(sc->sc_port + 2, 1); -} - -static void -reset_req(struct nic_softc * sc, unsigned box, int w) -{ - if(box >= 8) - return; - - (sc->sc_dpr)->msg_flg[box] = 0; - make_intr(box, sc); -} - -static int -en_q_d(struct nic_softc * sc, int t, int pl, int l, u_char * b) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[3]; - - if (dpr->card_state & ~4) - return (ENODEV); - if (dpr->msg_flg[3]) - return (EBUSY); - - bzero(mbx, 18); - mbx->type = t; - mbx->add_info = pl; - if (l) - { - mbx->data_len = l; - bcopy(b, mbx->data, l); - } - dpr->msg_flg[3] = 1; - make_intr(3, sc); - return (0); -} - -static int -en_q_b(struct nic_softc * sc, int mb, int t, int pl, int l, u_char * b) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[++mb]; - - if (mb == 7) - t |= 0x40; - - if (dpr->card_state) - return (ENODEV); - if (dpr->msg_flg[mb]) - return (EBUSY); - - bzero(mbx, 18); - mbx->type = t; - mbx->add_info = pl; - if (l) - { - mbx->data_len = l; - bcopy(b, mbx->data, l); - } - dpr->msg_flg[mb] = 1; - make_intr(mb, sc); - return (0); -} - -static void -badstate(mbx_type * mbx, int n, int mb, dpr_type *dpr) -{ - printf("Niccy: not implemented %x len %d at %d.", mbx->type,mbx->data_len,n); - if(mbx->data_len) - { - u_char *b = (u_char *) dpr; - int i; - - b += dpr->buf_ptr[mb]; - for(i=0; i<mbx->data_len; i++) printf(" %x",mbx->data[i]); - printf("."); - for(i=0; i<mbx->data_len; i++) printf(" %x",b[i]); - } - printf("\n"); -} - -int -nic_connect(int cn, int ap, int b_channel, int inf_mask, int out_serv - ,int out_serv_add, int src_subadr, unsigned ad_len - ,char *dest_addr, int spv) -{ - char buf[128]; - - if (ad_len > 22) - return (-1); - - buf[0] = spv ? 0x53 : 0; - buf[1] = b_channel; - if (spv) - inf_mask |= 0x40000000; - *(u_long *) & buf[2] = inf_mask; - buf[6] = out_serv; - buf[7] = out_serv_add; - buf[8] = src_subadr; - buf[9] = ad_len; - bcopy(dest_addr, &buf[10], ad_len); - return (en_q_d(&nic_sc[isdn_ctrl[cn].unit], DD_CONN_REQ, MK_APPL(ap), ad_len + 10, buf)); -} - -int -nic_listen(int cn, int ap, int inf_mask, int subadr_mask, int si_mask) -{ - u_short sbuf[4]; - - *(u_long *) sbuf = inf_mask; - sbuf[2] = subadr_mask; - sbuf[3] = si_mask; - return (en_q_d(&nic_sc[isdn_ctrl[cn].unit], DD_LISTEN_REQ, MK_APPL(ap), 8, (u_char *) sbuf)); -} - -int -nic_disconnect(int cn, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nic_softc *sc = &nic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - u_char buf[16]; - int l = 3; - int p; - int err; - - if(chan->ncci != -1) - { - bzero(buf,16); - *(u_short *) buf = chan->ncci; - l += sizeof(ncpi_t); - err= en_q_b(sc, C_CHAN(cn)?6:4, BD_DISC_B3_REQ, chan->plci, l, buf); - if(err==0) - { - chan->more= 0; - ctrl->o_len= -1; - } - return(err); - } - - p = chan->plci; - if((p == 0) || (p == -1)) - return (ENODEV); - - err= en_q_d(sc, DD_DISC_REQ, p, 1, (u_char *) & rea); - if(err==0) - { - chan->more= 0; - ctrl->o_len= -1; - } - return(err); -} - -int -nic_accept(int cn, int an, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nic_softc *sc = &nic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - isdn_appl_t *appl = &isdn_appl[an]; - - if (rea) - { - ctrl->appl= -1; - return(discon_req(1, sc, chan->plci, rea, 0)); - } - ctrl->appl= an; - ctrl->lastact = time.tv_sec; - appl->ctrl= cn; - appl->state= 4; - - return(sel_b2_prot_req(sc, C_CHAN(cn), chan->plci, &appl->dlpd)); -} - -int -nic_output(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nic_softc *sc = &nic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - int mb = C_CHAN(cn) ? 7 : 5; - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[mb]; - int r, l; - u_char *b = (u_char *) dpr; - int len= ctrl->o_len; - char *buf= ctrl->o_buf; - - if (dpr->card_state /* & ~4 */) - return (ENODEV); - - if ((chan->ncci == -1) || dpr->msg_flg[mb] || (chan->state != IDLE)) - return (EBUSY); - - chan->state = ACTIVE; - - bzero(mbx, 20); - mbx->type = BD_DATA_B3_REQ; - if (C_CHAN(cn)) - mbx->type |= 0x40; - *(u_short *) mbx->data = chan->ncci; - mbx->data[4] = chan->msg_nr++; - b += dpr->buf_ptr[mb]; - l = min(1024, len); - mbx->data_len = l; - bcopy(buf, b, l); - - if (l < len) - { - chan->more = min(len - l, 1024); /* This is a bug, but */ - /* max. blocks length is 2048 bytes including protokoll */ - chan->more_b = buf + l; - mbx->more_data = 1; - } else - { - chan->more = 0; - ctrl->o_len = -1; - } - - dpr->msg_flg[mb] = 3; - bsintr |= (1 << C_CHAN(cn)); - make_intr(mb, sc); - ctrl->lastact = time.tv_sec; - return (0); -} - -static void -con_resp(struct nic_softc * sc, int pl, int rea) -{ - en_q_d(sc, DD_CONN_RSP, pl, 1, (u_char *) & rea); -} - -static int -discon_req(int w, struct nic_softc * sc, int pl, int rea, int err) -{ - if ((pl == 0) || (pl == -1)) - return(0); - return(en_q_d(sc, DD_DISC_REQ, pl, 1, (u_char *) & rea)); -} - -static int -sel_b2_prot_req(struct nic_softc * sc, int c, int pl, dlpd_t * dlpd) -{ - return(en_q_b(sc, c ? 6 : 4, BD_SEL_PROT_REQ | 0x200, pl, - sizeof(dlpd_t), (u_char *) dlpd)); -} - -static void -sel_b3_prot_req(struct nic_softc * sc, int mb, u_short pl, ncpd_t * ncpd) -{ - en_q_b(sc, mb, BD_SEL_PROT_REQ | 0x300, pl, sizeof(ncpd_t), (u_char *) ncpd); -} - -static void -con_b3_resp(struct nic_softc * sc, int mb, u_short ncci, u_char reject) -{ - u_char buf[32]; - int l = 4; - - bzero(buf, 32); - *(u_short *) buf = ncci; - buf[2] = reject; - buf[3] = 0; /* ncpi ???? */ - l += 15; - en_q_b(sc, mb, BD_CONN_B3_RSP, 0, l, buf); -} - -static int -reset_plci(int w, chan_t * chan, int p) -{ - isdn_ctrl_t *ctrl; - - if (p == -1) - return (-1); - - if(chan == NULL) - return(p); - - ctrl = &isdn_ctrl[chan->ctrl]; - if (chan->plci == p) - { - if (ISBUSY(ctrl->appl)) - { - isdn_disconn_ind(ctrl->appl); - isdn_appl[ctrl->appl].ctrl = -1; - isdn_appl[ctrl->appl].state = 0; - } - ctrl->appl = -1; - ctrl->o_len = -1; - chan->plci = -1; - chan->ncci = -1; - chan->state = DISCON; - chan->i_len = 0; - chan->more = 0; - } - return (p); -} - -static void -reset_card(struct nic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[1]; - bzero(mbx, 16); - mbx->type = MD_RESET_REQ; - dpr->msg_flg[1] = 1; - make_intr(1, sc); -} - -/* - * nicopen() New open on device. - * - * We forbid all but first open - */ -int -nicopen(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct nic_softc *sc; - u_char unit; - dpr_type *dpr; - int x; - - unit = minor(dev); - - /* minor number out of limits ? */ - if (unit >= NNIC) - return (ENXIO); - sc = &nic_sc[unit]; - - sc->sc_flags |= OPEN; - dpr = sc->sc_dpr; - dpr->card_number = sc->sc_unit; - dpr->int_flg_pc = 0xff; - if (dpr->msg_flg[0]) - { - x = splhigh(); - s_intr(sc, dpr); - splx(x); - } - return (0); -} - -/* - * nicclose() Close device - */ -int -nicclose(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct nic_softc *sc = &nic_sc[minor(dev)]; - - sc->sc_flags = 0; - return (0); -} - -int -nicioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p) -{ - int error; - u_char unit; - int i, x; - struct nic_softc *sc = &nic_sc[minor(dev)]; - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx; - - dpr->int_flg_pc = 0xff; - - error = 0; - switch (cmd) - { - case NICCY_DEBUG: - data[0]= 0x38; - bcopy((char *)dpr, data+1, sizeof(dpr_type)); - break; - case NICCY_LOAD: - { - struct head *head = (struct head *) data; - u_char *b = (u_char *) dpr; - int len, l, off; - - x = splhigh(); - while (dpr->msg_flg[1]) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic1head", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - mbx = &dpr->dpr_mbx[1]; - bzero(mbx, 16); - mbx->type = MD_DNL_MOD_REQ | ((u_short) head->typ << 8); - mbx->data_len = 12; - bcopy(head->nam, mbx->data, 8); - *(u_long *) (mbx->data + 8) = head->len; - - sc->sc_flags = LOAD_HEAD; - sc->sc_stat = -1; - dpr->msg_flg[1] = 1; - make_intr(1, sc); - while (sc->sc_flags == LOAD_HEAD) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic2head", 1); - if (error != EWOULDBLOCK) - break; - } - - len= head->d_len; - off= 0; - b += dpr->buf_ptr[1]; - - while(len > 0) - { - while (dpr->msg_flg[1]) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic1load", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - bzero(mbx, 16); - mbx->type = MD_DNL_MOD_DATA | ((u_short) head->typ << 8); - l= min(len,1024); - len-= l; - mbx->buf_valid = 1; - mbx->more_data = len > 0; - mbx->data_len = l; - bcopy(head->nam, mbx->data, 8); - - if(error= copyin(head->data+off, b, l)) - { - splx(x); - return(error); - } - off+= l; - sc->sc_flags = LOAD_DATA; - sc->sc_stat = -1; - dpr->msg_flg[1] = 3; - make_intr(1, sc); - } - - while ((sc->sc_flags == LOAD_DATA) || (dpr->card_state & 0x20)) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic2load", 1); - if (error != EWOULDBLOCK) - break; - } - if (sc->sc_flags) - sc->sc_flags = OPEN; - head->status = sc->sc_stat; - splx(x); - return (0); - } - case NICCY_SET_CLOCK: - x = splhigh(); - if (dpr->msg_flg[1]) - { - splx(x); - return (EBUSY); - } - mbx = &dpr->dpr_mbx[1]; - bzero(mbx, 16); - mbx->type = MD_SET_CLOCK_REQ; - mbx->data_len = 14; - bcopy(data, mbx->data, 14); - - dpr->msg_flg[1] = 1; - if (dpr->int_flg_nic & 2) - make_intr(1, sc); - splx(x); - return (0); - case NICCY_SPY: - x = splhigh(); - if (dpr->msg_flg[1]) - { - splx(x); - return (EBUSY); - } - mbx = &dpr->dpr_mbx[1]; - bzero(mbx, 16); - mbx->type = MD_MANUFACT_REQ | (18<<8); - mbx->data_len = 1; - mbx->add_info = MK_APPL(ispy_applnr); -/* There are ilegal states. So I use them to toggle */ - if((data[0] == 0) && (old_spy == 0)) data[0]= 255; - else if(data[0] && old_spy ) data[0]= 0; - old_spy= mbx->data[0]= data[0]; - - dpr->msg_flg[1] = 1; - if (dpr->int_flg_nic & 2) - make_intr(1, sc); - splx(x); - return (0); - case NICCY_RESET: - x = splhigh(); - - reset_card(sc); - - while (dpr->card_state & 1) /* self test running */ - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic: reset", 10); - if (error != EWOULDBLOCK) - break; - } - dpr->card_number = sc->sc_unit; - dpr->int_flg_pc = 0xff; - if (dpr->msg_flg[0]) - s_intr(sc, dpr); - splx(x); - return (0); - - default: - error = ENODEV; - } - return (error); -} - -static void -b_intr(int mb, int c, struct nic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[mb]; - chan_t *chan = &sc->sc_chan[c]; - u_short ap, n, err = 0; - u_short pl = mbx->add_info; - isdn_ctrl_t *ctrl = &isdn_ctrl[chan->ctrl]; - - if(((unsigned)(mbx->type >> 8) > 3) || ((pl & 0xff00) == 0xff00)) - panic("3008 conflict with 16 bit card\nReconfig your system"); - - if (dpr->msg_flg[mb+1]) - return; /* can happen. Should make no problems */ - - if (ISBUSY(ap = ctrl->appl)) - switch (mbx->type & 0x1f) - { - case 0: /* SELECT PROT CONF */ - err = *(u_short *) mbx->data; - if (err) - { - discon_req(2, sc, pl, 0, err); - break; - } - - switch ((mbx->type >> 8) & 3) - { - case 2:/* SELECT B2 PROTOCOL */ - sel_b3_prot_req(sc, mb, pl, &isdn_appl[ap].ncpd); - break; - - case 3:/* SELECT B3 PROTOCOL */ - if (IS_DIAL(pl)) - con_b3_req(sc, mb, pl); - else - listen_b3_req(sc, mb, pl); - break; - } - break; - - case 1: /* LISTEN B3 CONF */ - err = *(u_short *) mbx->data; - if (err) - { - discon_req(4, sc, pl, 0, err); - break; - } - con_resp(sc, pl, 0); - break; - - case 2: /* CONNECT B3 CONF */ - err = *(u_short *) (mbx->data + 2); - n = *(u_short *) mbx->data; - - if (err) - { - discon_req(5, sc, pl, 0, err); - break; - } - chan->ncci = n; - chan->state = CONNECT; - break; - - case 3: /* CONNECT B3 IND */ - n = *(u_short *) mbx->data; - chan->ncci = n; - chan->state = CONNECT; - con_b3_resp(sc, mb, n, 0); - break; - - case 4: /* CONNECT B3 ACTIVE IND */ - if (chan->state < IDLE) - { - chan->state = IDLE; - ctrl->o_len = 0; - /* - * XXX the chan->ctrl arg is very bogus. - * Don't just use a cast to "fix" it. - */ - timeout(isdn_start_out, chan->ctrl, hz / 5); - break; - } - break; - - case 5: /* DISCONNECT B3 CONF */ - chan->state = ISDISCON; - err = *(u_short *) (mbx->data + 2); - if (err) - { - discon_req(6, sc, chan->plci, 0, err); - break; - } - break; - case 6: /* DISCONNECT B3 IND */ - chan->state = ISDISCON; - err = *(u_short *) (mbx->data + 2); - discon_req(7, sc, chan->plci, 0, err); - break; - - case 8: /* DATA B3 CONF */ - err = *(u_short *) (mbx->data + 2); - if (err) - { - ctrl->send_err++; - isdn_appl[ap].send_err++; - } - ctrl->o_len = 0; - chan->state= IDLE; - isdn_start_out(chan->ctrl); - break; - - case 9: /* DATA B3 IND */ - { - u_char *b = (u_char *) dpr; - u_char mno; - - b += dpr->buf_ptr[mb]; - if (mbx->more_data) - { - chan->morenr= mbx->data[4]; - if(chan->i_len) - { - chan->i_len= 0; - break; - } - bcopy(b, &chan->i_buf[chan->i_len], mbx->data_len); - chan->i_len = mbx->data_len; - break; - } /* mbx->more_data == 0 */ - if (chan->i_len) - { - int l; - if(chan->morenr != mbx->data[4]) - break; - - if ((l = chan->i_len + mbx->data_len) <= 2048) - { - bcopy(b, &chan->i_buf[chan->i_len], mbx->data_len); - if(isdn_input(ap, l, chan->i_buf, ctrl->islisten)) - ctrl->lastact = time.tv_sec; - } - chan->i_len = 0; - break; - } /* chan->i_len == 0 && mbx->more_data == 0 */ - if(isdn_input(ap, mbx->data_len, b, ctrl->islisten)) - ctrl->lastact = time.tv_sec; - break; - } - break; - - default: - badstate(mbx,1,mb,dpr); - } -/* - else badstate(mbx,2,mb,dpr); -*/ - - reset_req(sc, mb,1); -} - -static void -d_intr(struct nic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[2]; - chan_t *chan; - u_short ap, c, pl, err = 0; - isdn_ctrl_t *ctrl; - isdn_appl_t *appl; - - if (dpr->msg_flg[3]) - return; /* should not happen. might make problems */ - /* but there should be another intr., so what? */ - - pl = mbx->add_info; - if ((c = CHAN(pl)) < 2) - { - chan = &sc->sc_chan[c]; - ctrl = &isdn_ctrl[chan->ctrl]; - } else - { - c = 0xffff; - chan = NULL; - ctrl = NULL; - } - - ap= APPL(pl); - if(ctrl && (ctrl->appl & 0xC0) == 0) - appl= &isdn_appl[ctrl->appl]; - else if(ap < 0x30) - appl = &isdn_appl[ap]; - else if(ap < 0x40) - appl = NULL; - else - { - reset_req(sc, 2,2); - return; - } - - switch (mbx->type & 0x1f) - { - case 0: /* CONNECT CONF */ - err = *(u_short *) mbx->data; - if(err || (appl == NULL) || (chan == NULL) || (ctrl == NULL)) - { - if(chan) reset_plci(1, chan, pl); - if(appl) appl->state= 0; - break; - } - - if (ISBUSY(ctrl->appl)) - { - discon_req(8, sc, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr= 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = ap; - appl->ctrl = chan->ctrl; - ctrl->islisten= 0; - chan->state = DIAL; - appl->state = 3; - break; - - case 1: /* CONNECT IND */ - if (ISBUSY(ctrl->appl)) - { - discon_req(9, sc, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr= 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = 0x7f; - ctrl->islisten= 1; - chan->state = CALLED; - mbx->data[mbx->data[3] + 4] = 0; - isdn_accept_con_ind(ap, chan->ctrl, mbx->data[0], mbx->data[1] - ,mbx->data[2], mbx->data[3], (char *) &mbx->data[4]); - break; - - case 2: /* CONNECT ACTIVE IND */ - con_act_resp(sc, pl); - if (IS_LISTEN(pl)) - { - isdn_conn_ind(ctrl->appl,chan->ctrl,0); - break; - } - isdn_conn_ind(APPL(pl),chan->ctrl,1); - chan->state = CONNECT; - ctrl->appl = ap; - appl->ctrl = chan->ctrl; - break; - - case 3: /* DISCONNECT CONF */ - reset_plci(2, chan, pl); - break; - - case 4: /* DISCONNECT IND */ - discon_resp(sc, reset_plci(3, chan, pl)); - break; - - case 7: /* LISTEN CONF */ - isdn_state = *(u_short *) mbx->data; - break; - - case 10: /* INFO IND */ - isdn_info(ap,*(u_short *)mbx->data, mbx->data[2], mbx->data+3); - inf_resp(sc, pl); - break; - - default: - badstate(mbx,3,2,dpr); - } - reset_req(sc, 2,2); -} - -static void -s_intr(struct nic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[0]; - mbx_type *smbx = &dpr->dpr_mbx[1]; - - if (dpr->msg_flg[1]) - return; /* should not happen. might make problems */ - /* but there should be another intr., so what? */ - - bzero(smbx, 16); - - switch (mbx->type & 0x1f) - { - case 0: /* INIT CONF */ - break; - case 1: /* INIT IND */ - smbx->type = mbx->type + 0x20; - dpr->msg_flg[1] = 1; - make_intr(1, sc); - break; - case 4: /* DNL MOD CONF */ - sc->sc_stat = mbx->data[0]; - if (sc->sc_flags) - sc->sc_flags = OPEN; - break; - case 6: /* DNL MOD IND */ - smbx->type = mbx->type + 0x20; - smbx->data_len = 1; - smbx->data[0] = mbx->data[1]; - sc->sc_stat = mbx->data[0]; - if (sc->sc_flags) - sc->sc_flags = OPEN; - dpr->msg_flg[1] = 1; - make_intr(1, sc); - break; - case 0x0e: /* SET CLOCK CONF */ - dpr->watchdog_cnt = 0xFF; - dpr->int_flg_pc = 0xFF; - dpr->api_active = 1; - break; - case 0x15: /* POLL IND */ - dpr->watchdog_cnt = 0xFF; - dpr->int_flg_pc = 0xFF; - dpr->api_active = 1; - smbx->type = mbx->type + 0x20; - dpr->msg_flg[1] = 1; - make_intr(1, sc); - break; - case 0x1e: /* MANUFACT CONF */ - if(((mbx->type >> 8) == 18 ) && (*mbx->data == 0)) /* LISTEN */ - break; - badstate(mbx,4,0,dpr); - break; - case 0x1f: /* MANUFACT IND */ - if((mbx->type >> 8) == 19 ) /* DATA */ - { - u_char *b = (u_char *) dpr; - b += dpr->buf_ptr[0]; - isdn_input(ispy_applnr, mbx->data_len, b, 0); - smbx->type = mbx->type + 0x20; - dpr->msg_flg[1] = 1; - make_intr(1, sc); - break; - } - default: - badstate(mbx,5,0,dpr); - } - reset_req(sc, 0, 3); -} - -static void -bs_intr(int mb, int c, struct nic_softc * sc) -{ - chan_t *chan = &sc->sc_chan[c]; - isdn_ctrl_t *ctrl = &isdn_ctrl[chan->ctrl]; - - if (chan->state == ACTIVE) - { - if (chan->more) - { - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dpr_mbx[mb]; - u_char *b = (u_char *) dpr; - - bzero(mbx, 20); - mbx->type = BD_DATA_B3_REQ; - if (mb == 7) - mbx->type |= 0x40; - *(u_short *) mbx->data = chan->ncci; - mbx->data[4] = chan->msg_nr; - b += dpr->buf_ptr[mb]; - mbx->data_len = chan->more; - bcopy(chan->more_b, b, chan->more); - - chan->more = 0; - ctrl->o_len = -1; - - dpr->msg_flg[mb] = 3; - make_intr(mb, sc); - - ctrl->lastact = time.tv_sec; - return; - } - bsintr &= ~(1 << c); - } -} - -void -nicintr(int unit) -{ - register struct nic_softc *sc = &nic_sc[unit]; - dpr_type *dpr = sc->sc_dpr; - - if (dpr->msg_flg[2]) - d_intr(sc); - if (dpr->msg_flg[0]) - s_intr(sc); - if (dpr->msg_flg[6]) - b_intr(6, 1, sc); - if (dpr->msg_flg[4]) - b_intr(4, 0, sc); - if (bsintr) - { - if (dpr->msg_flg[7] == 0) - bs_intr(7, 1, sc); - if (dpr->msg_flg[5] == 0) - bs_intr(5, 0, sc); - } -} - -#endif /* NNIC > 0 */ diff --git a/sys/gnu/i386/isa/nic3008.h b/sys/gnu/i386/isa/nic3008.h deleted file mode 100644 index da82696..0000000 --- a/sys/gnu/i386/isa/nic3008.h +++ /dev/null @@ -1,114 +0,0 @@ -static char nic38hid[] = "@(#)$Id: nic3008.h,v 1.1 1995/01/25 14:06:18 jkr Exp jkr $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: nic3008.h,v $ - * - ******************************************************************************/ - -/* - * This file defines the NICCY 3008 Interface. - * Copyright Dr. Neuhaus GmbH, Hamburg and Dietmar Friede - * -*/ - -#pragma pack (1) - -typedef struct { - u_short type; /* Message Subtype/Type */ - u_char source; - u_char dest; - u_short number; /* laufende Nachrichten-Nummer */ - u_short timeoutval; /* Wert fr Timeout */ - u_char priority; /* Nachrichten-Priorit„t */ - u_char more_data; /* Nachricht vollst„ndig? */ - u_short data_len; /* Datenmenge */ - u_char buf_valid; /* im aux. buf.? */ - u_char reserved[1]; - u_short add_info; /* Maske */ - u_char data[0x30];/* Datenfeld */ -} mbx_type; - -/* ------------------------------------------------------------------------ */ - -typedef struct { -/* Offset 0x0000 ---------------------------------------------------------- */ - u_char msg_flg[8]; /* Messages in MBX i */ - u_char card_number; /* Kartennummer of Applikation */ - u_char card_state; /* Kartenstatus */ - u_short mainloop_cnt; /* NICCY's M'loop,68000-Notation*/ - u_char watchdog_cnt; /* Applikation "lebt"? */ - u_char hw_config; /* Steckmodule? */ - u_char jmp_config; /* Karten-Jumper? */ - u_char ram_config; /* Karten-Speicher? */ -/* Offset 0x0010 -----------------------------------------------------------*/ - char niccy_ver[0x0E]; /* "NICCY V x.yyy\c" */ - u_char int_flg_pc; /* Will PC Interrupts? */ - u_char int_flg_nic; /* Will NICCY Interrupts? */ -/* Offset 0x0020 -----------------------------------------------------------*/ - u_short buf_ptr[8]; /* Pointer to aux. buf. ... */ -/* Offset 0x0030 -----------------------------------------------------------*/ - u_short buf_len[8]; /* Size of aux. buf. ... */ -/* Offset 0x0040 -----------------------------------------------------------*/ - /* 0x40 Bytes fr die */ - /* frei verfgbar */ - u_char old_flg[8]; /* Messages in MBX i */ - u_char irq_level; /* welcher IRQ (als Bitmaske */ - u_char res[7]; /* FREI */ -/* Offset 0x0050 -----------------------------------------------------------*/ - u_char api_area_int_nr; /*SW-Int des API wenn API_ACTIVE*/ - u_char api_area_PLCI[2]; /* PLCI w„hrend ApiManufacturer */ - u_char capi_version[6]; /* Versionsnummer der CAPI */ - u_char api_area[0x27]; /* FREI */ -/* Offset 0x0080 -----------------------------------------------------------*/ - u_char api_active; /* Flag ob CAPI aktiv ist */ - u_char ext_hw_config; /* Bit 0: UART 16550 */ - /* Bit 1..7: reserved */ - u_char dpr_hw_id[0x0E]; /* Hardware ID */ -/* Offset 0x0090 -----------------------------------------------------------*/ - u_char dpr_listen_req;/* Anzahl Listen Request's */ - u_char dpr_state_b1; /* state B1 channel */ - /* 0x00 : channel ist frei */ - /* 0x01 : Verbindungsaufb. Req */ - /* 0x02 : Verbindungsaufb. Act */ - /* 0x03 : Verbindung besteht */ - /* 0x04 : eintreffender Ruf */ - /* 0x05 : Verbindung angenommen */ - /* 0x06 : Verbindungsabb. Req */ - /* 0x07 : Verbindungsabb. laeuft*/ - /* 0x08 : Verbindung getrennt */ - u_char dpr_state_b2; /* state B2 channel (siehe oben)*/ - u_char dpr_state_ic1; /* state of Intercomm-Channel */ - u_char dpr_state_ic2; /* ----------- " -------------- */ - u_char state_res[0x04]; - u_char dpr_si_b1; /* Service Indicator auf B1 */ - u_char dpr_si_b2; /* Service Indicator auf B2 */ - u_char dpr_state_res_0[0x05]; -/* Offset 0x00A0 -----------------------------------------------------------*/ - u_char dpr_state_hscx; /* state of HSCX */ - u_char dpr_state_itac; /* state of ITAC */ - u_char dpr_state_arcofi;/* state of ARCOFI */ - u_char dpr_state_modem; /* state of Aufsteckmodem */ - u_char dpr_state_com; /* state of COM */ - u_char dpr_state_res[0x0B]; -/* Offset 0x00B0 -----------------------------------------------------------*/ - u_char dpr_state_ia_tel;/* state of internal Appl. */ - u_char dpr_state_ia_com;/* state of internal Appl. */ - u_char dpr_state_ia_mod;/* state of internal Appl. */ - u_char dpr_state_res_1[0x0D]; -/* Offset 0x00C0 -----------------------------------------------------------*/ - u_char dpr_state_dcp[0x10];/* state of D-channel Prot */ -/* Offset 0x00D0 -----------------------------------------------------------*/ - u_char reserved[0x130]; -/* Offset 0x0200 -----------------------------------------------------------*/ - mbx_type dpr_mbx[8]; /* the mailboxes ... */ -} dpr_type; - -#pragma pack () diff --git a/sys/gnu/i386/isa/nic3009.c b/sys/gnu/i386/isa/nic3009.c deleted file mode 100644 index 7796158..0000000 --- a/sys/gnu/i386/isa/nic3009.c +++ /dev/null @@ -1,1246 +0,0 @@ -static char nic39_id[] = "@(#)$Id: nic3009.c,v 1.7 1995/09/08 11:06:47 bde Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.7 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: nic3009.c,v $ - * Revision 1.7 1995/09/08 11:06:47 bde - * Fix benign type mismatches in devsw functions. 82 out of 299 devsw - * functions were wrong. - * - * Revision 1.6 1995/05/11 19:25:56 rgrimes - * Fix -Wformat warnings from LINT kernel. - * - * Revision 1.5 1995/03/28 07:54:33 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.4 1995/02/16 08:06:21 jkh - * Fix a few bogons introduced when config lost the 3 char limitation. - * - * Revision 1.3 1995/02/15 11:59:41 jkh - * Fix a few more nits. Should compile better now! :_) - * - * Revision 1.2 1995/02/15 06:28:20 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:14 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -/* - * Copyright (c) 1994 Dietmar Friede (dietmar@friede.de) All rights reserved. - * FSF/FSAG GNU Copyright applies - * - * A low level driver for the NICCY-3009 ISDN Card. - * - */ - -#include "nnic.h" -#if NNNIC > 0 - -#include "param.h" -#include "ioctl.h" -#include "kernel.h" -#include "systm.h" -#include "proc.h" - -#include "i386/isa/isa_device.h" -#include "gnu/i386/isa/nic3009.h" -#include "gnu/i386/isa/niccyreg.h" -#include "gnu/isdn/isdn_ioctl.h" - -#define OPEN 1 -#define LOAD_HEAD 3 -#define LOAD_DATA 5 -#define LOAD_ENTITY 8 -#define IS_DIAL(p) (((p)&0x20)==0) -#define IS_LISTEN(p) ((p)&0x20) -#define CHAN(pl) (((pl)&7)-1) -#define C_CHAN(x) ((x)&1) -#define APPL(pl) ((((pl)>>6)&0x7f)-1) -#define CARD(pl) (((pl)>>13)&7) -#define MK_APPL(pl) (((pl)+1)<<6) - -#define min(a,b) ((a)<(b)?(a):(b)) - -extern isdn_appl_t isdn_appl[]; -extern u_short isdn_state; -extern isdn_ctrl_t isdn_ctrl[]; -extern int ispy_applnr; -extern int Isdn_Appl, Isdn_Ctrl, Isdn_Typ; -extern void isdn_start_out(); - -static old_spy= 0; - -int nnicprobe(), nnicattach(); -int nnic_connect(), nnic_listen(), nnic_disconnect(), nnic_accept(); -int nnic_output(), nnic_state(); - -static discon_req(), sel_b2_prot_req(), reset_plci(); -static short bsintr; - -struct isa_driver nnicdriver = {nnicprobe, nnicattach, "nnic"}; - -typedef enum -{ - DISCON, ISDISCON, DIAL, CALLED, CONNECT, IDLE, ACTIVE -} io_state; - -typedef struct -{ - char ctrl; - u_char msg_nr; - u_char morenr; - short plci; - short ncci; - short state; - short i_len; - char i_buf[2048]; - char o_buf[2048]; - u_short more; - char *more_b; -} chan_t; - -struct nnic_softc -{ - dpr_type *sc_dpr; /* card RAM virtual memory base */ - u_short sc_vector; /* interrupt vector */ - short sc_port; - u_char sc_flags; - u_char sc_unit; - u_char sc_ctrl; - u_char sc_type; - short sc_stat; - chan_t sc_chan[2]; -} nnic_sc[NNNIC]; - - -int -nnicprobe(struct isa_device * is) -{ - register struct nnic_softc *sc = &nnic_sc[is->id_unit & 127]; - dpr_type *dpr; - u_char *w; - int i; - - sc->sc_vector = is->id_irq; - sc->sc_port = is->id_iobase; - sc->sc_unit = is->id_unit; - w= (u_char *) dpr = sc->sc_dpr = (dpr_type *) is->id_maddr; - - i= ffs(sc->sc_vector)-1; - if(i == 9) i= 1; - outb(sc->sc_port, 0); - outb(sc->sc_port+1, i); - outb(sc->sc_port, ((unsigned) dpr >> 12) & 0xff); - -/* There should be memory, so lets test that */ - for (i=0;i<DPR_LEN;i++) - w[i] = (i+0xaf) & 0xff; - for (i=0;i<DPR_LEN;i++) - if (w[i] != ((i+0xaf) & 0xff)) - { - printf("Niccy card not found or bad memory %p\n", - is->id_maddr); - outb(sc->sc_port, 0); - return(0); - } - bzero(w,DPR_LEN-4); - - is->id_msize = DPR_LEN; - return (2); -} - -static void -nnic_reset(struct nnic_softc *sc, int reset) -{ - u_char o; - o= ffs(sc->sc_vector)-1; - if(reset == 0) - o|= 0x80; - outb(sc->sc_port+1,o); -} - -/* - * nnicattach() Install device - */ -int -nnicattach(struct isa_device * is) -{ - struct nnic_softc *sc; - int cn; - isdn_ctrl_t *ctrl0, *ctrl1; - - sc = &nnic_sc[is->id_unit]; - sc->sc_ctrl = -1; - if ((cn = isdn_ctrl_attach(2)) == -1) - { - return (0); - } - sc->sc_ctrl = cn; - sc->sc_chan[0].plci = sc->sc_chan[1].plci = -1; - - ctrl0 = &isdn_ctrl[cn]; - ctrl1 = &isdn_ctrl[cn + 1]; - sc->sc_chan[0].ctrl = ctrl0->ctrl = cn; - sc->sc_chan[1].ctrl = ctrl1->ctrl = cn + 1; - ctrl0->o_buf = sc->sc_chan[0].o_buf; - ctrl1->o_buf = sc->sc_chan[1].o_buf; - ctrl0->listen = ctrl1->listen = nnic_listen; - ctrl0->disconnect = ctrl1->disconnect = nnic_disconnect; - ctrl0->accept = ctrl1->accept = nnic_accept; - ctrl0->connect = ctrl1->connect = nnic_connect; - ctrl0->output = ctrl1->output = nnic_output; - ctrl0->state = ctrl1->state = nnic_state; - ctrl0->unit = ctrl1->unit = is->id_unit; - ctrl0->appl = ctrl1->appl = -1; - ctrl0->o_len = ctrl1->o_len = -1; - sc->sc_flags= LOAD_ENTITY; - - return (1); -} - -#define con_b3_req(unit,mb,pl) en_q(unit,mb|BD_CONN_B3_REQ,0,pl,0,NULL) -#define con_act_resp(unit,pl) en_q(unit,DD_CONN_ACT_RSP,0, pl,0,NULL) -#define discon_resp(sc,pl) en_q(unit,DD_DISC_RSP,0, pl,0,NULL) -#define inf_resp(unit,pl) en_q(unit,DD_INFO_RSP,0, pl,0,NULL) -#define listen_b3_req(unit,mb,pl) en_q(unit,mb|BD_LIST_B3_REQ,0,pl,0,NULL) - -/* If the Niccy card wants it: Interupt it. */ -static void -make_intr(void *gen) -{ - struct nnic_softc * sc = (struct nnic_softc *)gen; - dpr_type *dpr = sc->sc_dpr; - - dpr->watchdog_cnt = 0xFF; - - if (dpr->int_flg_nic) - dpr->signal_pc_to_niccy++; -} - -static int -en_q(int unit, int t, int st, int pl, int l, u_char *b) -{ - struct nnic_softc * sc= &nnic_sc[unit]; - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dn_mbx; - -/* - if (dpr->card_state & ~4) - return (ENODEV); -*/ - if (mbx->msg_flag) - return (EBUSY); - - bzero(&mbx->type, 18); - mbx->type = t; - mbx->subtype = st; - mbx->plci = pl; - if (l) - { - mbx->data_len = l; - bcopy(b, mbx->data, l); - } - mbx->msg_flag = 1; - make_intr(sc); - return (0); -} - -static void -badstate(mbx_type * mbx, int n, int mb, dpr_type *dpr) -{ - printf("Niccy: not implemented %x len %d at %d.", mbx->type,mbx->data_len,n); - if(mbx->data_len) - { - int i; - - for(i=0; i<mbx->data_len; i++) printf(" %x",mbx->data[i]); - } - printf("\n"); -} - -int -nnic_state(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nnic_softc *sc = &nnic_sc[ctrl->unit]; - chan_t *chan0 = &sc->sc_chan[0]; - chan_t *chan1 = &sc->sc_chan[1]; - dpr_type *dpr = sc->sc_dpr; - - if(sc->sc_flags == LOAD_ENTITY) - return(ENODEV); - if (dpr->card_state & ~4 ) - return (ENODEV); - if (dpr->card_state & 4 ) - return (EAGAIN); - if(chan0->state && chan1->state) - return(EBUSY); - return(0); -} - -int -nnic_output(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nnic_softc *sc = &nnic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx = &dpr->dn_mbx; - int l; - int len= ctrl->o_len; - - if (dpr->card_state /* & ~4 */) - return (ENODEV); - - if (bsintr || (chan->ncci == -1) || mbx->msg_flag || (chan->state != IDLE)) - return (EBUSY); - - chan->state = ACTIVE; - - bzero(&mbx->type, 20); - mbx->type = BD_DATA_B3_REQ; - if (C_CHAN(cn)) - mbx->type |= 0x40; - *(u_short *) mbx->data = chan->ncci; - mbx->data[4] = chan->msg_nr; - l = min(DATAFIELD_LEN-5, len); - mbx->data_len = l+5; - bcopy(ctrl->o_buf, &mbx->data[5], l); - - if (l < len) - { - chan->more = len - l; - chan->more_b = ctrl->o_buf + l; - mbx->more_data = 1; - bsintr = C_CHAN(cn)+1; - } else - { - chan->more = 0; - ctrl->o_len = -1; - bsintr= 0; - ++chan->msg_nr; - } - - mbx->msg_flag = 1; - make_intr(sc); - ctrl->lastact = time.tv_sec; - return (0); -} - -static int -con_resp(int unit, int pl, int rea) -{ - return(en_q(unit, DD_CONN_RSP, 0, pl, 1, (u_char *) & rea)); -} - -static int -reset_plci(int w, chan_t * chan, int p) -{ - isdn_ctrl_t *ctrl; - - if (p == -1) - return (-1); - - if(chan == NULL) - return(p); - - ctrl = &isdn_ctrl[chan->ctrl]; - if (chan->plci == p) - { - if (ISBUSY(ctrl->appl)) - { - isdn_disconn_ind(ctrl->appl); - isdn_appl[ctrl->appl].ctrl = -1; - isdn_appl[ctrl->appl].state = 0; - } - ctrl->appl = -1; - ctrl->o_len = -1; - chan->plci = -1; - chan->ncci = -1; - chan->state = DISCON; - chan->i_len = 0; - chan->more = 0; - } - return (p); -} - -static int -sel_b2_prot_req(int unit, int c, int pl, dlpd_t * dlpd) -{ - return(en_q(unit, (c ? 0x40 : 0)| BD_SEL_PROT_REQ, 2, pl, sizeof(dlpd_t), (u_char *) dlpd)); -} - -static int -sel_b3_prot_req(int unit, int mb, u_short pl, ncpd_t * ncpd) -{ - return(en_q(unit, mb | BD_SEL_PROT_REQ, 3, pl, sizeof(ncpd_t), (u_char *) ncpd)); -} - -static int -discon_req(int w, int unit , int pl, int rea, int err) -{ - if((pl == 0) || (pl == -1)) - return(0); - return(en_q(unit, DD_DISC_REQ,0, pl, 1, (u_char *) &rea)); -} - -static int -con_b3_resp(int unit, int mb, u_short ncci, u_short pl, u_char reject) -{ - u_char buf[32]; - int l = 4; - - bzero(buf, 32); - *(u_short *) buf = ncci; - buf[2] = reject; - buf[3] = 0; /* ncpi ??? */ - l += 15; - return(en_q(unit, mb | BD_CONN_B3_RSP,0, pl, l, buf)); -} - -int -nnic_connect(int cn, int ap, int b_channel, int inf_mask, int out_serv - ,int out_serv_add, int src_subadr, unsigned ad_len - ,char *dest_addr, int spv) -{ - char buf[128]; - - if (ad_len > 118) - return (-1); - - buf[0] = spv ? 0x53 : 0; - buf[1] = b_channel; - if (spv) - inf_mask |= 0x40000000; - *(u_long *) & buf[2] = inf_mask; - buf[6] = out_serv; - buf[7] = out_serv_add; - buf[8] = src_subadr; - buf[9] = ad_len; - bcopy(dest_addr, &buf[10], ad_len); - return (en_q(isdn_ctrl[cn].unit, DD_CONN_REQ, 0, MK_APPL(ap), ad_len + 10, buf)); -} - -int -nnic_listen(int cn, int ap, int inf_mask, int subadr_mask, int si_mask, int spv) -{ - u_short sbuf[4]; - - if (spv) - inf_mask |= 0x40000000; - *(u_long *) sbuf = inf_mask; - sbuf[2] = subadr_mask; - sbuf[3] = si_mask; - return (en_q(isdn_ctrl[cn].unit, DD_LISTEN_REQ, 0, MK_APPL(ap), 8, (u_char *) sbuf)); -} - -int -nnic_disconnect(int cn, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - chan_t *chan = &nnic_sc[ctrl->unit].sc_chan[C_CHAN(cn)]; - int p, err; - u_char buf[16]; - - if(chan->ncci != -1) - { - bzero(buf,16); - *(u_short *) buf = chan->ncci; - err= en_q(ctrl->unit, (C_CHAN(cn)?0x40:0)|BD_DISC_B3_REQ, 0 - , chan->plci, 3+sizeof(ncpi_t), buf); - if((err==0) && (ctrl->o_len == 0)) - ctrl->o_len= -1; - return(err); - } - p = chan->plci; - if ((p == 0) || (p == -1)) - return (ENODEV); - - err= en_q(ctrl->unit, DD_DISC_REQ, 0, p, 1, (u_char *) &rea); - if((err==0) && (ctrl->o_len == 0)) - ctrl->o_len= -1; - return(err); -} - -int -nnic_accept(int cn, int an, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct nnic_softc *sc = &nnic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - isdn_appl_t *appl = &isdn_appl[an]; - - if(ISFREE(ctrl->appl)) - return(ENODEV); - - if (rea) - { - ctrl->appl= -1; - return(discon_req(1, ctrl->unit, chan->plci, rea, 0)); - } - ctrl->appl= an; - ctrl->lastact = time.tv_sec; - appl->ctrl= cn; - appl->state= 4; - - return(sel_b2_prot_req(ctrl->unit, C_CHAN(cn), chan->plci, &appl->dlpd)); -} - -int -nnicopen(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct nnic_softc *sc; - u_char unit; - int x; - unsigned error; - u_char b= 0xff; - - unit = minor(dev); - /* minor number out of limits ? */ - if (unit >= NNNIC) - return (ENXIO); - sc = &nnic_sc[unit]; - - x= splhigh(); - /* Card busy ? */ -/* - if (sc->sc_flags & 7) - { - splx(x); - return (EBUSY); - } -*/ - sc->sc_flags |= OPEN; - - splx(x); - return (0); -} - -int -nnicclose(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct nnic_softc *sc = &nnic_sc[minor(dev)]; - - sc->sc_flags &= ~7; - return (0); -} - -int -nnicioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *pr) -{ - int error; - int i, x; - struct nnic_softc *sc = &nnic_sc[minor(dev)]; - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx= &dpr->dn_mbx; - u_char *p= (u_char *)dpr; - struct head *head = (struct head *) data; - - error = 0; - switch (cmd) - { - case NICCY_DEBUG: - data[0]= 0x39; - bcopy(p, &data[1], 2044); - break; - case NICCY_LOAD: - switch(head->status) - { - case 0: /* Loading initial boot code */ - x = splhigh(); - nnic_reset(sc,1); - if(error = copyin(head->data+0x16,p, head->d_len-0x16)) - { - splx(x); - return (error); - } - nnic_reset(sc,0); - i= hz; - while (p[7] && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_0", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - nnic_reset(sc,1); - splx(x); - if(p[7]) return(ENODEV); - return(0); - - case 1: /* Loading boot code */ - x = splhigh(); - - if(error = copyin(head->data+0x64,p, head->d_len-0x64)) - { - splx(x); - return (error); - } - nnic_reset(sc,0); - i= 5*hz; - while ((dpr->mainloop_cnt != 0x1147) && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_1", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - - if(dpr->mainloop_cnt != 0x1147) - { - splx(x); - return(ENODEV); - } - - i= 1*hz; - while ((dpr->up_mbx.type != 1) && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_2", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - if(dpr->up_mbx.type != 1) - { - splx(x); - return(ENODEV); - } - bzero(&mbx->type, 16); - dpr->up_mbx.msg_flag= 0; - mbx->type= 0x21; - mbx->msg_flag= 1; - - i= 1*hz; - while (mbx->msg_flag && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_3", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - if(mbx->msg_flag) - { - splx(x); - return(ENODEV); - } - - head->status= 0; - splx(x); - return(0); - - default: - x = splhigh(); - while (mbx->msg_flag) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_1h", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - - bzero(&mbx->type, 16); - mbx->type = MD_DNL_MOD_REQ; - mbx->subtype = head->typ; - sc->sc_type = head->typ; - mbx->data_len = 12; - bcopy(head->nam, mbx->data, 8); - *(u_long *) (mbx->data + 8) = head->len; - - mbx->msg_flag = 1; - make_intr(sc); - i= 1*hz; - while ((dpr->up_mbx.msg_flag == 0) && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_2", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - - if((dpr->up_mbx.type != MU_DNL_MOD_CNF) || dpr->up_mbx.data[0]) - { - dpr->up_mbx.msg_flag= 0; - make_intr(sc); - splx(x); - return(ENODEV); - } - dpr->up_mbx.msg_flag= 0; - make_intr(sc); - { - int len, l, off; - len= head->d_len; - off= 0; - l= 0x64; - - while(len > 0) - { - while (mbx->msg_flag) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_4load", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - mbx->type = MD_DNL_MOD_DATA; - len-= l; - mbx->more_data = len > 0; - mbx->data_len = l; - if(error= copyin(head->data+off, mbx->data, l)) - { - splx(x); - return (error); - } - off+= l; - l= min(len,512); - mbx->msg_flag = 1; - make_intr(sc); - } - } - - i= 3*hz; - while ((dpr->up_mbx.msg_flag == 0) && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_2", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - if(dpr->up_mbx.type == 0) - { - dpr->up_mbx.msg_flag= 0; - make_intr(sc); - i= 3*hz; - while ((dpr->up_mbx.msg_flag == 0) && i--) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "l9_3", 1); - if (error != EWOULDBLOCK) - { - splx(x); - return (error); - } - } - } - - if(dpr->up_mbx.type != MU_DNL_MOD_IND) - { - dpr->up_mbx.msg_flag= 0; - make_intr(sc); - splx(x); - return(ENODEV); - } - head->status = dpr->up_mbx.data[0]; - mbx->data[0] = dpr->up_mbx.data[1]; - mbx->type= 0x20|MU_DNL_MOD_IND; - mbx->subtype = head->typ; - mbx->data_len = 1; - dpr->card_number = sc->sc_unit; - dpr->up_mbx.msg_flag= 0; - mbx->msg_flag= 1; - make_intr(sc); - splx(x); - return (0); - } - splx(x); - return(0); - case NICCY_SET_CLOCK: - x = splhigh(); - dpr->int_flg_pc = 0xff; - dpr->card_number = sc->sc_unit; - if (mbx->msg_flag) - { - splx(x); - return (EBUSY); - } - bzero(&mbx->type, 16); - mbx->type = MD_SET_CLOCK_REQ; - mbx->data_len = 14; - bcopy(data, mbx->data, 14); - - mbx->msg_flag = 1; - make_intr(sc); - splx(x); - return (0); - case NICCY_SPY: - x = splhigh(); - if (mbx->msg_flag) - { - splx(x); - return (EBUSY); - } - bzero(&mbx->type, 16); - mbx->type = MD_MANUFACT_REQ; - mbx->subtype = 18; - mbx->data_len = 1; - mbx->plci = MK_APPL(ispy_applnr); -/* There are ilegal states. So I use them to toggle */ - if((data[0] == 0) && (old_spy == 0)) data[0]= 255; - else if(data[0] && old_spy ) data[0]= 0; - old_spy= mbx->data[0]= data[0]; - - mbx->msg_flag = 1; - make_intr(sc); - splx(x); - return (0); - - case NICCY_RESET: - x = splhigh(); - nnic_reset(sc,1); - bzero((u_char*)dpr,DPR_LEN); - sc->sc_flags= LOAD_ENTITY; - splx(x); - return (0); - - default: - error = ENODEV; - } - return (error); -} - -static void -dn_intr(unsigned unit, struct nnic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *mbx= &dpr->dn_mbx; - chan_t *chan; - isdn_ctrl_t *ctrl; - int c,l, len; - - c= bsintr-1; - chan = &sc->sc_chan[c]; - ctrl = &isdn_ctrl[chan->ctrl]; - - if ((chan->state == ACTIVE) && (chan->more)) - { - len= chan->more; - - bzero(&mbx->type, 20); - mbx->type = BD_DATA_B3_REQ; - if (c) - mbx->type |= 0x40; - *(u_short *) mbx->data = chan->ncci; - mbx->data[4] = chan->msg_nr; - l = min(DATAFIELD_LEN-5, len); - mbx->data_len = l+5; - bcopy(chan->more_b, &mbx->data[5], l); - - if (l < len) - { - chan->more = len - l; - chan->more_b += l; - mbx->more_data = 1; - } else - { - chan->more = 0; - ctrl->o_len = -1; - bsintr= 0; - ++chan->msg_nr; - } - - mbx->msg_flag = 1; - make_intr(sc); - ctrl->lastact = time.tv_sec; - return; - } - bsintr= 0; -} - -static void -up_intr(unsigned unit, struct nnic_softc * sc) -{ - dpr_type *dpr = sc->sc_dpr; - mbx_type *msg= &dpr->up_mbx; - chan_t *chan; - u_short n, mb, c, pl, err = 0; - isdn_ctrl_t *ctrl; - isdn_appl_t *appl; - int error= 0; - - chan= NULL; - ctrl= NULL; - appl= NULL; - mb= 0; - pl = msg->plci; - - if(pl && (msg->type >= 0x40) && (msg->type < 0xfd) && (msg->type != 0x47)) - { - if ((c = CHAN(pl)) < 2) - { - chan = &sc->sc_chan[c]; - ctrl = &isdn_ctrl[chan->ctrl]; - } else - { - c = 0xffff; - chan= NULL; - ctrl= NULL; - } - - if(ctrl && (ctrl->appl & 0xC0) == 0) - appl= &isdn_appl[ctrl->appl]; - else if( APPL(pl) < 0x30) - appl = &isdn_appl[APPL(pl)]; - else if( APPL(pl) < 0x40) - appl= NULL; - else goto fin; - - if(msg->type >= 0x80) - { - mb= msg->type & 0x40; - msg->type &= 0xbf; - } - } - - switch (msg->type) - { - case 0x01: /* INIT IND */ - if(dpr->dn_mbx.msg_flag) return; - error= en_q(unit,msg->type|0x20,0,0,0,NULL); - break; - case 0x04: /* DNL MOD */ - sc->sc_stat = msg->data[0]; - if (sc->sc_flags ) - sc->sc_flags = OPEN; - break; - case 0x06: /* DNL MOD IND */ - if(dpr->dn_mbx.msg_flag) return; - sc->sc_stat = msg->data[0]; - if (sc->sc_flags) - sc->sc_flags = OPEN; - if(sc->sc_stat) - break; - error= en_q(unit,msg->type|0x20,sc->sc_type,0,1, &msg->data[1]); - break; - case 0x0e: /* SET CLOCK CONF */ - dpr->card_number = unit; -/* - dpr->api_active = 1; - dpr->watchdog_cnt = 0xFF; - dpr->api_area[0] = 0; - dpr->api_area[2] = 0; -*/ - dpr->int_flg_pc = 0xFF; - break; - case 0x15: /* POLL IND */ - if(dpr->dn_mbx.msg_flag) return; - dpr->api_active = 1; - dpr->watchdog_cnt = 0xFF; - dpr->int_flg_pc = 0xFF; - error= en_q(unit,msg->type|0x20,0,0,0,NULL); - break; - case 0x16: /* STATE IND */ - if(dpr->dn_mbx.msg_flag) return; - if(sc->sc_flags & LOAD_ENTITY) - { - if(sc->sc_flags & 7) - sc->sc_flags = OPEN; - else sc->sc_flags= 0; - } - error= en_q(unit,msg->type|0x20,0,0,0,NULL); - break; - case 0x17: /* STATE RESP */ - break; - case 0x1e: /* MANUFACT CONF */ - if(msg->subtype == 18) - break; - badstate(msg,1,0,dpr); - break; - case 0x1f: /* MANUFACT IND */ - if(msg->subtype == 19) - { - if(dpr->dn_mbx.msg_flag) return; - isdn_input(ispy_applnr, msg->data_len, msg->data,0); - error= en_q(unit,msg->type|0x20,msg->subtype,0,0,NULL); - break; - } - badstate(msg,2,0,dpr); - break; - case 0x40: /* CONNECT CONF */ - err = *(u_short *) msg->data; - if (err || (appl == NULL) || (chan == NULL) || (ctrl == NULL)) - { - if(chan) reset_plci(3, chan, pl); - if(appl) appl->state= 0; - break; - } - if (ISBUSY(ctrl->appl)) - { - if(dpr->dn_mbx.msg_flag) return; - error= discon_req(2, unit, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr = 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = APPL(pl); - appl->ctrl = chan->ctrl; - ctrl->islisten= 0; - chan->state = DIAL; - appl->state= 3; - break; - - case 0x41: /* CONNECT IND */ - if (ISBUSY(ctrl->appl)) - { - if(dpr->dn_mbx.msg_flag) return; - error= discon_req(3, unit, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr = 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = 0x7f; - ctrl->islisten= 1; - chan->state = CALLED; - msg->data[msg->data[3] + 4] = 0; - isdn_accept_con_ind(APPL(pl), chan->ctrl, msg->data[0], msg->data[1] - ,msg->data[2], msg->data[3], (char *) &msg->data[4]); - break; - - case 0x42: /* CONNECT ACTIVE IND */ - if(dpr->dn_mbx.msg_flag) return; - error= con_act_resp(unit, pl); - if (IS_LISTEN(pl)) - { - isdn_conn_ind(ctrl->appl,chan->ctrl,0); - break; - } - isdn_conn_ind(APPL(pl),chan->ctrl,1); - chan->state = CONNECT; - ctrl->appl = APPL(pl); - appl->ctrl = chan->ctrl; - break; - - case 0x43: /* DISCONNECT CONF */ - reset_plci(4, chan, pl); - break; - - case 0x44: /* DISCONNECT IND */ - if(dpr->dn_mbx.msg_flag) return; - error= discon_resp(unit, reset_plci(5, chan, pl)); - break; - - case 0x47: /* LISTEN CONF */ - isdn_state = *(u_short *) msg->data; - break; - - case 0x4a: /* INFO IND */ - if(dpr->dn_mbx.msg_flag) return; - isdn_info(APPL(pl),*(u_short *)msg->data, msg->data[2], msg->data+3); - error= inf_resp(unit, pl); - break; - case 0x80: /* SELECT PROT CONF */ - if(dpr->dn_mbx.msg_flag) return; - err = *(u_short *) msg->data; - if (err) - { - error= discon_req(4, unit, pl, 0, err); - break; - } - - switch (msg->subtype) - { - case 2:/* SELECT B2 PROTOCOL */ - if(ISFREE(ctrl->appl)) - break; - error= sel_b3_prot_req(unit, mb, pl, &isdn_appl[ctrl->appl].ncpd); - break; - - case 3:/* SELECT B3 PROTOCOL */ - if (IS_DIAL(pl)) - error= con_b3_req(unit, mb, pl); - else - error= listen_b3_req(unit, mb, pl); - break; - } - break; - - case 0x81: /* LISTEN B3 CONF */ - if(dpr->dn_mbx.msg_flag) return; - err = *(u_short *) msg->data; - if (err) - { - error= discon_req(5, unit, pl, 0, err); - break; - } - error= con_resp(unit, pl, 0); - break; - - case 0x82: /* CONNECT B3 CONF */ - err = *(u_short *) (msg->data + 2); - n = *(u_short *) msg->data; - - if (err) - { - if(dpr->dn_mbx.msg_flag) return; - error= discon_req(6, unit, pl, 0, err); - break; - } - if(ISFREE(ctrl->appl)) - break; - chan->ncci = n; - chan->state = CONNECT; - break; - - case 0x83: /* CONNECT B3 IND */ - if(ISFREE(ctrl->appl)) - break; - if(dpr->dn_mbx.msg_flag) return; - n = *(u_short *) msg->data; - chan->ncci = n; - chan->state = CONNECT; - error= con_b3_resp(unit, mb, n, pl, 0); - break; - - case 0x84: /* CONNECT B3 ACTIVE IND */ - if(ISFREE(ctrl->appl)) - break; - if (chan->state < IDLE) - { - chan->state = IDLE; - ctrl->o_len = 0; - /* - * XXX the chan->ctrl arg is very bogus. - * Don't just use a cast to "fix" it. - */ - timeout(isdn_start_out, chan->ctrl, hz / 5); - } - break; - - case 0x85: /* DISCONNECT B3 CONF */ - if(ISBUSY(ctrl->appl)) - chan->state = ISDISCON; - err = *(u_short *) (msg->data + 2); - if (err) - { - if(dpr->dn_mbx.msg_flag) return; - error= discon_req(7, unit, pl, 0, err); - break; - } - break; - case 0x86: /* DISCONNECT B3 IND */ - if(dpr->dn_mbx.msg_flag) return; - if(ISBUSY(ctrl->appl)) - chan->state = ISDISCON; - err = *(u_short *) (msg->data + 2); - error= discon_req(8, unit, pl, 0, err); - break; - - case 0x88: /* DATA B3 CONF */ - if(ISFREE(ctrl->appl)) - break; - err = *(u_short *) (msg->data + 2); - if (err) - { - ctrl->send_err++; - isdn_appl[ctrl->appl].send_err++; - } - chan->state = IDLE; - ctrl->o_len = 0; - isdn_start_out(chan->ctrl); - break; - - case 0x89: /* DATA B3 IND */ - if(ISFREE(ctrl->appl)) - break; - if (msg->more_data) - { - if(chan->i_len) - { - if((chan->morenr != msg->data[4]) || ((chan->i_len + msg->data_len - 5) > 2048)) - break; - } - else - chan->morenr= msg->data[4]; - bcopy(msg->data+5, &chan->i_buf[chan->i_len], msg->data_len-5); - chan->i_len += msg->data_len -5; - break; - } /* msg->more_data == 0 */ - if (chan->i_len) - { - int l; - - if(chan->morenr != msg->data[4]) - break; - - if ((l = chan->i_len + msg->data_len - 5) <= 2048) - { - bcopy(msg->data+5, &chan->i_buf[chan->i_len], msg->data_len); - if(isdn_input(ctrl->appl, l, chan->i_buf, ctrl->islisten)) - ctrl->lastact = time.tv_sec; - } - chan->i_len = 0; - break; - } /* chan->i_len == 0 && msg->more_data == 0 */ - if(isdn_input(ctrl->appl, msg->data_len-5, msg->data+5,ctrl->islisten)) - ctrl->lastact = time.tv_sec; - break; - - default: - badstate(msg,3,mb,dpr); - break; - } - -fin: - if(error) - { -printf("E?%x",error); - return; - } - msg->msg_flag= 0; - timeout(make_intr, (void *)sc,1); -} - -static void -nnnicintr(void *gen) -{ - unsigned int unit = (int)gen; - register struct nnic_softc *sc = &nnic_sc[unit]; - dpr_type *dpr = sc->sc_dpr; - - if(dpr->up_mbx.msg_flag) - up_intr(unit,sc); - if (bsintr && (dpr->dn_mbx.msg_flag == 0)) - dn_intr(unit,sc); -} -void -nnicintr(int unit) -{ - timeout(nnnicintr, (void *)unit,1); -} - -#endif /* NNNIC > 0 */ diff --git a/sys/gnu/i386/isa/nic3009.h b/sys/gnu/i386/isa/nic3009.h deleted file mode 100644 index 223619f..0000000 --- a/sys/gnu/i386/isa/nic3009.h +++ /dev/null @@ -1,79 +0,0 @@ -static char nic39hid[] = "@(#)$Id: nic3009.h,v 1.1 1995/01/25 14:06:18 jkr Exp jkr $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: nic3009.h,v $ - * - ******************************************************************************/ - -/* - * This file defines the NICCY 3009 Interface. Copyright Dr. Neuhaus GmbH, - * Hamburg and Dietmar Friede - * - */ - -#define NO_MORE_DATA 0x00 /* der Message folgen keine Daten */ -#define MORE_DATA 0x01 /* der Message folgen weitere Daten */ - -#define DPR_LEN 0x800 /* 2 kBytes gross */ -#define DPR_VAR_AREA_LEN 0x100 /* davon fuer allg. Variablen */ - -#define DPR_MBX_LEN (DPR_LEN-DPR_VAR_AREA_LEN)/2 /* 0x380 lang */ -#define DPR_MBX_FLAG_LEN 2 /* zwei Bytes MBX-Zustand... */ -#define DPR_MSG_HDR_LEN 10 /* Msg-Laenge ohne Datafield */ -#define DATAFIELD_LEN (DPR_MBX_LEN-DPR_MBX_FLAG_LEN-DPR_MSG_HDR_LEN) -#define MAX_B3_LEN (2048+2) /* Daten und Network-Header */ - -#pragma pack (1) -typedef struct -{ - u_char msg_flag; /* Signalisierung NICCY / PC */ - u_char progress; /* NICCY-interne Verwendung ! */ - u_char type; - u_char subtype; - u_short number; - u_char more_data; - u_char reserved; - u_short data_len; - u_short plci; - u_char data[DATAFIELD_LEN]; -} mbx_type; - -typedef struct -{ - mbx_type up_mbx; /* Offset 0x000-0x37F */ - mbx_type dn_mbx; /* Offset 0x380-0x6FF */ - u_char card_number; /* Offset 0x700 */ - u_char card_state; /* Offset 0x701 */ - u_short mainloop_cnt; /* Offset 0x702-0x703 */ - u_char watchdog_cnt; /* Offset 0x704 */ - u_char hw_config; /* Offset 0x705 */ - u_char int_flg_pc; /* Offset 0x706 */ - u_char int_flg_nic; /* Offset 0x707 */ - u_char api_area[64]; /* Offset 0x708-0x747 */ - u_char api_active; /* Offset 0x748 */ - u_char tei; /* Offset 0x749 */ - u_char state_b1; /* Offset 0x74A */ - u_char state_b2; /* Offset 0x74B */ - u_char si_b1; /* Offset 0x74C */ - u_char si_b2; /* Offset 0x74D */ - u_short calls_in; /* Offset 0x74E-0x74F */ - u_short calls_out; /* Offset 0x750-0x751 */ - u_char ram_config; /* Offset 0x752 */ - u_char spv_request_flag; /* Offset 0x753 */ - u_char dcp_state_b1; /* Offset 0x754 */ - u_char dcp_state_b2; /* Offset 0x755 */ - u_char dc_protocol; /* Offset 0x756 */ - u_char poll_flag; /* Offset 0x757 */ - u_char debug[DPR_LEN - 0x758 - 4]; /* Offset 0x758-0x7FB */ - u_short signal_niccy_to_pc; /* Offset 0x7FC-0x7FD */ - u_short signal_pc_to_niccy; /* Offset 0x7FE-0x7FF */ -} dpr_type; -#pragma pack () diff --git a/sys/gnu/i386/isa/niccyreg.h b/sys/gnu/i386/isa/niccyreg.h deleted file mode 100644 index a9d8328..0000000 --- a/sys/gnu/i386/isa/niccyreg.h +++ /dev/null @@ -1,158 +0,0 @@ -static char nicregh_id[] = "@(#)$Id: niccyreg.h,v 1.1 1995/01/25 14:06:18 jkr Exp jkr $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: niccyreg.h,v $ - * - ******************************************************************************/ - -/* - * This file defines the NICCY 3008 Interface. - * Copyright Dr. Neuhaus GmbH, Hamburg and Dietmar Friede - * -*/ - -#define MBX_MU 0 -#define MBX_MD 1 -#define MBX_DU 2 -#define MBX_DD 3 -#define MBX_B1U 4 -#define MBX_B1D 5 -#define MBX_B2U 6 -#define MBX_B2D 7 - -#define MBX_xU 0x55 -#define MBX_xD 0xAA - -/* -------------------------------------------------------------------- */ - -#define MU_INIT_CNF 0x00 -#define MU_INIT_IND 0x01 -#define MU_RESET_CNF 0x02 -#define MU_HANDSET_IND 0x03 -#define MU_DNL_MOD_CNF 0x04 -/* reserved: 0x05 */ -#define MU_DNL_MOD_IND 0x06 -#define MU_DISC_MOD_CNF 0x07 -#define MU_LIST_MOD_CNF 0x08 -#define MU_LIST_MOD_DATA 0x09 -/* reserved: 0x0A to 0x0B */ -#define MU_HW_CONFIG_CNF 0x0C -#define MU_HW_ID_CNF 0x0D -#define MU_SET_CLOCK_CNF 0x0E -#define MU_GET_CLOCK_CNF 0x0F -#define MU_ACT_IA_CNF 0x10 -#define MU_ACT_IA_IND 0x11 -#define MU_DEACT_IA_CNF 0x12 -#define MU_DEACT_IA_IND 0x13 -#define MU_POLL_CNF 0x14 -#define MU_POLL_IND 0x15 -/* reserved: 0x16 to 0x1D */ -#define MU_MANUFACT_CNF 0x1E -#define MU_MANUFACT_IND 0x1F - -/*---------------------------------------------------------------------------*/ - -#define MD_INIT_REQ 0x20 -#define MD_INIT_RSP 0x21 -#define MD_RESET_REQ 0x22 -#define MD_HANDSET_RSP 0x23 -#define MD_DNL_MOD_REQ 0x24 -#define MD_DNL_MOD_DATA 0x25 -#define MD_DNL_MOD_RSP 0x26 -#define MD_DISC_MOD_REQ 0x27 -#define MD_LIST_MOD_REQ 0x28 -/* reserved: 0x29 to 0x2B */ -#define MD_HW_CONFIG_REQ 0x2C -#define MD_HW_ID_REQ 0x2D -#define MD_SET_CLOCK_REQ 0x2E -#define MD_GET_CLOCK_REQ 0x2F -#define MD_ACT_IA_REQ 0x30 -#define MD_ACT_IA_RSP 0x31 -#define MD_DEACT_IA_REQ 0x32 -#define MD_DEACT_IA_RSP 0x33 -#define MD_POLL_REQ 0x34 -#define MD_POLL_RSP 0x35 -#define MD_STATE_IND 0x37 -#define MD_MANUFACT_REQ 0x3E -#define MD_MANUFACT_RSP 0x3F - -/*---------------------------------------------------------------------------*/ - -#define DU_CONN_CNF 0x40 -#define DU_CONN_IND 0x41 -#define DU_CONN_ACT_IND 0x42 -#define DU_DISC_CNF 0x43 -#define DU_DISC_IND 0x44 -#define DU_DATA_CNF 0x45 -#define DU_DATA_IND 0x46 -#define DU_LISTEN_CNF 0x47 -#define DU_GET_PAR_CNF 0x48 -#define DU_INFO_CNF 0x49 -#define DU_INFO_IND 0x4A -#define DU_CONN_INFO_CNF 0x4B -#define DU_REL_PLCI_CNF 0x4C -/* reserved: 0x4C to 0x5E */ -#define DU_STR_NOT_COMP 0x5F - -/*---------------------------------------------------------------------------*/ - -#define DD_CONN_REQ 0x60 -#define DD_CONN_RSP 0x61 -#define DD_CONN_ACT_RSP 0x62 -#define DD_DISC_REQ 0x63 -#define DD_DISC_RSP 0x64 -#define DD_DATA_REQ 0x65 -#define DD_DATA_RSP 0x66 -#define DD_LISTEN_REQ 0x67 -#define DD_GET_PAR_REQ 0x68 -#define DD_INFO_REQ 0x69 -#define DD_INFO_RSP 0x6A -#define DD_CONN_INFO_REQ 0x6B -#define DD_REL_PLCI_REQ 0x6C - -/*---------------------------------------------------------------------------*/ - -#define BD_SEL_PROT_REQ 0xA0 -#define BD_LIST_B3_REQ 0xA1 -#define BD_CONN_B3_REQ 0xA2 -#define BD_CONN_B3_RSP 0xA3 -#define BD_C_B3_ACT_RSP 0xA4 -#define BD_DISC_B3_REQ 0xA5 -#define BD_DISC_B3_RSP 0xA6 -#define BD_GET_P_B3_REQ 0xA7 -#define BD_DATA_B3_REQ 0xA8 -#define BD_DATA_B3_RSP 0xA9 -#define BD_RESET_B3_REQ 0xAA -#define BD_RESET_B3_RSP 0xAB - -/*---------------------------------------------------------------------------*/ - - -#define NICCY_DEBUG _IOWR('N',1,dbg_type) -#define NICCY_RESET _IOWR('N',2,int) -#define NICCY_LOAD _IOWR('N',3,struct head) -#define NICCY_SET_CLOCK _IOWR('N',4,time_str_t) -#define NICCY_SPY _IOWR('N',5,int) - -struct head -{ - u_long len; - u_long sig; - char nam[8]; - char ver[5]; - u_char typ; - u_short status; - u_long d_len; - u_char *data; -}; - -typedef char time_str_t[14]; -typedef u_char dbg_type[10000]; diff --git a/sys/gnu/i386/isa/scd.c b/sys/gnu/i386/isa/scd.c deleted file mode 100644 index 92d31de..0000000 --- a/sys/gnu/i386/isa/scd.c +++ /dev/null @@ -1,1530 +0,0 @@ -/*- - * Copyright (c) 1995 Mikael Hybsch - * - * Portions of this file are copied from mcd.c - * which has the following copyrights: - * - * Copyright 1993 by Holger Veit (data part) - * Copyright 1993 by Brian Moore (audio part) - * Changes Copyright 1993 by Gary Clark II - * Changes Copyright (C) 1994 by Andrew A. Chernov - * - * Rewrote probe routine to work on newer Mitsumi drives. - * Additional changes (C) 1994 by Jordan K. Hubbard - * - * The Linux driver cdu31a has been used as a reference when writing this - * code, there fore bringing it under the GNU Public License. The following - * conditions of redistribution therefore apply: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* $Id: scd.c,v 1.7 1995/02/09 11:30:07 jkh Exp $ */ - -/* Please send any comments to micke@dynas.se */ - -#define SCD_DEBUG 0 - -#include "scd.h" -#if NSCD > 0 -#include <sys/types.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/file.h> -#include <sys/buf.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <sys/ioctl.h> -#include <sys/cdio.h> -#include <sys/errno.h> -#include <sys/dkbad.h> -#include <sys/disklabel.h> -#include <sys/devconf.h> -#include <machine/stdarg.h> - -#include <i386/isa/isa.h> -#include <i386/isa/isa_device.h> -#include <gnu/i386/isa/scdreg.h> - -#define scd_part(dev) ((minor(dev)) & 7) -#define scd_unit(dev) (((minor(dev)) & 0x38) >> 3) -#define scd_phys(dev) (((minor(dev)) & 0x40) >> 6) -#define RAW_PART 2 - -/* flags */ -#define SCDOPEN 0x0001 /* device opened */ -#define SCDVALID 0x0002 /* parameters loaded */ -#define SCDINIT 0x0004 /* device is init'd */ -#define SCDPROBING 0x0020 /* probing */ -#define SCDTOC 0x0100 /* already read toc */ -#define SCDMBXBSY 0x0200 /* local mbx is busy */ -#define SCDSPINNING 0x0400 /* drive is spun up */ - -#define SCD_S_BEGIN 0 -#define SCD_S_BEGIN1 1 -#define SCD_S_WAITSTAT 2 -#define SCD_S_WAITFIFO 3 -#define SCD_S_WAITSPIN 4 -#define SCD_S_WAITREAD 5 -#define SCD_S_WAITPARAM 6 - -#define RDELAY_WAIT 300 -#define RDELAY_WAITREAD 300 - -#define SCDBLKSIZE 2048 - -#ifdef SCD_DEBUG - int scd_debuglevel = SCD_DEBUG; -# define XDEBUG(level, data) {if (scd_debuglevel >= level) printf data;} -#else -# define XDEBUG(level, data) -#endif - -struct scd_mbx { - short unit; - short port; - short retry; - short nblk; - int sz; - u_long skip; - struct buf *bp; - int p_offset; - short count; -}; - -struct scd_data { - int iobase; - char double_speed; - char *name; - short flags; - int blksize; - u_long disksize; - struct disklabel dlabel; - int openflag; - struct { - unsigned char adr :4; - unsigned char ctl :4; /* xcdplayer needs this */ - unsigned char start_msf[3]; - } toc[MAX_TRACKS]; - short first_track; - short last_track; - struct ioc_play_msf last_play; - - short audio_status; - struct buf head; /* head of buf queue */ - struct scd_mbx mbx; -} scd_data[NSCD]; - -/* prototypes */ -int scdopen(dev_t dev); -int scdclose(dev_t dev); -void scdstrategy(struct buf *bp); -int scdioctl(dev_t dev, int cmd, caddr_t addr, int flags); -int scdsize(dev_t dev); - -static int bcd2bin(bcd_t b); -static bcd_t bin2bcd(int b); -static void hsg2msf(int hsg, bcd_t *msf); -static int msf2hsg(bcd_t *msf); - -static void process_attention(unsigned unit); -static inline void write_control(unsigned port, unsigned data); -static int waitfor_status_bits(int unit, int bits_set, int bits_clear); -static int waitfor_attention(int unit); -static int send_cmd(u_int unit, u_char cmd, u_int nargs, ...); -static void init_drive(unsigned unit); -static int spin_up(unsigned unit); -static int read_toc(dev_t dev); -static int get_result(u_int unit, int result_len, u_char *result); -static void print_error(int unit, int errcode); - -static void scd_start(int unit); -static void scd_doread(int state, struct scd_mbx *mbxin); - -static int scd_eject(int unit); -static int scd_stop(int unit); -static int scd_pause(int unit); -static int scd_resume(int unit); -static int scd_playtracks(int unit, struct ioc_play_track *pt); -static int scd_playmsf(int unit, struct ioc_play_msf *msf); -static int scd_play(int unit, struct ioc_play_msf *msf); -static int scd_subchan(int unit, struct ioc_read_subchannel *sc); -static int read_subcode(int unit, struct sony_subchannel_position_data *sc); - -/* for xcdplayer */ -static int scd_toc_header(int unit, struct ioc_toc_header *th); -static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te); -#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ - -extern int hz; - -int scd_probe(struct isa_device *dev); -int scd_attach(struct isa_device *dev); -struct isa_driver scddriver = { scd_probe, scd_attach, "scd" }; - -static struct kern_devconf kdc_scd[NSCD] = { { - 0, 0, 0, /* filled in by dev_attach */ - "scd", 0, { MDDT_ISA, 0, "bio" }, - isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, - &kdc_isa0, /* parent */ - 0, /* parentdata */ - DC_IDLE, /* status */ - "Sony CD-ROM drive" /* properly filled later */ -} }; - -static inline void -scd_registerdev(struct isa_device *id) -{ - if(id->id_unit) - kdc_scd[id->id_unit] = kdc_scd[0]; - kdc_scd[id->id_unit].kdc_unit = id->id_unit; - kdc_scd[id->id_unit].kdc_isa = id; - dev_attach(&kdc_scd[id->id_unit]); -} - -int scd_attach(struct isa_device *dev) -{ - struct scd_data *cd = scd_data + dev->id_unit; - int i; - - cd->iobase = dev->id_iobase; /* Already set by probe, but ... */ - - scd_registerdev(dev); - /* name filled in probe */ - kdc_scd[dev->id_unit].kdc_description = scd_data[dev->id_unit].name; - printf("scd%d: <%s>\n", dev->id_unit, scd_data[dev->id_unit].name); - - init_drive(dev->id_unit); - - cd->flags = SCDINIT; - cd->audio_status = CD_AS_AUDIO_INVALID; - - return 1; -} - -int -scdopen(dev_t dev) -{ - int unit,part,phys; - int rc; - struct scd_data *cd; - - unit = scd_unit(dev); - if (unit >= NSCD) - return ENXIO; - - cd = scd_data + unit; - part = scd_part(dev); - phys = scd_phys(dev); - - /* not initialized*/ - if (!(cd->flags & SCDINIT)) - return ENXIO; - - /* invalidated in the meantime? mark all open part's invalid */ - if (cd->openflag) - return ENXIO; - - XDEBUG(1,("scd%d: DEBUG: status = 0x%x\n", unit, inb(cd->iobase+IREG_STATUS))); - - if ((rc = spin_up(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - if (!(cd->flags & SCDTOC)) { - int loop_count = 3; - - while (loop_count-- > 0 && (rc = read_toc(dev)) != 0) { - if (rc == ERR_NOT_SPINNING) { - rc = spin_up(unit); - if (rc) { - print_error(unit, rc);\ - return EIO; - } - continue; - } - printf("scd%d: TOC read error 0x%x\n", unit, rc); - return EIO; - } - } - - cd->openflag = 1; - cd->flags |= SCDVALID; - kdc_scd[unit].kdc_state = DC_BUSY; - - return 0; -} - -int -scdclose(dev_t dev) -{ - int unit,part,phys; - struct scd_data *cd; - int rlen; - char rdata[10]; - - unit = scd_unit(dev); - if (unit >= NSCD) - return ENXIO; - - cd = scd_data + unit; - part = scd_part(dev); - phys = scd_phys(dev); - - if (!(cd->flags & SCDINIT) || !cd->openflag) - return ENXIO; - - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { - (void)send_cmd(unit, CMD_SPIN_DOWN, 0); - cd->flags &= ~SCDSPINNING; - } - - kdc_scd[unit].kdc_state = DC_IDLE; - - /* close channel */ - cd->openflag = 0; - - return 0; -} - -void -scdstrategy(struct buf *bp) -{ - struct scd_data *cd; - struct buf *qp; - int s; - int unit = scd_unit(bp->b_dev); - - cd = scd_data + unit; - - XDEBUG(2, ("scd%d: DEBUG: strategy: block=%ld, bcount=%ld\n", unit, bp->b_blkno, bp->b_bcount)); - - if (unit >= NSCD || bp->b_blkno < 0 || (bp->b_bcount % SCDBLKSIZE)) { - printf("scd%d: strategy failure: blkno = %d, bcount = %d\n", - unit, bp->b_blkno, bp->b_bcount); - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - - /* if device invalidated (e.g. media change, door open), error */ - if (!(cd->flags & SCDVALID)) { - printf("scd%d: media changed\n", unit); - bp->b_error = EIO; - goto bad; - } - - /* read only */ - if (!(bp->b_flags & B_READ)) { - bp->b_error = EROFS; - goto bad; - } - - /* no data to read */ - if (bp->b_bcount == 0) - goto done; - - if (!(cd->flags & SCDTOC)) { - bp->b_error = EIO; - goto bad; - } - /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) - goto done; - - bp->b_pblkno = bp->b_blkno; - bp->b_resid = 0; - - /* queue it */ - qp = &cd->head; - s = splbio(); - disksort(qp,bp); - splx(s); - - /* now check whether we can perform processing */ - scd_start(unit); - return; - -bad: - bp->b_flags |= B_ERROR; -done: - bp->b_resid = bp->b_bcount; - biodone(bp); - return; -} - -static void -scd_start(int unit) -{ - struct scd_data *cd = scd_data + unit; - struct buf *bp, *qp = &cd->head; - struct partition *p; - int part; - register s = splbio(); - - if (cd->flags & SCDMBXBSY) { - splx(s); - return; - } - - if ((bp = qp->b_actf) != 0) { - /* block found to process, dequeue */ - qp->b_actf = bp->b_actf; - cd->flags |= SCDMBXBSY; - splx(s); - } else { - /* nothing to do */ - splx(s); - return; - } - - p = cd->dlabel.d_partitions + scd_part(bp->b_dev); - - cd->mbx.unit = unit; - cd->mbx.port = cd->iobase; - cd->mbx.retry = 3; - cd->mbx.bp = bp; - cd->mbx.p_offset = p->p_offset; - splx(s); - - scd_doread(SCD_S_BEGIN,&(cd->mbx)); - return; -} - -int -scdioctl(dev_t dev, int cmd, caddr_t addr, int flags) -{ - struct scd_data *cd; - int unit,part; - - unit = scd_unit(dev); - part = scd_part(dev); - cd = scd_data + unit; - - XDEBUG(1, ("scd%d: ioctl: cmd=0x%lx\n", unit, cmd)); - - if (!(cd->flags & SCDVALID)) - return EIO; - - switch (cmd) { - case DIOCSBAD: - return EINVAL; - case DIOCGDINFO: - *(struct disklabel *)addr = cd->dlabel; - return 0; - case DIOCGPART: - ((struct partinfo *)addr)->disklab = &cd->dlabel; - ((struct partinfo *)addr)->part = - &cd->dlabel.d_partitions[0]; - return 0; - case CDIOCPLAYTRACKS: - return scd_playtracks(unit, (struct ioc_play_track *) addr); - case CDIOCPLAYBLOCKS: - return EINVAL; - case CDIOCPLAYMSF: - return scd_playmsf(unit, (struct ioc_play_msf *) addr); - case CDIOCREADSUBCHANNEL: - return scd_subchan(unit, (struct ioc_read_subchannel *) addr); - case CDIOREADTOCHEADER: - return scd_toc_header (unit, (struct ioc_toc_header *) addr); - case CDIOREADTOCENTRYS: - return scd_toc_entrys (unit, (struct ioc_read_toc_entry*) addr); - case CDIOCSETPATCH: - case CDIOCGETVOL: - case CDIOCSETVOL: - case CDIOCSETMONO: - case CDIOCSETSTERIO: - case CDIOCSETMUTE: - case CDIOCSETLEFT: - case CDIOCSETRIGHT: - return EINVAL; - case CDIOCRESUME: - return scd_resume(unit); - case CDIOCPAUSE: - return scd_pause(unit); - case CDIOCSTART: - return EINVAL; - case CDIOCSTOP: - return scd_stop(unit); - case CDIOCEJECT: - return scd_eject(unit); - case CDIOCALLOW: - return 0; - case CDIOCSETDEBUG: -#ifdef SCD_DEBUG - scd_debuglevel++; -#endif - return 0; - case CDIOCCLRDEBUG: -#ifdef SCD_DEBUG - scd_debuglevel = 0; - -#endif - return 0; - default: - printf("scd%d: unsupported ioctl (cmd=0x%lx)\n", unit, cmd); - return ENOTTY; - } -} - -int -scdsize(dev_t dev) -{ - return -1; -} - -void -scdintr() -{ - return; -} - -/*************************************************************** - * lower level of driver starts here - **************************************************************/ - -static int -scd_playtracks(int unit, struct ioc_play_track *pt) -{ - struct scd_data *cd = scd_data + unit; - struct ioc_play_msf msf; - int a = pt->start_track; - int z = pt->end_track; - int rc, i; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - if (rc == -ERR_NOT_SPINNING) { - if (spin_up(unit) != 0) - return EIO; - rc = read_toc(unit); - } - if (rc != 0) { - print_error(unit, rc); - return EIO; - } - } - - XDEBUG(1, ("scd%d: playtracks from %d:%d to %d:%d\n", unit, - a, pt->start_index, z, pt->end_index)); - - if ( a < cd->first_track - || a > cd->last_track - || a > z - || z > cd->last_track) - return EINVAL; - - bcopy(cd->toc[a].start_msf, &msf.start_m, 3); - hsg2msf(msf2hsg(cd->toc[z+1].start_msf)-1, &msf.end_m); - - return scd_play(unit, &msf); -} - -/* The start/end msf is expected to be in bin format */ -static int -scd_playmsf(int unit, struct ioc_play_msf *msfin) -{ - struct ioc_play_msf msf; - - msf.start_m = bin2bcd(msfin->start_m); - msf.start_s = bin2bcd(msfin->start_s); - msf.start_f = bin2bcd(msfin->start_f); - msf.end_m = bin2bcd(msfin->end_m); - msf.end_s = bin2bcd(msfin->end_s); - msf.end_f = bin2bcd(msfin->end_f); - - return scd_play(unit, &msf); -} - -/* The start/end msf is expected to be in bcd format */ -static int -scd_play(int unit, struct ioc_play_msf *msf) -{ - struct scd_data *cd = scd_data + unit; - int i, rc; - - XDEBUG(1, ("scd%d: playing: %02x:%02x:%02x -> %02x:%02x:%02x\n", unit, - msf->start_m, msf->start_s, msf->start_f, - msf->end_m, msf->end_s, msf->end_f)); - - for (i = 0; i < 2; i++) { - rc = send_cmd(unit, CMD_PLAY_AUDIO, 7, - 0x03, - msf->start_m, msf->start_s, msf->start_f, - msf->end_m, msf->end_s, msf->end_f); - if (rc == -ERR_NOT_SPINNING) { - cd->flags &= ~SCDSPINNING; - if (spin_up(unit) != 0) - return EIO; - } else if (rc < 0) { - print_error(unit, rc); - return EIO; - } else { - break; - } - } - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; - bcopy((char *)msf, (char *)&cd->last_play, sizeof(struct ioc_play_msf)); - return 0; -} - -static int -scd_stop(int unit) -{ - struct scd_data *cd = scd_data + unit; - - (void)send_cmd(unit, CMD_STOP_AUDIO, 0); - cd->audio_status = CD_AS_PLAY_COMPLETED; - return 0; -} - -static int -scd_pause(int unit) -{ - struct scd_data *cd = scd_data + unit; - struct sony_subchannel_position_data subpos; - - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) - return EINVAL; - - if (read_subcode(unit, &subpos) != 0) - return EIO; - - if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0) - return EIO; - - cd->last_play.start_m = subpos.abs_msf[0]; - cd->last_play.start_s = subpos.abs_msf[1]; - cd->last_play.start_f = subpos.abs_msf[2]; - cd->audio_status = CD_AS_PLAY_PAUSED; - - XDEBUG(1, ("scd%d: pause @ %02x:%02x:%02x\n", unit, - cd->last_play.start_m, - cd->last_play.start_s, - cd->last_play.start_f)); - - return 0; -} - -static int -scd_resume(int unit) -{ - if (scd_data[unit].audio_status != CD_AS_PLAY_PAUSED) - return EINVAL; - return scd_play(unit, &scd_data[unit].last_play); -} - -static int -scd_eject(int unit) -{ - struct scd_data *cd = scd_data + unit; - int port = cd->iobase; - - cd->audio_status = CD_AS_AUDIO_INVALID; - cd->flags &= ~(SCDSPINNING|SCDTOC); - - if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0 || - send_cmd(unit, CMD_SPIN_DOWN, 0) != 0 || - send_cmd(unit, CMD_EJECT, 0) != 0) - { - return EIO; - } - return 0; -} - -static int -scd_subchan(int unit, struct ioc_read_subchannel *sc) -{ - struct scd_data *cd = scd_data + unit; - struct sony_subchannel_position_data q; - struct cd_sub_channel_info data; - - XDEBUG(1, ("scd%d: subchan af=%d, df=%d\n", unit, - sc->address_format, - sc->data_format)); - - if (sc->address_format != CD_MSF_FORMAT) - return EINVAL; - - if (sc->data_format != CD_CURRENT_POSITION) - return EINVAL; - - if (read_subcode(unit, &q) != 0) - return EIO; - - data.header.audio_status = cd->audio_status; - data.what.position.data_format = CD_MSF_FORMAT; - data.what.position.track_number = bcd2bin(q.track_number); - data.what.position.reladdr.msf.unused = 0; - data.what.position.reladdr.msf.minute = bcd2bin(q.rel_msf[0]); - data.what.position.reladdr.msf.second = bcd2bin(q.rel_msf[1]); - data.what.position.reladdr.msf.frame = bcd2bin(q.rel_msf[2]); - data.what.position.absaddr.msf.unused = 0; - data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]); - data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]); - data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]); - - if (copyout(&data, sc->data, min(sizeof(struct cd_sub_channel_info), sc->data_len))!=0) - return EFAULT; - return 0; -} - -int -scd_probe(struct isa_device *dev) -{ - struct sony_drive_configuration drive_config; - int unit = dev->id_unit; - int rc; - static char namebuf[8+16+8+3]; - char *s = namebuf; - int loop_count = 0; - - scd_data[unit].flags = SCDPROBING; - scd_data[unit].iobase = dev->id_iobase; - - bzero(&drive_config, sizeof(drive_config)); - -again: - /* Reset drive */ - write_control(dev->id_iobase, CBIT_RESET_DRIVE); - - /* Calm down */ - DELAY(300000); - - /* Only the ATTENTION bit may be set */ - if ((inb(dev->id_iobase+IREG_STATUS) & ~1) != 0) { - XDEBUG(1, ("scd: too many bits set. probe failed.\n")); - return 0; - } - rc = send_cmd(unit, CMD_GET_DRIVE_CONFIG, 0); - if (rc != sizeof(drive_config)) { - /* Sometimes if the drive is playing audio I get */ - /* the bad result 82. Fix by repeating the reset */ - if (rc > 0 && loop_count++ == 0) - goto again; - return 0; - } - if (get_result(unit, rc, (u_char *)&drive_config) != 0) - return 0; - - bcopy(drive_config.vendor, namebuf, 8); - s = namebuf+8; - while (*(s-1) == ' ') /* Strip trailing spaces */ - s--; - *s++ = ' '; - bcopy(drive_config.product, s, 16); - s += 16; - while (*(s-1) == ' ') - s--; - *s++ = ' '; - bcopy(drive_config.revision, s, 8); - s += 8; - while (*(s-1) == ' ') - s--; - *s = 0; - - scd_data[unit].name = namebuf; - - if (drive_config.config & 0x10) - scd_data[unit].double_speed = 1; - else - scd_data[unit].double_speed = 0; - - return 4; -} - -static int -read_subcode(int unit, struct sony_subchannel_position_data *sc) -{ - int rc; - - rc = send_cmd(unit, CMD_GET_SUBCHANNEL_DATA, 0); - if (rc < 0 || rc < sizeof(*sc)) - return EIO; - if (get_result(unit, rc, (u_char *)sc) != 0) - return EIO; - return 0; -} - -/* State machine copied from mcd.c */ - -/* This (and the code in mcd.c) will not work with more than one drive */ -/* because there is only one mbxsave below. Should fix that some day. */ -/* (mbxsave & state should probably be included in the scd_data struct and */ -/* the unit number used as first argument to scd_doread().) /Micke */ - -/* state machine to process read requests - * initialize with SCD_S_BEGIN: reset state machine - * SCD_S_WAITSTAT: wait for ready (!busy) - * SCD_S_WAITSPIN: wait for drive to spin up (if not spinning) - * SCD_S_WAITFIFO: wait for param fifo to get ready, them exec. command. - * SCD_S_WAITREAD: wait for data ready, read data - * SCD_S_WAITPARAM: wait for command result params, read them, error if bad data read. - */ - -static struct scd_mbx *mbxsave; - -static void -scd_doread(int state, struct scd_mbx *mbxin) -{ - struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; - int unit = mbx->unit; - int port = mbx->port; - struct buf *bp = mbx->bp; - struct scd_data *cd = scd_data + unit; - int reg,i,k,c; - int blknum; - caddr_t addr; - char rdata[10]; - static char sdata[3]; /* Must be preserved between calls to this function */ - -loop: - switch (state) { - case SCD_S_BEGIN: - mbx = mbxsave = mbxin; - - case SCD_S_BEGIN1: - /* get status */ - mbx->count = RDELAY_WAIT; - - process_attention(unit); - goto trystat; - - case SCD_S_WAITSTAT: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITSTAT); - if (mbx->count-- <= 0) { - printf("scd%d: timeout. drive busy.\n",unit); - goto harderr; - } - -trystat: - if (IS_BUSY(port)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSTAT,hz/100); /* XXX */ - return; - } - - process_attention(unit); - - /* reject, if audio active */ - if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { - printf("scd%d: audio is active\n",unit); - goto harderr; - } - - mbx->sz = cd->blksize; - -firstblock: - /* for first block */ - mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; - mbx->skip = 0; - -nextblock: - if (!(cd->flags & SCDVALID)) - goto changed; - - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) - + mbx->p_offset + mbx->skip/mbx->sz; - - XDEBUG(2, ("scd%d: scd_doread: read blknum=%d\n", unit, blknum)); - - /* build parameter block */ - hsg2msf(blknum, sdata); - - write_control(port, CBIT_RESULT_READY_CLEAR); - write_control(port, CBIT_RPARAM_CLEAR); - write_control(port, CBIT_DATA_READY_CLEAR); - - if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) - goto writeparam; - - mbx->count = 100; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ - return; - - case SCD_S_WAITSPIN: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITSPIN); - if (mbx->count-- <= 0) { - printf("scd%d: timeout waiting for drive to spin up.\n", unit); - goto harderr; - } - if (!STATUS_BIT(port, SBIT_RESULT_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ - return; - } - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((i = inb(port+IREG_RESULT)) & 0xf0) { - case 0x20: - i = inb(port+IREG_RESULT); - print_error(unit, i); - goto harderr; - case 0x00: - (void)inb(port+IREG_RESULT); - cd->flags |= SCDSPINNING; - break; - } - XDEBUG(1, ("scd%d: DEBUG: spin up complete\n", unit)); - - state = SCD_S_BEGIN1; - goto loop; - - case SCD_S_WAITFIFO: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITFIFO); - if (mbx->count-- <= 0) { - printf("scd%d: timeout. write param not ready.\n",unit); - goto harderr; - } - if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ - return; - } - XDEBUG(1, ("scd%d: mbx->count (writeparamwait) = %d(%d)\n", unit, mbx->count, 100)); - -writeparam: - /* The reason this test isn't done 'till now is to make sure */ - /* that it is ok to send the SPIN_UP cmd below. */ - if (!(cd->flags & SCDSPINNING)) { - XDEBUG(1, ("scd%d: spinning up drive ...\n", unit)); - outb(port+OREG_COMMAND, CMD_SPIN_UP); - mbx->count = 300; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ - return; - } - - reg = port + OREG_WPARAMS; - /* send the read command */ - disable_intr(); - outb(reg, sdata[0]); - outb(reg, sdata[1]); - outb(reg, sdata[2]); - outb(reg, 0); - outb(reg, 0); - outb(reg, 1); - outb(port+OREG_COMMAND, CMD_READ); - enable_intr(); - - mbx->count = RDELAY_WAITREAD; - for (i = 0; i < 50; i++) { - if (STATUS_BIT(port, SBIT_DATA_READY)) - goto got_data; - DELAY(100); - } - - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ - return; - - case SCD_S_WAITREAD: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITREAD); - if (mbx->count-- <= 0) { - if (STATUS_BIT(port, SBIT_RESULT_READY)) - goto got_param; - printf("scd%d: timeout while reading data\n",unit); - goto readerr; - } - if (!STATUS_BIT(port, SBIT_DATA_READY)) { - process_attention(unit); - if (!(cd->flags & SCDVALID)) - goto changed; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ - return; - } - XDEBUG(2, ("scd%d: mbx->count (after RDY_BIT) = %d(%d)\n", unit, mbx->count, RDELAY_WAITREAD)); - -got_data: - /* data is ready */ - addr = bp->b_un.b_addr + mbx->skip; - write_control(port, CBIT_DATA_READY_CLEAR); - insb(port+IREG_DATA, addr, mbx->sz); - - mbx->count = 100; - for (i = 0; i < 20; i++) { - if (STATUS_BIT(port, SBIT_RESULT_READY)) - goto waitfor_param; - DELAY(100); - } - goto waitfor_param; - - case SCD_S_WAITPARAM: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITPARAM); - if (mbx->count-- <= 0) { - printf("scd%d: timeout waiting for params\n",unit); - goto readerr; - } - -waitfor_param: - if (!STATUS_BIT(port, SBIT_RESULT_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITPARAM,hz/100); /* XXX */ - return; - } -#if SCD_DEBUG - if (mbx->count < 100 && scd_debuglevel > 0) - printf("scd%d: mbx->count (paramwait) = %d(%d)\n", unit, mbx->count, 100); -#endif - -got_param: - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((i = inb(port+IREG_RESULT)) & 0xf0) { - case 0x50: - switch (i) { - case ERR_FATAL_READ_ERROR1: - case ERR_FATAL_READ_ERROR2: - printf("scd%d: unrecoverable read error 0x%x\n", unit, i); - goto harderr; - } - break; - case 0x20: - i = inb(port+IREG_RESULT); - switch (i) { - case ERR_NOT_SPINNING: - XDEBUG(1, ("scd%d: read error: drive not spinning\n", unit)); - if (mbx->retry-- > 0) { - state = SCD_S_BEGIN1; - cd->flags &= ~SCDSPINNING; - goto loop; - } - goto harderr; - default: - print_error(unit, i); - goto readerr; - } - case 0x00: - i = inb(port+IREG_RESULT); - break; - } - - if (--mbx->nblk > 0) { - mbx->skip += mbx->sz; - goto nextblock; - } - - /* return buffer */ - bp->b_resid = 0; - biodone(bp); - - cd->flags &= ~SCDMBXBSY; - scd_start(mbx->unit); - return; - } - -readerr: - if (mbx->retry-- > 0) { - printf("scd%d: retrying ...\n",unit); - state = SCD_S_BEGIN1; - goto loop; - } -harderr: - /* invalidate the buffer */ - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - bp->b_resid = bp->b_bcount; - biodone(bp); - - cd->flags &= ~SCDMBXBSY; - scd_start(mbx->unit); - return; - -changed: - printf("scd%d: media changed\n", unit); - goto harderr; -} - -static int -bcd2bin(bcd_t b) -{ - return (b >> 4) * 10 + (b & 15); -} - -static bcd_t -bin2bcd(int b) -{ - return ((b / 10) << 4) | (b % 10); -} - -static void -hsg2msf(int hsg, bcd_t *msf) -{ - hsg += 150; - M_msf(msf) = bin2bcd(hsg / 4500); - hsg %= 4500; - S_msf(msf) = bin2bcd(hsg / 75); - F_msf(msf) = bin2bcd(hsg % 75); -} - -static int -msf2hsg(bcd_t *msf) -{ - return (bcd2bin(M_msf(msf)) * 60 + - bcd2bin(S_msf(msf))) * 75 + - bcd2bin(F_msf(msf)) - 150; -} - -static void -process_attention(unsigned unit) -{ - unsigned port = scd_data[unit].iobase; - unsigned char code; - int count = 0; - int i; - - while (IS_ATTENTION(port) && count++ < 30) { - write_control(port, CBIT_ATTENTION_CLEAR); - code = inb(port+IREG_RESULT); - -#if SCD_DEBUG - if (scd_debuglevel > 0) { - if (count == 1) - printf("scd%d: DEBUG: ATTENTIONS = 0x%x", unit, code); - else - printf(",0x%x", code); - } -#endif - - switch (code) { - case ATTEN_SPIN_DOWN: - scd_data[unit].flags &= ~SCDSPINNING; - break; - - case ATTEN_SPIN_UP_DONE: - scd_data[unit].flags |= SCDSPINNING; - break; - - case ATTEN_AUDIO_DONE: - scd_data[unit].audio_status = CD_AS_PLAY_COMPLETED; - break; - - case ATTEN_DRIVE_LOADED: - scd_data[unit].flags &= ~(SCDTOC|SCDSPINNING|SCDVALID); - scd_data[unit].audio_status = CD_AS_AUDIO_INVALID; - break; - - case ATTEN_EJECT_PUSHED: - scd_data[unit].flags &= ~SCDVALID; - break; - } - DELAY(100); - } -#if SCD_DEBUG - if (scd_debuglevel > 0 && count > 0) - printf("\n"); -#endif -} - -/* Returns 0 OR sony error code */ -static int -spin_up(unsigned unit) -{ - unsigned char res_reg[12]; - unsigned int res_size; - int rc; - int loop_count = 0; - -again: - rc = send_cmd(unit, CMD_SPIN_UP, NULL, 0, res_reg, &res_size); - if (rc != 0) { - XDEBUG(2, ("scd%d: CMD_SPIN_UP error 0x%x\n", unit, rc)); - return rc; - } - - if (!(scd_data[unit].flags & SCDTOC)) { - rc = send_cmd(unit, CMD_READ_TOC, 0); - if (rc == ERR_NOT_SPINNING) { - if (loop_count++ < 3) - goto again; - return rc; - } - if (rc != 0) - return rc; - } - - scd_data[unit].flags |= SCDSPINNING; - - return 0; -} - -static struct sony_tracklist * -get_tl(struct sony_toc *toc, int size) -{ - struct sony_tracklist *tl = &toc->tracks[0]; - - if (tl->track != 0xb0) - return tl; - (char *)tl += 9; - if (tl->track != 0xb1) - return tl; - (char *)tl += 9; - if (tl->track != 0xb2) - return tl; - (char *)tl += 9; - if (tl->track != 0xb3) - return tl; - (char *)tl += 9; - if (tl->track != 0xb4) - return tl; - (char *)tl += 9; - if (tl->track != 0xc0) - return tl; - (char *)tl += 9; - return tl; -} - -static int -read_toc(dev_t dev) -{ - unsigned unit; - struct scd_data *cd; - unsigned part = 0; /* For now ... */ - struct sony_toc toc; - struct sony_tracklist *tl; - int rc, i, j; - u_long first, last; - - unit = scd_unit(dev); - cd = scd_data + unit; - - rc = send_cmd(unit, CMD_GET_TOC, 1, part+1); - if (rc < 0) - return rc; - if (rc > sizeof(toc)) { - printf("scd%d: program error: toc too large (%d)\n", unit, rc); - return EIO; - } - if (get_result(unit, rc, (u_char *)&toc) != 0) - return EIO; - - XDEBUG(1, ("scd%d: toc read. len = %d, sizeof(toc) = %d\n", unit, rc, sizeof(toc))); - - tl = get_tl(&toc, rc); - first = msf2hsg(tl->start_msf); - last = msf2hsg(toc.lead_out_start_msf); - cd->blksize = SCDBLKSIZE; - cd->disksize = last*cd->blksize/DEV_BSIZE; - - XDEBUG(1, ("scd%d: firstsector = %d, lastsector = %d", unit, - first, last)); - - cd->first_track = bcd2bin(toc.first_track); - cd->last_track = bcd2bin(toc.last_track); - if (cd->last_track > (MAX_TRACKS-2)) - cd->last_track = MAX_TRACKS-2; - for (j = 0, i = cd->first_track; i <= cd->last_track; i++, j++) { - cd->toc[i].adr = tl[j].adr; - cd->toc[i].ctl = tl[j].ctl; /* for xcdplayer */ - bcopy(tl[j].start_msf, cd->toc[i].start_msf, 3); -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) { - if ((j % 3) == 0) - printf("\nscd%d: tracks ", unit); - printf("[%03d: %2d %2d %2d] ", i, - bcd2bin(cd->toc[i].start_msf[0]), - bcd2bin(cd->toc[i].start_msf[1]), - bcd2bin(cd->toc[i].start_msf[2])); - } -#endif - } - bcopy(toc.lead_out_start_msf, cd->toc[cd->last_track+1].start_msf, 3); -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) { - i = cd->last_track+1; - printf("[END: %2d %2d %2d]\n", - bcd2bin(cd->toc[i].start_msf[0]), - bcd2bin(cd->toc[i].start_msf[1]), - bcd2bin(cd->toc[i].start_msf[2])); - } -#endif - - bzero(&cd->dlabel,sizeof(struct disklabel)); - /* filled with spaces first */ - strncpy(cd->dlabel.d_typename," ", - sizeof(cd->dlabel.d_typename)); - strncpy(cd->dlabel.d_typename, cd->name, - min(strlen(cd->name), sizeof(cd->dlabel.d_typename) - 1)); - strncpy(cd->dlabel.d_packname,"unknown ", - sizeof(cd->dlabel.d_packname)); - cd->dlabel.d_secsize = cd->blksize; - cd->dlabel.d_nsectors = 100; - cd->dlabel.d_ntracks = 1; - cd->dlabel.d_ncylinders = (cd->disksize/100)+1; - cd->dlabel.d_secpercyl = 100; - cd->dlabel.d_secperunit = cd->disksize; - cd->dlabel.d_rpm = 300; - cd->dlabel.d_interleave = 1; - cd->dlabel.d_flags = D_REMOVABLE; - cd->dlabel.d_npartitions= 1; - cd->dlabel.d_partitions[0].p_offset = 0; - cd->dlabel.d_partitions[0].p_size = cd->disksize; - cd->dlabel.d_partitions[0].p_fstype = 9; - cd->dlabel.d_magic = DISKMAGIC; - cd->dlabel.d_magic2 = DISKMAGIC; - cd->dlabel.d_checksum = dkcksum(&cd->dlabel); - - cd->flags |= SCDTOC; - - return 0; -} - -static inline void -write_control(unsigned port, unsigned data) -{ - outb(port + OREG_CONTROL, data); -} - -static void -init_drive(unsigned unit) -{ - int rc; - - rc = send_cmd(unit, CMD_SET_DRIVE_PARAM, 2, - 0x05, 0x03 | ((scd_data[unit].double_speed) ? 0x04: 0)); - if (rc != 0) - printf("scd%d: Unable to set parameters. Errcode = 0x%x\n", unit, rc); -} - -/* Returns 0 or errno */ -static int -get_result(u_int unit, int result_len, u_char *result) -{ - unsigned int port = scd_data[unit].iobase; - unsigned int res_reg = port + IREG_RESULT; - unsigned char c; - int loop_index = 2; /* send_cmd() reads two bytes ... */ - - XDEBUG(1, ("scd%d: DEBUG: get_result: bytes=%d\n", unit, result_len)); - - while (result_len-- > 0) { - if (loop_index++ >= 10) { - loop_index = 1; - if (waitfor_status_bits(unit, SBIT_RESULT_READY, 0)) - return EIO; - write_control(port, CBIT_RESULT_READY_CLEAR); - } - if (result) - *result++ = inb(res_reg); - else - (void)inb(res_reg); - } - return 0; -} - -/* Returns -0x100 for timeout, -(drive error code) OR number of result bytes */ -static int -send_cmd(u_int unit, u_char cmd, u_int nargs, ...) -{ - va_list ap; - u_int port = scd_data[unit].iobase; - u_int reg; - u_char c; - int rc; - int i; - - if (waitfor_status_bits(unit, 0, SBIT_BUSY)) { - printf("scd%d: drive busy\n", unit); - return -0x100; - } - - XDEBUG(1,("scd%d: DEBUG: send_cmd: cmd=0x%x nargs=%d", unit, cmd, nargs)); - - write_control(port, CBIT_RESULT_READY_CLEAR); - write_control(port, CBIT_RPARAM_CLEAR); - - for (i = 0; i < 100; i++) - if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) - break; - if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { - XDEBUG(1, ("\nscd%d: wparam timeout\n", unit)); - return -EIO; - } - - va_start(ap, nargs); - reg = port + OREG_WPARAMS; - for (i = 0; i < nargs; i++) { - c = (u_char)va_arg(ap, int); - outb(reg, c); - XDEBUG(1, (",{0x%x}", c)); - } - va_end(ap); - XDEBUG(1, ("\n")); - - outb(port+OREG_COMMAND, cmd); - - if (rc = waitfor_status_bits(unit, SBIT_RESULT_READY, SBIT_BUSY)) - return -0x100; - - reg = port + IREG_RESULT; - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((rc = inb(reg)) & 0xf0) { - case 0x20: - rc = inb(reg); - /* FALL TROUGH */ - case 0x50: - XDEBUG(1, ("scd%d: DEBUG: send_cmd: drive_error=0x%x\n", unit, rc)); - return -rc; - case 0x00: - default: - rc = inb(reg); - XDEBUG(1, ("scd%d: DEBUG: send_cmd: result_len=%d\n", unit, rc)); - return rc; - } -} - -static void -print_error(int unit, int errcode) -{ - switch (errcode) { - case -ERR_CD_NOT_LOADED: - printf("scd%d: door is open\n", unit); - break; - case -ERR_NO_CD_INSIDE: - printf("scd%d: no cd inside\n", unit); - break; - default: - if (errcode == -0x100 || errcode > 0) - printf("scd%d: device timeout\n", unit); - else - printf("scd%d: unexpected error 0x%x\n", unit, -errcode); - break; - } -} - -/* Returns 0 or errno value */ -static int -waitfor_status_bits(int unit, int bits_set, int bits_clear) -{ - u_int port = scd_data[unit].iobase; - u_int flags = scd_data[unit].flags; - u_int reg = port + IREG_STATUS; - u_int max_loop; - u_char c = 0; - - if (flags & SCDPROBING) { - max_loop = 0; - while (max_loop++ < 1000) { - c = inb(reg); - if (c == 0xff) - return EIO; - if (c & SBIT_ATTENTION) { - process_attention(unit); - continue; - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - break; - } - DELAY(10000); - } - } else { - max_loop = 100; - while (max_loop-- > 0) { - c = inb(reg); - if (c & SBIT_ATTENTION) { - process_attention(unit); - continue; - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - break; - } - tsleep(waitfor_status_bits, PZERO - 1, "waitfor", hz/10); - } - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - return 0; - } -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) - printf("scd%d: DEBUG: waitfor: TIMEOUT (0x%x,(0x%x,0x%x))\n", unit, c, bits_set, bits_clear); - else -#endif - printf("scd%d: timeout.\n", unit); - return EIO; -} - -/* these two routines for xcdplayer - "borrowed" from mcd.c */ -static int -scd_toc_header (int unit, struct ioc_toc_header* th) -{ - struct scd_data *cd = scd_data + unit; - int rc; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - - th->starting_track = cd->first_track; - th->ending_track = cd->last_track; - th->len = 0; /* not used */ - - return 0; -} - -static int -scd_toc_entrys (int unit, struct ioc_read_toc_entry *te) -{ - struct scd_data *cd = scd_data + unit; - struct cd_toc_entry toc_entry; - int rc, i, len = te->data_len; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - - /* find the toc to copy*/ - i = te->starting_track; - if (i == SCD_LASTPLUS1) - i = cd->last_track + 1; - - /* verify starting track */ - if (i < cd->first_track || i > cd->last_track+1) - return EINVAL; - - /* valid length ? */ - if (len < sizeof(struct cd_toc_entry) - || (len % sizeof(struct cd_toc_entry)) != 0) - return EINVAL; - - /* copy the toc data */ - toc_entry.control = cd->toc[i].ctl; - toc_entry.addr_type = te->address_format; - toc_entry.track = i; - if (te->address_format == CD_MSF_FORMAT) { - toc_entry.addr.msf.unused = 0; - toc_entry.addr.msf.minute = bcd2bin(cd->toc[i].start_msf[0]); - toc_entry.addr.msf.second = bcd2bin(cd->toc[i].start_msf[1]); - toc_entry.addr.msf.frame = bcd2bin(cd->toc[i].start_msf[2]); - } - - /* copy the data back */ - if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0) - return EFAULT; - - return 0; -} - - -#endif /* NSCD > 0 */ diff --git a/sys/gnu/i386/isa/scdreg.h b/sys/gnu/i386/isa/scdreg.h deleted file mode 100644 index 93ace5c..0000000 --- a/sys/gnu/i386/isa/scdreg.h +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 1995 Mikael Hybsch - * - * The Linux driver cdu31a has been used as a reference when writing this - * code, therefore bringing it under the GNU Public License. The following - * conditions of redistribution therefore apply: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: scdreg.h,v 1.2 1995/01/29 22:51:41 jkh Exp $ - * - */ - -#ifndef SCD_H -#define SCD_H - -#ifdef __GNUC__ -#if __GNUC__ >= 2 -#pragma pack(1) -#endif -#endif - -typedef unsigned char bcd_t; -#define M_msf(msf) msf[0] -#define S_msf(msf) msf[1] -#define F_msf(msf) msf[2] - -#define IS_ATTENTION(port) ((inb(port+IREG_STATUS) & SBIT_ATTENTION) != 0) -#define IS_BUSY(port) ((inb(port+IREG_STATUS) & SBIT_BUSY) != 0) -#define IS_DATA_RDY(port) ((inb(port+IREG_STATUS) & SBIT_DATA_READY) != 0) -#define STATUS_BIT(port, bit) ((inb(port+IREG_STATUS) & (bit)) != 0) -#define FSTATUS_BIT(port, bit) ((inb(port+IREG_FSTATUS) & (bit)) != 0) - -#define OREG_COMMAND 0 -#define OREG_WPARAMS 1 -#define OREG_CONTROL 3 -#define CBIT_ATTENTION_CLEAR 0x01 -#define CBIT_RESULT_READY_CLEAR 0x02 -#define CBIT_DATA_READY_CLEAR 0x04 -#define CBIT_RPARAM_CLEAR 0x40 -#define CBIT_RESET_DRIVE 0x80 - -#define IREG_STATUS 0 -#define SBIT_ATTENTION 0x01 -#define SBIT_RESULT_READY 0x02 -#define SBIT_DATA_READY 0x04 -#define SBIT_BUSY 0x80 - -#define IREG_RESULT 1 -#define IREG_DATA 2 -#define IREG_FSTATUS 3 -#define FBIT_WPARAM_READY 0x01 - -#define CMD_GET_DRIVE_CONFIG 0x00 -#define CMD_SET_DRIVE_PARAM 0x10 -#define CMD_GET_SUBCHANNEL_DATA 0x21 -#define CMD_GET_TOC 0x24 -#define CMD_READ_TOC 0x30 -#define CMD_READ 0x34 -#define CMD_PLAY_AUDIO 0x40 -#define CMD_STOP_AUDIO 0x41 -#define CMD_EJECT 0x50 -#define CMD_SPIN_UP 0x51 -#define CMD_SPIN_DOWN 0x52 - -#define ERR_CD_NOT_LOADED 0x20 -#define ERR_NO_CD_INSIDE 0x21 -#define ERR_NOT_SPINNING 0x22 -#define ERR_FATAL_READ_ERROR1 0x53 -#define ERR_FATAL_READ_ERROR2 0x57 - -#define ATTEN_DRIVE_LOADED 0x80 -#define ATTEN_EJECT_PUSHED 0x81 -#define ATTEN_AUDIO_DONE 0x90 -#define ATTEN_SPIN_UP_DONE 0x24 -#define ATTEN_SPIN_DOWN 0x27 -#define ATTEN_EJECT_DONE 0x28 - - -struct sony_drive_configuration { - char vendor[8]; - char product[16]; - char revision[8]; - u_short config; -}; - -/* Almost same as cd_sub_channel_position_data */ -struct sony_subchannel_position_data { - u_char control:4; - u_char addr_type:4; - u_char track_number; - u_char index_number; - u_char rel_msf[3]; - u_char dummy; - u_char abs_msf[3]; -}; - -struct sony_tracklist { - u_char adr :4; /* xcdplayer needs these two values */ - u_char ctl :4; - u_char track; - u_char start_msf[3]; -}; - -#define MAX_TRACKS 100 - -struct sony_toc { - u_char session_number; - - u_char :8; - u_char :8; - u_char first_track; - u_char :8; - u_char :8; - - u_char :8; - u_char :8; - u_char last_track; - u_char :8; - u_char :8; - - u_char :8; - u_char :8; - u_char lead_out_start_msf[3]; - - struct sony_tracklist tracks[MAX_TRACKS]; - - /* The rest is just to take space in case all data is returned */ - - u_char dummy[6*9]; -}; - -#endif /* SCD_H */ diff --git a/sys/gnu/i386/scd.c b/sys/gnu/i386/scd.c deleted file mode 100644 index 2ea212e..0000000 --- a/sys/gnu/i386/scd.c +++ /dev/null @@ -1,1530 +0,0 @@ -/*- - * Copyright (c) 1995 Mikael Hybsch - * - * Portions of this file are copied from mcd.c - * which has the following copyrights: - * - * Copyright 1993 by Holger Veit (data part) - * Copyright 1993 by Brian Moore (audio part) - * Changes Copyright 1993 by Gary Clark II - * Changes Copyright (C) 1994 by Andrew A. Chernov - * - * Rewrote probe routine to work on newer Mitsumi drives. - * Additional changes (C) 1994 by Jordan K. Hubbard - * - * The Linux driver cdu31a has been used as a reference when writing this - * code, there fore bringing it under the GNU Public License. The following - * conditions of redistribution therefore apply: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -/* $Id: scd.c,v 1.6 1995/02/06 22:35:06 jkh Exp $ */ - -/* Please send any comments to micke@dynas.se */ - -#define SCD_DEBUG 0 - -#include "scd.h" -#if NSCD > 0 -#include <sys/types.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/file.h> -#include <sys/buf.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <sys/ioctl.h> -#include <sys/cdio.h> -#include <sys/errno.h> -#include <sys/dkbad.h> -#include <sys/disklabel.h> -#include <sys/devconf.h> -#include <machine/stdarg.h> - -#include <i386/isa/isa.h> -#include <i386/isa/isa_device.h> -#include <gnu/i386/scdreg.h> - -#define scd_part(dev) ((minor(dev)) & 7) -#define scd_unit(dev) (((minor(dev)) & 0x38) >> 3) -#define scd_phys(dev) (((minor(dev)) & 0x40) >> 6) -#define RAW_PART 2 - -/* flags */ -#define SCDOPEN 0x0001 /* device opened */ -#define SCDVALID 0x0002 /* parameters loaded */ -#define SCDINIT 0x0004 /* device is init'd */ -#define SCDPROBING 0x0020 /* probing */ -#define SCDTOC 0x0100 /* already read toc */ -#define SCDMBXBSY 0x0200 /* local mbx is busy */ -#define SCDSPINNING 0x0400 /* drive is spun up */ - -#define SCD_S_BEGIN 0 -#define SCD_S_BEGIN1 1 -#define SCD_S_WAITSTAT 2 -#define SCD_S_WAITFIFO 3 -#define SCD_S_WAITSPIN 4 -#define SCD_S_WAITREAD 5 -#define SCD_S_WAITPARAM 6 - -#define RDELAY_WAIT 300 -#define RDELAY_WAITREAD 300 - -#define SCDBLKSIZE 2048 - -#ifdef SCD_DEBUG - int scd_debuglevel = SCD_DEBUG; -# define XDEBUG(level, data) {if (scd_debuglevel >= level) printf data;} -#else -# define XDEBUG(level, data) -#endif - -struct scd_mbx { - short unit; - short port; - short retry; - short nblk; - int sz; - u_long skip; - struct buf *bp; - int p_offset; - short count; -}; - -struct scd_data { - int iobase; - char double_speed; - char *name; - short flags; - int blksize; - u_long disksize; - struct disklabel dlabel; - int openflag; - struct { - unsigned char adr :4; - unsigned char ctl :4; /* xcdplayer needs this */ - unsigned char start_msf[3]; - } toc[MAX_TRACKS]; - short first_track; - short last_track; - struct ioc_play_msf last_play; - - short audio_status; - struct buf head; /* head of buf queue */ - struct scd_mbx mbx; -} scd_data[NSCD]; - -/* prototypes */ -int scdopen(dev_t dev); -int scdclose(dev_t dev); -void scdstrategy(struct buf *bp); -int scdioctl(dev_t dev, int cmd, caddr_t addr, int flags); -int scdsize(dev_t dev); - -static int bcd2bin(bcd_t b); -static bcd_t bin2bcd(int b); -static void hsg2msf(int hsg, bcd_t *msf); -static int msf2hsg(bcd_t *msf); - -static void process_attention(unsigned unit); -static inline void write_control(unsigned port, unsigned data); -static int waitfor_status_bits(int unit, int bits_set, int bits_clear); -static int waitfor_attention(int unit); -static int send_cmd(u_int unit, u_char cmd, u_int nargs, ...); -static void init_drive(unsigned unit); -static int spin_up(unsigned unit); -static int read_toc(dev_t dev); -static int get_result(u_int unit, int result_len, u_char *result); -static void print_error(int unit, int errcode); - -static void scd_start(int unit); -static void scd_doread(int state, struct scd_mbx *mbxin); - -static int scd_eject(int unit); -static int scd_stop(int unit); -static int scd_pause(int unit); -static int scd_resume(int unit); -static int scd_playtracks(int unit, struct ioc_play_track *pt); -static int scd_playmsf(int unit, struct ioc_play_msf *msf); -static int scd_play(int unit, struct ioc_play_msf *msf); -static int scd_subchan(int unit, struct ioc_read_subchannel *sc); -static int read_subcode(int unit, struct sony_subchannel_position_data *sc); - -/* for xcdplayer */ -static int scd_toc_header(int unit, struct ioc_toc_header *th); -static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te); -#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */ - -extern int hz; - -int scd_probe(struct isa_device *dev); -int scd_attach(struct isa_device *dev); -struct isa_driver scddriver = { scd_probe, scd_attach, "scd" }; - -static struct kern_devconf kdc_scd[NSCD] = { { - 0, 0, 0, /* filled in by dev_attach */ - "scd", 0, { MDDT_ISA, 0, "bio" }, - isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, - &kdc_isa0, /* parent */ - 0, /* parentdata */ - DC_IDLE, /* status */ - "Sony CD-ROM drive" /* properly filled later */ -} }; - -static inline void -scd_registerdev(struct isa_device *id) -{ - if(id->id_unit) - kdc_scd[id->id_unit] = kdc_scd[0]; - kdc_scd[id->id_unit].kdc_unit = id->id_unit; - kdc_scd[id->id_unit].kdc_isa = id; - dev_attach(&kdc_scd[id->id_unit]); -} - -int scd_attach(struct isa_device *dev) -{ - struct scd_data *cd = scd_data + dev->id_unit; - int i; - - cd->iobase = dev->id_iobase; /* Already set by probe, but ... */ - - scd_registerdev(dev); - /* name filled in probe */ - kdc_scd[dev->id_unit].kdc_description = scd_data[dev->id_unit].name; - printf("scd%d: <%s>\n", dev->id_unit, scd_data[dev->id_unit].name); - - init_drive(dev->id_unit); - - cd->flags = SCDINIT; - cd->audio_status = CD_AS_AUDIO_INVALID; - - return 1; -} - -int -scdopen(dev_t dev) -{ - int unit,part,phys; - int rc; - struct scd_data *cd; - - unit = scd_unit(dev); - if (unit >= NSCD) - return ENXIO; - - cd = scd_data + unit; - part = scd_part(dev); - phys = scd_phys(dev); - - /* not initialized*/ - if (!(cd->flags & SCDINIT)) - return ENXIO; - - /* invalidated in the meantime? mark all open part's invalid */ - if (cd->openflag) - return ENXIO; - - XDEBUG(1,("scd%d: DEBUG: status = 0x%x\n", unit, inb(cd->iobase+IREG_STATUS))); - - if ((rc = spin_up(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - if (!(cd->flags & SCDTOC)) { - int loop_count = 3; - - while (loop_count-- > 0 && (rc = read_toc(dev)) != 0) { - if (rc == ERR_NOT_SPINNING) { - rc = spin_up(unit); - if (rc) { - print_error(unit, rc);\ - return EIO; - } - continue; - } - printf("scd%d: TOC read error 0x%x\n", unit, rc); - return EIO; - } - } - - cd->openflag = 1; - cd->flags |= SCDVALID; - kdc_scd[unit].kdc_state = DC_BUSY; - - return 0; -} - -int -scdclose(dev_t dev) -{ - int unit,part,phys; - struct scd_data *cd; - int rlen; - char rdata[10]; - - unit = scd_unit(dev); - if (unit >= NSCD) - return ENXIO; - - cd = scd_data + unit; - part = scd_part(dev); - phys = scd_phys(dev); - - if (!(cd->flags & SCDINIT) || !cd->openflag) - return ENXIO; - - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { - (void)send_cmd(unit, CMD_SPIN_DOWN, 0); - cd->flags &= ~SCDSPINNING; - } - - kdc_scd[unit].kdc_state = DC_IDLE; - - /* close channel */ - cd->openflag = 0; - - return 0; -} - -void -scdstrategy(struct buf *bp) -{ - struct scd_data *cd; - struct buf *qp; - int s; - int unit = scd_unit(bp->b_dev); - - cd = scd_data + unit; - - XDEBUG(2, ("scd%d: DEBUG: strategy: block=%ld, bcount=%ld\n", unit, bp->b_blkno, bp->b_bcount)); - - if (unit >= NSCD || bp->b_blkno < 0 || (bp->b_bcount % SCDBLKSIZE)) { - printf("scd%d: strategy failure: blkno = %d, bcount = %d\n", - unit, bp->b_blkno, bp->b_bcount); - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto bad; - } - - /* if device invalidated (e.g. media change, door open), error */ - if (!(cd->flags & SCDVALID)) { - printf("scd%d: media changed\n", unit); - bp->b_error = EIO; - goto bad; - } - - /* read only */ - if (!(bp->b_flags & B_READ)) { - bp->b_error = EROFS; - goto bad; - } - - /* no data to read */ - if (bp->b_bcount == 0) - goto done; - - if (!(cd->flags & SCDTOC)) { - bp->b_error = EIO; - goto bad; - } - /* adjust transfer if necessary */ - if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) - goto done; - - bp->b_pblkno = bp->b_blkno; - bp->b_resid = 0; - - /* queue it */ - qp = &cd->head; - s = splbio(); - disksort(qp,bp); - splx(s); - - /* now check whether we can perform processing */ - scd_start(unit); - return; - -bad: - bp->b_flags |= B_ERROR; -done: - bp->b_resid = bp->b_bcount; - biodone(bp); - return; -} - -static void -scd_start(int unit) -{ - struct scd_data *cd = scd_data + unit; - struct buf *bp, *qp = &cd->head; - struct partition *p; - int part; - register s = splbio(); - - if (cd->flags & SCDMBXBSY) { - splx(s); - return; - } - - if ((bp = qp->b_actf) != 0) { - /* block found to process, dequeue */ - qp->b_actf = bp->b_actf; - cd->flags |= SCDMBXBSY; - splx(s); - } else { - /* nothing to do */ - splx(s); - return; - } - - p = cd->dlabel.d_partitions + scd_part(bp->b_dev); - - cd->mbx.unit = unit; - cd->mbx.port = cd->iobase; - cd->mbx.retry = 3; - cd->mbx.bp = bp; - cd->mbx.p_offset = p->p_offset; - splx(s); - - scd_doread(SCD_S_BEGIN,&(cd->mbx)); - return; -} - -int -scdioctl(dev_t dev, int cmd, caddr_t addr, int flags) -{ - struct scd_data *cd; - int unit,part; - - unit = scd_unit(dev); - part = scd_part(dev); - cd = scd_data + unit; - - XDEBUG(1, ("scd%d: ioctl: cmd=0x%lx\n", unit, cmd)); - - if (!(cd->flags & SCDVALID)) - return EIO; - - switch (cmd) { - case DIOCSBAD: - return EINVAL; - case DIOCGDINFO: - *(struct disklabel *)addr = cd->dlabel; - return 0; - case DIOCGPART: - ((struct partinfo *)addr)->disklab = &cd->dlabel; - ((struct partinfo *)addr)->part = - &cd->dlabel.d_partitions[0]; - return 0; - case CDIOCPLAYTRACKS: - return scd_playtracks(unit, (struct ioc_play_track *) addr); - case CDIOCPLAYBLOCKS: - return EINVAL; - case CDIOCPLAYMSF: - return scd_playmsf(unit, (struct ioc_play_msf *) addr); - case CDIOCREADSUBCHANNEL: - return scd_subchan(unit, (struct ioc_read_subchannel *) addr); - case CDIOREADTOCHEADER: - return scd_toc_header (unit, (struct ioc_toc_header *) addr); - case CDIOREADTOCENTRYS: - return scd_toc_entrys (unit, (struct ioc_read_toc_entry*) addr); - case CDIOCSETPATCH: - case CDIOCGETVOL: - case CDIOCSETVOL: - case CDIOCSETMONO: - case CDIOCSETSTERIO: - case CDIOCSETMUTE: - case CDIOCSETLEFT: - case CDIOCSETRIGHT: - return EINVAL; - case CDIOCRESUME: - return scd_resume(unit); - case CDIOCPAUSE: - return scd_pause(unit); - case CDIOCSTART: - return EINVAL; - case CDIOCSTOP: - return scd_stop(unit); - case CDIOCEJECT: - return scd_eject(unit); - case CDIOCALLOW: - return 0; - case CDIOCSETDEBUG: -#ifdef SCD_DEBUG - scd_debuglevel++; -#endif - return 0; - case CDIOCCLRDEBUG: -#ifdef SCD_DEBUG - scd_debuglevel = 0; - -#endif - return 0; - default: - printf("scd%d: unsupported ioctl (cmd=0x%lx)\n", unit, cmd); - return ENOTTY; - } -} - -int -scdsize(dev_t dev) -{ - return -1; -} - -void -scdintr() -{ - return; -} - -/*************************************************************** - * lower level of driver starts here - **************************************************************/ - -static int -scd_playtracks(int unit, struct ioc_play_track *pt) -{ - struct scd_data *cd = scd_data + unit; - struct ioc_play_msf msf; - int a = pt->start_track; - int z = pt->end_track; - int rc, i; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - if (rc == -ERR_NOT_SPINNING) { - if (spin_up(unit) != 0) - return EIO; - rc = read_toc(unit); - } - if (rc != 0) { - print_error(unit, rc); - return EIO; - } - } - - XDEBUG(1, ("scd%d: playtracks from %d:%d to %d:%d\n", unit, - a, pt->start_index, z, pt->end_index)); - - if ( a < cd->first_track - || a > cd->last_track - || a > z - || z > cd->last_track) - return EINVAL; - - bcopy(cd->toc[a].start_msf, &msf.start_m, 3); - hsg2msf(msf2hsg(cd->toc[z+1].start_msf)-1, &msf.end_m); - - return scd_play(unit, &msf); -} - -/* The start/end msf is expected to be in bin format */ -static int -scd_playmsf(int unit, struct ioc_play_msf *msfin) -{ - struct ioc_play_msf msf; - - msf.start_m = bin2bcd(msfin->start_m); - msf.start_s = bin2bcd(msfin->start_s); - msf.start_f = bin2bcd(msfin->start_f); - msf.end_m = bin2bcd(msfin->end_m); - msf.end_s = bin2bcd(msfin->end_s); - msf.end_f = bin2bcd(msfin->end_f); - - return scd_play(unit, &msf); -} - -/* The start/end msf is expected to be in bcd format */ -static int -scd_play(int unit, struct ioc_play_msf *msf) -{ - struct scd_data *cd = scd_data + unit; - int i, rc; - - XDEBUG(1, ("scd%d: playing: %02x:%02x:%02x -> %02x:%02x:%02x\n", unit, - msf->start_m, msf->start_s, msf->start_f, - msf->end_m, msf->end_s, msf->end_f)); - - for (i = 0; i < 2; i++) { - rc = send_cmd(unit, CMD_PLAY_AUDIO, 7, - 0x03, - msf->start_m, msf->start_s, msf->start_f, - msf->end_m, msf->end_s, msf->end_f); - if (rc == -ERR_NOT_SPINNING) { - cd->flags &= ~SCDSPINNING; - if (spin_up(unit) != 0) - return EIO; - } else if (rc < 0) { - print_error(unit, rc); - return EIO; - } else { - break; - } - } - cd->audio_status = CD_AS_PLAY_IN_PROGRESS; - bcopy((char *)msf, (char *)&cd->last_play, sizeof(struct ioc_play_msf)); - return 0; -} - -static int -scd_stop(int unit) -{ - struct scd_data *cd = scd_data + unit; - - (void)send_cmd(unit, CMD_STOP_AUDIO, 0); - cd->audio_status = CD_AS_PLAY_COMPLETED; - return 0; -} - -static int -scd_pause(int unit) -{ - struct scd_data *cd = scd_data + unit; - struct sony_subchannel_position_data subpos; - - if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) - return EINVAL; - - if (read_subcode(unit, &subpos) != 0) - return EIO; - - if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0) - return EIO; - - cd->last_play.start_m = subpos.abs_msf[0]; - cd->last_play.start_s = subpos.abs_msf[1]; - cd->last_play.start_f = subpos.abs_msf[2]; - cd->audio_status = CD_AS_PLAY_PAUSED; - - XDEBUG(1, ("scd%d: pause @ %02x:%02x:%02x\n", unit, - cd->last_play.start_m, - cd->last_play.start_s, - cd->last_play.start_f)); - - return 0; -} - -static int -scd_resume(int unit) -{ - if (scd_data[unit].audio_status != CD_AS_PLAY_PAUSED) - return EINVAL; - return scd_play(unit, &scd_data[unit].last_play); -} - -static int -scd_eject(int unit) -{ - struct scd_data *cd = scd_data + unit; - int port = cd->iobase; - - cd->audio_status = CD_AS_AUDIO_INVALID; - cd->flags &= ~(SCDSPINNING|SCDTOC); - - if (send_cmd(unit, CMD_STOP_AUDIO, 0) != 0 || - send_cmd(unit, CMD_SPIN_DOWN, 0) != 0 || - send_cmd(unit, CMD_EJECT, 0) != 0) - { - return EIO; - } - return 0; -} - -static int -scd_subchan(int unit, struct ioc_read_subchannel *sc) -{ - struct scd_data *cd = scd_data + unit; - struct sony_subchannel_position_data q; - struct cd_sub_channel_info data; - - XDEBUG(1, ("scd%d: subchan af=%d, df=%d\n", unit, - sc->address_format, - sc->data_format)); - - if (sc->address_format != CD_MSF_FORMAT) - return EINVAL; - - if (sc->data_format != CD_CURRENT_POSITION) - return EINVAL; - - if (read_subcode(unit, &q) != 0) - return EIO; - - data.header.audio_status = cd->audio_status; - data.what.position.data_format = CD_MSF_FORMAT; - data.what.position.track_number = bcd2bin(q.track_number); - data.what.position.reladdr.msf.unused = 0; - data.what.position.reladdr.msf.minute = bcd2bin(q.rel_msf[0]); - data.what.position.reladdr.msf.second = bcd2bin(q.rel_msf[1]); - data.what.position.reladdr.msf.frame = bcd2bin(q.rel_msf[2]); - data.what.position.absaddr.msf.unused = 0; - data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]); - data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]); - data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]); - - if (copyout(&data, sc->data, min(sizeof(struct cd_sub_channel_info), sc->data_len))!=0) - return EFAULT; - return 0; -} - -int -scd_probe(struct isa_device *dev) -{ - struct sony_drive_configuration drive_config; - int unit = dev->id_unit; - int rc; - static char namebuf[8+16+8+3]; - char *s = namebuf; - int loop_count = 0; - - scd_data[unit].flags = SCDPROBING; - scd_data[unit].iobase = dev->id_iobase; - - bzero(&drive_config, sizeof(drive_config)); - -again: - /* Reset drive */ - write_control(dev->id_iobase, CBIT_RESET_DRIVE); - - /* Calm down */ - DELAY(300000); - - /* Only the ATTENTION bit may be set */ - if ((inb(dev->id_iobase+IREG_STATUS) & ~1) != 0) { - XDEBUG(1, ("scd: too many bits set. probe failed.\n")); - return 0; - } - rc = send_cmd(unit, CMD_GET_DRIVE_CONFIG, 0); - if (rc != sizeof(drive_config)) { - /* Sometimes if the drive is playing audio I get */ - /* the bad result 82. Fix by repeating the reset */ - if (rc > 0 && loop_count++ == 0) - goto again; - return 0; - } - if (get_result(unit, rc, (u_char *)&drive_config) != 0) - return 0; - - bcopy(drive_config.vendor, namebuf, 8); - s = namebuf+8; - while (*(s-1) == ' ') /* Strip trailing spaces */ - s--; - *s++ = ' '; - bcopy(drive_config.product, s, 16); - s += 16; - while (*(s-1) == ' ') - s--; - *s++ = ' '; - bcopy(drive_config.revision, s, 8); - s += 8; - while (*(s-1) == ' ') - s--; - *s = 0; - - scd_data[unit].name = namebuf; - - if (drive_config.config & 0x10) - scd_data[unit].double_speed = 1; - else - scd_data[unit].double_speed = 0; - - return 4; -} - -static int -read_subcode(int unit, struct sony_subchannel_position_data *sc) -{ - int rc; - - rc = send_cmd(unit, CMD_GET_SUBCHANNEL_DATA, 0); - if (rc < 0 || rc < sizeof(*sc)) - return EIO; - if (get_result(unit, rc, (u_char *)sc) != 0) - return EIO; - return 0; -} - -/* State machine copied from mcd.c */ - -/* This (and the code in mcd.c) will not work with more than one drive */ -/* because there is only one mbxsave below. Should fix that some day. */ -/* (mbxsave & state should probably be included in the scd_data struct and */ -/* the unit number used as first argument to scd_doread().) /Micke */ - -/* state machine to process read requests - * initialize with SCD_S_BEGIN: reset state machine - * SCD_S_WAITSTAT: wait for ready (!busy) - * SCD_S_WAITSPIN: wait for drive to spin up (if not spinning) - * SCD_S_WAITFIFO: wait for param fifo to get ready, them exec. command. - * SCD_S_WAITREAD: wait for data ready, read data - * SCD_S_WAITPARAM: wait for command result params, read them, error if bad data read. - */ - -static struct scd_mbx *mbxsave; - -static void -scd_doread(int state, struct scd_mbx *mbxin) -{ - struct scd_mbx *mbx = (state!=SCD_S_BEGIN) ? mbxsave : mbxin; - int unit = mbx->unit; - int port = mbx->port; - struct buf *bp = mbx->bp; - struct scd_data *cd = scd_data + unit; - int reg,i,k,c; - int blknum; - caddr_t addr; - char rdata[10]; - static char sdata[3]; /* Must be preserved between calls to this function */ - -loop: - switch (state) { - case SCD_S_BEGIN: - mbx = mbxsave = mbxin; - - case SCD_S_BEGIN1: - /* get status */ - mbx->count = RDELAY_WAIT; - - process_attention(unit); - goto trystat; - - case SCD_S_WAITSTAT: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITSTAT); - if (mbx->count-- <= 0) { - printf("scd%d: timeout. drive busy.\n",unit); - goto harderr; - } - -trystat: - if (IS_BUSY(port)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSTAT,hz/100); /* XXX */ - return; - } - - process_attention(unit); - - /* reject, if audio active */ - if (cd->audio_status & CD_AS_PLAY_IN_PROGRESS) { - printf("scd%d: audio is active\n",unit); - goto harderr; - } - - mbx->sz = cd->blksize; - -firstblock: - /* for first block */ - mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; - mbx->skip = 0; - -nextblock: - if (!(cd->flags & SCDVALID)) - goto changed; - - blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) - + mbx->p_offset + mbx->skip/mbx->sz; - - XDEBUG(2, ("scd%d: scd_doread: read blknum=%d\n", unit, blknum)); - - /* build parameter block */ - hsg2msf(blknum, sdata); - - write_control(port, CBIT_RESULT_READY_CLEAR); - write_control(port, CBIT_RPARAM_CLEAR); - write_control(port, CBIT_DATA_READY_CLEAR); - - if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) - goto writeparam; - - mbx->count = 100; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ - return; - - case SCD_S_WAITSPIN: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITSPIN); - if (mbx->count-- <= 0) { - printf("scd%d: timeout waiting for drive to spin up.\n", unit); - goto harderr; - } - if (!STATUS_BIT(port, SBIT_RESULT_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ - return; - } - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((i = inb(port+IREG_RESULT)) & 0xf0) { - case 0x20: - i = inb(port+IREG_RESULT); - print_error(unit, i); - goto harderr; - case 0x00: - (void)inb(port+IREG_RESULT); - cd->flags |= SCDSPINNING; - break; - } - XDEBUG(1, ("scd%d: DEBUG: spin up complete\n", unit)); - - state = SCD_S_BEGIN1; - goto loop; - - case SCD_S_WAITFIFO: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITFIFO); - if (mbx->count-- <= 0) { - printf("scd%d: timeout. write param not ready.\n",unit); - goto harderr; - } - if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITFIFO,hz/100); /* XXX */ - return; - } - XDEBUG(1, ("scd%d: mbx->count (writeparamwait) = %d(%d)\n", unit, mbx->count, 100)); - -writeparam: - /* The reason this test isn't done 'till now is to make sure */ - /* that it is ok to send the SPIN_UP cmd below. */ - if (!(cd->flags & SCDSPINNING)) { - XDEBUG(1, ("scd%d: spinning up drive ...\n", unit)); - outb(port+OREG_COMMAND, CMD_SPIN_UP); - mbx->count = 300; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITSPIN,hz/100); /* XXX */ - return; - } - - reg = port + OREG_WPARAMS; - /* send the read command */ - disable_intr(); - outb(reg, sdata[0]); - outb(reg, sdata[1]); - outb(reg, sdata[2]); - outb(reg, 0); - outb(reg, 0); - outb(reg, 1); - outb(port+OREG_COMMAND, CMD_READ); - enable_intr(); - - mbx->count = RDELAY_WAITREAD; - for (i = 0; i < 50; i++) { - if (STATUS_BIT(port, SBIT_DATA_READY)) - goto got_data; - DELAY(100); - } - - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ - return; - - case SCD_S_WAITREAD: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITREAD); - if (mbx->count-- <= 0) { - if (STATUS_BIT(port, SBIT_RESULT_READY)) - goto got_param; - printf("scd%d: timeout while reading data\n",unit); - goto readerr; - } - if (!STATUS_BIT(port, SBIT_DATA_READY)) { - process_attention(unit); - if (!(cd->flags & SCDVALID)) - goto changed; - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITREAD,hz/100); /* XXX */ - return; - } - XDEBUG(2, ("scd%d: mbx->count (after RDY_BIT) = %d(%d)\n", unit, mbx->count, RDELAY_WAITREAD)); - -got_data: - /* data is ready */ - addr = bp->b_un.b_addr + mbx->skip; - write_control(port, CBIT_DATA_READY_CLEAR); - insb(port+IREG_DATA, addr, mbx->sz); - - mbx->count = 100; - for (i = 0; i < 20; i++) { - if (STATUS_BIT(port, SBIT_RESULT_READY)) - goto waitfor_param; - DELAY(100); - } - goto waitfor_param; - - case SCD_S_WAITPARAM: - untimeout((timeout_func_t)scd_doread,(caddr_t)SCD_S_WAITPARAM); - if (mbx->count-- <= 0) { - printf("scd%d: timeout waiting for params\n",unit); - goto readerr; - } - -waitfor_param: - if (!STATUS_BIT(port, SBIT_RESULT_READY)) { - timeout((timeout_func_t)scd_doread, - (caddr_t)SCD_S_WAITPARAM,hz/100); /* XXX */ - return; - } -#if SCD_DEBUG - if (mbx->count < 100 && scd_debuglevel > 0) - printf("scd%d: mbx->count (paramwait) = %d(%d)\n", unit, mbx->count, 100); -#endif - -got_param: - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((i = inb(port+IREG_RESULT)) & 0xf0) { - case 0x50: - switch (i) { - case ERR_FATAL_READ_ERROR1: - case ERR_FATAL_READ_ERROR2: - printf("scd%d: unrecoverable read error 0x%x\n", unit, i); - goto harderr; - } - break; - case 0x20: - i = inb(port+IREG_RESULT); - switch (i) { - case ERR_NOT_SPINNING: - XDEBUG(1, ("scd%d: read error: drive not spinning\n", unit)); - if (mbx->retry-- > 0) { - state = SCD_S_BEGIN1; - cd->flags &= ~SCDSPINNING; - goto loop; - } - goto harderr; - default: - print_error(unit, i); - goto readerr; - } - case 0x00: - i = inb(port+IREG_RESULT); - break; - } - - if (--mbx->nblk > 0) { - mbx->skip += mbx->sz; - goto nextblock; - } - - /* return buffer */ - bp->b_resid = 0; - biodone(bp); - - cd->flags &= ~SCDMBXBSY; - scd_start(mbx->unit); - return; - } - -readerr: - if (mbx->retry-- > 0) { - printf("scd%d: retrying ...\n",unit); - state = SCD_S_BEGIN1; - goto loop; - } -harderr: - /* invalidate the buffer */ - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - bp->b_resid = bp->b_bcount; - biodone(bp); - - cd->flags &= ~SCDMBXBSY; - scd_start(mbx->unit); - return; - -changed: - printf("scd%d: media changed\n", unit); - goto harderr; -} - -static int -bcd2bin(bcd_t b) -{ - return (b >> 4) * 10 + (b & 15); -} - -static bcd_t -bin2bcd(int b) -{ - return ((b / 10) << 4) | (b % 10); -} - -static void -hsg2msf(int hsg, bcd_t *msf) -{ - hsg += 150; - M_msf(msf) = bin2bcd(hsg / 4500); - hsg %= 4500; - S_msf(msf) = bin2bcd(hsg / 75); - F_msf(msf) = bin2bcd(hsg % 75); -} - -static int -msf2hsg(bcd_t *msf) -{ - return (bcd2bin(M_msf(msf)) * 60 + - bcd2bin(S_msf(msf))) * 75 + - bcd2bin(F_msf(msf)) - 150; -} - -static void -process_attention(unsigned unit) -{ - unsigned port = scd_data[unit].iobase; - unsigned char code; - int count = 0; - int i; - - while (IS_ATTENTION(port) && count++ < 30) { - write_control(port, CBIT_ATTENTION_CLEAR); - code = inb(port+IREG_RESULT); - -#if SCD_DEBUG - if (scd_debuglevel > 0) { - if (count == 1) - printf("scd%d: DEBUG: ATTENTIONS = 0x%x", unit, code); - else - printf(",0x%x", code); - } -#endif - - switch (code) { - case ATTEN_SPIN_DOWN: - scd_data[unit].flags &= ~SCDSPINNING; - break; - - case ATTEN_SPIN_UP_DONE: - scd_data[unit].flags |= SCDSPINNING; - break; - - case ATTEN_AUDIO_DONE: - scd_data[unit].audio_status = CD_AS_PLAY_COMPLETED; - break; - - case ATTEN_DRIVE_LOADED: - scd_data[unit].flags &= ~(SCDTOC|SCDSPINNING|SCDVALID); - scd_data[unit].audio_status = CD_AS_AUDIO_INVALID; - break; - - case ATTEN_EJECT_PUSHED: - scd_data[unit].flags &= ~SCDVALID; - break; - } - DELAY(100); - } -#if SCD_DEBUG - if (scd_debuglevel > 0 && count > 0) - printf("\n"); -#endif -} - -/* Returns 0 OR sony error code */ -static int -spin_up(unsigned unit) -{ - unsigned char res_reg[12]; - unsigned int res_size; - int rc; - int loop_count = 0; - -again: - rc = send_cmd(unit, CMD_SPIN_UP, NULL, 0, res_reg, &res_size); - if (rc != 0) { - XDEBUG(2, ("scd%d: CMD_SPIN_UP error 0x%x\n", unit, rc)); - return rc; - } - - if (!(scd_data[unit].flags & SCDTOC)) { - rc = send_cmd(unit, CMD_READ_TOC, 0); - if (rc == ERR_NOT_SPINNING) { - if (loop_count++ < 3) - goto again; - return rc; - } - if (rc != 0) - return rc; - } - - scd_data[unit].flags |= SCDSPINNING; - - return 0; -} - -static struct sony_tracklist * -get_tl(struct sony_toc *toc, int size) -{ - struct sony_tracklist *tl = &toc->tracks[0]; - - if (tl->track != 0xb0) - return tl; - (char *)tl += 9; - if (tl->track != 0xb1) - return tl; - (char *)tl += 9; - if (tl->track != 0xb2) - return tl; - (char *)tl += 9; - if (tl->track != 0xb3) - return tl; - (char *)tl += 9; - if (tl->track != 0xb4) - return tl; - (char *)tl += 9; - if (tl->track != 0xc0) - return tl; - (char *)tl += 9; - return tl; -} - -static int -read_toc(dev_t dev) -{ - unsigned unit; - struct scd_data *cd; - unsigned part = 0; /* For now ... */ - struct sony_toc toc; - struct sony_tracklist *tl; - int rc, i, j; - u_long first, last; - - unit = scd_unit(dev); - cd = scd_data + unit; - - rc = send_cmd(unit, CMD_GET_TOC, 1, part+1); - if (rc < 0) - return rc; - if (rc > sizeof(toc)) { - printf("scd%d: program error: toc too large (%d)\n", unit, rc); - return EIO; - } - if (get_result(unit, rc, (u_char *)&toc) != 0) - return EIO; - - XDEBUG(1, ("scd%d: toc read. len = %d, sizeof(toc) = %d\n", unit, rc, sizeof(toc))); - - tl = get_tl(&toc, rc); - first = msf2hsg(tl->start_msf); - last = msf2hsg(toc.lead_out_start_msf); - cd->blksize = SCDBLKSIZE; - cd->disksize = last*cd->blksize/DEV_BSIZE; - - XDEBUG(1, ("scd%d: firstsector = %d, lastsector = %d", unit, - first, last)); - - cd->first_track = bcd2bin(toc.first_track); - cd->last_track = bcd2bin(toc.last_track); - if (cd->last_track > (MAX_TRACKS-2)) - cd->last_track = MAX_TRACKS-2; - for (j = 0, i = cd->first_track; i <= cd->last_track; i++, j++) { - cd->toc[i].adr = tl[j].adr; - cd->toc[i].ctl = tl[j].ctl; /* for xcdplayer */ - bcopy(tl[j].start_msf, cd->toc[i].start_msf, 3); -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) { - if ((j % 3) == 0) - printf("\nscd%d: tracks ", unit); - printf("[%03d: %2d %2d %2d] ", i, - bcd2bin(cd->toc[i].start_msf[0]), - bcd2bin(cd->toc[i].start_msf[1]), - bcd2bin(cd->toc[i].start_msf[2])); - } -#endif - } - bcopy(toc.lead_out_start_msf, cd->toc[cd->last_track+1].start_msf, 3); -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) { - i = cd->last_track+1; - printf("[END: %2d %2d %2d]\n", - bcd2bin(cd->toc[i].start_msf[0]), - bcd2bin(cd->toc[i].start_msf[1]), - bcd2bin(cd->toc[i].start_msf[2])); - } -#endif - - bzero(&cd->dlabel,sizeof(struct disklabel)); - /* filled with spaces first */ - strncpy(cd->dlabel.d_typename," ", - sizeof(cd->dlabel.d_typename)); - strncpy(cd->dlabel.d_typename, cd->name, - min(strlen(cd->name), sizeof(cd->dlabel.d_typename) - 1)); - strncpy(cd->dlabel.d_packname,"unknown ", - sizeof(cd->dlabel.d_packname)); - cd->dlabel.d_secsize = cd->blksize; - cd->dlabel.d_nsectors = 100; - cd->dlabel.d_ntracks = 1; - cd->dlabel.d_ncylinders = (cd->disksize/100)+1; - cd->dlabel.d_secpercyl = 100; - cd->dlabel.d_secperunit = cd->disksize; - cd->dlabel.d_rpm = 300; - cd->dlabel.d_interleave = 1; - cd->dlabel.d_flags = D_REMOVABLE; - cd->dlabel.d_npartitions= 1; - cd->dlabel.d_partitions[0].p_offset = 0; - cd->dlabel.d_partitions[0].p_size = cd->disksize; - cd->dlabel.d_partitions[0].p_fstype = 9; - cd->dlabel.d_magic = DISKMAGIC; - cd->dlabel.d_magic2 = DISKMAGIC; - cd->dlabel.d_checksum = dkcksum(&cd->dlabel); - - cd->flags |= SCDTOC; - - return 0; -} - -static inline void -write_control(unsigned port, unsigned data) -{ - outb(port + OREG_CONTROL, data); -} - -static void -init_drive(unsigned unit) -{ - int rc; - - rc = send_cmd(unit, CMD_SET_DRIVE_PARAM, 2, - 0x05, 0x03 | ((scd_data[unit].double_speed) ? 0x04: 0)); - if (rc != 0) - printf("scd%d: Unable to set parameters. Errcode = 0x%x\n", unit, rc); -} - -/* Returns 0 or errno */ -static int -get_result(u_int unit, int result_len, u_char *result) -{ - unsigned int port = scd_data[unit].iobase; - unsigned int res_reg = port + IREG_RESULT; - unsigned char c; - int loop_index = 2; /* send_cmd() reads two bytes ... */ - - XDEBUG(1, ("scd%d: DEBUG: get_result: bytes=%d\n", unit, result_len)); - - while (result_len-- > 0) { - if (loop_index++ >= 10) { - loop_index = 1; - if (waitfor_status_bits(unit, SBIT_RESULT_READY, 0)) - return EIO; - write_control(port, CBIT_RESULT_READY_CLEAR); - } - if (result) - *result++ = inb(res_reg); - else - (void)inb(res_reg); - } - return 0; -} - -/* Returns -0x100 for timeout, -(drive error code) OR number of result bytes */ -static int -send_cmd(u_int unit, u_char cmd, u_int nargs, ...) -{ - va_list ap; - u_int port = scd_data[unit].iobase; - u_int reg; - u_char c; - int rc; - int i; - - if (waitfor_status_bits(unit, 0, SBIT_BUSY)) { - printf("scd%d: drive busy\n", unit); - return -0x100; - } - - XDEBUG(1,("scd%d: DEBUG: send_cmd: cmd=0x%x nargs=%d", unit, cmd, nargs)); - - write_control(port, CBIT_RESULT_READY_CLEAR); - write_control(port, CBIT_RPARAM_CLEAR); - - for (i = 0; i < 100; i++) - if (FSTATUS_BIT(port, FBIT_WPARAM_READY)) - break; - if (!FSTATUS_BIT(port, FBIT_WPARAM_READY)) { - XDEBUG(1, ("\nscd%d: wparam timeout\n", unit)); - return -EIO; - } - - va_start(ap, nargs); - reg = port + OREG_WPARAMS; - for (i = 0; i < nargs; i++) { - c = (u_char)va_arg(ap, int); - outb(reg, c); - XDEBUG(1, (",{0x%x}", c)); - } - va_end(ap); - XDEBUG(1, ("\n")); - - outb(port+OREG_COMMAND, cmd); - - if (rc = waitfor_status_bits(unit, SBIT_RESULT_READY, SBIT_BUSY)) - return -0x100; - - reg = port + IREG_RESULT; - write_control(port, CBIT_RESULT_READY_CLEAR); - switch ((rc = inb(reg)) & 0xf0) { - case 0x20: - rc = inb(reg); - /* FALL TROUGH */ - case 0x50: - XDEBUG(1, ("scd%d: DEBUG: send_cmd: drive_error=0x%x\n", unit, rc)); - return -rc; - case 0x00: - default: - rc = inb(reg); - XDEBUG(1, ("scd%d: DEBUG: send_cmd: result_len=%d\n", unit, rc)); - return rc; - } -} - -static void -print_error(int unit, int errcode) -{ - switch (errcode) { - case -ERR_CD_NOT_LOADED: - printf("scd%d: door is open\n", unit); - break; - case -ERR_NO_CD_INSIDE: - printf("scd%d: no cd inside\n", unit); - break; - default: - if (errcode == -0x100 || errcode > 0) - printf("scd%d: device timeout\n", unit); - else - printf("scd%d: unexpected error 0x%x\n", unit, -errcode); - break; - } -} - -/* Returns 0 or errno value */ -static int -waitfor_status_bits(int unit, int bits_set, int bits_clear) -{ - u_int port = scd_data[unit].iobase; - u_int flags = scd_data[unit].flags; - u_int reg = port + IREG_STATUS; - u_int max_loop; - u_char c = 0; - - if (flags & SCDPROBING) { - max_loop = 0; - while (max_loop++ < 1000) { - c = inb(reg); - if (c == 0xff) - return EIO; - if (c & SBIT_ATTENTION) { - process_attention(unit); - continue; - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - break; - } - DELAY(10000); - } - } else { - max_loop = 100; - while (max_loop-- > 0) { - c = inb(reg); - if (c & SBIT_ATTENTION) { - process_attention(unit); - continue; - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - break; - } - tsleep(waitfor_status_bits, PZERO - 1, "waitfor", hz/10); - } - } - if ((c & bits_set) == bits_set && - (c & bits_clear) == 0) - { - return 0; - } -#ifdef SCD_DEBUG - if (scd_debuglevel > 0) - printf("scd%d: DEBUG: waitfor: TIMEOUT (0x%x,(0x%x,0x%x))\n", unit, c, bits_set, bits_clear); - else -#endif - printf("scd%d: timeout.\n", unit); - return EIO; -} - -/* these two routines for xcdplayer - "borrowed" from mcd.c */ -static int -scd_toc_header (int unit, struct ioc_toc_header* th) -{ - struct scd_data *cd = scd_data + unit; - int rc; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - - th->starting_track = cd->first_track; - th->ending_track = cd->last_track; - th->len = 0; /* not used */ - - return 0; -} - -static int -scd_toc_entrys (int unit, struct ioc_read_toc_entry *te) -{ - struct scd_data *cd = scd_data + unit; - struct cd_toc_entry toc_entry; - int rc, i, len = te->data_len; - - if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) { - print_error(unit, rc); - return EIO; - } - - /* find the toc to copy*/ - i = te->starting_track; - if (i == SCD_LASTPLUS1) - i = cd->last_track + 1; - - /* verify starting track */ - if (i < cd->first_track || i > cd->last_track+1) - return EINVAL; - - /* valid length ? */ - if (len < sizeof(struct cd_toc_entry) - || (len % sizeof(struct cd_toc_entry)) != 0) - return EINVAL; - - /* copy the toc data */ - toc_entry.control = cd->toc[i].ctl; - toc_entry.addr_type = te->address_format; - toc_entry.track = i; - if (te->address_format == CD_MSF_FORMAT) { - toc_entry.addr.msf.unused = 0; - toc_entry.addr.msf.minute = bcd2bin(cd->toc[i].start_msf[0]); - toc_entry.addr.msf.second = bcd2bin(cd->toc[i].start_msf[1]); - toc_entry.addr.msf.frame = bcd2bin(cd->toc[i].start_msf[2]); - } - - /* copy the data back */ - if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0) - return EFAULT; - - return 0; -} - - -#endif /* NSCD > 0 */ diff --git a/sys/gnu/i386/scdreg.h b/sys/gnu/i386/scdreg.h deleted file mode 100644 index 93ace5c..0000000 --- a/sys/gnu/i386/scdreg.h +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 1995 Mikael Hybsch - * - * The Linux driver cdu31a has been used as a reference when writing this - * code, therefore bringing it under the GNU Public License. The following - * conditions of redistribution therefore apply: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: scdreg.h,v 1.2 1995/01/29 22:51:41 jkh Exp $ - * - */ - -#ifndef SCD_H -#define SCD_H - -#ifdef __GNUC__ -#if __GNUC__ >= 2 -#pragma pack(1) -#endif -#endif - -typedef unsigned char bcd_t; -#define M_msf(msf) msf[0] -#define S_msf(msf) msf[1] -#define F_msf(msf) msf[2] - -#define IS_ATTENTION(port) ((inb(port+IREG_STATUS) & SBIT_ATTENTION) != 0) -#define IS_BUSY(port) ((inb(port+IREG_STATUS) & SBIT_BUSY) != 0) -#define IS_DATA_RDY(port) ((inb(port+IREG_STATUS) & SBIT_DATA_READY) != 0) -#define STATUS_BIT(port, bit) ((inb(port+IREG_STATUS) & (bit)) != 0) -#define FSTATUS_BIT(port, bit) ((inb(port+IREG_FSTATUS) & (bit)) != 0) - -#define OREG_COMMAND 0 -#define OREG_WPARAMS 1 -#define OREG_CONTROL 3 -#define CBIT_ATTENTION_CLEAR 0x01 -#define CBIT_RESULT_READY_CLEAR 0x02 -#define CBIT_DATA_READY_CLEAR 0x04 -#define CBIT_RPARAM_CLEAR 0x40 -#define CBIT_RESET_DRIVE 0x80 - -#define IREG_STATUS 0 -#define SBIT_ATTENTION 0x01 -#define SBIT_RESULT_READY 0x02 -#define SBIT_DATA_READY 0x04 -#define SBIT_BUSY 0x80 - -#define IREG_RESULT 1 -#define IREG_DATA 2 -#define IREG_FSTATUS 3 -#define FBIT_WPARAM_READY 0x01 - -#define CMD_GET_DRIVE_CONFIG 0x00 -#define CMD_SET_DRIVE_PARAM 0x10 -#define CMD_GET_SUBCHANNEL_DATA 0x21 -#define CMD_GET_TOC 0x24 -#define CMD_READ_TOC 0x30 -#define CMD_READ 0x34 -#define CMD_PLAY_AUDIO 0x40 -#define CMD_STOP_AUDIO 0x41 -#define CMD_EJECT 0x50 -#define CMD_SPIN_UP 0x51 -#define CMD_SPIN_DOWN 0x52 - -#define ERR_CD_NOT_LOADED 0x20 -#define ERR_NO_CD_INSIDE 0x21 -#define ERR_NOT_SPINNING 0x22 -#define ERR_FATAL_READ_ERROR1 0x53 -#define ERR_FATAL_READ_ERROR2 0x57 - -#define ATTEN_DRIVE_LOADED 0x80 -#define ATTEN_EJECT_PUSHED 0x81 -#define ATTEN_AUDIO_DONE 0x90 -#define ATTEN_SPIN_UP_DONE 0x24 -#define ATTEN_SPIN_DOWN 0x27 -#define ATTEN_EJECT_DONE 0x28 - - -struct sony_drive_configuration { - char vendor[8]; - char product[16]; - char revision[8]; - u_short config; -}; - -/* Almost same as cd_sub_channel_position_data */ -struct sony_subchannel_position_data { - u_char control:4; - u_char addr_type:4; - u_char track_number; - u_char index_number; - u_char rel_msf[3]; - u_char dummy; - u_char abs_msf[3]; -}; - -struct sony_tracklist { - u_char adr :4; /* xcdplayer needs these two values */ - u_char ctl :4; - u_char track; - u_char start_msf[3]; -}; - -#define MAX_TRACKS 100 - -struct sony_toc { - u_char session_number; - - u_char :8; - u_char :8; - u_char first_track; - u_char :8; - u_char :8; - - u_char :8; - u_char :8; - u_char last_track; - u_char :8; - u_char :8; - - u_char :8; - u_char :8; - u_char lead_out_start_msf[3]; - - struct sony_tracklist tracks[MAX_TRACKS]; - - /* The rest is just to take space in case all data is returned */ - - u_char dummy[6*9]; -}; - -#endif /* SCD_H */ diff --git a/sys/gnu/isdn/if_ii.c b/sys/gnu/isdn/if_ii.c deleted file mode 100644 index 280023d..0000000 --- a/sys/gnu/isdn/if_ii.c +++ /dev/null @@ -1,257 +0,0 @@ -static char _if_iiid[] = "@(#)$Id: if_ii.c,v 1.2 1995/02/15 06:28:26 jkh Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.2 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: if_ii.c,v $ - * Revision 1.2 1995/02/15 06:28:26 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:27 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -/* - * Copyright (c) 1994 Dietmar Friede (dietmar@friede.de) All rights reserved. - * FSF/FSAG GNU Copyright applies - * - * A high level ip isdn driver. - * - * Uses loop driver as template. Small - and simple - is beautiful. - */ - -#include "param.h" -#include "systm.h" -#include "mbuf.h" -#include "socket.h" -#include "errno.h" -#include "ioctl.h" -#include "protosw.h" - -#include "net/if.h" -#include "net/if_types.h" -#include "net/netisr.h" -#include "net/route.h" - -#ifdef INET -#include "netinet/in.h" -#include "netinet/in_systm.h" -#include "netinet/in_var.h" -#include "netinet/ip.h" -#endif - -#include "ii.h" -#include "gnu/isdn/isdn_ioctl.h" - -#define IIMTU 1500 - -static struct ifnet ii_if[NII]; -static int applnr[NII]; -static int next_if = 0; -int iioutput(), ii_ioctl(); - -int -iiattach(int ap) -{ - register struct ifnet *ifp; - - if (next_if >= NII) - return -1; - - applnr[next_if] = ap; - ifp = &ii_if[next_if]; - ifp->if_unit = next_if; - ifp->if_name = "ii"; - ifp->if_mtu = IIMTU; - ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT ; - ifp->if_ioctl = ii_ioctl; - ifp->if_output = iioutput; - ifp->if_type = IFT_ISDNBASIC; - ifp->if_hdrlen = 0; - ifp->if_addrlen = 0; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - if_attach(ifp); - /* ifp->if_flags |= IFF_RUNNING; */ - return next_if++; -} - -int -iioutput(struct ifnet * ifp, struct mbuf * m, struct sockaddr * dst) -{ - int s, isr; - register struct ifqueue *ifq = 0; - - if (dst->sa_family != AF_INET) - { - m_freem(m); - return EAFNOSUPPORT; - } - s = splhigh(); - if (IF_QFULL(&ifp->if_snd)) - { - IF_DROP(&ifp->if_snd); - m_freem(m); - ifp->if_oerrors++; - isdn_output(applnr[ifp->if_unit]); - splx(s); - return (ENOBUFS); - } - IF_ENQUEUE(&ifp->if_snd, m); - - ifp->if_opackets++; - ifp->if_obytes += m->m_pkthdr.len; - - isdn_output(applnr[ifp->if_unit]); - splx(s); - return (0); -} - -int -ii_input(int no, int len, char *buf) -{ - int error = 0; - struct mbuf *m; - struct ifnet *ifp = &(ii_if[no]); - int s; - - s = splhigh(); - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == 0) - { - splx(s); - return (0); - } - - if (len >= MHLEN) - { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) - { - (void) m_free(m); - splx(s); - return (0); - } - } - bcopy((caddr_t) buf, mtod(m, caddr_t), len); - m->m_pkthdr.rcvif = ifp; - m->m_pkthdr.len = len; - m->m_len = len; - - if (IF_QFULL(&ipintrq)) - { - IF_DROP(&ipintrq); - ifp->if_ierrors++; - m_freem(m); - splx(s); - return(0); - } - IF_ENQUEUE(&ipintrq, m); - ifp->if_ipackets++; - schednetisr(NETISR_IP); - splx(s); - return(len); -} - -void -ii_connect(int no) -{ - struct ifnet *ifp = &ii_if[no]; - ifp->if_flags |= IFF_RUNNING; -} - -void -ii_disconnect(int no) -{ - struct ifnet *ifp = &ii_if[no]; - ifp->if_flags &= ~IFF_RUNNING; -} - -int -ii_out(int no, char *buf, int len) -{ - struct ifnet *ifp = &ii_if[no]; - struct mbuf *m0, *m; - int l; - - IF_DEQUEUE(&ifp->if_snd, m); - if (m == 0) - { - return (0); - } - /* - * Copy the mbuf chain into the transmit buf - */ - l = 0; - for (m0 = m; m != 0; m = m->m_next) - { - if((l+= m->m_len) > len) - { - m_freem(m0); - return(0); - } - bcopy(mtod(m, caddr_t), buf, m->m_len); - buf += m->m_len; - } - m_freem(m0); - - return (l); -} - -/* - * Process an ioctl request. - */ -int -ii_ioctl(ifp, cmd, data) - register struct ifnet *ifp; - int cmd; - caddr_t data; -{ - struct ifaddr *ifa = (struct ifaddr *) data; - struct ifreq *ifr = (struct ifreq *) data; - int s; - - switch (cmd) - { - case SIOCSIFDSTADDR: - case SIOCAIFADDR: - case SIOCSIFADDR: - if (ifa->ifa_addr->sa_family != AF_INET) - return(EAFNOSUPPORT); - ifp->if_flags |= IFF_UP; - /* FALLTHROUGH */ - case SIOCSIFFLAGS: - s= splhigh(); - if((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) - { - isdn_disconnect(applnr[ifp->if_unit],0); - ifp->if_flags &= ~IFF_RUNNING; - } - break; - case SIOCSIFMTU: - ifr->ifr_metric = ifp->if_mtu; - break; - case SIOCGIFMTU: - if(ifr->ifr_metric < 2048) - return(EAFNOSUPPORT); - ifp->if_mtu = ifr->ifr_metric; - break; - default: -printf("IIO %x",cmd); - return(EINVAL); - } - return(0); -} diff --git a/sys/gnu/isdn/iispy.c b/sys/gnu/isdn/iispy.c deleted file mode 100644 index 6acaf61..0000000 --- a/sys/gnu/isdn/iispy.c +++ /dev/null @@ -1,183 +0,0 @@ -static char _ispyid[] = "@(#)$Id: iispy.c,v 1.3 1995/03/28 07:54:40 bde Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.3 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: iispy.c,v $ - * Revision 1.3 1995/03/28 07:54:40 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.2 1995/02/15 06:28:27 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:29 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -#include "ispy.h" -#if NISPY > 0 - -#include "param.h" -#include "buf.h" -#include "systm.h" -#include "ioctl.h" -#include "tty.h" -#include "proc.h" -#include "user.h" -#include "uio.h" -#include "kernel.h" -/*#include "malloc.h"*/ - -#include "gnu/isdn/isdn_ioctl.h" - -int nispy = NISPY; -int ispy_applnr; -static int next_if =0; -static unsigned long ispy_cnt, ispy_out; -static char dir; -#define ISPY_SIZE 260 -#define OPEN 1 -#define READ_WAIT 2 -#define ISPYBUF 16 -#define ISPYMASK (ISPYBUF-1) -/* ISPYBUF has to be a power of 2 */ - -static -struct ispy_data -{ - struct ispy_buf - { - unsigned long cnt; - struct timeval stamp; - char ibuf[ISPY_SIZE]; - unsigned char dir; - int ilen; - } b[ISPYBUF]; - int state; -} ispy_data[NISPY]; - -int -ispyattach(int ap) -{ - struct ispy_data *ispy; - if(next_if >= NISPY) - return(-1); - ispy= &ispy_data[next_if]; - ispy->state= 0; - ispy_applnr= ap; - return(next_if++); -} - -int -ispy_input(int no, int len, char *buf, int out) -{ - struct ispy_data *ispy= &ispy_data[no]; - struct ispy_buf *b= &ispy->b[ispy_cnt&ISPYMASK]; - - if(len > ISPY_SIZE) - return(0); - if(len) - { - b->cnt= ispy_cnt++; - b->stamp= time; - b->dir= out; - bcopy(buf, b->ibuf, len); - } - b->ilen= len; - if(ispy->state & READ_WAIT) - { - ispy->state &= ~READ_WAIT; - wakeup((caddr_t) &ispy->state); - } - return(len); -} - -int -ispyopen(dev_t dev, int flags, int fmt, struct proc *p) -{ - int err; - struct ispy_data *ispy; - - if (minor(dev)>NISPY) - return (ENXIO); - - ispy= &ispy_data[minor(dev)]; - - if(ispy->state&OPEN) return(EBUSY); - ispy->state |= OPEN; - - return (0); -} - -int -ispyclose(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct ispy_data *ispy= &ispy_data[minor(dev)]; - - if(ispy->state & READ_WAIT) - wakeup((caddr_t) &ispy->state); - ispy->state = 0; - return (0); -} - -int -ispyioctl (dev_t dev, int cmd, caddr_t data, int flags, struct proc *p) -{ - int unit = minor(dev); - - switch (cmd) { - default: - return (ENOTTY); - } - return (0); -} - -int -ispyread(dev_t dev, struct uio * uio, int ioflag) -{ - int x; - int error = 0; - struct ispy_data *ispy= &ispy_data[minor(dev)]; - struct ispy_buf *b; - - if((ispy_cnt-ispy_out) > ISPYBUF) - ispy_out= ispy_cnt - ISPYBUF; - b= &ispy->b[ispy_out&ISPYMASK]; - ispy_out++; - while(b->ilen == 0) - { - ispy->state |= READ_WAIT; - if(error= tsleep((caddr_t) &ispy->state, TTIPRI | PCATCH, "ispy", 0 )) - return(error); - } - - x = splhigh(); - if(b->ilen) - { - error = uiomove((char *) &b->dir, 1, uio); - if(error == 0) - error = uiomove((char *) &b->cnt - ,sizeof(unsigned long)+sizeof(struct timeval)+b->ilen, uio); - b->ilen= 0; - } - splx(x); - return error; -} - -#endif diff --git a/sys/gnu/isdn/iitel.c b/sys/gnu/isdn/iitel.c deleted file mode 100644 index c09644a..0000000 --- a/sys/gnu/isdn/iitel.c +++ /dev/null @@ -1,249 +0,0 @@ -static char _itelid[] = "@(#)$Id: iitel.c,v 1.4 1995/07/16 10:11:10 bde Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.4 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: iitel.c,v $ - * Revision 1.4 1995/07/16 10:11:10 bde - * Don't include <sys/tty.h> in drivers that aren't tty drivers or in general - * files that don't depend on the internals of <sys/tty.h> - * - * Revision 1.3 1995/03/28 07:54:41 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.2 1995/02/15 06:28:27 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:30 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -#include "itel.h" -#if NITEL > 0 - -#include "param.h" -#include "buf.h" -#include "systm.h" -#include "ioctl.h" -#include "proc.h" -#include "user.h" -#include "uio.h" -#include "kernel.h" -#include "malloc.h" - -#include "gnu/isdn/isdn_ioctl.h" - -int nitel = NITEL; -static int applnr[NITEL]; -static int next_if =0; -#define ITEL_SIZE 1024 -#define OPEN 1 -#define CONNECT 2 -#define READ_WAIT 4 -#define WRITE_WAIT 8 -#define min(a,b) ((a)<(b)?(a):(b)) - -static -struct itel_data -{ - char ibuf[ITEL_SIZE]; - char obuf[ITEL_SIZE]; - int state; - int ilen, olen; -} itel_data[NITEL]; - -int -itelattach(int ap) -{ - struct itel_data *itel; - if(next_if >= NITEL) - return(-1); - itel= &itel_data[next_if]; - itel->ilen= itel->olen= 0; - itel->state= 0; - applnr[next_if]= ap; - return(next_if++); -} - -int -itel_input(int no, int len, char *buf) -{ - struct itel_data *itel= &itel_data[no]; - - if(itel->ilen || ( len > ITEL_SIZE)) - return(0); - if(len) - bcopy(buf, itel->ibuf, len); - itel->ilen= len; - if(itel->state & READ_WAIT) - { - itel->state &= ~READ_WAIT; - wakeup((caddr_t) itel->ibuf); - } - return(len); -} - -int -itel_out(int no, char *buf, int len) -{ - struct itel_data *itel= &itel_data[no]; - int l; - - if((itel->state & CONNECT) == 0) - return(0); - if((l= itel->olen) && (itel->olen <= len)) - bcopy(itel->obuf, buf, l); - - itel->olen= 0; - if(itel->state & WRITE_WAIT) - { - itel->state &= ~WRITE_WAIT; - wakeup((caddr_t) itel->obuf); - } - return(l); -} - -void -itel_connect(int no) -{ - itel_data[no].state |= CONNECT; -} - -void -itel_disconnect(int no) -{ - struct itel_data *itel= &itel_data[no]; - int s; - - s= itel->state; - if(itel->state &= OPEN) - { - itel->ilen= itel->olen= 0; - if(s & READ_WAIT) - wakeup((caddr_t) itel->ibuf); - if(s & WRITE_WAIT) - wakeup((caddr_t) itel->obuf); - } -} - -int -itelopen(dev_t dev, int flags, int fmt, struct proc *p) -{ - int err; - struct itel_data *itel; - - if (minor(dev)>NITEL) - return (ENXIO); - - itel= &itel_data[minor(dev)]; - if((itel->state & CONNECT) == 0) - return(EIO); - - if(itel->state&OPEN) return(0); - itel->ilen= itel->olen= 0; - itel->state |= OPEN; - - return (0); -} - -int -itelclose(dev_t dev, int flags, int fmt, struct proc *p) -{ - struct itel_data *itel= &itel_data[minor(dev)]; - - if(itel->state & READ_WAIT) - wakeup((caddr_t) itel->ibuf); - if(itel->state & WRITE_WAIT) - wakeup((caddr_t) itel->obuf); - itel_data[minor(dev)].state &= CONNECT; - return (0); -} - -int -itelioctl (dev_t dev, int cmd, caddr_t data, int flags, struct proc *p) -{ - int unit = minor(dev); - - switch (cmd) { - default: - return (ENOTTY); - } - return (0); -} - -int -itelread(dev_t dev, struct uio * uio, int ioflag) -{ - int x; - int error = 0; - struct itel_data *itel= &itel_data[minor(dev)]; - - if((itel->state & CONNECT) == 0) - return(EIO); - - while((itel->ilen == 0) && (itel->state & CONNECT)) - { - itel->state |= READ_WAIT; - sleep((caddr_t) itel->ibuf, PZERO | PCATCH); - } - - x = splhigh(); - if(itel->ilen) - { - error = uiomove(itel->ibuf, itel->ilen, uio); - itel->ilen= 0; - } else error= EIO; - splx(x); - return error; -} - -int -itelwrite(dev_t dev, struct uio * uio, int ioflag) -{ - int x; - int error = 0; - struct itel_data *itel= &itel_data[minor(dev)]; - - if((itel->state & CONNECT) == 0) - return(EIO); - - while(itel->olen && (itel->state & CONNECT)) - { - itel->state |= WRITE_WAIT; - sleep((caddr_t) itel->obuf, PZERO | PCATCH); - } - - x = splhigh(); - if((itel->state & CONNECT) == 0) - { - splx(x); - return(0); - } - - if(itel->olen == 0) - { - itel->olen= min(ITEL_SIZE, uio->uio_resid); - error = uiomove(itel->obuf, itel->olen, uio); - isdn_output(applnr[minor(dev)]); - } - splx(x); - return error; -} - -#endif diff --git a/sys/gnu/isdn/iitty.c b/sys/gnu/isdn/iitty.c deleted file mode 100644 index 5a41045..0000000 --- a/sys/gnu/isdn/iitty.c +++ /dev/null @@ -1,442 +0,0 @@ -static char _ittyid[] = "@(#)$Id: iitty.c,v 1.10 1995/07/31 21:01:03 bde Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.10 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: iitty.c,v $ - * Revision 1.10 1995/07/31 21:01:03 bde - * Obtained from: partly from ancient patches of mine via 1.1.5 - * - * Introduce TS_CONNECTED and TS_ZOMBIE states. TS_CONNECTED is set - * while a connection is established. It is set while (TS_CARR_ON or - * CLOCAL is set) and TS_ZOMBIE is clear. TS_ZOMBIE is set for on to - * off transitions of TS_CARR_ON that occur when CLOCAL is clear and - * is cleared for off to on transitions of CLOCAL. I/o can only occur - * while TS_CONNECTED is set. TS_ZOMBIE prevents further i/o. - * - * Split the input-event sleep address TSA_CARR_ON(tp) into TSA_CARR_ON(tp) - * and TSA_HUP_OR_INPUT(tp). The former address is now used only for - * off to on carrier transitions and equivalent CLOCAL transitions. - * The latter is used for all input events, all carrier transitions - * and certain CLOCAL transitions. There are some harmless extra - * wakeups for rare connection- related events. Previously there were - * too many extra wakeups for non-rare input events. - * - * Drivers now call l_modem() instead of setting TS_CARR_ON directly - * to handle even the initial off to on transition of carrier. They - * should always have done this. l_modem() now handles TS_CONNECTED - * and TS_ZOMBIE as well as TS_CARR_ON. - * - * gnu/isdn/iitty.c: - * Set TS_CONNECTED for first open ourself to go with bogusly setting - * CLOCAL. - * - * i386/isa/syscons.c, i386/isa/pcvt/pcvt_drv.c: - * We fake carrier, so don't also fake CLOCAL. - * - * kern/tty.c: - * Testing TS_CONNECTED instead of TS_CARR_ON fixes TIOCCONS forgetting to - * test CLOCAL. TS_ISOPEN was tested instead, but that broke when we disabled - * the clearing of TS_ISOPEN for certain transitions of CLOCAL. - * - * Testing TS_CONNECTED fixes ttyselect() returning false success for output - * to devices in state !TS_CARR_ON && !CLOCAL. - * - * Optimize the other selwakeup() call (this is not related to the other - * changes). - * - * kern/tty_pty.c: - * ptcopen() can be declared in traditional C now that dev_t isn't short. - * - * Revision 1.9 1995/07/22 16:44:26 bde - * Obtained from: partly from ancient patches of mine via 1.1.5 - * - * Give names to the magic tty i/o sleep addresses and use them. This makes - * it easier to remember what the addresses are for and to keep them unique. - * - * Revision 1.8 1995/07/22 01:29:28 bde - * Move the inline code for waking up writers to a new function - * ttwwakeup(). The conditions for doing the wakeup will soon become - * more complicated and I don't want them duplicated in all drivers. - * - * It's probably not worth making ttwwakeup() a macro or an inline - * function. The cost of the function call is relatively small when - * there is a process to wake up. There is usually a process to wake - * up for large writes and the system call overhead dwarfs the function - * call overhead for small writes. - * - * Revision 1.7 1995/07/21 20:52:21 bde - * Obtained from: partly from ancient patches by ache and me via 1.1.5 - * - * Nuke `symbolic sleep message strings'. Use unique literal messages so that - * `ps l' shows unambiguously where processes are sleeping. - * - * Revision 1.6 1995/07/21 16:30:37 bde - * Obtained from: partly from an ancient patch of mine via 1.1.5 - * - * Temporarily nuke TS_WOPEN. It was only used for the obscure MDMBUF - * flow control option in the kernel and for informational purposes - * in `pstat -t'. The latter worked properly only for ptys. In - * general there may be multiple processes sleeping in open() and - * multiple processes that successfully opened the tty by opening it - * in O_NONBLOCK mode or during a window when CLOCAL was set. tty.c - * doesn't have enough information to maintain the flag but always - * cleared it in ttyopen(). - * - * TS_WOPEN should be restored someday just so that `pstat -t' can - * display it (MDMBUF is already fixed). Fixing it requires counting - * of processes sleeping in open() in too many serial drivers. - * - * Revision 1.5 1995/03/28 07:54:43 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.4 1995/02/28 00:20:30 pst - * Incorporate bde's code-review comments. - * - * (a) bring back ttselect, now that we have xxxdevtotty() it isn't dangerous. - * (b) remove all of the wrappers that have been replaced by ttselect - * (c) fix formatting in syscons.c and definition in syscons.h - * (d) add cxdevtotty - * - * NOT DONE: - * (e) make pcvt work... it was already broken...when someone fixes pcvt to - * link properly, just rename get_pccons to xxxdevtotty and we're done - * - * Revision 1.3 1995/02/25 20:08:52 pst - * (a) remove the pointer to each driver's tty structure array from cdevsw - * (b) add a function callback vector to tty drivers that will return a pointer - * to a valid tty structure based upon a dev_t - * (c) make syscons structures the same size whether or not APM is enabled so - * utilities don't crash if NAPM changes (and make the damn kernel compile!) - * (d) rewrite /dev/snp ioctl interface so that it is device driver and i386 - * independant - * - * Revision 1.2 1995/02/15 06:28:28 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:32 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -#include "ity.h" -#if NITY > 0 - -#include "param.h" -#include "systm.h" -#include "ioctl.h" -#include "select.h" -#include "tty.h" -#include "proc.h" -#include "user.h" -#include "conf.h" -#include "file.h" -#include "uio.h" -#include "kernel.h" -#include "syslog.h" -#include "types.h" - -#include "gnu/isdn/isdn_ioctl.h" - -int ityparam(); -void itystart(); - -int nity = NITY; -int itydefaultrate = 64000; -short ity_addr[NITY]; -struct tty ity_tty[NITY]; -static int applnr[NITY]; -static int next_if= 0; - -#define UNIT(x) (minor(x)&0x3f) -#define OUTBOUND(x) ((minor(x)&0x80)==0x80) - -int -ityattach(int ap) -{ - if(next_if >= NITY) - return(-1); - - applnr[next_if]= ap; - return(next_if++); -} - -/* ARGSUSED */ -int -ityopen(dev_t dev, int flag, int mode, struct proc * p) -{ - register struct tty *tp; - register int unit; - int error = 0; - - unit = UNIT(dev); - if (unit >= next_if) - return (ENXIO); - - tp = &ity_tty[unit]; - tp->t_oproc = itystart; - tp->t_param = ityparam; - tp->t_dev = dev; - if ((tp->t_state & TS_ISOPEN) == 0) - { - ttychars(tp); - if (tp->t_ispeed == 0) - { - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = TTYDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - tp->t_ispeed = tp->t_ospeed = itydefaultrate; - } - ityparam(tp, &tp->t_termios); - ttsetwater(tp); - } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) - return (EBUSY); - (void) spltty(); - - if (OUTBOUND(dev)) { - /* - * XXX should call l_modem() here and not meddle with CLOCAL, - * but itystart() wants TS_CARR_ON to give the true carrier. - */ - tp->t_cflag |= CLOCAL; - tp->t_state |= TS_CONNECTED; - } - - while ((flag & O_NONBLOCK) == 0 && (tp->t_cflag & CLOCAL) == 0 && - (tp->t_state & TS_CARR_ON) == 0) - { - error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "iidcd", 0); - if (error) - break; - } - (void) spl0(); - if (error == 0) - error = (*linesw[tp->t_line].l_open) (dev, tp); - return (error); -} - -/* ARGSUSED */ -int -ityclose(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - register struct tty *tp; - register ity; - register int unit; - - unit = UNIT(dev); - ity = ity_addr[unit]; - if(tp = &ity_tty[unit]) - (*linesw[tp->t_line].l_close) (tp, flag); - ttyclose(tp); - isdn_disconnect(applnr[unit],0); - return (0); -} - -int -ityread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - register struct tty *tp = &ity_tty[UNIT(dev)]; - - return ((*linesw[tp->t_line].l_read) (tp, uio, flag)); -} - -int -itywrite(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - int unit = UNIT(dev); - register struct tty *tp = &ity_tty[unit]; - - return ((*linesw[tp->t_line].l_write) (tp, uio, flag)); -} - -int -ity_input(int no, int len, char *buf) -{ - register struct tty *tp = &ity_tty[no]; - int i; - - if (tp->t_state & TS_ISOPEN) - for(i= 0; i<len; i++) - (*linesw[tp->t_line].l_rint)(buf[i], tp); - else len= 0; - return(len); -} - -void -itystart(struct tty *tp) -{ - int s, unit; - - unit = UNIT(tp->t_dev); - - s = splhigh(); - if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) - { - splx(s); - return; - } - ttwwakeup(tp); - if (tp->t_outq.c_cc) - { - if(OUTBOUND(tp->t_dev) && (tp->t_cflag & CLOCAL) && - ((tp->t_state & TS_CARR_ON) == 0)) - isdn_msg(applnr[unit]); - else isdn_output(applnr[unit]); - tp->t_state |= TS_BUSY; - } - splx(s); -} - -int -ity_out(int no, char *buf, int len) -{ - struct tty *tp = &ity_tty[no]; - int i; - - if(tp == NULL) - return(0); - if(tp->t_outq.c_cc) - { - for (i = 0; i < len && tp->t_outq.c_cc; ++i) - buf[i]= getc(&tp->t_outq); - return(i); - } - tp->t_state &=~ (TS_BUSY|TS_FLUSH); - if (tp->t_line) - (*linesw[tp->t_line].l_start)(tp); - else - itystart(tp); - return(0); -} - -void -ity_connect(int no) -{ - struct tty *tp = &ity_tty[no]; - - if(tp == NULL) - return; - if(OUTBOUND(tp->t_dev)) tp->t_cflag &= ~CLOCAL; - (*linesw[tp->t_line].l_modem) (tp, 1); - tp->t_state &=~ (TS_BUSY|TS_FLUSH); - if (tp->t_line) - (*linesw[tp->t_line].l_start)(tp); - else - itystart(tp); -} - -void -ity_disconnect(int no) -{ - struct tty *tp = &ity_tty[no]; - if(tp) (*linesw[tp->t_line].l_modem) (tp, 0); -} - -int -ityioctl(dev, cmd, data, flag,p) - dev_t dev; - int cmd; - caddr_t data; - int flag; - struct proc *p; -{ - register struct tty *tp; - register int unit = UNIT(dev); - register int error; - - tp = &ity_tty[unit]; - error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag,p); - if (error >= 0) - return (error); - error = ttioctl(tp, cmd, data, flag); - if (error >= 0) - return (error); - - switch (cmd) - { - default: - return (ENOTTY); - } - return (0); -} - -int -ityparam(tp, t) - register struct tty *tp; - register struct termios *t; -{ - register ity; - register int cfcr, cflag = t->c_cflag; - int unit = UNIT(tp->t_dev); - int ospeed = t->c_ospeed; - - /* check requested parameters */ - if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) - return (EINVAL); - /* and copy to tty */ - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = cflag; - - if (ospeed == 0) - { - isdn_disconnect(applnr[unit],0); - return (0); - } - return (0); -} - -/* - * Stop output on a line. - */ -/* ARGSUSED */ -void -itystop(struct tty *tp, int flag) -{ - register int s; - - s = splhigh(); - if (tp->t_state & TS_BUSY) - { - if ((tp->t_state & TS_TTSTOP) == 0) - tp->t_state |= TS_FLUSH; - } - splx(s); -} - -struct tty * -itydevtotty(dev_t dev) -{ - register int unit = UNIT(dev); - if (unit >= next_if) - return (NULL); - - return (&ity_tty[unit]); -} - -#endif diff --git a/sys/gnu/isdn/isdn.c b/sys/gnu/isdn/isdn.c deleted file mode 100644 index edb87f7..0000000 --- a/sys/gnu/isdn/isdn.c +++ /dev/null @@ -1,644 +0,0 @@ -static char _isdnid[] = "@(#)$Id: isdn.c,v 1.4 1995/05/30 07:58:02 rgrimes Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.4 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: isdn.c,v $ - * Revision 1.4 1995/05/30 07:58:02 rgrimes - * Remove trailing whitespace. - * - * Revision 1.3 1995/03/28 07:54:44 bde - * Add and move declarations to fix all of the warnings from `gcc -Wimplicit' - * (except in netccitt, netiso and netns) that I didn't notice when I fixed - * "all" such warnings before. - * - * Revision 1.2 1995/02/15 06:28:29 jkh - * Fix up include paths, nuke some warnings. - * - * Revision 1.1 1995/02/14 15:00:33 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -/* - * Copyright (c) 1994 Dietmar Friede (dietmar@friede.de) All rights reserved. - * FSF/FSAG GNU Copyright applies - * - * An intermediate level for ISDN Drivers. - * - */ - -#include "isdn.h" -#include "ii.h" -#include "ity.h" -#include "itel.h" -#include "ispy.h" -#if NISDN > 0 - -#define TYPNR 4 -#define N_ISDN_APPL (NII + NITY + NITEL + NISPY) - -#include "param.h" -#include "ioctl.h" -#include "kernel.h" -#include "systm.h" -#include "proc.h" - -#include "gnu/isdn/isdn_ioctl.h" - -isdn_appl_t isdn_appl[N_ISDN_APPL]; -isdn_ctrl_t isdn_ctrl[N_ISDN_CTRL]; -int Isdn_Appl, Isdn_Ctrl, Isdn_Typ; - -int ii_input(), ii_out(), ii_connect(), ii_disconnect(); -int ity_input(), ity_out(), ity_connect(), ity_disconnect(); -int itel_input(), itel_out(), itel_connect(), itel_disconnect(); -int ispy_input(); -int isdn_stat(); - -static int o_flags, r_flags, bufind[TYPNR]; -static char buffer[TYPNR][257]; -static u_char appl_list[TYPNR]; - -typedef u_char prot[2]; -static u_char prot_size[2] = {0, 2}; -static prot passiv[6] = {{0}, {3, 3}}; -static prot activ[6] = {{0}, {1, 3}}; -static void passout(); - -u_short isdn_state= 0; -static isdn_timeout= 0; - -int -isdn_get_prot_size(int ap) -{ - return (prot_size[isdn_appl[ap].prot]); -} - -char * -isdn_get_prot(int ap, int dir) -{ - if(dir) - return(activ[isdn_appl[ap].prot]); - return(passiv[isdn_appl[ap].prot]); -} - -int -isdn_set_prot(int ap, int dir, char *p) -{ - char *pr; - int i, l; - if ((l = isdn_get_prot_size(ap)) == 0) - return (0); - if (dir) - pr = passiv[isdn_appl[ap].prot]; - else - pr = activ[isdn_appl[ap].prot]; - for (i = 0; i < l; i++, pr++, p++) - *p = *pr; - return (l); -} - -void -isdn_attach() -{ - isdn_appl_t *appl; - int i, an; - - appl_list[0]= Isdn_Typ= an= 0; - - for(i= 0 ; i<NII; i++,an++) - { - appl = &isdn_appl[an]; - appl->ctrl = -1; - appl->state = 0; - appl->appl = an; - appl->typ = Isdn_Typ; - appl->drivno = iiattach(an); - appl->PassUp = ii_input; - appl->PassDown = ii_out; - appl->Connect = ii_connect; - appl->DisConn = ii_disconnect; - } - - appl_list[1]= an; - Isdn_Typ= 1; - for(i= 0 ; i<NITY; i++,an++) - { - appl = &isdn_appl[an]; - appl->ctrl = -1; - appl->state = 0; - appl->appl = an; - appl->typ = Isdn_Typ; - appl->drivno = ityattach(an); - appl->PassUp = ity_input; - appl->PassDown = ity_out; - appl->Connect = ity_connect; - appl->DisConn = ity_disconnect; - } - - appl_list[2]= an; - Isdn_Typ= 2; - for(i= 0 ; i<NITEL; i++,an++) - { - appl = &isdn_appl[an]; - appl->ctrl = -1; - appl->state = 0; - appl->appl = an; - appl->typ = Isdn_Typ; - appl->drivno = itelattach(an); - appl->PassUp = itel_input; - appl->PassDown = itel_out; - appl->Connect = itel_connect; - appl->DisConn = itel_disconnect; - } - - appl_list[3]= an; - Isdn_Typ= 3; - for(i= 0 ; i<NISPY; i++,an++) - { - appl = &isdn_appl[an]; - appl->ctrl = -1; - appl->state = 0; - appl->appl = an; - appl->typ = Isdn_Typ; - appl->drivno = ispyattach(an); - appl->PassUp = ispy_input; - } - Isdn_Appl= an; -} - -int -isdn_ctrl_attach(int n) -{ - int c = Isdn_Ctrl; - - if(Isdn_Ctrl == 0) isdn_attach(); - if ((Isdn_Ctrl += n) <= N_ISDN_CTRL) - return (c); - Isdn_Ctrl = c; - return (-1); -} - -/* - * isdnopen() New open on device. - * - * I forbid all but one open per application. The only programs opening the - * isdn device are the ISDN-daemon - */ -int -isdnopen(dev_t dev, int flags, int fmt, struct proc *p) -{ - int err; - - if (minor(dev)>Isdn_Typ) - return (ENXIO); - - /* Card busy ? */ - if (o_flags & (1 << minor(dev))) - return (EBUSY); - - o_flags |= (1 << minor(dev)); - - return (0); -} - -int -isdnclose(dev_t dev, int flags, int fmt, struct proc *p) -{ - o_flags &= ~(1 << minor(dev)); - return (0); -} - -int -isdnread(dev_t dev, struct uio * uio, int ioflag) -{ - int x; - int error = 0; - int unit= minor(dev); - - r_flags &= ~(1 << unit); - - x = splhigh(); - if(bufind[unit] == 0) - { - r_flags |= (1 << unit); - error= tsleep((caddr_t) buffer[unit], PZERO + 1, "isdnin", hz); - } - if(bufind[unit]) - { - buffer[unit][bufind[unit]++]= 0; - error = uiomove(buffer[unit], bufind[unit], uio); - bufind[unit] = 0; - } - splx(x); - return error; -} - -int -isdnioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p) -{ - int err, x, i; - isdn_appl_t *appl; - isdn_ctrl_t *ctrl; - short *val = (short *) data; - unsigned ab, an, cn; - - err = 0; - ab= appl_list[minor(dev)]; - - switch (cmd) - { - case ISDN_LISTEN: - { - listen_t *s= (listen_t *) data; - - an= ab; - if (s->ctrl >= Isdn_Ctrl) - return (ENODEV); - cn= s->ctrl; - ctrl = &isdn_ctrl[cn]; - - x = splhigh(); - while(isdn_state) - { - err = tsleep((caddr_t) ctrl, PZERO | PCATCH, "slisten", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - - isdn_state = 0xffff; - while((err = (*ctrl->listen) (s->ctrl, minor(dev) | 0x30 - , s->inf_mask ,s->subadr_mask ,s->si_mask)) == EBUSY) - { - err = tsleep((caddr_t) ctrl, PZERO | PCATCH, "blisten", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - - if (err) - { - splx(x); - return (err); - } - while (isdn_state == 0xffff) - { - err = tsleep((caddr_t) ctrl, PZERO | PCATCH, "ilisten", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - splx(x); - err= isdn_state; - isdn_state= 0; - return (err); /* tricky but it works */ - } - break; - - case ISDN_DIAL: - { - dial_t *d= (dial_t*)data; - telno_t *t= &d->telno; - - an = d->appl + ab; - cn = d->ctrl; - - if (an >= Isdn_Appl || cn >= Isdn_Ctrl) - return (ENODEV); - - appl = &isdn_appl[an]; - - if (ISBUSY(appl->ctrl) || appl->state) - return (EBUSY); - - appl->state= 1; - x = splhigh(); - - while((err = (*isdn_ctrl[cn].connect) (cn, an - ,d->b_channel, d->inf_mask, d->out_serv - ,d->out_serv_add, d->src_subadr, t->length - ,t->no, d->spv)) == EBUSY) - { - err = tsleep((caddr_t) appl, PZERO | PCATCH, "idial", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - if(err) appl->state= 0; - splx(x); - return(err); - } - break; - case ISDN_HANGUP: - cn = data[0]; - if (cn >= Isdn_Ctrl) - return (ENODEV); - x = splhigh(); - - while((err = (*isdn_ctrl[cn].disconnect) (cn, data[1])) == EBUSY) - { - err = tsleep((caddr_t) data, PZERO | PCATCH, "ihang", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - splx(x); - break; - case ISDN_ACCEPT: - cn = data[0]; - an = data[1] + ab; - if (cn >= Isdn_Ctrl) - return (ENODEV); - x = splhigh(); - while((err = (*isdn_ctrl[cn].accept) (cn, an, data[2])) == EBUSY) - { - err = tsleep((caddr_t) data, PZERO | PCATCH, "iaccept", 2); - if (err != EWOULDBLOCK) - { - splx(x); - return (err); - } - } - splx(x); - break; - case ISDN_SET_PARAM: - { - isdn_param *p = (isdn_param *) data; - - an = p->appl + ab; - if (an >= Isdn_Appl) - return (ENODEV); - appl = &isdn_appl[an]; - bcopy(p, appl, sizeof(isdn_param)); - appl->appl+= ab; - } - break; - case ISDN_GET_PARAM: - { - isdn_param *p = (isdn_param *) data; - an = p->appl + ab; - if (an >= Isdn_Appl) - return (ENODEV); - appl = &isdn_appl[an]; - bcopy(appl, p, sizeof(isdn_param)); - } - break; - default: - err = ENODEV; - } - - return (err); -} - -void -isdn_start_out(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - isdn_appl_t *appl = &isdn_appl[ctrl->appl]; - int x; - - x= splhigh(); - if (ctrl->o_len == 0) - { - int l; - l = isdn_set_prot(ctrl->appl, ctrl->islisten, ctrl->o_buf); - ctrl->o_len = (*appl->PassDown) (appl->drivno, ctrl->o_buf+l,2048-l); - - if (ctrl->o_len == 0) - { - splx(x); - return; - } - ctrl->o_len+= l; - (*ctrl->output) (cn); - } - - splx(x); -} - -int -isdn_stat(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - return((*ctrl->state) (cn)); -} - -int -isdn_output(int an) -{ - isdn_appl_t *appl = &isdn_appl[an]; - - if (ISFREE(appl->ctrl)) - { - int l; - char buf[10]; - - if(appl->state) - return(0); - - l = sprintf(buf,"d %d", an-appl_list[appl->typ]); - passout(appl->typ,l,buf); - return(0); - } - isdn_start_out(appl->ctrl); - return (0); -} - -int -isdn_msg(int an) -{ - isdn_appl_t *appl = &isdn_appl[an]; - - if (ISFREE(appl->ctrl)) - { - int l; - char buf[256]; - - l = sprintf(buf,"M %d", an-appl_list[appl->typ]); - l += (*appl->PassDown) (appl->drivno, buf+l,256-l); - passout(appl->typ,l,buf); - return(0); - } - return (1); -} - -int -isdn_input(int an, int len, char *buf, int dir) -{ - int l; - char *p; - isdn_appl_t *appl = &isdn_appl[an]; - - if (l = isdn_get_prot_size(an)) - { - p= isdn_get_prot(an,dir); - if((p[0] != buf[0]) || (p[1] != buf[1])) - return(0); - len -= l; - buf += l; - } - return ((*appl->PassUp) (appl->drivno, len, buf, dir)); -} - -void -isdn_accept_con_ind(int an, int cn, char serv, char serv_add, char subadr, char nl, char *num) -{ - int l; - char buf[32]; - - an&= 0xf; - l = sprintf(buf, "a %d %d %d %d %c %d %d %s", an, cn ,serv, serv_add - , subadr,(u_char) num[0], nl, num + 1); - passout(an,l,buf); -} - -void -isdn_info(int an, int typ, int len, char *data) -{ - int l; - char buf[64]; - u_short no; - - if(an < Isdn_Appl) - no= isdn_appl[an].typ; - else no= an&0xf; - - if(no > Isdn_Typ) no= 3; - - if(len>48) len= 48; - data[len]= 0; - l = sprintf(buf,"i %d %d %d %s", an, typ, len, data); - passout(no,l,buf); -} - -static void -isdn_check() -{ - int i; - - isdn_timeout= 0; - for(i= 0; i < Isdn_Ctrl; i++) - { - int an; - isdn_ctrl_t *ctrl = &isdn_ctrl[i]; - - if((an= ctrl->appl) < Isdn_Appl) - { - isdn_appl_t *appl = &isdn_appl[an]; - - if(appl->timeout) - { - isdn_timeout= 1; - if(time.tv_sec > (ctrl->lastact + (appl->timeout))) - { - isdn_disconnect(an,0); - break; - } - } - } - } - - if(isdn_timeout) - { - timeout(isdn_check,0,hz/2); - } -} - -void -isdn_conn_ind(int an, int cn, int dial) -{ - isdn_appl_t *appl = &isdn_appl[an]; - int l; - char buf[10]; - - if (appl->Connect) - (*appl->Connect) (appl->drivno); - - l = sprintf(buf,"C %d %d %d", an-appl_list[appl->typ], cn, dial); - passout(appl->typ,l,buf); - if((isdn_timeout == 0) && appl->timeout) - { - isdn_timeout= 1; - timeout(isdn_check,0,hz/2); - } -} - -void -isdn_disconn_ind(int an) -{ - isdn_appl_t *appl = &isdn_appl[an]; - int l; - char buf[10]; - - if(( an < 0) || (an >= Isdn_Appl)) - return; - - appl->state= 0; - if (appl->DisConn) - (*appl->DisConn) (appl->drivno); - l = sprintf(buf,"D %d", an-appl_list[appl->typ]); - passout(appl->typ,l,buf); -} - -void -isdn_disconnect(int an, int rea) -{ - isdn_appl_t *appl = &isdn_appl[an]; - - if (ISBUSY(appl->ctrl)) - { - int x; - x = splhigh(); - (*isdn_ctrl[appl->ctrl].disconnect)(appl->ctrl,rea); - splx(x); - } -} - -static void -passout(int unit, int l, char *buf) -{ - int x; - - x = splhigh(); - if ((bufind[unit] + l) >= 256) - { - splx(x); - return; - } - bcopy(buf,&buffer[unit][bufind[unit]],l); - bufind[unit] += l; - buffer[unit][bufind[unit]++]= 0; - if (r_flags & (1<<unit)) - { - r_flags &= ~(1 << unit); - wakeup((caddr_t) buffer[unit]); - } - splx(x); -} - -#endif /* NISDN > 0 */ diff --git a/sys/gnu/isdn/isdn_ioctl.h b/sys/gnu/isdn/isdn_ioctl.h deleted file mode 100644 index e0475d1..0000000 --- a/sys/gnu/isdn/isdn_ioctl.h +++ /dev/null @@ -1,175 +0,0 @@ -static char _isdn_ioctl_id[] = "@(#)$Id: isdn_ioctl.h,v 1.1 1995/02/14 15:00:35 jkh Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: isdn_ioctl.h,v $ - * Revision 1.1 1995/02/14 15:00:35 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - - -#pragma pack (1) -typedef struct -{ - u_char protokoll; - u_char length; - u_short data_length; - u_char link_addr_a; - u_char link_addr_b; - u_char modulo_mode; - u_char window_size; - u_char xid; -} dlpd_t; - -typedef struct -{ - u_char protokoll; - u_char length; - u_short lic, hic, ltc, htc, loc, hoc; - u_char modulo_mode; -}ncpd_t; - -typedef struct -{ - u_char length; - u_short lic, hic, ltc, htc, loc, hoc; - u_char modulo_mode; -}ncpi_t; - -typedef struct -{ - u_char stat; - u_char length; - u_char no[124]; -} telno_t; - -#pragma pack () - -typedef struct -{ - short appl; - dlpd_t dlpd; - ncpd_t ncpd; - u_long timeout; - u_char prot; - int (*PassUp)(); /* pass data from isdn interface upstream to appl. */ - int (*PassUpInfo)(); /* pass info from isdn interface upstream to appl. */ - int (*PassDown)(); /* get data from application */ - int (*Connect)(); /* Connect Indikation */ - int (*DisConn)(); /* Disconnect Indikation */ - short drivno; /* Number of the high level Driver */ - char ctrl; - char typ; - short state; - short listen_state; - u_long send_err; -} isdn_appl_t; - -typedef struct -{ - char ctrl; - char islisten; - short unit; - short appl; - int (*connect)(); - int (*listen)(); - int (*accept)(); - int (*disconnect)(); - int (*output)(); - int (*state)(); - short o_len; - char *o_buf; - time_t lastact; - u_long send_err; - u_long rcv_err; -} isdn_ctrl_t; - -typedef struct -{ - short appl; - dlpd_t dlpd; - ncpd_t ncpd; - u_long timeout; - u_char prot; -} isdn_param; - -typedef struct -{ - short appl; - short ctrl; - u_char b_channel; - u_long inf_mask; - u_char out_serv; - u_char out_serv_add; - u_char src_subadr; - u_char spv; - telno_t telno; -} dial_t; - -typedef struct -{ - short appl; - short ctrl; - u_long inf_mask; - u_short subadr_mask; - u_short si_mask; -} listen_t; - -#define ISBUSY(x) (((x) & 0x80) == 0) -#define ISFREE(x) (((x) & 0x80) == 0x80) -#define TELNO_VALID 1 -#define TELNO_PROMISC 2 - -#define N_ISDN_CTRL 2 - -#define ISDN_DIAL _IOWR('I',1,dial_t) -#define ISDN_LISTEN _IOWR('I',2,listen_t) -#define ISDN_ACCEPT _IOWR('I',3,int) -#define ISDN_HANGUP _IOWR('I',4,int) -#define ISDN_SET_PARAM _IOWR('I',8,isdn_param) -#define ISDN_GET_PARAM _IOWR('I',9,isdn_param) - -#ifdef KERNEL - -/* XXX should be elsewhere. */ - -/* From isdn.c. */ -void isdn_accept_con_ind __P((int an, int cn, char serv, char serv_add, - char subadr, char nl, char *num)); -void isdn_conn_ind __P((int an, int cn, int dial)); -int isdn_ctrl_attach __P((int n)); -void isdn_disconn_ind __P((int an)); -void isdn_disconnect __P((int an, int rea)); -void isdn_info __P((int an, int typ, int len, char *data)); -int isdn_input __P((int an, int len, char *buf, int dir)); -int isdn_msg __P((int an)); -int isdn_output __P((int an)); - -/* From if_ii.c. */ -int iiattach __P((int ap)); - -/* From iispy.c. */ -int ispyattach __P((int ap)); - -/* From iitel.c. */ -int itelattach __P((int ap)); - -/* From iitty.c. */ -int ityattach __P((int ap)); - -#endif /* KERNEL */ diff --git a/sys/gnu/misc/aha274x.seq b/sys/gnu/misc/aha274x.seq deleted file mode 100644 index 9b83b84..0000000 --- a/sys/gnu/misc/aha274x.seq +++ /dev/null @@ -1,1064 +0,0 @@ -# @(#)aic7xxx.seq 1.30 94/11/09 jda -# -# Adaptec 274x device driver for Linux. -# Copyright (c) 1994 The University of Calgary Department of Computer Science. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -VERSION AIC7XXX_SEQ_VERSION 1.30 - -MAXSCB-1 = 0xf - -SCSISEQ = 0x00 -SXFRCTL0 = 0x01 -SXFRCTL1 = 0x02 -SCSISIGI = 0x03 -SCSISIGO = 0x03 -SCSIRATE = 0x04 -SCSIID = 0x05 -SCSIDATL = 0x06 -STCNT = 0x08 -STCNT+0 = 0x08 -STCNT+1 = 0x09 -STCNT+2 = 0x0a -SSTAT0 = 0x0b -CLRSINT1 = 0x0c -SSTAT1 = 0x0c -SIMODE1 = 0x11 -SCSIBUSL = 0x12 -SHADDR = 0x14 -SELID = 0x19 -SBLKCTL = 0x1f -SEQCTL = 0x60 -A = 0x64 # == ACCUM -SINDEX = 0x65 -DINDEX = 0x66 -ALLZEROS = 0x6a -NONE = 0x6a -SINDIR = 0x6c -DINDIR = 0x6d -FUNCTION1 = 0x6e -HADDR = 0x88 -HCNT = 0x8c -HCNT+0 = 0x8c -HCNT+1 = 0x8d -HCNT+2 = 0x8e -SCBPTR = 0x90 -INTSTAT = 0x91 -DFCNTRL = 0x93 -DFSTATUS = 0x94 -DFDAT = 0x99 -QINFIFO = 0x9b -QINCNT = 0x9c -QOUTFIFO = 0x9d - -SCSICONF = 0x5a - -# The two reserved bytes at SCBARRAY+1[23] are expected to be set to -# zero, and the reserved bit in SCBARRAY+0 is used as an internal flag -# to indicate whether or not to reload scatter-gather parameters after -# a disconnect. -# -SCBARRAY+0 = 0xa0 -SCBARRAY+1 = 0xa1 -SCBARRAY+2 = 0xa2 -SCBARRAY+3 = 0xa3 -SCBARRAY+7 = 0xa7 -SCBARRAY+11 = 0xab -SCBARRAY+14 = 0xae -SCBARRAY+15 = 0xaf -SCBARRAY+16 = 0xb0 -SCBARRAY+17 = 0xb1 -SCBARRAY+18 = 0xb2 -SCBARRAY+19 = 0xb3 -SCBARRAY+20 = 0xb4 -SCBARRAY+21 = 0xb5 -SCBARRAY+22 = 0xb6 -SCBARRAY+23 = 0xb7 -SCBARRAY+24 = 0xb8 -SCBARRAY+25 = 0xb9 - -SIGNAL_0 = 0x01 # unknown scsi bus phase -SIGNAL_1 = 0x11 # message reject -SIGNAL_2 = 0x21 # no IDENTIFY after reconnect -SIGNAL_3 = 0x31 # no cmd match for reconnect -SIGNAL_4 = 0x41 # SDTR -> SCSIRATE conversion -STATUS_ERROR = 0x51 - -# The host adapter card (at least the BIOS) uses 20-2f for SCSI -# device information, 32-33 and 5a-5f as well. Since we don't support -# wide or twin-bus SCSI, 28-2f can be reclaimed. As it turns out, the -# BIOS trashes 20-27 anyway, writing the synchronous negotiation results -# on top of the BIOS values, so we re-use those for our per-target -# scratchspace (actually a value that can be copied directly into -# SCSIRATE). This implies, since we can't get the BIOS config values, -# that all targets will be negotiated with for synchronous transfer. -# NEEDSDTR has one bit per target indicating if an SDTR message is -# needed for that device - this will be set initially, as well as -# after a bus reset condition. -# -# The high bit of DROPATN is set if ATN should be dropped before the ACK -# when outb is called. REJBYTE contains the first byte of a MESSAGE IN -# message, so the driver can report an intelligible error if a message is -# rejected. -# -# RESELECT's high bit is true if we are currently handling a reselect; -# its next-highest bit is true ONLY IF we've seen an IDENTIFY message -# from the reselecting target. If we haven't had IDENTIFY, then we have -# no idea what the lun is, and we can't select the right SCB register -# bank, so force a kernel panic if the target attempts a data in/out or -# command phase instead of corrupting something. -# -# Note that SG_NEXT occupies four bytes. -# -SYNCNEG = 0x20 -DISC_DSB_A = 0x32 - -DROPATN = 0x30 -REJBYTE = 0x31 -RESELECT = 0x34 - -MSG_FLAGS = 0x35 -MSG_LEN = 0x36 -MSG_START+0 = 0x37 -MSG_START+1 = 0x38 -MSG_START+2 = 0x39 -MSG_START+3 = 0x3a -MSG_START+4 = 0x3b -MSG_START+5 = 0x3c --MSG_START+0 = 0xc9 # 2's complement of MSG_START+0 - -ARG_1 = 0x4c # sdtr conversion args & return -ARG_2 = 0x4d -RETURN_1 = 0x4c - -SIGSTATE = 0x4e # value written to SCSISIGO -NEEDSDTR = 0x4f # send SDTR message, 1 bit/trgt - -SG_SIZEOF = 0x8 # sizeof(struct scatterlist) -SG_NOLOAD = 0x50 # load SG pointer/length? -SG_COUNT = 0x51 # working value of SG count -SG_NEXT = 0x52 # working value of SG pointer -SG_NEXT+0 = 0x52 -SG_NEXT+1 = 0x53 -SG_NEXT+2 = 0x54 -SG_NEXT+3 = 0x55 - -SCBCOUNT = 0x56 # the actual number of SCBs -ACTIVE_A = 0x57 - -# Poll QINCNT for work - the lower three bits contain -# the number of entries in the Queue In FIFO. -# -start: - test SCSISIGI,0x4 jnz reselect # BSYI - test QINCNT,MAXSCB-1 jz start - -# We have at least one queued SCB now. Set the SCB pointer -# from the FIFO so we see the right bank of SCB registers, -# then set SCSI options and set the initiator and target -# SCSI IDs. -# - mov SCBPTR,QINFIFO - -# See if there is not already an active SCB for this target. This code -# will have to be modified when we add support for dual and wide busses. - - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - test ACTIVE_A,A jz active -# Place the currently active back on the queue for later processing - mov QINFIFO, SCBPTR - jmp start - -# Mark the current target as busy and get working on the SCB -active: - or ACTIVE_A,A - mov SCBARRAY+1 call initialize - clr SG_NOLOAD - clr RESELECT - -# As soon as we get a successful selection, the target should go -# into the message out phase since we have ATN asserted. Prepare -# the message to send, locking out the device driver. If the device -# driver hasn't beaten us with an ABORT or RESET message, then tack -# on a SDTR negotation if required. -# -# Messages are stored in scratch RAM starting with a flag byte (high bit -# set means active message), one length byte, and then the message itself. -# - mov SCBARRAY+1 call disconnect # disconnect ok? - - and SINDEX,0x7,SCBARRAY+1 # lun - or SINDEX,A # return value from disconnect - or SINDEX,0x80 call mk_mesg # IDENTIFY message - - mov A,SINDEX - cmp MSG_START+0,A jne !message # did driver beat us? - mvi MSG_START+1 call mk_sdtr # build SDTR message if needed - -!message: - -# Enable selection phase as an initiator, and do automatic ATN -# after the selection. -# - mvi SCSISEQ,0x48 # ENSELO|ENAUTOATNO - -# Wait for successful arbitration. The AIC-7770 documentation says -# that SELINGO indicates successful arbitration, and that it should -# be used to look for SELDO. However, if the sequencer is paused at -# just the right time - a parallel fsck(8) on two drives did it for -# me - then SELINGO can flip back to false before we've seen it. This -# makes the sequencer sit in the arbitration loop forever. This is -# Not Good. -# -# Therefore, I've added a check in the arbitration loop for SELDO -# too. This could arguably be made a critical section by disabling -# pauses, but I don't want to make a potentially infinite loop a CS. -# I suppose you could fold it into the select loop, too, but since -# I've been hunting this bug for four days it's kinda like a trophy. -# -arbitrate: - test SSTAT0,0x40 jnz *select # SELDO - test SSTAT0,0x10 jz arbitrate # SELINGO - -# Wait for a successful selection. If the hardware selection -# timer goes off, then the driver gets the interrupt, so we don't -# need to worry about it. -# -select: - test SSTAT0,0x40 jz select # SELDO - jmp *select - -# Reselection is being initiated by a target - we've seen the BSY -# line driven active, and we didn't do it! Enable the reselection -# hardware, and wait for it to finish. Make a note that we've been -# reselected, but haven't seen an IDENTIFY message from the target -# yet. -# -reselect: - mvi SCSISEQ,0x10 # ENRSELI - -reselect1: - test SSTAT0,0x20 jz reselect1 # SELDI - mov SELID call initialize - - mvi RESELECT,0x80 # reselected, no IDENTIFY - -# After the [re]selection, make sure that the [re]selection enable -# bit is off. This chip is flaky enough without extra things -# turned on. Also clear the BUSFREE bit in SSTAT1 since we'll be -# using it shortly. -# -*select: - clr SCSISEQ - mvi CLRSINT1,0x8 # CLRBUSFREE - -# Main loop for information transfer phases. If BSY is false, then -# we have a bus free condition, expected or not. Otherwise, wait -# for the target to assert REQ before checking MSG, C/D and I/O -# for the bus phase. -# -# We can't simply look at the values of SCSISIGI here (if we want -# to do synchronous data transfer), because the target won't assert -# REQ if it's already sent us some data that we haven't acknowledged -# yet. -# -ITloop: - test SSTAT1,0x8 jnz p_busfree # BUSFREE - test SSTAT1,0x1 jz ITloop # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - - cmp ALLZEROS,A je p_dataout - cmp A,0x40 je p_datain - cmp A,0x80 je p_command - cmp A,0xc0 je p_status - cmp A,0xa0 je p_mesgout - cmp A,0xe0 je p_mesgin - - mvi INTSTAT,SIGNAL_0 # unknown - signal driver - -p_dataout: - mvi 0 call scsisig # !CDO|!IOO|!MSGO - call assert - call sg_load - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+23 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy - - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - -# After a DMA finishes, save the final transfer pointer and count -# back into the SCB, in case a device disconnects in the middle of -# a transfer. Use SHADDR and STCNT instead of HADDR and HCNT, since -# it's a reflection of how many bytes were transferred on the SCSI -# (as opposed to the host) bus. -# - mvi A,3 - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy - - mvi A,4 - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -p_datain: - mvi 0x40 call scsisig # !CDO|IOO|!MSGO - call assert - call sg_load - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+23 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy - - mvi 0x39 call dma # SCSIEN|SDMAEN|HDMAEN| - # !DIRECTION|FIFORESET - mvi A,3 - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy - - mvi A,4 - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -# Command phase. Set up the DMA registers and let 'er rip - the -# two bytes after the SCB SCSI_cmd_length are zeroed by the driver, -# so we can copy those three bytes directly into HCNT. -# -p_command: - mvi 0x80 call scsisig # CDO|!IOO|!MSGO - call assert - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+11 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+11 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+7 call bcopy - - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - jmp ITloop - -# Status phase. Wait for the data byte to appear, then read it -# and store it into the SCB. -# -p_status: - mvi 0xc0 call scsisig # CDO|IOO|!MSGO - - mvi SCBARRAY+14 call inb - jmp ITloop - -# Message out phase. If there is no active message, but the target -# took us into this phase anyway, build a no-op message and send it. -# -p_mesgout: - mvi 0xa0 call scsisig # CDO|!IOO|MSGO - mvi 0x8 call mk_mesg # build NOP message - -# Set up automatic PIO transfer from MSG_START. Bit 3 in -# SXFRCTL0 (SPIOEN) is already on. -# - mvi SINDEX,MSG_START+0 - mov DINDEX,MSG_LEN - clr A - -# When target asks for a byte, drop ATN if it's the last one in -# the message. Otherwise, keep going until the message is exhausted. -# (We can't use outb for this since it wants the input in SINDEX.) -# -# Keep an eye out for a phase change, in case the target issues -# a MESSAGE REJECT. -# -p_mesgout2: - test SSTAT0,0x2 jz p_mesgout2 # SPIORDY - test SSTAT1,0x10 jnz p_mesgout6 # PHASEMIS - - cmp DINDEX,1 jne p_mesgout3 # last byte? - mvi CLRSINT1,0x40 # CLRATNO - drop ATN - -# Write a byte to the SCSI bus. The AIC-7770 refuses to automatically -# send ACKs in automatic PIO or DMA mode unless you make sure that the -# "expected" bus phase in SCSISIGO matches the actual bus phase. This -# behaviour is completely undocumented and caused me several days of -# grief. -# -# After plugging in different drives to test with and using a longer -# SCSI cable, I found that I/O in Automatic PIO mode ceased to function, -# especially when transferring >1 byte. It seems to be much more stable -# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is -# polled for transfer completion - for both output _and_ input. The -# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL -# is accessed (like the documentation says it does), and that on a longer -# cable run, the sequencer code was fast enough to loop back and see -# an SPIORDY that hadn't dropped yet. -# -p_mesgout3: - call one_stcnt - mov SCSIDATL,SINDIR - -p_mesgout4: - test SSTAT0,0x4 jz p_mesgout4 # SDONE - dec DINDEX - inc A - cmp MSG_LEN,A jne p_mesgout2 - -# If the next bus phase after ATN drops is a message out, it means -# that the target is requesting that the last message(s) be resent. -# -p_mesgout5: - test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE - test SSTAT1,0x1 jz p_mesgout5 # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - cmp A,0xa0 jne p_mesgout6 - mvi 0x10 call scsisig # ATNO - re-assert ATN - - jmp ITloop - -p_mesgout6: - mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS - clr MSG_FLAGS # no active msg - jmp ITloop - -# Message in phase. Bytes are read using Automatic PIO mode, but not -# using inb. This alleviates a race condition, namely that if ATN had -# to be asserted under Automatic PIO mode, it had to beat the SCSI -# circuitry sending an ACK to the target. This showed up under heavy -# loads and really confused things, since ABORT commands wouldn't be -# seen by the drive after an IDENTIFY message in until it had changed -# to a data I/O phase. -# -p_mesgin: - mvi 0xe0 call scsisig # CDO|IOO|MSGO - mvi A call inb_first # read the 1st message byte - mvi REJBYTE,A # save it for the driver - - cmp ALLZEROS,A jne p_mesgin1 - -# We got a "command complete" message, so put the SCB pointer -# into the Queue Out, and trigger a completion interrupt. -# Check status for non zero return and interrupt driver if needed -# This allows the driver to do a sense command to find out the -# source of error. We don't bother to post to the QOUTFIFO in -# the error case since it would require extra work in the kernel -# driver to ensure that the entry was removed before the command -# complete code tried processing it. - -# First, mark this target as free. - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - xor ACTIVE_A,A - - test SCBARRAY+14,0xff jz status_ok # 0 Status? - call inb_last # ack & turn auto PIO back on - mvi INTSTAT,STATUS_ERROR # let driver know - jmp ITloop -status_ok: - mov QOUTFIFO,SCBPTR - mvi INTSTAT,0x2 # CMDCMPLT - jmp p_mesgin_done - -# Is it an extended message? We only support the synchronous data -# transfer request message, which will probably be in response to -# an SDTR message out from us. If it's not an SDTR, reject it - -# apparently this can be done after any message in byte, according -# to the SCSI-2 spec. -# -# XXX - we should really reject this if we didn't initiate the SDTR -# negotiation; this may cause problems with unusual devices. -# -p_mesgin1: - cmp A,1 jne p_mesgin2 # extended message code? - - mvi A call inb_next - cmp A,3 jne p_mesginN # extended mesg length = 3 - mvi A call inb_next - cmp A,1 jne p_mesginN # SDTR code - - mvi ARG_1 call inb_next # xfer period - mvi ARG_2 call inb_next # REQ/ACK offset - mvi INTSTAT,SIGNAL_4 # call driver to convert - - call ndx_sdtr # index sync config for target - mov DINDEX,SINDEX - mov DINDIR,RETURN_1 # save returned value - - not A # turn off "need sdtr" flag - and NEEDSDTR,A - -# Even though the SCSI-2 specification says that a device responding -# to our SDTR message should honor our parameters for transmitting -# to us, it doesn't seem to work too well in real life. In particular, -# a lot of CD-ROM and tape units don't function: try using the SDTR -# parameters the device sent us for both transmitting and receiving. -# - mov SCSIRATE,RETURN_1 - jmp p_mesgin_done - -# Is it a disconnect message? Set a flag in the SCB to remind us -# and await the bus going free. -# -p_mesgin2: - cmp A,4 jne p_mesgin3 # disconnect code? - - or SCBARRAY+0,0x4 # set "disconnected" bit - jmp p_mesgin_done - -# Save data pointers message? Copy working values into the SCB, -# usually in preparation for a disconnect. -# -p_mesgin3: - cmp A,2 jne p_mesgin4 # save data pointers code? - - call sg_ram2scb - jmp p_mesgin_done - -# Restore pointers message? Data pointers are recopied from the -# SCB anyway at the start of any DMA operation, so the only thing -# to copy is the scatter-gather values. -# -p_mesgin4: - cmp A,3 jne p_mesgin5 # restore pointers code? - - call sg_scb2ram - jmp p_mesgin_done - -# Identify message? For a reconnecting target, this tells us the lun -# that the reconnection is for - find the correct SCB and switch to it, -# clearing the "disconnected" bit so we don't "find" it by accident later. -# -p_mesgin5: - test A,0x80 jz p_mesgin6 # identify message? - - test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved - - mov A call findSCB # switch to correct SCB - -# If a active message is present after calling findSCB, then either it -# or the driver is trying to abort the command. Either way, something -# untoward has happened and we should just leave it alone. -# - test MSG_FLAGS,0x80 jnz p_mesgin_done - - xor SCBARRAY+0,0x4 # clear disconnect bit in SCB - mvi RESELECT,0xc0 # make note of IDENTIFY - - call sg_scb2ram # implied restore pointers - # required on reselect - jmp p_mesgin_done - -# Message reject? If we have an outstanding SDTR negotiation, assume -# that it's a response from the target selecting asynchronous transfer, -# otherwise just ignore it since we have no clue what it pertains to. -# -# XXX - I don't have a device that responds this way. Does this code -# actually work? -# -p_mesgin6: - cmp A,7 jne p_mesgin7 # message reject code? - - and FUNCTION1,0x70,SCSIID # outstanding SDTR message? - mov A,FUNCTION1 - test NEEDSDTR,A jz p_mesgin_done # no - ignore rejection - - call ndx_sdtr # note use of asynch xfer - mov DINDEX,SINDEX - clr DINDIR - - not A # turn off "active sdtr" flag - and NEEDSDTR,A - - clr SCSIRATE # select asynch xfer - jmp p_mesgin_done - -# [ ADD MORE MESSAGE HANDLING HERE ] -# -p_mesgin7: - -# We have no idea what this message in is, and there's no way -# to pass it up to the kernel, so we issue a message reject and -# hope for the best. Since we're now using manual PIO mode to -# read in the message, there should no longer be a race condition -# present when we assert ATN. In any case, rejection should be a -# rare occurrence - signal the driver when it happens. -# -p_mesginN: - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - mvi INTSTAT,SIGNAL_1 # let driver know - - mvi 0x7 call mk_mesg # MESSAGE REJECT message - -p_mesgin_done: - call inb_last # ack & turn auto PIO back on - jmp ITloop - -# Bus free phase. It might be useful to interrupt the device -# driver if we aren't expecting this. For now, make sure that -# ATN isn't being asserted and look for a new command. -# -p_busfree: - mvi CLRSINT1,0x40 # CLRATNO - clr SIGSTATE - jmp start - -# Bcopy: number of bytes to transfer should be in A, DINDEX should -# contain the destination address, and SINDEX should contain the -# source address. All input parameters are trashed on return. -# -bcopy: - mov DINDIR,SINDIR - dec A - cmp ALLZEROS,A jne bcopy - ret - -# Locking the driver out, build a one-byte message passed in SINDEX -# if there is no active message already. SINDEX is returned intact. -# -mk_mesg: - mvi SEQCTL,0x40 # PAUSEDIS - test MSG_FLAGS,0x80 jnz mk_mesg1 # active message? - - mvi MSG_FLAGS,0x80 # if not, there is now - mvi MSG_LEN,1 # length = 1 - mov MSG_START+0,SINDEX # 1-byte message - -mk_mesg1: - clr SEQCTL # !PAUSEDIS - ret - -# Input byte in Automatic PIO mode. The address to store the byte -# in should be in SINDEX. DINDEX will be used by this routine. -# -inb: - test SSTAT0,0x2 jz inb # SPIORDY - mov DINDEX,SINDEX - call one_stcnt # xfer one byte - mov DINDIR,SCSIDATL -inb1: - test SSTAT0,0x4 jz inb1 # SDONE - wait to "finish" - ret - -# Carefully read data in Automatic PIO mode. I first tried this using -# Manual PIO mode, but it gave me continual underrun errors, probably -# indicating that I did something wrong, but I feel more secure leaving -# Automatic PIO on all the time. -# -# According to Adaptec's documentation, an ACK is not sent on input from -# the target until SCSIDATL is read from. So we wait until SCSIDATL is -# latched (the usual way), then read the data byte directly off the bus -# using SCSIBUSL. When we have pulled the ATN line, or we just want to -# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI -# spec guarantees that the target will hold the data byte on the bus until -# we send our ACK. -# -# The assumption here is that these are called in a particular sequence, -# and that REQ is already set when inb_first is called. inb_{first,next} -# use the same calling convention as inb. -# -inb_first: - mov DINDEX,SINDEX - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_next: - mov DINDEX,SINDEX # save SINDEX - - call one_stcnt # xfer one byte - mov NONE,SCSIDATL # dummy read from latch to ACK -inb_next1: - test SSTAT0,0x4 jz inb_next1 # SDONE -inb_next2: - test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_last: - call one_stcnt # ACK with dummy read - mov NONE,SCSIDATL -inb_last1: - test SSTAT0,0x4 jz inb_last1 # wait for completion - ret - -# Output byte in Automatic PIO mode. The byte to output should be -# in SINDEX. If DROPATN's high bit is set, then ATN will be dropped -# before the byte is output. -# -outb: - test SSTAT0,0x2 jz outb # SPIORDY - call one_stcnt # xfer one byte - - test DROPATN,0x80 jz outb1 - mvi CLRSINT1,0x40 # CLRATNO - clr DROPATN -outb1: - mov SCSIDATL,SINDEX -outb2: - test SSTAT0,0x4 jz outb2 # SDONE - ret - -# Write the value "1" into the STCNT registers, for Automatic PIO -# transfers. -# -one_stcnt: - clr STCNT+2 - clr STCNT+1 - mvi STCNT+0,1 ret - -# DMA data transfer. HADDR and HCNT must be loaded first, and -# SINDEX should contain the value to load DFCNTRL with - 0x3d for -# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared -# during initialization. -# -dma: - mov DFCNTRL,SINDEX -dma1: -dma2: - test SSTAT0,0x1 jnz dma3 # DMADONE - test SSTAT1,0x10 jz dma1 # PHASEMIS, ie. underrun - -# We will be "done" DMAing when the transfer count goes to zero, or -# the target changes the phase (in light of this, it makes sense that -# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are -# doing a SCSI->Host transfer, flush the data FIFO. -# -dma3: - test SINDEX,0x4 jnz dma5 # DIRECTION - and SINDEX,0xfe # mask out FIFORESET - or DFCNTRL,0x2,SINDEX # FIFOFLUSH -dma4: - test DFCNTRL,0x2 jnz dma4 # FIFOFLUSHACK - -# Now shut the DMA enables off, and copy STCNT (ie. the underrun -# amount, if any) to the SCB registers; SG_COUNT will get copied to -# the SCB's residual S/G count field after sg_advance is called. Make -# sure that the DMA enables are actually off first lest we get an ILLSADDR. -# -dma5: - clr DFCNTRL # disable DMA -dma6: - test DFCNTRL,0x38 jnz dma6 # SCSIENACK|SDMAENACK|HDMAENACK - - mvi A,3 - mvi DINDEX,SCBARRAY+15 - mvi STCNT call bcopy - - ret - -# Common SCSI initialization for selection and reselection. Expects -# the target SCSI ID to be in the upper four bits of SINDEX, and A's -# contents are stomped on return. -# -initialize: - clr SBLKCTL # channel A, !wide - and SCSIID,0xf0,SINDEX # target ID - and A,0x7,SCSICONF # SCSI_ID_A[210] - or SCSIID,A - -# Esundry initialization. -# - clr DROPATN - clr SIGSTATE - -# Turn on Automatic PIO mode now, before we expect to see an REQ -# from the target. It shouldn't hurt anything to leave it on. Set -# CLRCHN here before the target has entered a data transfer mode - -# with synchronous SCSI, if you do it later, you blow away some -# data in the SCSI FIFO that the target has already sent to you. -# - mvi SXFRCTL0,0xa # SPIOEN|CLRCHN - -# Set SCSI bus parity checking and the selection timeout value, -# and enable the hardware selection timer. Set the SELTO interrupt -# to signal the driver. -# - and A,0x38,SCSICONF # PARITY_ENB_A|SEL_TIM_A[10] - or SXFRCTL1,0x4,A # ENSTIMER - mvi SIMODE1,0x84 # ENSELTIMO|ENSCSIPERR - -# Initialize scatter-gather pointers by setting up the working copy -# in scratch RAM. -# - call sg_scb2ram - -# Initialize SCSIRATE with the appropriate value for this target. -# - call ndx_sdtr - mov SCSIRATE,SINDIR - ret - -# Assert that if we've been reselected, then we've seen an IDENTIFY -# message. -# -assert: - test RESELECT,0x80 jz assert1 # reselected? - test RESELECT,0x40 jnz assert1 # seen IDENTIFY? - - mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic - -assert1: - ret - -# Find out if disconnection is ok from the information the BIOS has left -# us. The target ID should be in the upper four bits of SINDEX; A will -# contain either 0x40 (disconnection ok) or 0x00 (diconnection not ok) -# on exit. -# -# This is the only place the target ID is limited to three bits, so we -# can use the FUNCTION1 register. -# -disconnect: - and FUNCTION1,0x70,SINDEX # strip off extra just in case - mov A,FUNCTION1 - test DISC_DSB_A,A jz disconnect1 # bit nonzero if DISabled - - clr A ret -disconnect1: - mvi A,0x40 ret - -# Locate the SCB matching the target ID in SELID and the lun in the lower -# three bits of SINDEX, and switch the SCB to it. Have the kernel print -# a warning message if it can't be found, and generate an ABORT message -# to the target. We keep the value of the t/c/l that we are trying to -# in DINDEX so it is not overwritten during our check to see if we are -# at the last SCB. -# -findSCB: - and A,0x7,SINDEX # lun in lower three bits - or DINDEX,A,SELID # can I do this? - and DINDEX,0xf7 # only channel A implemented - - clr SINDEX - -findSCB1: - mov SCBPTR,SINDEX # switch to new SCB - mov A,DINDEX - cmp SCBARRAY+1,A jne findSCB2 # target ID/channel/lun match? - test SCBARRAY+0,0x4 jz findSCB2 # should be disconnected - - ret - -findSCB2: - inc SINDEX - mov A,SCBCOUNT - cmp SINDEX,A jne findSCB1 - - mvi INTSTAT,SIGNAL_3 # not found - signal kernel - mvi 0x6 call mk_mesg # ABORT message - - or SINDEX,0x10,SIGSTATE # assert ATNO - call scsisig - ret - -# Make a working copy of the scatter-gather parameters in the SCB. -# -sg_scb2ram: - mov SG_COUNT,SCBARRAY+2 - - mvi A,4 - mvi DINDEX,SG_NEXT - mvi SCBARRAY+3 call bcopy - - mvi SG_NOLOAD,0x80 - test SCBARRAY+0,0x10 jnz sg_scb2ram1 # don't reload s/g? - clr SG_NOLOAD - -sg_scb2ram1: - ret - -# Copying RAM values back to SCB, for Save Data Pointers message. -# -sg_ram2scb: - mov SCBARRAY+2,SG_COUNT - - mvi A,4 - mvi DINDEX,SCBARRAY+3 - mvi SG_NEXT call bcopy - - and SCBARRAY+0,0xef,SCBARRAY+0 - test SG_NOLOAD,0x80 jz sg_ram2scb1 # reload s/g? - or SCBARRAY+0,0x10 - -sg_ram2scb1: - ret - -# Load a struct scatter if needed and set up the data address and -# length. If the working value of the SG count is nonzero, then -# we need to load a new set of values. -# -# This, like the above DMA, assumes a little-endian host data storage. -# -sg_load: - test SG_COUNT,0xff jz sg_load3 # SG being used? - test SG_NOLOAD,0x80 jnz sg_load3 # don't reload s/g? - - clr HCNT+2 - clr HCNT+1 - mvi HCNT+0,SG_SIZEOF - - mvi A,4 - mvi DINDEX,HADDR - mvi SG_NEXT call bcopy - - mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET - -# Wait for DMA from host memory to data FIFO to complete, then disable -# DMA and wait for it to acknowledge that it's off. -# -sg_load1: - test DFSTATUS,0x8 jz sg_load1 # HDONE - - clr DFCNTRL # disable DMA -sg_load2: - test DFCNTRL,0x8 jnz sg_load2 # HDMAENACK - -# Copy data from FIFO into SCB data pointer and data count. This assumes -# that the struct scatterlist has this structure (this and sizeof(struct -# scatterlist) == 12 are asserted in aic7xxx.c): -# -# struct scatterlist { -# char *address; /* four bytes, little-endian order */ -# ... /* four bytes, ignored */ -# unsigned short length; /* two bytes, little-endian order */ -# } -# - -# Not in FreeBSD. the scatter list is only 8 bytes. -# -# struct ahc_dma_seg { -# physaddr addr; /* four bytes, little-endian order */ -# long len; /* four bytes, little endian order */ -# }; -# - - mov SCBARRAY+19,DFDAT # new data address - mov SCBARRAY+20,DFDAT - mov SCBARRAY+21,DFDAT - mov SCBARRAY+22,DFDAT - - mov SCBARRAY+23,DFDAT - mov SCBARRAY+24,DFDAT - mov SCBARRAY+25,DFDAT - mov NONE,DFDAT #Only support 24 bit length. - -sg_load3: - ret - -# Advance the scatter-gather pointers only IF NEEDED. If SG is enabled, -# and the SCSI transfer count is zero (note that this should be called -# right after a DMA finishes), then move the working copies of the SG -# pointer/length along. If the SCSI transfer count is not zero, then -# presumably the target is disconnecting - do not reload the SG values -# next time. -# -sg_advance: - test SG_COUNT,0xff jz sg_advance2 # s/g enabled? - - test STCNT+0,0xff jnz sg_advance1 # SCSI transfer count nonzero? - test STCNT+1,0xff jnz sg_advance1 - test STCNT+2,0xff jnz sg_advance1 - - clr SG_NOLOAD # reload s/g next time - dec SG_COUNT # one less segment to go - - clr A # add sizeof(struct scatter) - add SG_NEXT+0,SG_SIZEOF,SG_NEXT+0 - adc SG_NEXT+1,A,SG_NEXT+1 - adc SG_NEXT+2,A,SG_NEXT+2 - adc SG_NEXT+3,A,SG_NEXT+3 - - ret - -sg_advance1: - mvi SG_NOLOAD,0x80 # don't reload s/g next time -sg_advance2: - ret - -# Add the array base SYNCNEG to the target offset (the target address -# is in SCSIID), and return the result in SINDEX. The accumulator -# contains the 3->8 decoding of the target ID on return. -# -ndx_sdtr: - shr A,SCSIID,4 - and A,0x7 - add SINDEX,SYNCNEG,A - - and FUNCTION1,0x70,SCSIID # 3-bit target address decode - mov A,FUNCTION1 ret - -# If we need to negotiate transfer parameters, build the SDTR message -# starting at the address passed in SINDEX. DINDEX is modified on return. -# -mk_sdtr: - mov DINDEX,SINDEX # save SINDEX - - call ndx_sdtr - test NEEDSDTR,A jnz mk_sdtr1 # do we need negotiation? - ret - -mk_sdtr1: - mvi DINDIR,1 # extended message - mvi DINDIR,3 # extended message length = 3 - mvi DINDIR,1 # SDTR code - mvi DINDIR,25 # REQ/ACK transfer period - mvi DINDIR,15 # REQ/ACK offset - - add MSG_LEN,-MSG_START+0,DINDEX # update message length - ret - -# Set SCSI bus control signal state. This also saves the last-written -# value into a location where the higher-level driver can read it - if -# it has to send an ABORT or RESET message, then it needs to know this -# so it can assert ATN without upsetting SCSISIGO. The new value is -# expected in SINDEX. Change the actual state last to avoid contention -# from the driver. -# -scsisig: - mov SIGSTATE,SINDEX - mov SCSISIGO,SINDEX ret - diff --git a/sys/gnu/misc/aha274x_seq.c b/sys/gnu/misc/aha274x_seq.c deleted file mode 100644 index 46bb647..0000000 --- a/sys/gnu/misc/aha274x_seq.c +++ /dev/null @@ -1,355 +0,0 @@ -#define AIC7XXX_SEQ_VERSION "1.30" -unsigned char seqprog[] = { - 0x04, 0x03, 0x18, 0x1a, - 0x0f, 0x9c, 0x00, 0x1e, - 0xff, 0x9b, 0x90, 0x02, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x08, 0x1e, - 0xff, 0x90, 0x9b, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0x00, 0x57, 0x57, 0x00, - 0x00, 0xa1, 0xf3, 0x16, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x34, 0x02, - 0x00, 0xa1, 0x05, 0x17, - 0x07, 0xa1, 0x65, 0x02, - 0x00, 0x65, 0x65, 0x00, - 0x80, 0x65, 0xc2, 0x16, - 0xff, 0x65, 0x64, 0x02, - 0x00, 0x37, 0x13, 0x18, - 0x38, 0x6a, 0x53, 0x17, - 0x48, 0x6a, 0x00, 0x00, - 0x40, 0x0b, 0x1c, 0x1a, - 0x10, 0x0b, 0x14, 0x1e, - 0x40, 0x0b, 0x16, 0x1e, - 0x00, 0x65, 0x1c, 0x10, - 0x10, 0x6a, 0x00, 0x00, - 0x20, 0x0b, 0x19, 0x1e, - 0x00, 0x19, 0xf3, 0x16, - 0x80, 0x6a, 0x34, 0x00, - 0xff, 0x6a, 0x00, 0x02, - 0x08, 0x6a, 0x0c, 0x00, - 0x08, 0x0c, 0xbb, 0x1a, - 0x01, 0x0c, 0x1e, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0x00, 0x6a, 0x28, 0x1c, - 0x40, 0x64, 0x3e, 0x1c, - 0x80, 0x64, 0x54, 0x1c, - 0xc0, 0x64, 0x61, 0x1c, - 0xa0, 0x64, 0x64, 0x1c, - 0xe0, 0x64, 0x7c, 0x1c, - 0x01, 0x6a, 0x91, 0x00, - 0x00, 0x6a, 0x5e, 0x17, - 0x00, 0x65, 0x01, 0x17, - 0x00, 0x65, 0x2b, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x40, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x5e, 0x17, - 0x00, 0x65, 0x01, 0x17, - 0x00, 0x65, 0x2b, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x39, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x40, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x80, 0x6a, 0x5e, 0x17, - 0x00, 0x65, 0x01, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xa7, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xc0, 0x6a, 0x5e, 0x17, - 0xae, 0x6a, 0xc9, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xa0, 0x6a, 0x5e, 0x17, - 0x08, 0x6a, 0xc2, 0x16, - 0x37, 0x6a, 0x65, 0x00, - 0xff, 0x36, 0x66, 0x02, - 0xff, 0x6a, 0x64, 0x02, - 0x02, 0x0b, 0x69, 0x1e, - 0x10, 0x0c, 0x79, 0x1a, - 0x01, 0x66, 0x6d, 0x18, - 0x40, 0x6a, 0x0c, 0x00, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x6c, 0x06, 0x02, - 0x04, 0x0b, 0x6f, 0x1e, - 0xff, 0x66, 0x66, 0x06, - 0x01, 0x64, 0x64, 0x06, - 0x00, 0x36, 0x69, 0x18, - 0x08, 0x0c, 0x79, 0x1a, - 0x01, 0x0c, 0x73, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0xa0, 0x64, 0x79, 0x18, - 0x10, 0x6a, 0x5e, 0x17, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x35, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0xe0, 0x6a, 0x5e, 0x17, - 0x64, 0x6a, 0xcf, 0x16, - 0x00, 0x6a, 0x31, 0x00, - 0x00, 0x6a, 0x8a, 0x18, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x57, 0x04, - 0xff, 0xae, 0x87, 0x1e, - 0x00, 0x65, 0xd7, 0x16, - 0x51, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x1e, 0x10, - 0xff, 0x90, 0x9d, 0x02, - 0x02, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x01, 0x64, 0x99, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x03, 0x64, 0xb5, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x01, 0x64, 0xb5, 0x18, - 0x4c, 0x6a, 0xd1, 0x16, - 0x4d, 0x6a, 0xd1, 0x16, - 0x41, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x4e, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x4c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x4c, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x04, 0x64, 0x9c, 0x18, - 0x04, 0xa0, 0xa0, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x02, 0x64, 0x9f, 0x18, - 0x00, 0x65, 0x23, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x03, 0x64, 0xa2, 0x18, - 0x00, 0x65, 0x1b, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x80, 0x64, 0xaa, 0x1e, - 0x78, 0x64, 0xb5, 0x1a, - 0x00, 0x64, 0x0a, 0x17, - 0x80, 0x35, 0xb9, 0x1a, - 0x04, 0xa0, 0xa0, 0x04, - 0xc0, 0x6a, 0x34, 0x00, - 0x00, 0x65, 0x1b, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x07, 0x64, 0xb5, 0x18, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x4f, 0xb9, 0x1e, - 0x00, 0x65, 0x4e, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x6a, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x6a, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5e, 0x17, - 0x11, 0x6a, 0x91, 0x00, - 0x07, 0x6a, 0xc2, 0x16, - 0x00, 0x65, 0xd7, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x4e, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0xff, 0x6c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x06, - 0x00, 0x6a, 0xbe, 0x18, - 0xff, 0x6a, 0x6a, 0x03, - 0x40, 0x6a, 0x60, 0x00, - 0x80, 0x35, 0xc7, 0x1a, - 0x80, 0x6a, 0x35, 0x00, - 0x01, 0x6a, 0x36, 0x00, - 0xff, 0x65, 0x37, 0x02, - 0xff, 0x6a, 0x60, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xc9, 0x1e, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6d, 0x02, - 0x04, 0x0b, 0xcd, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x12, 0x6d, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd4, 0x1e, - 0x02, 0x0b, 0xd5, 0x1e, - 0xff, 0x12, 0x6d, 0x03, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd9, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xdb, 0x1e, - 0x00, 0x65, 0xe3, 0x16, - 0x80, 0x30, 0xe0, 0x1e, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x65, 0x06, 0x02, - 0x04, 0x0b, 0xe1, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x0a, 0x02, - 0xff, 0x6a, 0x09, 0x02, - 0x01, 0x6a, 0x08, 0x01, - 0xff, 0x65, 0x93, 0x02, - 0x01, 0x0b, 0xe9, 0x1a, - 0x10, 0x0c, 0xe7, 0x1e, - 0x04, 0x65, 0xed, 0x1a, - 0xfe, 0x65, 0x65, 0x02, - 0x02, 0x65, 0x93, 0x00, - 0x02, 0x93, 0xec, 0x1a, - 0xff, 0x6a, 0x93, 0x02, - 0x38, 0x93, 0xee, 0x1a, - 0x03, 0x6a, 0x64, 0x00, - 0xaf, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x1f, 0x02, - 0xf0, 0x65, 0x05, 0x02, - 0x07, 0x5a, 0x64, 0x02, - 0x00, 0x05, 0x05, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x6a, 0x4e, 0x02, - 0x0a, 0x6a, 0x01, 0x00, - 0x38, 0x5a, 0x64, 0x02, - 0x04, 0x64, 0x02, 0x00, - 0x84, 0x6a, 0x11, 0x00, - 0x00, 0x65, 0x1b, 0x17, - 0x00, 0x65, 0x4e, 0x17, - 0xff, 0x6c, 0x04, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x34, 0x04, 0x1f, - 0x40, 0x34, 0x04, 0x1b, - 0x21, 0x6a, 0x91, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x70, 0x65, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x32, 0x09, 0x1f, - 0xff, 0x6a, 0x64, 0x03, - 0x40, 0x6a, 0x64, 0x01, - 0x07, 0x65, 0x64, 0x02, - 0x00, 0x19, 0x66, 0x00, - 0xf7, 0x66, 0x66, 0x02, - 0xff, 0x6a, 0x65, 0x02, - 0xff, 0x65, 0x90, 0x02, - 0xff, 0x66, 0x64, 0x02, - 0x00, 0xa1, 0x13, 0x19, - 0x04, 0xa0, 0x13, 0x1f, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x65, 0x65, 0x06, - 0xff, 0x56, 0x64, 0x02, - 0x00, 0x65, 0x0e, 0x19, - 0x31, 0x6a, 0x91, 0x00, - 0x06, 0x6a, 0xc2, 0x16, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5e, 0x17, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0xa2, 0x51, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0x52, 0x6a, 0x66, 0x00, - 0xa3, 0x6a, 0xbe, 0x16, - 0x80, 0x6a, 0x50, 0x00, - 0x10, 0xa0, 0x22, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0xa2, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0xa3, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0xef, 0xa0, 0xa0, 0x02, - 0x80, 0x50, 0x2a, 0x1f, - 0x10, 0xa0, 0xa0, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x3f, 0x1f, - 0x80, 0x50, 0x3f, 0x1b, - 0xff, 0x6a, 0x8e, 0x02, - 0xff, 0x6a, 0x8d, 0x02, - 0x08, 0x6a, 0x8c, 0x00, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0x0d, 0x6a, 0x93, 0x00, - 0x08, 0x94, 0x34, 0x1f, - 0xff, 0x6a, 0x93, 0x02, - 0x08, 0x93, 0x36, 0x1b, - 0xff, 0x99, 0xb3, 0x02, - 0xff, 0x99, 0xb4, 0x02, - 0xff, 0x99, 0xb5, 0x02, - 0xff, 0x99, 0xb6, 0x02, - 0xff, 0x99, 0xb7, 0x02, - 0xff, 0x99, 0xb8, 0x02, - 0xff, 0x99, 0xb9, 0x02, - 0xff, 0x99, 0x6a, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x4d, 0x1f, - 0xff, 0x08, 0x4c, 0x1b, - 0xff, 0x09, 0x4c, 0x1b, - 0xff, 0x0a, 0x4c, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x51, 0x51, 0x06, - 0xff, 0x6a, 0x64, 0x02, - 0x08, 0x52, 0x52, 0x06, - 0x00, 0x53, 0x53, 0x08, - 0x00, 0x54, 0x54, 0x08, - 0x00, 0x55, 0x55, 0x08, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x6a, 0x50, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x4c, 0x05, 0x64, 0x0a, - 0x07, 0x64, 0x64, 0x02, - 0x20, 0x64, 0x65, 0x06, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0x4e, 0x17, - 0x00, 0x4f, 0x57, 0x1b, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x6a, 0x6d, 0x00, - 0x03, 0x6a, 0x6d, 0x00, - 0x01, 0x6a, 0x6d, 0x00, - 0x19, 0x6a, 0x6d, 0x00, - 0x0f, 0x6a, 0x6d, 0x00, - 0xc9, 0x66, 0x36, 0x06, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x4e, 0x02, - 0xff, 0x65, 0x03, 0x03, -}; diff --git a/sys/gnu/misc/aic7770/COPYING b/sys/gnu/misc/aic7770/COPYING deleted file mode 100644 index a43ea21..0000000 --- a/sys/gnu/misc/aic7770/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/sys/gnu/misc/aic7770/COPYRIGHT b/sys/gnu/misc/aic7770/COPYRIGHT deleted file mode 100644 index 905285d..0000000 --- a/sys/gnu/misc/aic7770/COPYRIGHT +++ /dev/null @@ -1,16 +0,0 @@ -Adaptec 274x device driver for Linux. -Copyright (c) 1994 The University of Calgary Department of Computer Science. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/sys/gnu/misc/aic7770/README b/sys/gnu/misc/aic7770/README deleted file mode 100644 index 1e4e5a0..0000000 --- a/sys/gnu/misc/aic7770/README +++ /dev/null @@ -1,94 +0,0 @@ -@(#)README 1.16 94/11/09 jda - -AHA274x/284x DRIVER - -*** THIS SHOULD BE CONSIDERED BETA SOFTWARE *** - -BACKGROUND & LIMITATIONS - -For various reasons, we ended up with one of these cards under the -impression that support was soon forthcoming. In mid-May, I asked -Scott Ferris (the official person who's supposed to be writing this -driver) what documentation he used, _finally_ got it from Adaptec, -and started writing this driver. It is now at what I would consider -a stable state - it runs our news server and is battered by SCSI -requests 24 hours a day without dying. There are a few devices it -reportedly doesn't like working with - those are being sorted out. Due -to some unexpected equipment loans, I am able to support this at least -for the time being. - -YOU MUST HAVE THE BIOS ENABLED OR THIS WILL NOT WORK. The BIOS extracts -some configuration information that I cannot get to portably yet, as -well as provides some self-tests which this driver does not attempt to -duplicate. - -Scott's driver development is stalled for now, and after discussions -with him, this is now officially out of "pre-alpha" status and into -beta until the remaining device problems can be resolved. The latest -patches can be obtained via anonymous ftp from ftp.cpsc.ucalgary.ca in -/pub/systems/linux/aha274x. - -It supports both EISA 274x and VL-bus 284x, either single or twin-bus cards -(but not the second SCSI bus of twin cards - see aha274x.c), and supports -disconnection, synchronous SCSI, and scatter-gather. Unlike previous -versions, abort() and reset() are now implemented, and both hosts.c and -aha274x.c should give a clean compile. Code is now present to detect parity -errors, but has not been tested. - -I wrote this using a 1.0.9 kernel. Unfortunately, I'm getting tired of -#ifdef'ing everything to handle two or three different evolutionary steps -in the SCSI kernel code, so I've upgraded my system to 1.1.49, and will -only leave in code to support versions from about 1.1.45 onward. - -Thanks to patches supplied by Mark Olson <molson@tricord.com>, this driver -will now work with the 284x series (the VL-bus version of this card). The -294x (PCI-bus) support is based on patches sent to me by Mark Olson and -Alan Hourihane <alanh@fairlite.demon.co.uk>. - -Under protest, this driver is subject to the GPL - see the file -COPYING for details. - -Thanks to the following people for bug fixes/code improvements (also -thanks to the people who have sent me feedback): - - "David F. Carlson" <dave@ee.rochester.edu> - Jimen Ching <jiching@wiliki.eng.hawaii.edu> - mday@artisoft.com (Matt Day) - "Dean W. Gehnert" <deang@ims.com> - Darcy Grant <darcy@cpsc.ucalgary.ca> - Alan Hourihane <alanh@fairlite.demon.co.uk> - isely@fncrd8.fnal.gov (Mike Isely) - Mike Jerger <jerger@ux1.cso.uiuc.edu> - tm@netcom.com (Toshiyasu Morita) - neal@interact.org (Neal Norwitz) - Mark Olson <molson@tricord.com> - map@europa.ecn.uoknor.edu (Michael A. Parker) - Thomas Scheunemann <thomas@dagobert.uni-duisburg.de> - -Special thanks to Drew Eckhardt <drew@kinglear.cs.Colorado.EDU> for -fielding my questions about synchronous negotiation. Steffen Moeller -<smoe0024@rz.uni-hildesheim.de> sent me installation instructions which -were previously included in this README. - -David Pirie <pirie@cpsc.ucalgary.ca> was nice enough to loan me his -2842 card for a week so I could track down one bug, as well as his -CD-ROM drive later, and also thanks to Doug Fortune at Riley's Data Share -in Calgary, who arranged a long-term loan of a 2842 board for further work. - -Many thanks to the fearless prerelease testers! Dean Gehnert has been -building Slackware boot disks for the driver, which are available from -ftp.cpsc.ucalgary.ca in /pub/systems/linux/aha274x/slackware_boot. - -Carl Riches <cgr@poplar1.cfr.washington.edu> has set up a mailing list -for aic7xxx driver development. To subscribe, send a message to -aic7770-list@poplar1.cfr.washington.edu with a message body of: - - subscribe AIC7770-LIST <your name here, without the angle brackets> - -Please direct questions and discussions to that list instead of me. When -sending bug reports, please include a description of your hardware, the -release numbers displayed by the driver at boot time, and as accurate a -facsimilie of any error message you're mailing about. - -John Aycock -aycock@cpsc.ucalgary.ca diff --git a/sys/gnu/misc/aic7770/README-FIRST b/sys/gnu/misc/aic7770/README-FIRST deleted file mode 100644 index 056dbc8..0000000 --- a/sys/gnu/misc/aic7770/README-FIRST +++ /dev/null @@ -1,19 +0,0 @@ -This is VERY MUCH ALPHA SOFTWARE. You MUST know what you're doing to -use this, or else!!! - -Ok, everything's been renamed to reference an "aic7xxx" driver instead -of "aha274x", and a merger of the two PCI patches I had has been put in, -along with re-doing the detection and configuration routines. To summarize -the status: it compiles cleanly. I don't expect it to work off the bat, -but it's for the 294x development people to synchronize their code -together. - -The file scsi-diffs-1.1.59 is NOT a proper patch file, but some diffs -to kernel files concatenated together. I've sent these off to Drew, -but if you're testing this you'll have to apply them - it allows a -per-driver-instance can_queue variable, which for the aic7xxx driver -is the number of SCBs the card supports. - -Good luck! I await your comments.. Mark, Alan - let me know where I -broke it, please ;-) -:ja diff --git a/sys/gnu/misc/aic7770/aic7770.1 b/sys/gnu/misc/aic7770/aic7770.1 deleted file mode 100644 index 2009f8c..0000000 --- a/sys/gnu/misc/aic7770/aic7770.1 +++ /dev/null @@ -1,54 +0,0 @@ -.\" Copyright (c) 1994 -.\" Justin T. Gibbs. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Justin T. Gibbs. -.\" 4. The name of Justin T. Gibbs may not be used to endorse or promote -.\" products derived from this software without specific prior written -.\" permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JUSTIN T. GIBBS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)aic7770.1 11/15/94 -.\" -.Dd November 11, 1994 -.Dt AIC7770 1 -.Os BSD 4 -.Sh NAME -.Nm aic7770 -.Nd aic7770 SCSI controller assembler -.Sh SYNOPSIS -.Nm aic7770 -.Op Fl o destination -.Ar source-file -.Sh DESCRIPTION -.Ar Source-file -is a file containing Aic7770 compatible assembly code. The output of the -assembler defaults to -.Ar a.out -but can be optionally redirected to -.Ar destination. -.Pp -.Sh AUTHOR -This aic7770 compiler was written by John Aycock (aycock@cpsc.ucalgary.ca) and -is subject to the GNU Public License. - diff --git a/sys/gnu/misc/aic7770/aic7770.c b/sys/gnu/misc/aic7770/aic7770.c deleted file mode 100644 index 417a352..0000000 --- a/sys/gnu/misc/aic7770/aic7770.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Adaptec 274x device driver for Linux. - * Copyright (c) 1994 The University of Calgary Department of Computer Science. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Comments are started by `#' and continue to the end of the line; lines - * may be of the form: - * - * <label>* - * <label>* <undef-sym> = <value> - * <label>* <opcode> <operand>* - * - * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas - * are token separators. - */ - -/* #define _POSIX_SOURCE 1 */ -#define _POSIX_C_SOURCE 2 - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#define MEMORY 512 /* 2^9 29-bit words */ -#define MAXLINE 1024 -#define MAXTOKEN 32 -#define ADOTOUT "a.out" -#define NOVALUE -1 - -/* - * AIC-7770 register definitions - */ -#define R_SINDEX 0x65 -#define R_ALLONES 0x69 -#define R_ALLZEROS 0x6a -#define R_NONE 0x6a - -static -char sccsid[] = - "@(#)aic7770.c 1.10 94/07/22 jda"; - -int debug; -int lineno, LC; -char *filename; -FILE *ifp, *ofp; -unsigned char M[MEMORY][4]; - -void error(char *s) -{ - fprintf(stderr, "%s: %s at line %d\n", filename, s, lineno); - exit(EXIT_FAILURE); -} - -void *Malloc(size_t size) -{ - void *p = malloc(size); - if (!p) - error("out of memory"); - return(p); -} - -void *Realloc(void *ptr, size_t size) -{ - void *p = realloc(ptr, size); - if (!p) - error("out of memory"); - return(p); -} - -char *Strdup(char *s) -{ - char *p = (char *)Malloc(strlen(s) + 1); - strcpy(p, s); - return(p); -} - -typedef struct sym_t { - struct sym_t *next; /* MUST BE FIRST */ - char *name; - int value; - int npatch, *patch; -} sym_t; - -sym_t *head; - -void define(char *name, int value) -{ - sym_t *p, *q; - - for (p = head, q = (sym_t *)&head; p; p = p->next) { - if (!strcmp(p->name, name)) - error("redefined symbol"); - q = p; - } - - p = q->next = (sym_t *)Malloc(sizeof(sym_t)); - p->next = NULL; - p->name = Strdup(name); - p->value = value; - p->npatch = 0; - p->patch = NULL; - - if (debug) { - fprintf(stderr, "\"%s\" ", p->name); - if (p->value != NOVALUE) - fprintf(stderr, "defined as 0x%x\n", p->value); - else - fprintf(stderr, "undefined\n"); - } -} - -sym_t *lookup(char *name) -{ - sym_t *p; - - for (p = head; p; p = p->next) - if (!strcmp(p->name, name)) - return(p); - return(NULL); -} - -void patch(sym_t *p, int location) -{ - p->npatch += 1; - p->patch = (int *)Realloc(p->patch, p->npatch * sizeof(int *)); - - p->patch[p->npatch - 1] = location; -} - -void backpatch(void) -{ - int i; - sym_t *p; - - for (p = head; p; p = p->next) { - - if (p->value == NOVALUE) { - fprintf(stderr, - "%s: undefined symbol \"%s\"\n", - filename, p->name); - exit(EXIT_FAILURE); - } - - if (p->npatch) { - if (debug) - fprintf(stderr, - "\"%s\" (0x%x) patched at", - p->name, p->value); - - for (i = 0; i < p->npatch; i++) { - M[p->patch[i]][0] &= ~1; - M[p->patch[i]][0] |= ((p->value >> 8) & 1); - M[p->patch[i]][1] = p->value & 0xff; - - if (debug) - fprintf(stderr, " 0x%x", p->patch[i]); - } - - if (debug) - fputc('\n', stderr); - } - } -} - -/* - * Output words in byte-reversed order (least significant first) - * since the sequencer RAM is loaded that way. - */ -void output(FILE *fp) -{ - int i; - - for (i = 0; i < LC; i++) - fprintf(fp, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", - M[i][3], - M[i][2], - M[i][1], - M[i][0]); -} - -char **getl(int *n) -{ - int i; - char *p; - static char buf[MAXLINE]; - static char *a[MAXTOKEN]; - - i = 0; - - while (fgets(buf, sizeof(buf), ifp)) { - - lineno += 1; - - if (buf[strlen(buf)-1] != '\n') - error("line too long"); - - p = strchr(buf, '#'); - if (p) - *p = '\0'; - - for (p = strtok(buf, ", \t\n"); p; p = strtok(NULL, ", \t\n")) - if (i < MAXTOKEN-1) - a[i++] = p; - else - error("too many tokens"); - if (i) { - *n = i; - return(a); - } - } - return(NULL); -} - -#define A 0x8000 /* `A'ccumulator ok */ -#define I 0x4000 /* use as immediate value */ -#define SL 0x2000 /* shift left */ -#define SR 0x1000 /* shift right */ -#define RL 0x0800 /* rotate left */ -#define RR 0x0400 /* rotate right */ -#define LO 0x8000 /* lookup: ori-{jmp,jc,jnc,call} */ -#define LA 0x4000 /* lookup: and-{jz,jnz} */ -#define LX 0x2000 /* lookup: xor-{je,jne} */ -#define NA -1 /* not applicable */ - -struct { - char *name; - int n; /* number of operands, including opcode */ - unsigned int op; /* immediate or L?|pos_from_0 */ - unsigned int dest; /* NA, pos_from_0, or I|immediate */ - unsigned int src; /* NA, pos_from_0, or I|immediate */ - unsigned int imm; /* pos_from_0, A|pos_from_0, or I|immediate */ - unsigned int addr; /* NA or pos_from_0 */ - int fmt; /* instruction format - 1, 2, or 3 */ -} instr[] = { -/* - * N OP DEST SRC IMM ADDR FMT - */ - "mov", 3, 1, 1, 2, I|0xff, NA, 1, - "mov", 4, LO|2, NA, 1, I|0, 3, 3, - "mvi", 3, 0, 1, I|R_ALLZEROS, A|2, NA, 1, - "mvi", 4, LO|2, NA, I|R_ALLZEROS, 1, 3, 3, - "not", 2, 2, 1, 1, I|0xff, NA, 1, - "not", 3, 2, 1, 2, I|0xff, NA, 1, - "and", 3, 1, 1, 1, A|2, NA, 1, - "and", 4, 1, 1, 3, A|2, NA, 1, - "or", 3, 0, 1, 1, A|2, NA, 1, - "or", 4, 0, 1, 3, A|2, NA, 1, - "or", 5, LO|3, NA, 1, 2, 4, 3, - "xor", 3, 2, 1, 1, A|2, NA, 1, - "xor", 4, 2, 1, 3, A|2, NA, 1, - "nop", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1, - "inc", 2, 3, 1, 1, I|1, NA, 1, - "inc", 3, 3, 1, 2, I|1, NA, 1, - "dec", 2, 3, 1, 1, I|0xff, NA, 1, - "dec", 3, 3, 1, 2, I|0xff, NA, 1, - "jmp", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3, - "jc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3, - "jnc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3, - "call", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3, - "test", 5, LA|3, NA, 1, A|2, 4, 3, - "cmp", 5, LX|3, NA, 1, A|2, 4, 3, - "ret", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1, - "clc", 1, 3, I|R_NONE, I|R_ALLZEROS, I|1, NA, 1, - "clc", 4, 3, 2, I|R_ALLZEROS, A|3, NA, 1, - "stc", 1, 3, I|R_NONE, I|R_ALLONES, I|1, NA, 1, - "stc", 2, 3, 1, I|R_ALLONES, I|1, NA, 1, - "add", 3, 3, 1, 1, A|2, NA, 1, - "add", 4, 3, 1, 3, A|2, NA, 1, - "adc", 3, 4, 1, 1, A|2, NA, 1, - "adc", 4, 4, 1, 3, A|2, NA, 1, - "shl", 3, 5, 1, 1, SL|2, NA, 2, - "shl", 4, 5, 1, 2, SL|3, NA, 2, - "shr", 3, 5, 1, 1, SR|2, NA, 2, - "shr", 4, 5, 1, 2, SR|3, NA, 2, - "rol", 3, 5, 1, 1, RL|2, NA, 2, - "rol", 4, 5, 1, 2, RL|3, NA, 2, - "ror", 3, 5, 1, 1, RR|2, NA, 2, - "ror", 4, 5, 1, 2, RR|3, NA, 2, - /* - * Extensions (note also that mvi allows A) - */ - "clr", 2, 1, 1, I|R_ALLZEROS, I|0xff, NA, 1, - 0 -}; - -int eval_operand(char **a, int spec) -{ - int i; - unsigned int want = spec & (LO|LA|LX); - - static struct { - unsigned int what; - char *name; - int value; - } jmptab[] = { - LO, "jmp", 8, - LO, "jc", 9, - LO, "jnc", 10, - LO, "call", 11, - LA, "jz", 15, - LA, "jnz", 13, - LX, "je", 14, - LX, "jne", 12, - }; - - spec &= ~(LO|LA|LX); - - for (i = 0; i < sizeof(jmptab)/sizeof(jmptab[0]); i++) - if (jmptab[i].what == want && - !strcmp(jmptab[i].name, a[spec])) - { - return(jmptab[i].value); - } - - if (want) - error("invalid jump"); - - return(spec); /* "case 0" - no flags set */ -} - -int eval_sdi(char **a, int spec) -{ - sym_t *p; - unsigned val; - - if (spec == NA) - return(NA); - - switch (spec & (A|I|SL|SR|RL|RR)) { - case SL: - case SR: - case RL: - case RR: - if (isdigit(*a[spec &~ (SL|SR|RL|RR)])) - val = strtol(a[spec &~ (SL|SR|RL|RR)], NULL, 0); - else { - p = lookup(a[spec &~ (SL|SR|RL|RR)]); - if (!p) - error("undefined symbol used"); - val = p->value; - } - - switch (spec & (SL|SR|RL|RR)) { /* blech */ - case SL: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (val % 8)); - case SR: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (1 << 3) | - ((8 - (val % 8)) % 8)); - case RL: - return(val % 8); - case RR: - return((8 - (val % 8)) % 8); - } - case I: - return(spec &~ I); - case A: - /* - * An immediate field of zero selects - * the accumulator. Vigorously object - * if zero is given otherwise - it's - * most likely an error. - */ - spec &= ~A; - if (!strcmp("A", a[spec])) - return(0); - if (isdigit(*a[spec]) && - strtol(a[spec], NULL, 0) == 0) - { - error("immediate value of zero selects accumulator"); - } - /* falls through */ - case 0: - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - p = lookup(a[spec]); - if (p) - return(p->value); - error("undefined symbol used"); - } - - return(NA); /* shut the compiler up */ -} - -int eval_addr(char **a, int spec) -{ - sym_t *p; - - if (spec == NA) - return(NA); - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - - p = lookup(a[spec]); - - if (p) { - if (p->value != NOVALUE) - return(p->value); - patch(p, LC); - } else { - define(a[spec], NOVALUE); - p = lookup(a[spec]); - patch(p, LC); - } - - return(NA); /* will be patched in later */ -} - -int crack(char **a, int n) -{ - int i; - int I_imm, I_addr; - int I_op, I_dest, I_src, I_ret; - - /* - * Check for "ret" at the end of the line; remove - * it unless it's "ret" alone - we still want to - * look it up in the table. - */ - I_ret = (strcmp(a[n-1], "ret") ? 0 : !0); - if (I_ret && n > 1) - n -= 1; - - for (i = 0; instr[i].name; i++) { - /* - * Look for match in table given constraints, - * currently just the name and the number of - * operands. - */ - if (!strcmp(instr[i].name, *a) && instr[i].n == n) - break; - } - if (!instr[i].name) - error("unknown opcode or wrong number of operands"); - - I_op = eval_operand(a, instr[i].op); - I_src = eval_sdi(a, instr[i].src); - I_imm = eval_sdi(a, instr[i].imm); - I_dest = eval_sdi(a, instr[i].dest); - I_addr = eval_addr(a, instr[i].addr); - - switch (instr[i].fmt) { - case 1: - case 2: - M[LC][0] = (I_op << 1) | I_ret; - M[LC][1] = I_dest; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - case 3: - if (I_ret) - error("illegal use of \"ret\""); - M[LC][0] = (I_op << 1) | ((I_addr >> 8) & 1); - M[LC][1] = I_addr & 0xff; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - } - - return(1); /* no two-byte instructions yet */ -} - -#undef SL -#undef SR -#undef RL -#undef RR -#undef LX -#undef LA -#undef LO -#undef I -#undef A - -void assemble(void) -{ - int n; - char **a; - sym_t *p; - - while ((a = getl(&n))) { - - while (a[0][strlen(*a)-1] == ':') { - a[0][strlen(*a)-1] = '\0'; - p = lookup(*a); - if (p) - p->value = LC; - else - define(*a, LC); - a += 1; - n -= 1; - } - - if (!n) /* line was all labels */ - continue; - - if (n == 3 && !strcmp("VERSION", *a)) - fprintf(ofp, "#define %s \"%s\"\n", a[1], a[2]); - else { - if (n == 3 && !strcmp("=", a[1])) - define(*a, strtol(a[2], NULL, 0)); - else - LC += crack(a, n); - } - } - - backpatch(); - output(ofp); - - if (debug) - output(stderr); -} - -int main(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "dho:")) != EOF) { - switch (c) { - case 'd': - debug = !0; - break; - case 'o': - ofp = fopen(optarg, "w"); - if (!ofp) { - perror(optarg); - exit(EXIT_FAILURE); - } - break; - case 'h': - printf("usage: %s [-d] [-ooutput] input\n", *argv); - exit(EXIT_SUCCESS); - case NULL: - /* - * An impossible option to shut the compiler - * up about sccsid[]. - */ - exit((int)sccsid); - default: - exit(EXIT_FAILURE); - } - } - - if (argc - optind != 1) { - fprintf(stderr, "%s: must have one input file\n", *argv); - exit(EXIT_FAILURE); - } - filename = argv[optind]; - - ifp = fopen(filename, "r"); - if (!ifp) { - perror(filename); - exit(EXIT_FAILURE); - } - - if (!ofp) { - ofp = fopen(ADOTOUT, "w"); - if (!ofp) { - perror(ADOTOUT); - exit(EXIT_FAILURE); - } - } - - assemble(); - exit(EXIT_SUCCESS); -} diff --git a/sys/gnu/misc/aic7770/aic7770.seq b/sys/gnu/misc/aic7770/aic7770.seq deleted file mode 100644 index a112033..0000000 --- a/sys/gnu/misc/aic7770/aic7770.seq +++ /dev/null @@ -1,1157 +0,0 @@ -# @(#)aic7xxx.seq 1.31 94/11/25 jda -# -# Adaptec 274x device driver for Linux. -# Copyright (c) 1994 The University of Calgary Department of Computer Science. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -VERSION AIC7XXX_SEQ_VERSION 1.31 - -SCBMASK = 0x1f - -SCSISEQ = 0x00 -SXFRCTL0 = 0x01 -SXFRCTL1 = 0x02 -SCSISIGI = 0x03 -SCSISIGO = 0x03 -SCSIRATE = 0x04 -SCSIID = 0x05 -SCSIDATL = 0x06 -STCNT = 0x08 -STCNT+0 = 0x08 -STCNT+1 = 0x09 -STCNT+2 = 0x0a -SSTAT0 = 0x0b -CLRSINT1 = 0x0c -SSTAT1 = 0x0c -SIMODE1 = 0x11 -SCSIBUSL = 0x12 -SHADDR = 0x14 -SELID = 0x19 -SBLKCTL = 0x1f -SEQCTL = 0x60 -A = 0x64 # == ACCUM -SINDEX = 0x65 -DINDEX = 0x66 -ALLZEROS = 0x6a -NONE = 0x6a -SINDIR = 0x6c -DINDIR = 0x6d -FUNCTION1 = 0x6e -HADDR = 0x88 -HCNT = 0x8c -HCNT+0 = 0x8c -HCNT+1 = 0x8d -HCNT+2 = 0x8e -SCBPTR = 0x90 -INTSTAT = 0x91 -DFCNTRL = 0x93 -DFSTATUS = 0x94 -DFDAT = 0x99 -QINFIFO = 0x9b -QINCNT = 0x9c -QOUTFIFO = 0x9d - -SCSICONF_A = 0x5a -SCSICONF_B = 0x5b - -# The two reserved bytes at SCBARRAY+1[23] are expected to be set to -# zero, and the reserved bit in SCBARRAY+0 is used as an internal flag -# to indicate whether or not to reload scatter-gather parameters after -# a disconnect. -# -SCBARRAY+0 = 0xa0 -SCBARRAY+1 = 0xa1 -SCBARRAY+2 = 0xa2 -SCBARRAY+3 = 0xa3 -SCBARRAY+7 = 0xa7 -SCBARRAY+11 = 0xab -SCBARRAY+14 = 0xae -SCBARRAY+15 = 0xaf -SCBARRAY+16 = 0xb0 -SCBARRAY+17 = 0xb1 -SCBARRAY+18 = 0xb2 -SCBARRAY+19 = 0xb3 -SCBARRAY+20 = 0xb4 -SCBARRAY+21 = 0xb5 -SCBARRAY+22 = 0xb6 -SCBARRAY+23 = 0xb7 -SCBARRAY+24 = 0xb8 -SCBARRAY+25 = 0xb9 - -SIGNAL_0 = 0x01 # unknown scsi bus phase -SIGNAL_1 = 0x11 # message reject -SIGNAL_2 = 0x21 # no IDENTIFY after reconnect -SIGNAL_3 = 0x31 # no cmd match for reconnect -SIGNAL_4 = 0x41 # SDTR -> SCSIRATE conversion -STATUS_ERROR = 0x51 - -# The host adapter card (at least the BIOS) uses 20-2f for SCSI -# device information, 32-33 and 5a-5f as well. As it turns out, the -# BIOS trashes 20-2f, writing the synchronous negotiation results -# on top of the BIOS values, so we re-use those for our per-target -# scratchspace (actually a value that can be copied directly into -# SCSIRATE). The kernel driver will enable synchronous negotiation -# for all targets that have a value other than 0 in the lower four -# bits of the target scratch space. This should work irregardless of -# whether the bios has been installed. NEEDSDTR has one bit per target -# indicating if an SDTR message is needed for that device - this will -# be set initially (based on a search through the target scratch space), -# as well as after a bus reset condition. -# -# The high bit of DROPATN is set if ATN should be dropped before the ACK -# when outb is called. REJBYTE contains the first byte of a MESSAGE IN -# message, so the driver can report an intelligible error if a message is -# rejected. -# -# RESELECT's high bit is true if we are currently handling a reselect; -# its next-highest bit is true ONLY IF we've seen an IDENTIFY message -# from the reselecting target. If we haven't had IDENTIFY, then we have -# no idea what the lun is, and we can't select the right SCB register -# bank, so force a kernel panic if the target attempts a data in/out or -# command phase instead of corrupting something. -# -# Note that SG_NEXT occupies four bytes. -# -SYNCNEG = 0x20 - -DROPATN = 0x30 -REJBYTE = 0x31 -DISC_DSB_A = 0x32 -DISC_DSB_B = 0x33 -RESELECT = 0x34 - -MSG_FLAGS = 0x35 -MSG_LEN = 0x36 -MSG_START+0 = 0x37 -MSG_START+1 = 0x38 -MSG_START+2 = 0x39 -MSG_START+3 = 0x3a -MSG_START+4 = 0x3b -MSG_START+5 = 0x3c --MSG_START+0 = 0xc9 # 2's complement of MSG_START+0 - -ARG_1 = 0x4c # sdtr conversion args & return -RETURN_1 = 0x4c - -SIGSTATE = 0x4d # value written to SCSISIGO -NEEDSDTR_A = 0x4e # send SDTR message, 1 bit/trgt -NEEDSDTR_B = 0x4f - -SG_SIZEOF = 0x8 # sizeof(struct scatterlist) -SG_NOLOAD = 0x50 # load SG pointer/length? -SG_COUNT = 0x51 # working value of SG count -SG_NEXT = 0x52 # working value of SG pointer -SG_NEXT+0 = 0x52 -SG_NEXT+1 = 0x53 -SG_NEXT+2 = 0x54 -SG_NEXT+3 = 0x55 - -SCBCOUNT = 0x56 # the actual number of SCBs -FLAGS = 0x57 # Device configuration flags -TWIN_BUS = 0x01 -WIDE_BUS = 0x02 - -ACTIVE_A = 0x58 -ACTIVE_B = 0x59 - -# Poll QINCNT for work - the lower bits contain -# the number of entries in the Queue In FIFO. -# -start: - test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device? -# For fairness, we check the other bus first, since we just finished a -# transaction on the current channel. - xor SBLKCTL,0x08 # Toggle to the other bus - test SCSISIGI,0x4 jnz reselect # BSYI - xor SBLKCTL,0x08 # Toggle to the original bus -start2: - test SCSISIGI,0x4 jnz reselect # BSYI - test QINCNT,SCBMASK jz start - -# We have at least one queued SCB now. Set the SCB pointer -# from the FIFO so we see the right bank of SCB registers, -# then set SCSI options and set the initiator and target -# SCSI IDs. -# - mov SCBPTR,QINFIFO - -# See if there is not already an active SCB for this target. This code -# locks out on a per target basis instead of target/lun. Although this -# is not ideal for devices that have multiple luns active at the same -# time, it is faster than looping through all SCB's looking for active -# commands. It may be benificial to make findscb a more general procedure -# to see if the added cost of the search is negligible. This code also -# assumes that the kernel driver will clear the active flags on board -# initialization, board reset, and a target's SELTO. - - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel - - test ACTIVE_B,A jnz requeue - or ACTIVE_B,A # Mark the current target as busy - jmp start_scb - -# Place the currently active back on the queue for later processing -requeue: - mov QINFIFO, SCBPTR - jmp start - -test_a: - test ACTIVE_A,A jnz requeue - or ACTIVE_A,A # Mark the current target as busy - -start_scb: - and A,0x08,SCBARRAY+1 - mov SBLKCTL,A # select channel, !wide - mov SCBARRAY+1 call initialize - clr SG_NOLOAD - clr RESELECT - -# As soon as we get a successful selection, the target should go -# into the message out phase since we have ATN asserted. Prepare -# the message to send, locking out the device driver. If the device -# driver hasn't beaten us with an ABORT or RESET message, then tack -# on an SDTR negotiation if required. -# -# Messages are stored in scratch RAM starting with a flag byte (high bit -# set means active message), one length byte, and then the message itself. -# - mov SCBARRAY+1 call disconnect # disconnect ok? - - and SINDEX,0x7,SCBARRAY+1 # lun - or SINDEX,A # return value from disconnect - or SINDEX,0x80 call mk_mesg # IDENTIFY message - - mov A,SINDEX - cmp MSG_START+0,A jne !message # did driver beat us? - mvi MSG_START+1 call mk_sdtr # build SDTR message if needed - -!message: - -# Enable selection phase as an initiator, and do automatic ATN -# after the selection. -# - mvi SCSISEQ,0x48 # ENSELO|ENAUTOATNO - -# Wait for successful arbitration. The AIC-7770 documentation says -# that SELINGO indicates successful arbitration, and that it should -# be used to look for SELDO. However, if the sequencer is paused at -# just the right time - a parallel fsck(8) on two drives did it for -# me - then SELINGO can flip back to false before we've seen it. This -# makes the sequencer sit in the arbitration loop forever. This is -# Not Good. -# -# Therefore, I've added a check in the arbitration loop for SELDO -# too. This could arguably be made a critical section by disabling -# pauses, but I don't want to make a potentially infinite loop a CS. -# I suppose you could fold it into the select loop, too, but since -# I've been hunting this bug for four days it's kinda like a trophy. -# -arbitrate: - test SSTAT0,0x40 jnz *select # SELDO - test SSTAT0,0x10 jz arbitrate # SELINGO - -# Wait for a successful selection. If the hardware selection -# timer goes off, then the driver gets the interrupt, so we don't -# need to worry about it. -# -select: - test SSTAT0,0x40 jz select # SELDO - jmp *select - -# Reselection is being initiated by a target - we've seen the BSY -# line driven active, and we didn't do it! Enable the reselection -# hardware, and wait for it to finish. Make a note that we've been -# reselected, but haven't seen an IDENTIFY message from the target -# yet. -# -reselect: - mvi SCSISEQ,0x10 # ENRSELI - -reselect1: - test SSTAT0,0x20 jz reselect1 # SELDI - mov SELID call initialize - - mvi RESELECT,0x80 # reselected, no IDENTIFY - -# After the [re]selection, make sure that the [re]selection enable -# bit is off. This chip is flaky enough without extra things -# turned on. Also clear the BUSFREE bit in SSTAT1 since we'll be -# using it shortly. -# -*select: - clr SCSISEQ - mvi CLRSINT1,0x8 # CLRBUSFREE - -# Main loop for information transfer phases. If BSY is false, then -# we have a bus free condition, expected or not. Otherwise, wait -# for the target to assert REQ before checking MSG, C/D and I/O -# for the bus phase. -# -# We can't simply look at the values of SCSISIGI here (if we want -# to do synchronous data transfer), because the target won't assert -# REQ if it's already sent us some data that we haven't acknowledged -# yet. -# -ITloop: - test SSTAT1,0x8 jnz p_busfree # BUSFREE - test SSTAT1,0x1 jz ITloop # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - - cmp ALLZEROS,A je p_dataout - cmp A,0x40 je p_datain - cmp A,0x80 je p_command - cmp A,0xc0 je p_status - cmp A,0xa0 je p_mesgout - cmp A,0xe0 je p_mesgin - - mvi INTSTAT,SIGNAL_0 # unknown - signal driver - -p_dataout: - mvi 0 call scsisig # !CDO|!IOO|!MSGO - call assert - call sg_load - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+23 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy - - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - -# After a DMA finishes, save the final transfer pointer and count -# back into the SCB, in case a device disconnects in the middle of -# a transfer. Use SHADDR and STCNT instead of HADDR and HCNT, since -# it's a reflection of how many bytes were transferred on the SCSI -# (as opposed to the host) bus. -# - mvi A,3 - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy - - mvi A,4 - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -p_datain: - mvi 0x40 call scsisig # !CDO|IOO|!MSGO - call assert - call sg_load - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+23 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy - - mvi 0x39 call dma # SCSIEN|SDMAEN|HDMAEN| - # !DIRECTION|FIFORESET - mvi A,3 - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy - - mvi A,4 - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -# Command phase. Set up the DMA registers and let 'er rip - the -# two bytes after the SCB SCSI_cmd_length are zeroed by the driver, -# so we can copy those three bytes directly into HCNT. -# -p_command: - mvi 0x80 call scsisig # CDO|!IOO|!MSGO - call assert - - mvi A,3 - mvi DINDEX,HCNT - mvi SCBARRAY+11 call bcopy - - mvi A,3 - mvi DINDEX,STCNT - mvi SCBARRAY+11 call bcopy - - mvi A,4 - mvi DINDEX,HADDR - mvi SCBARRAY+7 call bcopy - - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - jmp ITloop - -# Status phase. Wait for the data byte to appear, then read it -# and store it into the SCB. -# -p_status: - mvi 0xc0 call scsisig # CDO|IOO|!MSGO - - mvi SCBARRAY+14 call inb - jmp ITloop - -# Message out phase. If there is no active message, but the target -# took us into this phase anyway, build a no-op message and send it. -# -p_mesgout: - mvi 0xa0 call scsisig # CDO|!IOO|MSGO - mvi 0x8 call mk_mesg # build NOP message - -# Set up automatic PIO transfer from MSG_START. Bit 3 in -# SXFRCTL0 (SPIOEN) is already on. -# - mvi SINDEX,MSG_START+0 - mov DINDEX,MSG_LEN - clr A - -# When target asks for a byte, drop ATN if it's the last one in -# the message. Otherwise, keep going until the message is exhausted. -# (We can't use outb for this since it wants the input in SINDEX.) -# -# Keep an eye out for a phase change, in case the target issues -# a MESSAGE REJECT. -# -p_mesgout2: - test SSTAT0,0x2 jz p_mesgout2 # SPIORDY - test SSTAT1,0x10 jnz p_mesgout6 # PHASEMIS - - cmp DINDEX,1 jne p_mesgout3 # last byte? - mvi CLRSINT1,0x40 # CLRATNO - drop ATN - -# Write a byte to the SCSI bus. The AIC-7770 refuses to automatically -# send ACKs in automatic PIO or DMA mode unless you make sure that the -# "expected" bus phase in SCSISIGO matches the actual bus phase. This -# behaviour is completely undocumented and caused me several days of -# grief. -# -# After plugging in different drives to test with and using a longer -# SCSI cable, I found that I/O in Automatic PIO mode ceased to function, -# especially when transferring >1 byte. It seems to be much more stable -# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is -# polled for transfer completion - for both output _and_ input. The -# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL -# is accessed (like the documentation says it does), and that on a longer -# cable run, the sequencer code was fast enough to loop back and see -# an SPIORDY that hadn't dropped yet. -# -p_mesgout3: - call one_stcnt - mov SCSIDATL,SINDIR - -p_mesgout4: - test SSTAT0,0x4 jz p_mesgout4 # SDONE - dec DINDEX - inc A - cmp MSG_LEN,A jne p_mesgout2 - -# If the next bus phase after ATN drops is a message out, it means -# that the target is requesting that the last message(s) be resent. -# -p_mesgout5: - test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE - test SSTAT1,0x1 jz p_mesgout5 # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - cmp A,0xa0 jne p_mesgout6 - mvi 0x10 call scsisig # ATNO - re-assert ATN - - jmp ITloop - -p_mesgout6: - mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS - clr MSG_FLAGS # no active msg - jmp ITloop - -# Message in phase. Bytes are read using Automatic PIO mode, but not -# using inb. This alleviates a race condition, namely that if ATN had -# to be asserted under Automatic PIO mode, it had to beat the SCSI -# circuitry sending an ACK to the target. This showed up under heavy -# loads and really confused things, since ABORT commands wouldn't be -# seen by the drive after an IDENTIFY message in until it had changed -# to a data I/O phase. -# -p_mesgin: - mvi 0xe0 call scsisig # CDO|IOO|MSGO - mvi A call inb_first # read the 1st message byte - mvi REJBYTE,A # save it for the driver - - cmp ALLZEROS,A jne p_mesgin1 - -# We got a "command complete" message, so put the SCB pointer -# into the Queue Out, and trigger a completion interrupt. -# Check status for non zero return and interrupt driver if needed -# This allows the driver to interpret errors only when they occur -# instead of always uploading the scb. If the status is SCSI_CHECK, -# the driver will download a new scb requesting sense, to replace -# the old one and the sequencer code will imediately jump to start -# working on it. If the kernel driver does not wish to request sense, -# the sequencer program counter is incremented by 1, preventing another run -# on the current SCB and the command is allowed to complete. We don't -# bother to post to the QOUTFIFO in the error case since it would require -# extra work in the kernel driver to ensure that the entry was removed -# before the command complete code tried processing it. - - test SCBARRAY+14,0xff jz status_ok # 0 Status? - call inb_last # ack & turn auto PIO back on - mvi INTSTAT,STATUS_ERROR # let driver know - jmp start_scb - -status_ok: - -# First, mark this target as free. - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - test SCBARRAY+1,0x88 jz clear_a - xor ACTIVE_B,A - jmp complete - -clear_a: - xor ACTIVE_A,A - -complete: - mov QOUTFIFO,SCBPTR - mvi INTSTAT,0x02 # CMDCMPLT - jmp p_mesgin_done - -# Is it an extended message? We only support the synchronous data -# transfer request message, which will probably be in response to -# an SDTR message out from us. If it's not an SDTR, reject it - -# apparently this can be done after any message in byte, according -# to the SCSI-2 spec. -# -# XXX - we should really reject this if we didn't initiate the SDTR -# negotiation; this may cause problems with unusual devices. -# -p_mesgin1: - cmp A,1 jne p_mesgin2 # extended message code? - - mvi A call inb_next - cmp A,3 jne p_mesginN # extended mesg length = 3 - mvi A call inb_next - cmp A,1 jne p_mesginN # SDTR code - - mvi ARG_1 call inb_next # xfer period - mvi A call inb_next # REQ/ACK offset - mvi INTSTAT,SIGNAL_4 # call driver to convert - - call ndx_sdtr # index sync config for target - mov DINDEX,SINDEX - not A # turn off "need sdtr" flag - test SBLKCTL,0x08 jnz p_mesgin1_b - test SCSIID,0x80 jnz p_mesgin1_b - and NEEDSDTR_A,A - jmp p_mesgin1_save - -p_mesgin1_b: - and NEEDSDTR_B,A - -p_mesgin1_save: - and A,0x80,SINDIR # get the WIDEXFER flag - or RETURN_1,A # Set WIDEXFER if necessary - mov DINDIR,RETURN_1 # save returned value - -# Even though the SCSI-2 specification says that a device responding -# to our SDTR message should honor our parameters for transmitting -# to us, it doesn't seem to work too well in real life. In particular, -# a lot of CD-ROM and tape units don't function: try using the SDTR -# parameters the device sent us for both transmitting and receiving. -# - mov SCSIRATE,RETURN_1 - jmp p_mesgin_done - -# Is it a disconnect message? Set a flag in the SCB to remind us -# and await the bus going free. -# -p_mesgin2: - cmp A,4 jne p_mesgin3 # disconnect code? - - or SCBARRAY+0,0x4 # set "disconnected" bit - jmp p_mesgin_done - -# Save data pointers message? Copy working values into the SCB, -# usually in preparation for a disconnect. -# -p_mesgin3: - cmp A,2 jne p_mesgin4 # save data pointers code? - - call sg_ram2scb - jmp p_mesgin_done - -# Restore pointers message? Data pointers are recopied from the -# SCB anyway at the start of any DMA operation, so the only thing -# to copy is the scatter-gather values. -# -p_mesgin4: - cmp A,3 jne p_mesgin5 # restore pointers code? - - call sg_scb2ram - jmp p_mesgin_done - -# Identify message? For a reconnecting target, this tells us the lun -# that the reconnection is for - find the correct SCB and switch to it, -# clearing the "disconnected" bit so we don't "find" it by accident later. -# -p_mesgin5: - test A,0x80 jz p_mesgin6 # identify message? - - test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved - - mov A call findSCB # switch to correct SCB - -# If a active message is present after calling findSCB, then either it -# or the driver is trying to abort the command. Either way, something -# untoward has happened and we should just leave it alone. -# - test MSG_FLAGS,0x80 jnz p_mesgin_done - - and SCBARRAY+0,0xfb # clear disconnect bit in SCB - mvi RESELECT,0xc0 # make note of IDENTIFY - - call sg_scb2ram # implied restore pointers - # required on reselect - jmp p_mesgin_done - -# Message reject? If we have an outstanding SDTR negotiation, assume -# that it's a response from the target selecting asynchronous transfer, -# otherwise just ignore it since we have no clue what it pertains to. -# -# XXX - I don't have a device that responds this way. Does this code -# actually work? -# -p_mesgin6: - cmp A,7 jne p_mesgin7 # message reject code? - - and FUNCTION1,0x70,SCSIID # outstanding SDTR message? - mov A,FUNCTION1 - - test SBLKCTL,0x08 jnz p_mesgin6_b - test SCSIID,0x80 jnz p_mesgin6_b - test NEEDSDTR_A,A jz p_mesgin_done # no - ignore rejection - call ndx_sdtr # note use of asynch xfer - mov DINDEX,SINDEX - clr DINDIR - - not A - and NEEDSDTR_A,A - jmp p_mesgin6_done - -p_mesgin6_b: - test NEEDSDTR_B,A jz p_mesgin_done # no - ignore rejection - call ndx_sdtr # note use of asynch xfer - mov DINDEX,SINDEX - clr DINDIR - - not A - and NEEDSDTR_B,A - -p_mesgin6_done: - - clr SCSIRATE # select asynch xfer - jmp p_mesgin_done - -# [ ADD MORE MESSAGE HANDLING HERE ] -# -p_mesgin7: - -# We have no idea what this message in is, and there's no way -# to pass it up to the kernel, so we issue a message reject and -# hope for the best. Since we're now using manual PIO mode to -# read in the message, there should no longer be a race condition -# present when we assert ATN. In any case, rejection should be a -# rare occurrence - signal the driver when it happens. -# -p_mesginN: - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - mvi INTSTAT,SIGNAL_1 # let driver know - - mvi 0x7 call mk_mesg # MESSAGE REJECT message - -p_mesgin_done: - call inb_last # ack & turn auto PIO back on - jmp ITloop - -# Bus free phase. It might be useful to interrupt the device -# driver if we aren't expecting this. For now, make sure that -# ATN isn't being asserted and look for a new command. -# -p_busfree: - mvi CLRSINT1,0x40 # CLRATNO - clr SIGSTATE - jmp start - -# Bcopy: number of bytes to transfer should be in A, DINDEX should -# contain the destination address, and SINDEX should contain the -# source address. All input parameters are trashed on return. -# -bcopy: - mov DINDIR,SINDIR - dec A - cmp ALLZEROS,A jne bcopy - ret - -# Locking the driver out, build a one-byte message passed in SINDEX -# if there is no active message already. SINDEX is returned intact. -# -mk_mesg: - mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE - test MSG_FLAGS,0x80 jnz mk_mesg1 # active message? - - mvi MSG_FLAGS,0x80 # if not, there is now - mvi MSG_LEN,1 # length = 1 - mov MSG_START+0,SINDEX # 1-byte message - -mk_mesg1: - mvi SEQCTL,0x10 # !PAUSEDIS|FASTMODE - ret - -# Input byte in Automatic PIO mode. The address to store the byte -# in should be in SINDEX. DINDEX will be used by this routine. -# -inb: - test SSTAT0,0x2 jz inb # SPIORDY - mov DINDEX,SINDEX - call one_stcnt # xfer one byte - mov DINDIR,SCSIDATL -inb1: - test SSTAT0,0x4 jz inb1 # SDONE - wait to "finish" - ret - -# Carefully read data in Automatic PIO mode. I first tried this using -# Manual PIO mode, but it gave me continual underrun errors, probably -# indicating that I did something wrong, but I feel more secure leaving -# Automatic PIO on all the time. -# -# According to Adaptec's documentation, an ACK is not sent on input from -# the target until SCSIDATL is read from. So we wait until SCSIDATL is -# latched (the usual way), then read the data byte directly off the bus -# using SCSIBUSL. When we have pulled the ATN line, or we just want to -# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI -# spec guarantees that the target will hold the data byte on the bus until -# we send our ACK. -# -# The assumption here is that these are called in a particular sequence, -# and that REQ is already set when inb_first is called. inb_{first,next} -# use the same calling convention as inb. -# -inb_first: - mov DINDEX,SINDEX - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_next: - mov DINDEX,SINDEX # save SINDEX - - call one_stcnt # xfer one byte - mov NONE,SCSIDATL # dummy read from latch to ACK -inb_next1: - test SSTAT0,0x4 jz inb_next1 # SDONE -inb_next2: - test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_last: - call one_stcnt # ACK with dummy read - mov NONE,SCSIDATL -inb_last1: - test SSTAT0,0x4 jz inb_last1 # wait for completion - ret - -# Output byte in Automatic PIO mode. The byte to output should be -# in SINDEX. If DROPATN's high bit is set, then ATN will be dropped -# before the byte is output. -# -outb: - test SSTAT0,0x2 jz outb # SPIORDY - call one_stcnt # xfer one byte - - test DROPATN,0x80 jz outb1 - mvi CLRSINT1,0x40 # CLRATNO - clr DROPATN -outb1: - mov SCSIDATL,SINDEX -outb2: - test SSTAT0,0x4 jz outb2 # SDONE - ret - -# Write the value "1" into the STCNT registers, for Automatic PIO -# transfers. -# -one_stcnt: - clr STCNT+2 - clr STCNT+1 - mvi STCNT+0,1 ret - -# DMA data transfer. HADDR and HCNT must be loaded first, and -# SINDEX should contain the value to load DFCNTRL with - 0x3d for -# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared -# during initialization. -# -dma: - mov DFCNTRL,SINDEX -dma1: -dma2: - test SSTAT0,0x1 jnz dma3 # DMADONE - test SSTAT1,0x10 jz dma1 # PHASEMIS, ie. underrun - -# We will be "done" DMAing when the transfer count goes to zero, or -# the target changes the phase (in light of this, it makes sense that -# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are -# doing a SCSI->Host transfer, the data FIFO should be flushed auto- -# magically on STCNT=0 or a phase change, so just wait for FIFO empty -# status. -# -dma3: - test SINDEX,0x4 jnz dma5 # DIRECTION -dma4: - test DFSTATUS,0x1 jz dma4 # FIFOEMP - -# Now shut the DMA enables off, and copy STCNT (ie. the underrun -# amount, if any) to the SCB registers; SG_COUNT will get copied to -# the SCB's residual S/G count field after sg_advance is called. Make -# sure that the DMA enables are actually off first lest we get an ILLSADDR. -# -dma5: - clr DFCNTRL # disable DMA -dma6: - test DFCNTRL,0x38 jnz dma6 # SCSIENACK|SDMAENACK|HDMAENACK - - mvi A,3 - mvi DINDEX,SCBARRAY+15 - mvi STCNT call bcopy - - ret - -# Common SCSI initialization for selection and reselection. Expects -# the target SCSI ID to be in the upper four bits of SINDEX, and A's -# contents are stomped on return. -# -initialize: - and SCSIID,0xf0,SINDEX # target ID - test SBLKCTL,0x08 jnz initialize_b - mvi SINDEX,SCSICONF_A - test FLAGS,WIDE_BUS jnz initialize_wide - and A,0x7,SCSICONF_A # SCSI_ID_A[210] - jmp initialize_2 -initialize_b: - and A,0x7,SCSICONF_B # SCSI_ID_B[210] - mvi SCSICONF_B jmp initialize_2 - -initialize_wide: - and A, 0xf,SCSICONF_B - -initialize_2: - or SCSIID,A - -# Esundry initialization. -# - clr DROPATN - clr SIGSTATE - -# Turn on Automatic PIO mode now, before we expect to see an REQ -# from the target. It shouldn't hurt anything to leave it on. Set -# CLRCHN here before the target has entered a data transfer mode - -# with synchronous SCSI, if you do it later, you blow away some -# data in the SCSI FIFO that the target has already sent to you. -# -# DFON is a 7870 bit enabling digital filtering of REQ and ACK signals. -# - mvi SXFRCTL0,0x8a # DFON|SPIOEN|CLRCHN - -# Set SCSI bus parity checking and the selection timeout value, -# and enable the hardware selection timer. Set the SELTO interrupt -# to signal the driver. -# -# STPWEN is 7870-specific, enabling an external termination power source. -# - and A,0x38,SINDIR # PARITY_ENB|SEL_TIM[10] - or SXFRCTL1,0x7,A # ENSTIMER|ACTNEGEN|STPWEN - mvi SIMODE1,0x84 # ENSELTIMO|ENSCSIPERR - -# Initialize scatter-gather pointers by setting up the working copy -# in scratch RAM. -# - call sg_scb2ram - -# Initialize SCSIRATE with the appropriate value for this target. -# - call ndx_sdtr - mov SCSIRATE,SINDIR - ret - -# Assert that if we've been reselected, then we've seen an IDENTIFY -# message. -# -assert: - test RESELECT,0x80 jz assert1 # reselected? - test RESELECT,0x40 jnz assert1 # seen IDENTIFY? - - mvi INTSTAT,SIGNAL_2 # no - cause a kernel panic - -assert1: - ret - -# Find out if disconnection is ok from the information the BIOS has left -# us. The tcl from SCBARRAY+1 should be in SINDEX; A will -# contain either 0x40 (disconnection ok) or 0x00 (disconnection not ok) -# on exit. -# -# To allow for wide or twin busses, we check the upper bit of the target ID -# and the channel ID and look at the appropriate disconnect register. -# -disconnect: - and FUNCTION1,0x70,SINDEX # strip off extra just in case - mov A,FUNCTION1 - test SINDEX, 0x88 jz disconnect_a - - test DISC_DSB_B,A jz disconnect1 # bit nonzero if DISabled - clr A ret - -disconnect_a: - test DISC_DSB_A,A jz disconnect1 # bit nonzero if DISabled - clr A ret - -disconnect1: - mvi A,0x40 ret - -# Locate the SCB matching the target ID in SELID and the lun in the lower -# three bits of SINDEX, and switch the SCB to it. Have the kernel print -# a warning message if it can't be found, and generate an ABORT message -# to the target. We keep the value of the t/c/l that we are trying to find -# in DINDEX so it is not overwritten during our check to see if we are -# at the last SCB. -# -findSCB: - and A,0x7,SINDEX # lun in lower three bits - or DINDEX,A,SELID - and DINDEX,0xf7 - and A,0x08,SBLKCTL # B Channel?? - or DINDEX,A - clr SINDEX - -findSCB1: - mov A,DINDEX - mov SCBPTR,SINDEX # switch to new SCB - cmp SCBARRAY+1,A jne findSCB2 # target ID/channel/lun match? - test SCBARRAY+0,0x4 jz findSCB2 # should be disconnected - ret - -findSCB2: - inc SINDEX - mov A,SCBCOUNT - cmp SINDEX,A jne findSCB1 - - mvi INTSTAT,SIGNAL_3 # not found - signal kernel - mvi 0x6 call mk_mesg # ABORT message - - or SINDEX,0x10,SIGSTATE # assert ATNO - call scsisig - ret - -# Make a working copy of the scatter-gather parameters in the SCB. -# -sg_scb2ram: - mov SG_COUNT,SCBARRAY+2 - - mvi A,4 - mvi DINDEX,SG_NEXT - mvi SCBARRAY+3 call bcopy - - mvi SG_NOLOAD,0x80 - test SCBARRAY+0,0x10 jnz sg_scb2ram1 # don't reload s/g? - clr SG_NOLOAD - -sg_scb2ram1: - ret - -# Copying RAM values back to SCB, for Save Data Pointers message. -# -sg_ram2scb: - mov SCBARRAY+2,SG_COUNT - - mvi A,4 - mvi DINDEX,SCBARRAY+3 - mvi SG_NEXT call bcopy - - and SCBARRAY+0,0xef,SCBARRAY+0 - test SG_NOLOAD,0x80 jz sg_ram2scb1 # reload s/g? - or SCBARRAY+0,0x10 - -sg_ram2scb1: - ret - -# Load a struct scatter if needed and set up the data address and -# length. If the working value of the SG count is nonzero, then -# we need to load a new set of values. -# -# This, like the above DMA, assumes a little-endian host data storage. -# -sg_load: - test SG_COUNT,0xff jz sg_load3 # SG being used? - test SG_NOLOAD,0x80 jnz sg_load3 # don't reload s/g? - - clr HCNT+2 - clr HCNT+1 - mvi HCNT+0,SG_SIZEOF - - mvi A,4 - mvi DINDEX,HADDR - mvi SG_NEXT call bcopy - - mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET - -# Wait for DMA from host memory to data FIFO to complete, then disable -# DMA and wait for it to acknowledge that it's off. -# -sg_load1: - test DFSTATUS,0x8 jz sg_load1 # HDONE - - clr DFCNTRL # disable DMA -sg_load2: - test DFCNTRL,0x8 jnz sg_load2 # HDMAENACK - -# Copy data from FIFO into SCB data pointer and data count. This assumes -# that the struct scatterlist has this structure (this and sizeof(struct -# scatterlist) == 12 are asserted in aic7xxx.c): -# -# struct scatterlist { -# char *address; /* four bytes, little-endian order */ -# ... /* four bytes, ignored */ -# unsigned short length; /* two bytes, little-endian order */ -# } -# - -# Not in FreeBSD. the scatter list is only 8 bytes. -# -# struct ahc_dma_seg { -# physaddr addr; /* four bytes, little-endian order */ -# long len; /* four bytes, little endian order */ -# }; -# - - mov SCBARRAY+19,DFDAT # new data address - mov SCBARRAY+20,DFDAT - mov SCBARRAY+21,DFDAT - mov SCBARRAY+22,DFDAT - - mov SCBARRAY+23,DFDAT - mov SCBARRAY+24,DFDAT - mov SCBARRAY+25,DFDAT - mov NONE,DFDAT #Only support 24 bit length. - -sg_load3: - ret - -# Advance the scatter-gather pointers only IF NEEDED. If SG is enabled, -# and the SCSI transfer count is zero (note that this should be called -# right after a DMA finishes), then move the working copies of the SG -# pointer/length along. If the SCSI transfer count is not zero, then -# presumably the target is disconnecting - do not reload the SG values -# next time. -# -sg_advance: - test SG_COUNT,0xff jz sg_advance2 # s/g enabled? - - test STCNT+0,0xff jnz sg_advance1 # SCSI transfer count nonzero? - test STCNT+1,0xff jnz sg_advance1 - test STCNT+2,0xff jnz sg_advance1 - - clr SG_NOLOAD # reload s/g next time - dec SG_COUNT # one less segment to go - - clr A # add sizeof(struct scatter) - add SG_NEXT+0,SG_SIZEOF,SG_NEXT+0 - adc SG_NEXT+1,A,SG_NEXT+1 - adc SG_NEXT+2,A,SG_NEXT+2 - adc SG_NEXT+3,A,SG_NEXT+3 - - ret - -sg_advance1: - mvi SG_NOLOAD,0x80 # don't reload s/g next time -sg_advance2: - ret - -# Add the array base SYNCNEG to the target offset (the target address -# is in SCSIID), and return the result in SINDEX. The accumulator -# contains the 3->8 decoding of the target ID on return. -# -ndx_sdtr: - shr A,SCSIID,4 - test SBLKCTL,0x08 jz ndx_sdtr_2 - or A,0x08 # Channel B entries add 8 -ndx_sdtr_2: - add SINDEX,SYNCNEG,A - - and FUNCTION1,0x70,SCSIID # 3-bit target address decode - mov A,FUNCTION1 ret - -# If we need to negotiate transfer parameters, build the SDTR message -# starting at the address passed in SINDEX. DINDEX is modified on return. -# -mk_sdtr: - mov DINDEX,SINDEX # save SINDEX - - call ndx_sdtr - test SCBARRAY+1,0x88 jz mk_sdtr1_a - test NEEDSDTR_B,A jnz mk_sdtr1 # do we need negotiation? - ret -mk_sdtr1_a: - test NEEDSDTR_A,A jnz mk_sdtr1 # do we need negotiation? - ret - -mk_sdtr1: - mvi DINDIR,1 # extended message - mvi DINDIR,3 # extended message length = 3 - mvi DINDIR,1 # SDTR code - mvi DINDIR,25 # REQ/ACK transfer period - mvi DINDIR,15 # REQ/ACK offset - - add MSG_LEN,-MSG_START+0,DINDEX # update message length - ret - -# Set SCSI bus control signal state. This also saves the last-written -# value into a location where the higher-level driver can read it - if -# it has to send an ABORT or RESET message, then it needs to know this -# so it can assert ATN without upsetting SCSISIGO. The new value is -# expected in SINDEX. Change the actual state last to avoid contention -# from the driver. -# -scsisig: - mov SIGSTATE,SINDEX - mov SCSISIGO,SINDEX ret diff --git a/sys/gnu/misc/aic7770/aic7770_seq.h b/sys/gnu/misc/aic7770/aic7770_seq.h deleted file mode 100644 index 24fa91b..0000000 --- a/sys/gnu/misc/aic7770/aic7770_seq.h +++ /dev/null @@ -1,351 +0,0 @@ -#define AIC7XXX_SEQ_VERSION "1.31" - 0x04, 0x03, 0x18, 0x1a, - 0x1f, 0x9c, 0x00, 0x1e, - 0xff, 0x9b, 0x90, 0x02, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x08, 0x1e, - 0xff, 0x90, 0x9b, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0x00, 0x57, 0x57, 0x00, - 0x00, 0xa1, 0xf1, 0x16, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x34, 0x02, - 0x00, 0xa1, 0x03, 0x17, - 0x07, 0xa1, 0x65, 0x02, - 0x00, 0x65, 0x65, 0x00, - 0x80, 0x65, 0xc2, 0x16, - 0xff, 0x65, 0x64, 0x02, - 0x00, 0x37, 0x13, 0x18, - 0x38, 0x6a, 0x51, 0x17, - 0x48, 0x6a, 0x00, 0x00, - 0x40, 0x0b, 0x1c, 0x1a, - 0x10, 0x0b, 0x14, 0x1e, - 0x40, 0x0b, 0x16, 0x1e, - 0x00, 0x65, 0x1c, 0x10, - 0x10, 0x6a, 0x00, 0x00, - 0x20, 0x0b, 0x19, 0x1e, - 0x00, 0x19, 0xf1, 0x16, - 0x80, 0x6a, 0x34, 0x00, - 0xff, 0x6a, 0x00, 0x02, - 0x08, 0x6a, 0x0c, 0x00, - 0x08, 0x0c, 0xbb, 0x1a, - 0x01, 0x0c, 0x1e, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0x00, 0x6a, 0x28, 0x1c, - 0x40, 0x64, 0x3e, 0x1c, - 0x80, 0x64, 0x54, 0x1c, - 0xc0, 0x64, 0x61, 0x1c, - 0xa0, 0x64, 0x64, 0x1c, - 0xe0, 0x64, 0x7c, 0x1c, - 0x01, 0x6a, 0x91, 0x00, - 0x00, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x00, 0x65, 0x29, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x3e, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x00, 0x65, 0x29, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x39, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x3e, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x80, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xa7, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xc0, 0x6a, 0x5c, 0x17, - 0xae, 0x6a, 0xc9, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xa0, 0x6a, 0x5c, 0x17, - 0x08, 0x6a, 0xc2, 0x16, - 0x37, 0x6a, 0x65, 0x00, - 0xff, 0x36, 0x66, 0x02, - 0xff, 0x6a, 0x64, 0x02, - 0x02, 0x0b, 0x69, 0x1e, - 0x10, 0x0c, 0x79, 0x1a, - 0x01, 0x66, 0x6d, 0x18, - 0x40, 0x6a, 0x0c, 0x00, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x6c, 0x06, 0x02, - 0x04, 0x0b, 0x6f, 0x1e, - 0xff, 0x66, 0x66, 0x06, - 0x01, 0x64, 0x64, 0x06, - 0x00, 0x36, 0x69, 0x18, - 0x08, 0x0c, 0x79, 0x1a, - 0x01, 0x0c, 0x73, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0xa0, 0x64, 0x79, 0x18, - 0x10, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x35, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0xe0, 0x6a, 0x5c, 0x17, - 0x64, 0x6a, 0xcf, 0x16, - 0x00, 0x6a, 0x31, 0x00, - 0x00, 0x6a, 0x8a, 0x18, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x57, 0x04, - 0xff, 0xae, 0x87, 0x1e, - 0x00, 0x65, 0xd7, 0x16, - 0x51, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x1e, 0x10, - 0xff, 0x90, 0x9d, 0x02, - 0x02, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x01, 0x64, 0x99, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x03, 0x64, 0xb5, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x01, 0x64, 0xb5, 0x18, - 0x4c, 0x6a, 0xd1, 0x16, - 0x4d, 0x6a, 0xd1, 0x16, - 0x41, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x4c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x4c, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x04, 0x64, 0x9c, 0x18, - 0x04, 0xa0, 0xa0, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x02, 0x64, 0x9f, 0x18, - 0x00, 0x65, 0x21, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x03, 0x64, 0xa2, 0x18, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x80, 0x64, 0xaa, 0x1e, - 0x78, 0x64, 0xb5, 0x1a, - 0x00, 0x64, 0x08, 0x17, - 0x80, 0x35, 0xb9, 0x1a, - 0x04, 0xa0, 0xa0, 0x04, - 0xc0, 0x6a, 0x34, 0x00, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x07, 0x64, 0xb5, 0x18, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x4f, 0xb9, 0x1e, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x6a, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x6a, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5c, 0x17, - 0x11, 0x6a, 0x91, 0x00, - 0x07, 0x6a, 0xc2, 0x16, - 0x00, 0x65, 0xd7, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x4e, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0xff, 0x6c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x06, - 0x00, 0x6a, 0xbe, 0x18, - 0xff, 0x6a, 0x6a, 0x03, - 0x50, 0x6a, 0x60, 0x00, - 0x80, 0x35, 0xc7, 0x1a, - 0x80, 0x6a, 0x35, 0x00, - 0x01, 0x6a, 0x36, 0x00, - 0xff, 0x65, 0x37, 0x02, - 0x10, 0x6a, 0x60, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xc9, 0x1e, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6d, 0x02, - 0x04, 0x0b, 0xcd, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x12, 0x6d, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd4, 0x1e, - 0x02, 0x0b, 0xd5, 0x1e, - 0xff, 0x12, 0x6d, 0x03, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd9, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xdb, 0x1e, - 0x00, 0x65, 0xe3, 0x16, - 0x80, 0x30, 0xe0, 0x1e, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x65, 0x06, 0x02, - 0x04, 0x0b, 0xe1, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x0a, 0x02, - 0xff, 0x6a, 0x09, 0x02, - 0x01, 0x6a, 0x08, 0x01, - 0xff, 0x65, 0x93, 0x02, - 0x01, 0x0b, 0xe9, 0x1a, - 0x10, 0x0c, 0xe7, 0x1e, - 0x04, 0x65, 0xeb, 0x1a, - 0x01, 0x94, 0xea, 0x1e, - 0xff, 0x6a, 0x93, 0x02, - 0x38, 0x93, 0xec, 0x1a, - 0x03, 0x6a, 0x64, 0x00, - 0xaf, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x1f, 0x02, - 0xf0, 0x65, 0x05, 0x02, - 0x07, 0x5a, 0x64, 0x02, - 0x00, 0x05, 0x05, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x6a, 0x4e, 0x02, - 0x8a, 0x6a, 0x01, 0x00, - 0x38, 0x5a, 0x64, 0x02, - 0x05, 0x64, 0x02, 0x00, - 0x84, 0x6a, 0x11, 0x00, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x6c, 0x04, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x34, 0x02, 0x1f, - 0x40, 0x34, 0x02, 0x1b, - 0x21, 0x6a, 0x91, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x70, 0x65, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x32, 0x07, 0x1f, - 0xff, 0x6a, 0x64, 0x03, - 0x40, 0x6a, 0x64, 0x01, - 0x07, 0x65, 0x64, 0x02, - 0x00, 0x19, 0x66, 0x00, - 0xf7, 0x66, 0x66, 0x02, - 0xff, 0x6a, 0x65, 0x02, - 0xff, 0x66, 0x64, 0x02, - 0xff, 0x65, 0x90, 0x02, - 0x00, 0xa1, 0x11, 0x19, - 0x04, 0xa0, 0x11, 0x1f, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x65, 0x65, 0x06, - 0xff, 0x56, 0x64, 0x02, - 0x00, 0x65, 0x0c, 0x19, - 0x31, 0x6a, 0x91, 0x00, - 0x06, 0x6a, 0xc2, 0x16, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5c, 0x17, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0xa2, 0x51, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0x52, 0x6a, 0x66, 0x00, - 0xa3, 0x6a, 0xbe, 0x16, - 0x80, 0x6a, 0x50, 0x00, - 0x10, 0xa0, 0x20, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0xa2, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0xa3, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0xef, 0xa0, 0xa0, 0x02, - 0x80, 0x50, 0x28, 0x1f, - 0x10, 0xa0, 0xa0, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x3d, 0x1f, - 0x80, 0x50, 0x3d, 0x1b, - 0xff, 0x6a, 0x8e, 0x02, - 0xff, 0x6a, 0x8d, 0x02, - 0x08, 0x6a, 0x8c, 0x00, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0x0d, 0x6a, 0x93, 0x00, - 0x08, 0x94, 0x32, 0x1f, - 0xff, 0x6a, 0x93, 0x02, - 0x08, 0x93, 0x34, 0x1b, - 0xff, 0x99, 0xb3, 0x02, - 0xff, 0x99, 0xb4, 0x02, - 0xff, 0x99, 0xb5, 0x02, - 0xff, 0x99, 0xb6, 0x02, - 0xff, 0x99, 0xb7, 0x02, - 0xff, 0x99, 0xb8, 0x02, - 0xff, 0x99, 0xb9, 0x02, - 0xff, 0x99, 0x6a, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x4b, 0x1f, - 0xff, 0x08, 0x4a, 0x1b, - 0xff, 0x09, 0x4a, 0x1b, - 0xff, 0x0a, 0x4a, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x51, 0x51, 0x06, - 0xff, 0x6a, 0x64, 0x02, - 0x08, 0x52, 0x52, 0x06, - 0x00, 0x53, 0x53, 0x08, - 0x00, 0x54, 0x54, 0x08, - 0x00, 0x55, 0x55, 0x08, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x6a, 0x50, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x4c, 0x05, 0x64, 0x0a, - 0x07, 0x64, 0x64, 0x02, - 0x20, 0x64, 0x65, 0x06, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0x4c, 0x17, - 0x00, 0x4f, 0x55, 0x1b, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x6a, 0x6d, 0x00, - 0x03, 0x6a, 0x6d, 0x00, - 0x01, 0x6a, 0x6d, 0x00, - 0x19, 0x6a, 0x6d, 0x00, - 0x0f, 0x6a, 0x6d, 0x00, - 0xc9, 0x66, 0x36, 0x06, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x4e, 0x02, - 0xff, 0x65, 0x03, 0x03, diff --git a/sys/gnu/misc/aic7xxx/COPYING b/sys/gnu/misc/aic7xxx/COPYING deleted file mode 100644 index a43ea21..0000000 --- a/sys/gnu/misc/aic7xxx/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/sys/gnu/misc/aic7xxx/COPYRIGHT b/sys/gnu/misc/aic7xxx/COPYRIGHT deleted file mode 100644 index 905285d..0000000 --- a/sys/gnu/misc/aic7xxx/COPYRIGHT +++ /dev/null @@ -1,16 +0,0 @@ -Adaptec 274x device driver for Linux. -Copyright (c) 1994 The University of Calgary Department of Computer Science. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/sys/gnu/misc/aic7xxx/README b/sys/gnu/misc/aic7xxx/README deleted file mode 100644 index 1e4e5a0..0000000 --- a/sys/gnu/misc/aic7xxx/README +++ /dev/null @@ -1,94 +0,0 @@ -@(#)README 1.16 94/11/09 jda - -AHA274x/284x DRIVER - -*** THIS SHOULD BE CONSIDERED BETA SOFTWARE *** - -BACKGROUND & LIMITATIONS - -For various reasons, we ended up with one of these cards under the -impression that support was soon forthcoming. In mid-May, I asked -Scott Ferris (the official person who's supposed to be writing this -driver) what documentation he used, _finally_ got it from Adaptec, -and started writing this driver. It is now at what I would consider -a stable state - it runs our news server and is battered by SCSI -requests 24 hours a day without dying. There are a few devices it -reportedly doesn't like working with - those are being sorted out. Due -to some unexpected equipment loans, I am able to support this at least -for the time being. - -YOU MUST HAVE THE BIOS ENABLED OR THIS WILL NOT WORK. The BIOS extracts -some configuration information that I cannot get to portably yet, as -well as provides some self-tests which this driver does not attempt to -duplicate. - -Scott's driver development is stalled for now, and after discussions -with him, this is now officially out of "pre-alpha" status and into -beta until the remaining device problems can be resolved. The latest -patches can be obtained via anonymous ftp from ftp.cpsc.ucalgary.ca in -/pub/systems/linux/aha274x. - -It supports both EISA 274x and VL-bus 284x, either single or twin-bus cards -(but not the second SCSI bus of twin cards - see aha274x.c), and supports -disconnection, synchronous SCSI, and scatter-gather. Unlike previous -versions, abort() and reset() are now implemented, and both hosts.c and -aha274x.c should give a clean compile. Code is now present to detect parity -errors, but has not been tested. - -I wrote this using a 1.0.9 kernel. Unfortunately, I'm getting tired of -#ifdef'ing everything to handle two or three different evolutionary steps -in the SCSI kernel code, so I've upgraded my system to 1.1.49, and will -only leave in code to support versions from about 1.1.45 onward. - -Thanks to patches supplied by Mark Olson <molson@tricord.com>, this driver -will now work with the 284x series (the VL-bus version of this card). The -294x (PCI-bus) support is based on patches sent to me by Mark Olson and -Alan Hourihane <alanh@fairlite.demon.co.uk>. - -Under protest, this driver is subject to the GPL - see the file -COPYING for details. - -Thanks to the following people for bug fixes/code improvements (also -thanks to the people who have sent me feedback): - - "David F. Carlson" <dave@ee.rochester.edu> - Jimen Ching <jiching@wiliki.eng.hawaii.edu> - mday@artisoft.com (Matt Day) - "Dean W. Gehnert" <deang@ims.com> - Darcy Grant <darcy@cpsc.ucalgary.ca> - Alan Hourihane <alanh@fairlite.demon.co.uk> - isely@fncrd8.fnal.gov (Mike Isely) - Mike Jerger <jerger@ux1.cso.uiuc.edu> - tm@netcom.com (Toshiyasu Morita) - neal@interact.org (Neal Norwitz) - Mark Olson <molson@tricord.com> - map@europa.ecn.uoknor.edu (Michael A. Parker) - Thomas Scheunemann <thomas@dagobert.uni-duisburg.de> - -Special thanks to Drew Eckhardt <drew@kinglear.cs.Colorado.EDU> for -fielding my questions about synchronous negotiation. Steffen Moeller -<smoe0024@rz.uni-hildesheim.de> sent me installation instructions which -were previously included in this README. - -David Pirie <pirie@cpsc.ucalgary.ca> was nice enough to loan me his -2842 card for a week so I could track down one bug, as well as his -CD-ROM drive later, and also thanks to Doug Fortune at Riley's Data Share -in Calgary, who arranged a long-term loan of a 2842 board for further work. - -Many thanks to the fearless prerelease testers! Dean Gehnert has been -building Slackware boot disks for the driver, which are available from -ftp.cpsc.ucalgary.ca in /pub/systems/linux/aha274x/slackware_boot. - -Carl Riches <cgr@poplar1.cfr.washington.edu> has set up a mailing list -for aic7xxx driver development. To subscribe, send a message to -aic7770-list@poplar1.cfr.washington.edu with a message body of: - - subscribe AIC7770-LIST <your name here, without the angle brackets> - -Please direct questions and discussions to that list instead of me. When -sending bug reports, please include a description of your hardware, the -release numbers displayed by the driver at boot time, and as accurate a -facsimilie of any error message you're mailing about. - -John Aycock -aycock@cpsc.ucalgary.ca diff --git a/sys/gnu/misc/aic7xxx/README-FIRST b/sys/gnu/misc/aic7xxx/README-FIRST deleted file mode 100644 index 056dbc8..0000000 --- a/sys/gnu/misc/aic7xxx/README-FIRST +++ /dev/null @@ -1,19 +0,0 @@ -This is VERY MUCH ALPHA SOFTWARE. You MUST know what you're doing to -use this, or else!!! - -Ok, everything's been renamed to reference an "aic7xxx" driver instead -of "aha274x", and a merger of the two PCI patches I had has been put in, -along with re-doing the detection and configuration routines. To summarize -the status: it compiles cleanly. I don't expect it to work off the bat, -but it's for the 294x development people to synchronize their code -together. - -The file scsi-diffs-1.1.59 is NOT a proper patch file, but some diffs -to kernel files concatenated together. I've sent these off to Drew, -but if you're testing this you'll have to apply them - it allows a -per-driver-instance can_queue variable, which for the aic7xxx driver -is the number of SCBs the card supports. - -Good luck! I await your comments.. Mark, Alan - let me know where I -broke it, please ;-) -:ja diff --git a/sys/gnu/misc/aic7xxx/aic7770_seq.h b/sys/gnu/misc/aic7xxx/aic7770_seq.h deleted file mode 100644 index 24fa91b..0000000 --- a/sys/gnu/misc/aic7xxx/aic7770_seq.h +++ /dev/null @@ -1,351 +0,0 @@ -#define AIC7XXX_SEQ_VERSION "1.31" - 0x04, 0x03, 0x18, 0x1a, - 0x1f, 0x9c, 0x00, 0x1e, - 0xff, 0x9b, 0x90, 0x02, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x08, 0x1e, - 0xff, 0x90, 0x9b, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0x00, 0x57, 0x57, 0x00, - 0x00, 0xa1, 0xf1, 0x16, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x34, 0x02, - 0x00, 0xa1, 0x03, 0x17, - 0x07, 0xa1, 0x65, 0x02, - 0x00, 0x65, 0x65, 0x00, - 0x80, 0x65, 0xc2, 0x16, - 0xff, 0x65, 0x64, 0x02, - 0x00, 0x37, 0x13, 0x18, - 0x38, 0x6a, 0x51, 0x17, - 0x48, 0x6a, 0x00, 0x00, - 0x40, 0x0b, 0x1c, 0x1a, - 0x10, 0x0b, 0x14, 0x1e, - 0x40, 0x0b, 0x16, 0x1e, - 0x00, 0x65, 0x1c, 0x10, - 0x10, 0x6a, 0x00, 0x00, - 0x20, 0x0b, 0x19, 0x1e, - 0x00, 0x19, 0xf1, 0x16, - 0x80, 0x6a, 0x34, 0x00, - 0xff, 0x6a, 0x00, 0x02, - 0x08, 0x6a, 0x0c, 0x00, - 0x08, 0x0c, 0xbb, 0x1a, - 0x01, 0x0c, 0x1e, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0x00, 0x6a, 0x28, 0x1c, - 0x40, 0x64, 0x3e, 0x1c, - 0x80, 0x64, 0x54, 0x1c, - 0xc0, 0x64, 0x61, 0x1c, - 0xa0, 0x64, 0x64, 0x1c, - 0xe0, 0x64, 0x7c, 0x1c, - 0x01, 0x6a, 0x91, 0x00, - 0x00, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x00, 0x65, 0x29, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x3e, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x00, 0x65, 0x29, 0x17, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xb7, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xb3, 0x6a, 0xbe, 0x16, - 0x39, 0x6a, 0xe6, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0xb7, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0xb3, 0x6a, 0x66, 0x00, - 0x14, 0x6a, 0xbe, 0x16, - 0x00, 0x65, 0x3e, 0x17, - 0xff, 0x51, 0xb2, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0x80, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0xff, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x8c, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x03, 0x6a, 0x64, 0x00, - 0x08, 0x6a, 0x66, 0x00, - 0xab, 0x6a, 0xbe, 0x16, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0xa7, 0x6a, 0xbe, 0x16, - 0x3d, 0x6a, 0xe6, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xc0, 0x6a, 0x5c, 0x17, - 0xae, 0x6a, 0xc9, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0xa0, 0x6a, 0x5c, 0x17, - 0x08, 0x6a, 0xc2, 0x16, - 0x37, 0x6a, 0x65, 0x00, - 0xff, 0x36, 0x66, 0x02, - 0xff, 0x6a, 0x64, 0x02, - 0x02, 0x0b, 0x69, 0x1e, - 0x10, 0x0c, 0x79, 0x1a, - 0x01, 0x66, 0x6d, 0x18, - 0x40, 0x6a, 0x0c, 0x00, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x6c, 0x06, 0x02, - 0x04, 0x0b, 0x6f, 0x1e, - 0xff, 0x66, 0x66, 0x06, - 0x01, 0x64, 0x64, 0x06, - 0x00, 0x36, 0x69, 0x18, - 0x08, 0x0c, 0x79, 0x1a, - 0x01, 0x0c, 0x73, 0x1e, - 0xe0, 0x03, 0x64, 0x02, - 0xa0, 0x64, 0x79, 0x18, - 0x10, 0x6a, 0x5c, 0x17, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x35, 0x02, - 0x00, 0x65, 0x1e, 0x10, - 0xe0, 0x6a, 0x5c, 0x17, - 0x64, 0x6a, 0xcf, 0x16, - 0x00, 0x6a, 0x31, 0x00, - 0x00, 0x6a, 0x8a, 0x18, - 0x70, 0xa1, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x57, 0x57, 0x04, - 0xff, 0xae, 0x87, 0x1e, - 0x00, 0x65, 0xd7, 0x16, - 0x51, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x1e, 0x10, - 0xff, 0x90, 0x9d, 0x02, - 0x02, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x01, 0x64, 0x99, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x03, 0x64, 0xb5, 0x18, - 0x64, 0x6a, 0xd1, 0x16, - 0x01, 0x64, 0xb5, 0x18, - 0x4c, 0x6a, 0xd1, 0x16, - 0x4d, 0x6a, 0xd1, 0x16, - 0x41, 0x6a, 0x91, 0x00, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x4c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x4c, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x04, 0x64, 0x9c, 0x18, - 0x04, 0xa0, 0xa0, 0x00, - 0x00, 0x65, 0xb9, 0x10, - 0x02, 0x64, 0x9f, 0x18, - 0x00, 0x65, 0x21, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x03, 0x64, 0xa2, 0x18, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x80, 0x64, 0xaa, 0x1e, - 0x78, 0x64, 0xb5, 0x1a, - 0x00, 0x64, 0x08, 0x17, - 0x80, 0x35, 0xb9, 0x1a, - 0x04, 0xa0, 0xa0, 0x04, - 0xc0, 0x6a, 0x34, 0x00, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0xb9, 0x10, - 0x07, 0x64, 0xb5, 0x18, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x4f, 0xb9, 0x1e, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x6a, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x04, - 0x00, 0x4f, 0x4f, 0x02, - 0xff, 0x6a, 0x04, 0x02, - 0x00, 0x65, 0xb9, 0x10, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5c, 0x17, - 0x11, 0x6a, 0x91, 0x00, - 0x07, 0x6a, 0xc2, 0x16, - 0x00, 0x65, 0xd7, 0x16, - 0x00, 0x65, 0x1e, 0x10, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x4e, 0x02, - 0x00, 0x65, 0x00, 0x10, - 0xff, 0x6c, 0x6d, 0x02, - 0xff, 0x64, 0x64, 0x06, - 0x00, 0x6a, 0xbe, 0x18, - 0xff, 0x6a, 0x6a, 0x03, - 0x50, 0x6a, 0x60, 0x00, - 0x80, 0x35, 0xc7, 0x1a, - 0x80, 0x6a, 0x35, 0x00, - 0x01, 0x6a, 0x36, 0x00, - 0xff, 0x65, 0x37, 0x02, - 0x10, 0x6a, 0x60, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xc9, 0x1e, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6d, 0x02, - 0x04, 0x0b, 0xcd, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0xff, 0x12, 0x6d, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd4, 0x1e, - 0x02, 0x0b, 0xd5, 0x1e, - 0xff, 0x12, 0x6d, 0x03, - 0x00, 0x65, 0xe3, 0x16, - 0xff, 0x06, 0x6a, 0x02, - 0x04, 0x0b, 0xd9, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0x02, 0x0b, 0xdb, 0x1e, - 0x00, 0x65, 0xe3, 0x16, - 0x80, 0x30, 0xe0, 0x1e, - 0x40, 0x6a, 0x0c, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x65, 0x06, 0x02, - 0x04, 0x0b, 0xe1, 0x1e, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x0a, 0x02, - 0xff, 0x6a, 0x09, 0x02, - 0x01, 0x6a, 0x08, 0x01, - 0xff, 0x65, 0x93, 0x02, - 0x01, 0x0b, 0xe9, 0x1a, - 0x10, 0x0c, 0xe7, 0x1e, - 0x04, 0x65, 0xeb, 0x1a, - 0x01, 0x94, 0xea, 0x1e, - 0xff, 0x6a, 0x93, 0x02, - 0x38, 0x93, 0xec, 0x1a, - 0x03, 0x6a, 0x64, 0x00, - 0xaf, 0x6a, 0x66, 0x00, - 0x08, 0x6a, 0xbe, 0x16, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x6a, 0x1f, 0x02, - 0xf0, 0x65, 0x05, 0x02, - 0x07, 0x5a, 0x64, 0x02, - 0x00, 0x05, 0x05, 0x00, - 0xff, 0x6a, 0x30, 0x02, - 0xff, 0x6a, 0x4e, 0x02, - 0x8a, 0x6a, 0x01, 0x00, - 0x38, 0x5a, 0x64, 0x02, - 0x05, 0x64, 0x02, 0x00, - 0x84, 0x6a, 0x11, 0x00, - 0x00, 0x65, 0x19, 0x17, - 0x00, 0x65, 0x4c, 0x17, - 0xff, 0x6c, 0x04, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x34, 0x02, 0x1f, - 0x40, 0x34, 0x02, 0x1b, - 0x21, 0x6a, 0x91, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x70, 0x65, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x02, - 0x00, 0x32, 0x07, 0x1f, - 0xff, 0x6a, 0x64, 0x03, - 0x40, 0x6a, 0x64, 0x01, - 0x07, 0x65, 0x64, 0x02, - 0x00, 0x19, 0x66, 0x00, - 0xf7, 0x66, 0x66, 0x02, - 0xff, 0x6a, 0x65, 0x02, - 0xff, 0x66, 0x64, 0x02, - 0xff, 0x65, 0x90, 0x02, - 0x00, 0xa1, 0x11, 0x19, - 0x04, 0xa0, 0x11, 0x1f, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x65, 0x65, 0x06, - 0xff, 0x56, 0x64, 0x02, - 0x00, 0x65, 0x0c, 0x19, - 0x31, 0x6a, 0x91, 0x00, - 0x06, 0x6a, 0xc2, 0x16, - 0x10, 0x4e, 0x65, 0x00, - 0x00, 0x65, 0x5c, 0x17, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0xa2, 0x51, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0x52, 0x6a, 0x66, 0x00, - 0xa3, 0x6a, 0xbe, 0x16, - 0x80, 0x6a, 0x50, 0x00, - 0x10, 0xa0, 0x20, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0xa2, 0x02, - 0x04, 0x6a, 0x64, 0x00, - 0xa3, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0xef, 0xa0, 0xa0, 0x02, - 0x80, 0x50, 0x28, 0x1f, - 0x10, 0xa0, 0xa0, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x3d, 0x1f, - 0x80, 0x50, 0x3d, 0x1b, - 0xff, 0x6a, 0x8e, 0x02, - 0xff, 0x6a, 0x8d, 0x02, - 0x08, 0x6a, 0x8c, 0x00, - 0x04, 0x6a, 0x64, 0x00, - 0x88, 0x6a, 0x66, 0x00, - 0x52, 0x6a, 0xbe, 0x16, - 0x0d, 0x6a, 0x93, 0x00, - 0x08, 0x94, 0x32, 0x1f, - 0xff, 0x6a, 0x93, 0x02, - 0x08, 0x93, 0x34, 0x1b, - 0xff, 0x99, 0xb3, 0x02, - 0xff, 0x99, 0xb4, 0x02, - 0xff, 0x99, 0xb5, 0x02, - 0xff, 0x99, 0xb6, 0x02, - 0xff, 0x99, 0xb7, 0x02, - 0xff, 0x99, 0xb8, 0x02, - 0xff, 0x99, 0xb9, 0x02, - 0xff, 0x99, 0x6a, 0x02, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x51, 0x4b, 0x1f, - 0xff, 0x08, 0x4a, 0x1b, - 0xff, 0x09, 0x4a, 0x1b, - 0xff, 0x0a, 0x4a, 0x1b, - 0xff, 0x6a, 0x50, 0x02, - 0xff, 0x51, 0x51, 0x06, - 0xff, 0x6a, 0x64, 0x02, - 0x08, 0x52, 0x52, 0x06, - 0x00, 0x53, 0x53, 0x08, - 0x00, 0x54, 0x54, 0x08, - 0x00, 0x55, 0x55, 0x08, - 0xff, 0x6a, 0x6a, 0x03, - 0x80, 0x6a, 0x50, 0x00, - 0xff, 0x6a, 0x6a, 0x03, - 0x4c, 0x05, 0x64, 0x0a, - 0x07, 0x64, 0x64, 0x02, - 0x20, 0x64, 0x65, 0x06, - 0x70, 0x05, 0x6e, 0x02, - 0xff, 0x6e, 0x64, 0x03, - 0xff, 0x65, 0x66, 0x02, - 0x00, 0x65, 0x4c, 0x17, - 0x00, 0x4f, 0x55, 0x1b, - 0xff, 0x6a, 0x6a, 0x03, - 0x01, 0x6a, 0x6d, 0x00, - 0x03, 0x6a, 0x6d, 0x00, - 0x01, 0x6a, 0x6d, 0x00, - 0x19, 0x6a, 0x6d, 0x00, - 0x0f, 0x6a, 0x6d, 0x00, - 0xc9, 0x66, 0x36, 0x06, - 0xff, 0x6a, 0x6a, 0x03, - 0xff, 0x65, 0x4e, 0x02, - 0xff, 0x65, 0x03, 0x03, diff --git a/sys/gnu/misc/aic7xxx/aic7xxx.1 b/sys/gnu/misc/aic7xxx/aic7xxx.1 deleted file mode 100644 index 2ff33b7..0000000 --- a/sys/gnu/misc/aic7xxx/aic7xxx.1 +++ /dev/null @@ -1,70 +0,0 @@ -.\" Copyright (c) 1994, 1995 -.\" Justin T. Gibbs. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" -.Dd November 11, 1994 -.Dt AIC7XXX_ASM 1 -.Os BSD 4 -.Sh NAME -.Nm aic7xxx_asm -.Nd Assembler for the Adaptec aic7xxx family of asics -.Sh SYNOPSIS -.Nm aic7xxx_asm -.Op Fl d -.Op Fl D Ar variable=value -.Op Fl v -.Op Fl o Ar file -.Ar source-file -.Sh DESCRIPTION -The Adaptec aic7xxx family of asics are single chip SCSI controllers with a -RISC like command processor. This assembler parses the language outlined -in the Adaptec technical document -.%T "AIC-7770 (EISA/ISA Bus Master Single-Chip SCSI Host Adaptor) Data Book" -and produces ascii output intended for a C byte array. -.Pp -The aic7xxx assembler is required to compile kernels with aic7xxx SCSI -adaptor support (AHA-274x, AHA-284x, AHA-294x controllers) and is compiled, -installed, and used automatically in the kernel compile directory when -necessary. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl D Ar variable=value -Define -.Ar variable -to be -.Ar value -in the global context -.It Fl d -Turn on debugging -.It Fl v -Print version information -.It Fl o Ar file -Redirect assembler output to -.Ar file -.Pp -.Sh AUTHOR -This aic7770 assembler was written by -John Aycock (aycock@cpsc.ucalgary.ca) diff --git a/sys/gnu/misc/aic7xxx/aic7xxx.c b/sys/gnu/misc/aic7xxx/aic7xxx.c deleted file mode 100644 index 5f910d4..0000000 --- a/sys/gnu/misc/aic7xxx/aic7xxx.c +++ /dev/null @@ -1,643 +0,0 @@ -/*+M************************************************************************* - * Adaptec AIC7770/AIC7870 sequencer code assembler. - * - * Copyright (c) 1994 John Aycock - * The University of Calgary Department of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of Calgary - * Department of Computer Science and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Comments are started by `#' and continue to the end of the line; lines - * may be of the form: - * <label>* - * <label>* <undef-sym> = <value> - * <label>* <opcode> <operand>* - * - * A <label> is an <undef-sym> ending in a colon. Spaces, tabs, and commas - * are token separators. - * - *-M*************************************************************************/ -static char id[] = "$Id$"; -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#define MEMORY 448 -#define MAXLINE 1024 -#define MAXTOKEN 32 -#define ADOTOUT "a.out" -#define NOVALUE -1 - -/* - * AIC-7770/AIC-7870 register definitions - */ -#define R_SINDEX 0x65 -#define R_ALLONES 0x69 -#define R_ALLZEROS 0x6a -#define R_NONE 0x6a - -int debug; -int lineno, LC; -char *filename; -FILE *ifp, *ofp; -unsigned char M[MEMORY][4]; - -void -error(char *s) -{ - fprintf(stderr, "%s: %s at line %d\n", filename, s, lineno); - exit(EXIT_FAILURE); -} - -void * -Malloc(size_t size) -{ - void *p = malloc(size); - if (!p) - error("out of memory"); - return(p); -} - -void * -Realloc(void *ptr, size_t size) -{ - void *p = realloc(ptr, size); - if (!p) - error("out of memory"); - return(p); -} - -char * -Strdup(char *s) -{ - char *p = (char *)Malloc(strlen(s) + 1); - strcpy(p, s); - return(p); -} - -typedef struct sym_t { - struct sym_t *next; /* MUST BE FIRST */ - char *name; - int value; - int npatch; - int *patch; -} sym_t; - -sym_t *head; - -void -define(char *name, int value) -{ - sym_t *p, *q; - - for (p = head, q = (sym_t *)&head; p; p = p->next) { - if (!strcmp(p->name, name)) - error("redefined symbol"); - q = p; - } - - p = q->next = (sym_t *)Malloc(sizeof(sym_t)); - p->next = NULL; - p->name = Strdup(name); - p->value = value; - p->npatch = 0; - p->patch = NULL; - - if (debug) { - fprintf(stderr, "\"%s\" ", p->name); - if (p->value != NOVALUE) - fprintf(stderr, "defined as 0x%x\n", p->value); - else - fprintf(stderr, "undefined\n"); - } -} - -sym_t * -lookup(char *name) -{ - sym_t *p; - - for (p = head; p; p = p->next) - if (!strcmp(p->name, name)) - return(p); - return(NULL); -} - -void -patch(sym_t *p, int location) -{ - p->npatch += 1; - p->patch = (int *)Realloc(p->patch, p->npatch * sizeof(int *)); - - p->patch[p->npatch - 1] = location; -} - -void backpatch(void) -{ - int i; - sym_t *p; - - for (p = head; p; p = p->next) { - - if (p->value == NOVALUE) { - fprintf(stderr, - "%s: undefined symbol \"%s\"\n", - filename, p->name); - exit(EXIT_FAILURE); - } - - if (p->npatch) { - if (debug) - fprintf(stderr, - "\"%s\" (0x%x) patched at", - p->name, p->value); - - for (i = 0; i < p->npatch; i++) { - M[p->patch[i]][0] &= ~1; - M[p->patch[i]][0] |= ((p->value >> 8) & 1); - M[p->patch[i]][1] = p->value & 0xff; - - if (debug) - fprintf(stderr, " 0x%x", p->patch[i]); - } - - if (debug) - fputc('\n', stderr); - } - } -} - -/* - * Output words in byte-reversed order (least significant first) - * since the sequencer RAM is loaded that way. - */ -void -output(FILE *fp) -{ - int i; - - for (i = 0; i < LC; i++) - fprintf(fp, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", - M[i][3], - M[i][2], - M[i][1], - M[i][0]); - printf("%d out of %d instructions used.\n", LC, MEMORY); -} - -char ** -getl(int *n) -{ - int i; - char *p, *quote; - static char buf[MAXLINE]; - static char *a[MAXTOKEN]; - - i = 0; - - while (fgets(buf, sizeof(buf), ifp)) { - - lineno += 1; - - if (buf[strlen(buf)-1] != '\n') - error("line too long"); - - p = strchr(buf, '#'); - if (p) - *p = '\0'; - p = buf; -rescan: - quote = strchr(p, '\"'); - if (quote) - *quote = '\0'; - for (p = strtok(p, ", \t\n"); p; p = strtok(NULL, ", \t\n")) - if (i < MAXTOKEN-1) - a[i++] = p; - else - error("too many tokens"); - if (quote) { - quote++; - p = strchr(quote, '\"'); - if (!p) - error("unterminated string constant"); - else if (i < MAXTOKEN-1) { - a[i++] = quote; - *p = '\0'; - p++; - } - else - error("too many tokens"); - goto rescan; - } - if (i) { - *n = i; - return(a); - } - } - return(NULL); -} - -#define A 0x8000 /* `A'ccumulator ok */ -#define I 0x4000 /* use as immediate value */ -#define SL 0x2000 /* shift left */ -#define SR 0x1000 /* shift right */ -#define RL 0x0800 /* rotate left */ -#define RR 0x0400 /* rotate right */ -#define LO 0x8000 /* lookup: ori-{jmp,jc,jnc,call} */ -#define LA 0x4000 /* lookup: and-{jz,jnz} */ -#define LX 0x2000 /* lookup: xor-{je,jne} */ -#define NA -1 /* not applicable */ - -struct { - char *name; - int n; /* number of operands, including opcode */ - unsigned int op; /* immediate or L?|pos_from_0 */ - unsigned int dest; /* NA, pos_from_0, or I|immediate */ - unsigned int src; /* NA, pos_from_0, or I|immediate */ - unsigned int imm; /* pos_from_0, A|pos_from_0, or I|immediate */ - unsigned int addr; /* NA or pos_from_0 */ - int fmt; /* instruction format - 1, 2, or 3 */ -} instr[] = { -/* - * N OP DEST SRC IMM ADDR FMT - */ - { "mov", 3, 1, 1, 2, I|0xff, NA, 1 }, - { "mov", 4, LO|2, NA, 1, I|0, 3, 3 }, - { "mvi", 3, 0, 1, I|R_ALLZEROS, A|2, NA, 1 }, - { "mvi", 4, LO|2, NA, I|R_ALLZEROS, 1, 3, 3 }, - { "not", 2, 2, 1, 1, I|0xff, NA, 1 }, - { "and", 3, 1, 1, 1, A|2, NA, 1 }, - { "and", 4, 1, 1, 3, A|2, NA, 1 }, - { "or", 3, 0, 1, 1, A|2, NA, 1 }, - { "or", 4, 0, 1, 3, A|2, NA, 1 }, - { "or", 5, LO|3, NA, 1, 2, 4, 3 }, - { "xor", 3, 2, 1, 1, A|2, NA, 1 }, - { "xor", 4, 2, 1, 3, A|2, NA, 1 }, - { "nop", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "inc", 2, 3, 1, 1, I|1, NA, 1 }, - { "inc", 3, 3, 1, 2, I|1, NA, 1 }, - { "dec", 2, 3, 1, 1, I|0xff, NA, 1 }, - { "dec", 3, 3, 1, 2, I|0xff, NA, 1 }, - { "jmp", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "jc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "jnc", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "call", 2, LO|0, NA, I|R_SINDEX, I|0, 1, 3 }, - { "test", 5, LA|3, NA, 1, A|2, 4, 3 }, - { "cmp", 5, LX|3, NA, 1, A|2, 4, 3 }, - { "ret", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "ret", 1, 1, I|R_NONE, I|R_ALLZEROS, I|0xff, NA, 1 }, - { "clc", 1, 3, I|R_NONE, I|R_ALLZEROS, I|1, NA, 1 }, - { "clc", 4, 3, 2, I|R_ALLZEROS, A|3, NA, 1 }, - { "stc", 2, 3, 1, I|R_ALLONES, I|1, NA, 1 }, - { "add", 3, 3, 1, 1, A|2, NA, 1 }, - { "add", 4, 3, 1, 3, A|2, NA, 1 }, - { "adc", 3, 4, 1, 1, A|2, NA, 1 }, - { "adc", 4, 4, 1, 3, A|2, NA, 1 }, - { "shl", 3, 5, 1, 1, SL|2, NA, 2 }, - { "shl", 4, 5, 1, 2, SL|3, NA, 2 }, - { "shr", 3, 5, 1, 1, SR|2, NA, 2 }, - { "shr", 4, 5, 1, 2, SR|3, NA, 2 }, - { "rol", 3, 5, 1, 1, RL|2, NA, 2 }, - { "rol", 4, 5, 1, 2, RL|3, NA, 2 }, - { "ror", 3, 5, 1, 1, RR|2, NA, 2 }, - { "ror", 4, 5, 1, 2, RR|3, NA, 2 }, - /* - * Extensions (note also that mvi allows A) - */ - { "clr", 2, 1, 1, I|R_ALLZEROS, I|0xff, NA, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -int -eval_operand(char **a, int spec) -{ - int i; - unsigned int want = spec & (LO|LA|LX); - - static struct { - unsigned int what; - char *name; - int value; - } jmptab[] = { - { LO, "jmp", 8 }, - { LO, "jc", 9 }, - { LO, "jnc", 10 }, - { LO, "call", 11 }, - { LA, "jz", 15 }, - { LA, "jnz", 13 }, - { LX, "je", 14 }, - { LX, "jne", 12 }, - }; - - spec &= ~(LO|LA|LX); - - for (i = 0; i < sizeof(jmptab)/sizeof(jmptab[0]); i++) - if (jmptab[i].what == want && - !strcmp(jmptab[i].name, a[spec])) - { - return(jmptab[i].value); - } - - if (want) - error("invalid jump"); - - return(spec); /* "case 0" - no flags set */ -} - -int -eval_sdi(char **a, int spec) -{ - sym_t *p; - unsigned val; - - if (spec == NA) - return(NA); - - switch (spec & (A|I|SL|SR|RL|RR)) { - case SL: - case SR: - case RL: - case RR: - if (isdigit(*a[spec &~ (SL|SR|RL|RR)])) - val = strtol(a[spec &~ (SL|SR|RL|RR)], NULL, 0); - else { - p = lookup(a[spec &~ (SL|SR|RL|RR)]); - if (!p) - error("undefined symbol used"); - val = p->value; - } - - switch (spec & (SL|SR|RL|RR)) { /* blech */ - case SL: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (val % 8)); - case SR: - if (val > 7) - return(0xf0); - return(((val % 8) << 4) | - (1 << 3) | - ((8 - (val % 8)) % 8)); - case RL: - return(val % 8); - case RR: - return((8 - (val % 8)) % 8); - } - case I: - return(spec &~ I); - case A: - /* - * An immediate field of zero selects - * the accumulator. Vigorously object - * if zero is given otherwise - it's - * most likely an error. - */ - spec &= ~A; - if (!strcmp("A", a[spec])) - return(0); - if (isdigit(*a[spec]) && - strtol(a[spec], NULL, 0) == 0) - { - error("immediate value of zero selects accumulator"); - } - /* falls through */ - case 0: - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - p = lookup(a[spec]); - if (p) - return(p->value); - error("undefined symbol used"); - } - - return(NA); /* shut the compiler up */ -} - -int -eval_addr(char **a, int spec) -{ - sym_t *p; - - if (spec == NA) - return(NA); - if (isdigit(*a[spec])) - return(strtol(a[spec], NULL, 0)); - - p = lookup(a[spec]); - - if (p) { - if (p->value != NOVALUE) - return(p->value); - patch(p, LC); - } else { - define(a[spec], NOVALUE); - p = lookup(a[spec]); - patch(p, LC); - } - - return(NA); /* will be patched in later */ -} - -int -crack(char **a, int n) -{ - int i; - int I_imm, I_addr; - int I_op, I_dest, I_src, I_ret; - - /* - * Check for "ret" at the end of the line; remove - * it unless it's "ret" alone - we still want to - * look it up in the table. - */ - I_ret = (strcmp(a[n-1], "ret") ? 0 : !0); - if (I_ret && n > 1) - n -= 1; - - for (i = 0; instr[i].name; i++) { - /* - * Look for match in table given constraints, - * currently just the name and the number of - * operands. - */ - if (!strcmp(instr[i].name, *a) && instr[i].n == n) - break; - } - if (!instr[i].name) - error("unknown opcode or wrong number of operands"); - - I_op = eval_operand(a, instr[i].op); - I_src = eval_sdi(a, instr[i].src); - I_imm = eval_sdi(a, instr[i].imm); - I_dest = eval_sdi(a, instr[i].dest); - I_addr = eval_addr(a, instr[i].addr); - - if( LC >= MEMORY ) - error("Memory exhausted!\n"); - - switch (instr[i].fmt) { - case 1: - case 2: - M[LC][0] = (I_op << 1) | I_ret; - M[LC][1] = I_dest; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - case 3: - if (I_ret) - error("illegal use of \"ret\""); - M[LC][0] = (I_op << 1) | ((I_addr >> 8) & 1); - M[LC][1] = I_addr & 0xff; - M[LC][2] = I_src; - M[LC][3] = I_imm; - break; - } - - return (1); /* no two-byte instructions yet */ -} - -#undef SL -#undef SR -#undef RL -#undef RR -#undef LX -#undef LA -#undef LO -#undef I -#undef A - -void -assemble(void) -{ - int n; - char **a; - sym_t *p; - - while ((a = getl(&n))) { - - while (a[0][strlen(*a)-1] == ':') { - a[0][strlen(*a)-1] = '\0'; - p = lookup(*a); - if (p) - p->value = LC; - else - define(*a, LC); - a += 1; - n -= 1; - } - - if (!n) /* line was all labels */ - continue; - - if (n == 3 && !strcmp("VERSION", *a)) - fprintf(ofp, "#define %s \"%s\"\n", a[1], a[2]); - else { - if (n == 3 && !strcmp("=", a[1])) - define(*a, strtol(a[2], NULL, 0)); - else - LC += crack(a, n); - } - } - - backpatch(); - output(ofp); - - if (debug) - output(stderr); -} - -int -main(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "dho:vD")) != EOF) { - switch (c) { - case 'd': - debug = !0; - break; - case 'D': - { - char *p; - if ((p = strchr(optarg, '=')) != NULL) { - *p = '\0'; - define(optarg, strtol(p + 1, NULL, 0)); - } - else - define(optarg, 1); - break; - } - case 'o': - ofp = fopen(optarg, "w"); - if (!ofp) { - perror(optarg); - exit(EXIT_FAILURE); - } - break; - case 'h': - printf("usage: %s [-d] [-Dname] [-ooutput] input\n", - *argv); - exit(EXIT_SUCCESS); - break; - case 'v': - printf("%s\n", id); - exit(EXIT_SUCCESS); - break; - default: - exit(EXIT_FAILURE); - break; - } - } - - if (argc - optind != 1) { - fprintf(stderr, "%s: must have one input file\n", *argv); - exit(EXIT_FAILURE); - } - filename = argv[optind]; - - ifp = fopen(filename, "r"); - if (!ifp) { - perror(filename); - exit(EXIT_FAILURE); - } - - if (!ofp) { - ofp = fopen(ADOTOUT, "w"); - if (!ofp) { - perror(ADOTOUT); - exit(EXIT_FAILURE); - } - } - - assemble(); - exit(EXIT_SUCCESS); -} diff --git a/sys/gnu/misc/aic7xxx/aic7xxx.seq b/sys/gnu/misc/aic7xxx/aic7xxx.seq deleted file mode 100644 index 435da74..0000000 --- a/sys/gnu/misc/aic7xxx/aic7xxx.seq +++ /dev/null @@ -1,1253 +0,0 @@ -##+M######################################################################### -# Adaptec 274x/284x/294x device driver for Linux and FreeBSD. -# -# Copyright (c) 1994 John Aycock -# The University of Calgary Department of Computer Science. -# All rights reserved. -# -# Modifications/enhancements: -# Copyright (c) 1994, 1995 Justin Gibbs. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of Calgary -# Department of Computer Science and its contributors. -# 4. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# FreeBSD, Twin, Wide, 2 command per target support, tagged queuing and other -# optimizations provided by Justin T. Gibbs (gibbs@FreeBSD.org) -# -##-M######################################################################### - -VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.13 1995/04/09 06:40:16 gibbs Exp $" - -SCBMASK = 0x1f - -SCSISEQ = 0x00 -SXFRCTL0 = 0x01 -SXFRCTL1 = 0x02 -SCSISIGI = 0x03 -SCSISIGO = 0x03 -SCSIRATE = 0x04 -SCSIID = 0x05 -SCSIDATL = 0x06 -STCNT = 0x08 -STCNT+0 = 0x08 -STCNT+1 = 0x09 -STCNT+2 = 0x0a -SSTAT0 = 0x0b -CLRSINT1 = 0x0c -SSTAT1 = 0x0c -SIMODE1 = 0x11 -SCSIBUSL = 0x12 -SHADDR = 0x14 -SELID = 0x19 -SBLKCTL = 0x1f -SEQCTL = 0x60 -A = 0x64 # == ACCUM -SINDEX = 0x65 -DINDEX = 0x66 -ALLZEROS = 0x6a -NONE = 0x6a -SINDIR = 0x6c -DINDIR = 0x6d -FUNCTION1 = 0x6e -HADDR = 0x88 -HADDR+1 = 0x89 -HADDR+2 = 0x8a -HADDR+3 = 0x8b -HCNT = 0x8c -HCNT+0 = 0x8c -HCNT+1 = 0x8d -HCNT+2 = 0x8e -SCBPTR = 0x90 -INTSTAT = 0x91 -DFCNTRL = 0x93 -DFSTATUS = 0x94 -DFDAT = 0x99 -QINFIFO = 0x9b -QINCNT = 0x9c -QOUTFIFO = 0x9d - -SCSICONF_A = 0x5a -SCSICONF_B = 0x5b - -# The two reserved bytes at SCBARRAY+1[23] are expected to be set to -# zero, and the reserved bit in SCBARRAY+0 is used as an internal flag -# to indicate whether or not to reload scatter-gather parameters after -# a disconnect. We also use bits 6 & 7 to indicate whether or not to -# initiate SDTR or WDTR repectively when starting this command. -# -SCBARRAY+0 = 0xa0 - -DISCONNECTED = 0x04 -NEEDDMA = 0x08 -SG_LOAD = 0x10 -TAG_ENB = 0x20 -NEEDSDTR = 0x40 -NEEDWDTR = 0x80 - -SCBARRAY+1 = 0xa1 -SCBARRAY+2 = 0xa2 -SCBARRAY+3 = 0xa3 -SCBARRAY+4 = 0xa4 -SCBARRAY+5 = 0xa5 -SCBARRAY+6 = 0xa6 -SCBARRAY+7 = 0xa7 -SCBARRAY+8 = 0xa8 -SCBARRAY+9 = 0xa9 -SCBARRAY+10 = 0xaa -SCBARRAY+11 = 0xab -SCBARRAY+12 = 0xac -SCBARRAY+13 = 0xad -SCBARRAY+14 = 0xae -SCBARRAY+15 = 0xaf -SCBARRAY+16 = 0xb0 -SCBARRAY+17 = 0xb1 -SCBARRAY+18 = 0xb2 -SCBARRAY+19 = 0xb3 -SCBARRAY+20 = 0xb4 -SCBARRAY+21 = 0xb5 -SCBARRAY+22 = 0xb6 -SCBARRAY+23 = 0xb7 -SCBARRAY+24 = 0xb8 -SCBARRAY+25 = 0xb9 -SCBARRAY+26 = 0xba -SCBARRAY+27 = 0xbb -SCBARRAY+28 = 0xbc -SCBARRAY+29 = 0xbd - -BAD_PHASE = 0x01 # unknown scsi bus phase -CMDCMPLT = 0x02 -SEND_REJECT = 0x11 # sending a message reject -NO_IDENT = 0x21 # no IDENTIFY after reconnect -NO_MATCH = 0x31 # no cmd match for reconnect -MSG_SDTR = 0x41 # SDTR message recieved -MSG_WDTR = 0x51 # WDTR message recieved -MSG_REJECT = 0x61 # Reject message recieved -BAD_STATUS = 0x71 # Bad status from target -RESIDUAL = 0x81 # Residual byte count != 0 -ABORT_TAG = 0x91 # Sent an ABORT_TAG message - -# The host adapter card (at least the BIOS) uses 20-2f for SCSI -# device information, 32-33 and 5a-5f as well. As it turns out, the -# BIOS trashes 20-2f, writing the synchronous negotiation results -# on top of the BIOS values, so we re-use those for our per-target -# scratchspace (actually a value that can be copied directly into -# SCSIRATE). The kernel driver will enable synchronous negotiation -# for all targets that have a value other than 0 in the lower four -# bits of the target scratch space. This should work irregardless of -# whether the bios has been installed. NEEDWDTR and NEEDSDTR are the top -# two bits of the SCB control byte. The kernel driver will set these -# when a WDTR or SDTR message should be sent to the target the SCB's -# command references. -# -# The high bit of DROPATN is set if ATN should be dropped before the ACK -# when outb is called. REJBYTE contains the first byte of a MESSAGE IN -# message, so the driver can report an intelligible error if a message is -# rejected. -# -# FLAGS's high bit is true if we are currently handling a reselect; -# its next-highest bit is true ONLY IF we've seen an IDENTIFY message -# from the reselecting target. If we haven't had IDENTIFY, then we have -# no idea what the lun is, and we can't select the right SCB register -# bank, so force a kernel panic if the target attempts a data in/out or -# command phase instead of corrupting something. -# -# Note that SG_NEXT occupies four bytes. -# -SYNCNEG = 0x20 - -DROPATN = 0x30 -REJBYTE = 0x31 -DISC_DSB_A = 0x32 -DISC_DSB_B = 0x33 - -MSG_LEN = 0x34 -MSG_START+0 = 0x35 -MSG_START+1 = 0x36 -MSG_START+2 = 0x37 -MSG_START+3 = 0x38 -MSG_START+4 = 0x39 -MSG_START+5 = 0x3a --MSG_START+0 = 0xcb # 2's complement of MSG_START+0 - -ARG_1 = 0x4a # sdtr conversion args & return -BUS_16_BIT = 0x01 -RETURN_1 = 0x4a - -SIGSTATE = 0x4b # value written to SCSISIGO - -# Linux users should use 0xc (12) for SG_SIZEOF -SG_SIZEOF = 0x8 # sizeof(struct ahc_dma) -#SG_SIZEOF = 0xc # sizeof(struct scatterlist) -SCB_SIZEOF = 0x13 # sizeof SCB to DMA (19 bytes) - -SG_NOLOAD = 0x4c # load SG pointer/length? -SG_COUNT = 0x4d # working value of SG count -SG_NEXT = 0x4e # working value of SG pointer -SG_NEXT+0 = 0x4e -SG_NEXT+1 = 0x4f -SG_NEXT+2 = 0x50 -SG_NEXT+3 = 0x51 - -SCBCOUNT = 0x52 # the actual number of SCBs -FLAGS = 0x53 # Device configuration flags -TWIN_BUS = 0x01 -WIDE_BUS = 0x02 -MAX_SYNC = 0x08 -SENSE = 0x10 -ACTIVE_MSG = 0x20 -IDENTIFY_SEEN = 0x40 -RESELECTED = 0x80 - -ACTIVE_A = 0x54 -ACTIVE_B = 0x55 -SAVED_TCL = 0x56 -# Poll QINCNT for work - the lower bits contain -# the number of entries in the Queue In FIFO. -# -start: - test FLAGS,SENSE jnz start_sense -start_nosense: - test FLAGS,TWIN_BUS jz start2 # Are we a twin channel device? -# For fairness, we check the other bus first, since we just finished a -# transaction on the current channel. - xor SBLKCTL,0x08 # Toggle to the other bus - test SCSISIGI,0x4 jnz reselect # BSYI - xor SBLKCTL,0x08 # Toggle to the original bus -start2: - test SCSISIGI,0x4 jnz reselect # BSYI - test QINCNT,SCBMASK jz start_nosense - -# We have at least one queued SCB now. Set the SCB pointer -# from the FIFO so we see the right bank of SCB registers, -# then set SCSI options and set the initiator and target -# SCSI IDs. -# - mov SCBPTR,QINFIFO - -# If the control byte of this SCB has the NEEDDMA flag set, we have -# yet to DMA it from host memory - -test SCBARRAY+0,NEEDDMA jz test_busy - clr HCNT+2 - clr HCNT+1 - mvi HCNT+0,SCB_SIZEOF - - mvi DINDEX,HADDR - mvi SCBARRAY+26 call bcopy_4 - - mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET - -# Wait for DMA from host memory to data FIFO to complete, then disable -# DMA and wait for it to acknowledge that it's off. -# - call dma_finish - -# Copy the SCB from the FIFO to the SCBARRAY - - mvi DINDEX, SCBARRAY+0 - call bcopy_3_dfdat - call bcopy_4_dfdat - call bcopy_4_dfdat - call bcopy_4_dfdat - call bcopy_4_dfdat - -# See if there is not already an active SCB for this target. This code -# locks out on a per target basis instead of target/lun. Although this -# is not ideal for devices that have multiple luns active at the same -# time, it is faster than looping through all SCB's looking for active -# commands. It may be benificial to make findscb a more general procedure -# to see if the added cost of the search is negligible. This code also -# assumes that the kernel driver will clear the active flags on board -# initialization, board reset, and a target's SELTO. - -test_busy: - test SCBARRAY+0,0x20 jnz start_scb - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - test SCBARRAY+1,0x88 jz test_a # Id < 8 && A channel - - test ACTIVE_B,A jnz requeue - or ACTIVE_B,A # Mark the current target as busy - jmp start_scb - -start_sense: -# Clear the SENSE flag first, then do a normal start_scb - and FLAGS,0xef - jmp start_scb - -# Place the currently active back on the queue for later processing -requeue: - mov QINFIFO, SCBPTR - jmp start_nosense - -test_a: - test ACTIVE_A,A jnz requeue - or ACTIVE_A,A # Mark the current target as busy - -start_scb: - or SCBARRAY+0,NEEDDMA - and SINDEX,0xf7,SBLKCTL #Clear the channel select bit - and A,0x08,SCBARRAY+1 #Get new channel bit - or SINDEX,A - mov SBLKCTL,SINDEX # select channel - mov SCBARRAY+1 call initialize - clr SG_NOLOAD - and FLAGS,0x3f # !RESELECTING - -# As soon as we get a successful selection, the target should go -# into the message out phase since we have ATN asserted. Prepare -# the message to send, locking out the device driver. If the device -# driver hasn't beaten us with an ABORT or RESET message, then tack -# on an SDTR negotiation if required. -# -# Messages are stored in scratch RAM starting with a flag byte (high bit -# set means active message), one length byte, and then the message itself. -# - mov SCBARRAY+1 call disconnect # disconnect ok? - - and SINDEX,0x7,SCBARRAY+1 # lun - or SINDEX,A # return value from disconnect - or SINDEX,0x80 call mk_mesg # IDENTIFY message - - mov A,SINDEX - test SCBARRAY+0,0xe0 jz !message # WDTR, SDTR or TAG?? - cmp MSG_START+0,A jne !message # did driver beat us? - -# Tag Message if Tag enabled in SCB control block. Use SCBPTR as the tag -# value - -mk_tag: - mvi DINDEX, MSG_START+1 - test SCBARRAY+0,TAG_ENB jz mk_tag_done - and A,0x23,SCBARRAY+0 - mov DINDIR,A - mov DINDIR,SCBPTR - - add MSG_LEN,-MSG_START+0,DINDEX # update message length - -mk_tag_done: - - mov DINDEX call mk_dtr # build DTR message if needed - -!message: - -# Enable selection phase as an initiator, and do automatic ATN -# after the selection. -# - mvi SCSISEQ,0x48 # ENSELO|ENAUTOATNO - -# Wait for successful arbitration. The AIC-7770 documentation says -# that SELINGO indicates successful arbitration, and that it should -# be used to look for SELDO. However, if the sequencer is paused at -# just the right time - a parallel fsck(8) on two drives did it for -# me - then SELINGO can flip back to false before we've seen it. This -# makes the sequencer sit in the arbitration loop forever. This is -# Not Good. -# -# Therefore, I've added a check in the arbitration loop for SELDO -# too. This could arguably be made a critical section by disabling -# pauses, but I don't want to make a potentially infinite loop a CS. -# I suppose you could fold it into the select loop, too, but since -# I've been hunting this bug for four days it's kinda like a trophy. -# -arbitrate: - test SSTAT0,0x40 jnz *select # SELDO - test SSTAT0,0x10 jz arbitrate # SELINGO - -# Wait for a successful selection. If the hardware selection -# timer goes off, then the driver gets the interrupt, so we don't -# need to worry about it. -# -select: - test SSTAT0,0x40 jz select # SELDO - jmp *select - -# Reselection is being initiated by a target - we've seen the BSY -# line driven active, and we didn't do it! Enable the reselection -# hardware, and wait for it to finish. Make a note that we've been -# reselected, but haven't seen an IDENTIFY message from the target -# yet. -# -reselect: - mvi SCSISEQ,0x10 # ENRSELI - -reselect1: - test SSTAT0,0x20 jz reselect1 # SELDI - mov SELID call initialize - - and FLAGS,0x3f # reselected, no IDENTIFY - or FLAGS,RESELECTED - -# After the [re]selection, make sure that the [re]selection enable -# bit is off. This chip is flaky enough without extra things -# turned on. Also clear the BUSFREE bit in SSTAT1 since we'll be -# using it shortly. -# -*select: - clr SCSISEQ - mvi CLRSINT1,0x8 # CLRBUSFREE - -# Main loop for information transfer phases. If BSY is false, then -# we have a bus free condition, expected or not. Otherwise, wait -# for the target to assert REQ before checking MSG, C/D and I/O -# for the bus phase. -# -# We can't simply look at the values of SCSISIGI here (if we want -# to do synchronous data transfer), because the target won't assert -# REQ if it's already sent us some data that we haven't acknowledged -# yet. -# -ITloop: - test SSTAT1,0x8 jnz p_busfree # BUSFREE - test SSTAT1,0x1 jz ITloop # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - - cmp ALLZEROS,A je p_dataout - cmp A,0x40 je p_datain - cmp A,0x80 je p_command - cmp A,0xc0 je p_status - cmp A,0xa0 je p_mesgout - cmp A,0xe0 je p_mesgin - - mvi INTSTAT,BAD_PHASE # unknown - signal driver - -p_dataout: - mvi 0 call scsisig # !CDO|!IOO|!MSGO - call assert - call sg_load - - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy_4 - -# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR - mvi SCBARRAY+23 call bcopy_3 - - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy_3 - -# If we are the last SG block, don't set wideodd. - test SCBARRAY+18,0xff jnz p_dataout_wideodd - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - jmp p_dataout_rest - -p_dataout_wideodd: - mvi 0xbd call dma # WIDEODD|SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - -p_dataout_rest: -# After a DMA finishes, save the final transfer pointer and count -# back into the SCB, in case a device disconnects in the middle of -# a transfer. Use SHADDR and STCNT instead of HADDR and HCNT, since -# it's a reflection of how many bytes were transferred on the SCSI -# (as opposed to the host) bus. -# - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy_3 - - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy_4 - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -p_datain: - mvi 0x40 call scsisig # !CDO|IOO|!MSGO - call assert - call sg_load - - mvi DINDEX,HADDR - mvi SCBARRAY+19 call bcopy_4 - -# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR - mvi SCBARRAY+23 call bcopy_3 - - mvi DINDEX,STCNT - mvi SCBARRAY+23 call bcopy_3 - -# If we are the last SG block, don't set wideodd. - test SCBARRAY+18,0xff jnz p_datain_wideodd - mvi 0x39 call dma # SCSIEN|SDMAEN|HDMAEN| - # !DIRECTION|FIFORESET - jmp p_datain_rest -p_datain_wideodd: - mvi 0xb9 call dma # WIDEODD|SCSIEN|SDMAEN|HDMAEN| - # !DIRECTION|FIFORESET -p_datain_rest: - mvi DINDEX,SCBARRAY+23 - mvi STCNT call bcopy_3 - - mvi DINDEX,SCBARRAY+19 - mvi SHADDR call bcopy_4 - - call sg_advance - mov SCBARRAY+18,SG_COUNT # residual S/G count - - jmp ITloop - -# Command phase. Set up the DMA registers and let 'er rip - the -# two bytes after the SCB SCSI_cmd_length are zeroed by the driver, -# so we can copy those three bytes directly into HCNT. -# -p_command: - mvi 0x80 call scsisig # CDO|!IOO|!MSGO - call assert - - mvi DINDEX,HADDR - mvi SCBARRAY+7 call bcopy_4 - -# mvi DINDEX,HCNT # implicit since HCNT is next to HADDR - mvi SCBARRAY+11 call bcopy_3 - - mvi DINDEX,STCNT - mvi SCBARRAY+11 call bcopy_3 - - mvi 0x3d call dma # SCSIEN|SDMAEN|HDMAEN| - # DIRECTION|FIFORESET - jmp ITloop - -# Status phase. Wait for the data byte to appear, then read it -# and store it into the SCB. -# -p_status: - mvi 0xc0 call scsisig # CDO|IOO|!MSGO - - mvi SCBARRAY+14 call inb_first - jmp p_mesgin_done - -# Message out phase. If there is no active message, but the target -# took us into this phase anyway, build a no-op message and send it. -# -p_mesgout: - mvi 0xa0 call scsisig # CDO|!IOO|MSGO - mvi 0x8 call mk_mesg # build NOP message - - clr STCNT+2 - clr STCNT+1 - -# Set up automatic PIO transfer from MSG_START. Bit 3 in -# SXFRCTL0 (SPIOEN) is already on. -# - mvi SINDEX,MSG_START+0 - mov DINDEX,MSG_LEN - -# When target asks for a byte, drop ATN if it's the last one in -# the message. Otherwise, keep going until the message is exhausted. -# (We can't use outb for this since it wants the input in SINDEX.) -# -# Keep an eye out for a phase change, in case the target issues -# a MESSAGE REJECT. -# -p_mesgout2: - test SSTAT0,0x2 jz p_mesgout2 # SPIORDY - test SSTAT1,0x10 jnz p_mesgout6 # PHASEMIS - - cmp DINDEX,1 jne p_mesgout3 # last byte? - mvi CLRSINT1,0x40 # CLRATNO - drop ATN - -# Write a byte to the SCSI bus. The AIC-7770 refuses to automatically -# send ACKs in automatic PIO or DMA mode unless you make sure that the -# "expected" bus phase in SCSISIGO matches the actual bus phase. This -# behaviour is completely undocumented and caused me several days of -# grief. -# -# After plugging in different drives to test with and using a longer -# SCSI cable, I found that I/O in Automatic PIO mode ceased to function, -# especially when transferring >1 byte. It seems to be much more stable -# if STCNT is set to one before the transfer, and SDONE (in SSTAT0) is -# polled for transfer completion - for both output _and_ input. The -# only theory I have is that SPIORDY doesn't drop right away when SCSIDATL -# is accessed (like the documentation says it does), and that on a longer -# cable run, the sequencer code was fast enough to loop back and see -# an SPIORDY that hadn't dropped yet. -# -p_mesgout3: - mvi STCNT+0, 0x01 - mov SCSIDATL,SINDIR - -p_mesgout4: - test SSTAT0,0x4 jz p_mesgout4 # SDONE - dec DINDEX - test DINDEX,0xff jnz p_mesgout2 - -# If the next bus phase after ATN drops is a message out, it means -# that the target is requesting that the last message(s) be resent. -# -p_mesgout5: - test SSTAT1,0x8 jnz p_mesgout6 # BUSFREE - test SSTAT1,0x1 jz p_mesgout5 # REQINIT - - and A,0xe0,SCSISIGI # CDI|IOI|MSGI - cmp A,0xa0 jne p_mesgout6 - mvi 0x10 call scsisig # ATNO - re-assert ATN - - jmp ITloop - -p_mesgout6: - mvi CLRSINT1,0x40 # CLRATNO - in case of PHASEMIS - and FLAGS,0xdf # no active msg - jmp ITloop - -# Message in phase. Bytes are read using Automatic PIO mode, but not -# using inb. This alleviates a race condition, namely that if ATN had -# to be asserted under Automatic PIO mode, it had to beat the SCSI -# circuitry sending an ACK to the target. This showed up under heavy -# loads and really confused things, since ABORT commands wouldn't be -# seen by the drive after an IDENTIFY message in until it had changed -# to a data I/O phase. -# -p_mesgin: - mvi 0xe0 call scsisig # CDO|IOO|MSGO - mvi A call inb_first # read the 1st message byte - mvi REJBYTE,A # save it for the driver - - cmp ALLZEROS,A jne p_mesgin1 - -# We got a "command complete" message, so put the SCB pointer -# into the Queue Out, and trigger a completion interrupt. -# Check status for non zero return and interrupt driver if needed -# This allows the driver to interpret errors only when they occur -# instead of always uploading the scb. If the status is SCSI_CHECK, -# the driver will download a new scb requesting sense, to replace -# the old one and set the SENSE sequencer flag. If the sense flag is -# set, the sequencer imediately jumps to start working on the sense -# command. If the kernel driver does not wish to request sense, it need -# do nothing, and the command is allowed to complete. We don't -# bother to post to the QOUTFIFO in the error case since it would require -# extra work in the kernel driver to ensure that the entry was removed -# before the command complete code tried processing it. - -# First check for residuals - test SCBARRAY+15,0xff jnz resid - test SCBARRAY+16,0xff jnz resid - test SCBARRAY+17,0xff jnz resid - -check_status: - test SCBARRAY+14,0xff jz status_ok # 0 Status? - mvi INTSTAT,BAD_STATUS # let driver know - test FLAGS,SENSE jz status_ok - jmp p_mesgin_done - -status_ok: -# First, mark this target as free. - test SCBARRAY+0,0x20 jnz complete # Tagged command - and FUNCTION1,0x70,SCBARRAY+1 - mov A,FUNCTION1 - test SCBARRAY+1,0x88 jz clear_a - xor ACTIVE_B,A - jmp complete - -clear_a: - xor ACTIVE_A,A - -complete: - mov QOUTFIFO,SCBPTR - mvi INTSTAT,CMDCMPLT - jmp p_mesgin_done - -# If we have a residual count, interrupt and tell the host. Other -# alternatives are to pause the sequencer on all command completes (yuck), -# dma the resid directly to the host (slick, but a ton of instructions), or -# have the sequencer pause itself when it encounters a non-zero resid -# (unecessary pause just to flag the command -- yuck, but takes few instructions -# and since it shouldn't happen that often is good enough for our purposes). - -resid: - mvi INTSTAT,RESIDUAL - jmp check_status - -# Is it an extended message? We only support the synchronous and wide data -# transfer request messages, which will probably be in response to -# WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it - -# apparently this can be done after any message in byte, according -# to the SCSI-2 spec. -# -p_mesgin1: - cmp A,1 jne p_mesgin2 # extended message code? - - mvi ARG_1 call inb_next # extended message length - mvi A call inb_next # extended message code - - cmp A,1 je p_mesginSDTR # Syncronous negotiation message - cmp A,3 je p_mesginWDTR # Wide negotiation message - jmp p_mesginN - -p_mesginWDTR: - cmp ARG_1,2 jne p_mesginN # extended mesg length = 2 - mvi A call inb_next # Width of bus - mvi INTSTAT,MSG_WDTR # let driver know - test RETURN_1,0x80 jz p_mesgin_done# Do we need to send WDTR? - -# We didn't initiate the wide negotiation, so we must respond to the request - and RETURN_1,0x7f # Clear the SEND_WDTR Flag - or FLAGS,ACTIVE_MSG - mvi DINDEX,MSG_START+0 - mvi MSG_START+0 call mk_wdtr # build WDTR message - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - jmp p_mesgin_done - -p_mesginSDTR: - cmp ARG_1,3 jne p_mesginN # extended mesg length = 3 - mvi ARG_1 call inb_next # xfer period - mvi A call inb_next # REQ/ACK offset - mvi INTSTAT,MSG_SDTR # call driver to convert - - test RETURN_1,0xc0 jz p_mesgin_done# Do we need to mk_sdtr or rej? - test RETURN_1,0x40 jnz p_mesginN # Requested SDTR too small - rej - or FLAGS,ACTIVE_MSG - mvi DINDEX, MSG_START+0 - mvi MSG_START+0 call mk_sdtr - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - jmp p_mesgin_done - -# Is it a disconnect message? Set a flag in the SCB to remind us -# and await the bus going free. -# -p_mesgin2: - cmp A,4 jne p_mesgin3 # disconnect code? - - or SCBARRAY+0,0x4 # set "disconnected" bit - jmp p_mesgin_done - -# Save data pointers message? Copy working values into the SCB, -# usually in preparation for a disconnect. -# -p_mesgin3: - cmp A,2 jne p_mesgin4 # save data pointers code? - - call sg_ram2scb - jmp p_mesgin_done - -# Restore pointers message? Data pointers are recopied from the -# SCB anyway at the start of any DMA operation, so the only thing -# to copy is the scatter-gather values. -# -p_mesgin4: - cmp A,3 jne p_mesgin5 # restore pointers code? - - call sg_scb2ram - jmp p_mesgin_done - -# Identify message? For a reconnecting target, this tells us the lun -# that the reconnection is for - find the correct SCB and switch to it, -# clearing the "disconnected" bit so we don't "find" it by accident later. -# -p_mesgin5: - test A,0x80 jz p_mesgin6 # identify message? - - test A,0x78 jnz p_mesginN # !DiscPriv|!LUNTAR|!Reserved - - and A,0x07 # lun in lower three bits - or SAVED_TCL,A,SELID - and SAVED_TCL,0xf7 - and A,0x08,SBLKCTL # B Channel?? - or SAVED_TCL,A - call inb_last # ACK - mov ALLZEROS call findSCB -setup_SCB: - and SCBARRAY+0,0xfb # clear disconnect bit in SCB - or FLAGS,IDENTIFY_SEEN # make note of IDENTIFY - - call sg_scb2ram # implied restore pointers - # required on reselect - jmp ITloop -get_tag: - mvi A call inb_first - cmp A,0x20 jne return # Simple Tag message? - mvi A call inb_next - call inb_last - test A,0xf0 jnz abort_tag # Tag in range? - mov SCBPTR,A - mov A,SAVED_TCL - cmp SCBARRAY+1,A jne abort_tag - test SCBARRAY+0,TAG_ENB jz abort_tag - ret -abort_tag: - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - mvi INTSTAT,ABORT_TAG # let driver know - mvi 0xd call mk_mesg # ABORT TAG message - ret - -# Message reject? Let the kernel driver handle this. If we have an -# outstanding WDTR or SDTR negotiation, assume that it's a response from -# the target selecting 8bit or asynchronous transfer, otherwise just ignore -# it since we have no clue what it pertains to. -# -p_mesgin6: - cmp A,7 jne p_mesgin7 # message reject code? - - mvi INTSTAT, MSG_REJECT - jmp p_mesgin_done - -# [ ADD MORE MESSAGE HANDLING HERE ] -# -p_mesgin7: - -# We have no idea what this message in is, and there's no way -# to pass it up to the kernel, so we issue a message reject and -# hope for the best. Since we're now using manual PIO mode to -# read in the message, there should no longer be a race condition -# present when we assert ATN. In any case, rejection should be a -# rare occurrence - signal the driver when it happens. -# -p_mesginN: - or SINDEX,0x10,SIGSTATE # turn on ATNO - call scsisig - mvi INTSTAT,SEND_REJECT # let driver know - - mvi 0x7 call mk_mesg # MESSAGE REJECT message - -p_mesgin_done: - call inb_last # ack & turn auto PIO back on - jmp ITloop - - -# Bus free phase. It might be useful to interrupt the device -# driver if we aren't expecting this. For now, make sure that -# ATN isn't being asserted and look for a new command. -# -p_busfree: - mvi CLRSINT1,0x40 # CLRATNO - clr SIGSTATE - jmp start - -# Instead of a generic bcopy routine that requires an argument, we unroll -# the two cases that are actually used, and call them explicitly. This -# not only reduces the overhead of doing a bcopy by 2/3rds, but ends up -# saving space in the program since you don't have to put the argument -# into the accumulator before the call. Both functions expect DINDEX to -# contain the destination address and SINDEX to contain the source -# address. -bcopy_3: - mov DINDIR,SINDIR - mov DINDIR,SINDIR - mov DINDIR,SINDIR ret - -bcopy_4: - mov DINDIR,SINDIR - mov DINDIR,SINDIR - mov DINDIR,SINDIR - mov DINDIR,SINDIR ret - -bcopy_3_dfdat: - mov DINDIR,DFDAT - mov DINDIR,DFDAT - mov DINDIR,DFDAT ret - -bcopy_4_dfdat: - mov DINDIR,DFDAT - mov DINDIR,DFDAT - mov DINDIR,DFDAT - mov DINDIR,DFDAT ret - -# Locking the driver out, build a one-byte message passed in SINDEX -# if there is no active message already. SINDEX is returned intact. -# -mk_mesg: - mvi SEQCTL,0x50 # PAUSEDIS|FASTMODE - test FLAGS,ACTIVE_MSG jnz mk_mesg1 # active message? - - or FLAGS,ACTIVE_MSG # if not, there is now - mvi MSG_LEN,1 # length = 1 - mov MSG_START+0,SINDEX # 1-byte message - -mk_mesg1: - mvi SEQCTL,0x10 ret # !PAUSEDIS|FASTMODE - -# Carefully read data in Automatic PIO mode. I first tried this using -# Manual PIO mode, but it gave me continual underrun errors, probably -# indicating that I did something wrong, but I feel more secure leaving -# Automatic PIO on all the time. -# -# According to Adaptec's documentation, an ACK is not sent on input from -# the target until SCSIDATL is read from. So we wait until SCSIDATL is -# latched (the usual way), then read the data byte directly off the bus -# using SCSIBUSL. When we have pulled the ATN line, or we just want to -# acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI -# spec guarantees that the target will hold the data byte on the bus until -# we send our ACK. -# -# The assumption here is that these are called in a particular sequence, -# and that REQ is already set when inb_first is called. inb_{first,next} -# use the same calling convention as inb. -# -inb_first: - clr STCNT+2 - clr STCNT+1 - mov DINDEX,SINDEX - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_next: - mov DINDEX,SINDEX # save SINDEX - - mvi STCNT+0,1 # xfer one byte - mov NONE,SCSIDATL # dummy read from latch to ACK -inb_next1: - test SSTAT0,0x4 jz inb_next1 # SDONE -inb_next2: - test SSTAT0,0x2 jz inb_next2 # SPIORDY - wait for next byte - mov DINDIR,SCSIBUSL ret # read byte directly from bus - -inb_last: - mvi STCNT+0,1 # ACK with dummy read - mov NONE,SCSIDATL -inb_last1: - test SSTAT0,0x4 jz inb_last1 # wait for completion - ret - -# DMA data transfer. HADDR and HCNT must be loaded first, and -# SINDEX should contain the value to load DFCNTRL with - 0x3d for -# host->scsi, or 0x39 for scsi->host. The SCSI channel is cleared -# during initialization. -# -dma: - mov DFCNTRL,SINDEX -dma1: -dma2: - test SSTAT0,0x1 jnz dma3 # DMADONE - test SSTAT1,0x10 jz dma1 # PHASEMIS, ie. underrun - -# We will be "done" DMAing when the transfer count goes to zero, or -# the target changes the phase (in light of this, it makes sense that -# the DMA circuitry doesn't ACK when PHASEMIS is active). If we are -# doing a SCSI->Host transfer, the data FIFO should be flushed auto- -# magically on STCNT=0 or a phase change, so just wait for FIFO empty -# status. -# -dma3: - test SINDEX,0x4 jnz dma5 # DIRECTION -dma4: - test DFSTATUS,0x1 jz dma4 # !FIFOEMP - -# Now shut the DMA enables off, and copy STCNT (ie. the underrun -# amount, if any) to the SCB registers; SG_COUNT will get copied to -# the SCB's residual S/G count field after sg_advance is called. Make -# sure that the DMA enables are actually off first lest we get an ILLSADDR. -# -dma5: - clr DFCNTRL # disable DMA -dma6: - test DFCNTRL,0x38 jnz dma6 # SCSIENACK|SDMAENACK|HDMAENACK - - mvi DINDEX,SCBARRAY+15 - mvi STCNT call bcopy_3 - - ret - -dma_finish: - test DFSTATUS,0x8 jz dma_finish # HDONE - - clr DFCNTRL # disable DMA -dma_finish2: - test DFCNTRL,0x8 jnz dma_finish2 # HDMAENACK - ret - -# Common SCSI initialization for selection and reselection. Expects -# the target SCSI ID to be in the upper four bits of SINDEX, and A's -# contents are stomped on return. -# -initialize: - and SINDEX,0xf0 # Get target ID - and A,0x0f,SCSIID - or SINDEX,A - mov SCSIID,SINDEX - -# Esundry initialization. -# - clr DROPATN - clr SIGSTATE - -# Turn on Automatic PIO mode now, before we expect to see a REQ -# from the target. It shouldn't hurt anything to leave it on. Set -# CLRCHN here before the target has entered a data transfer mode - -# with synchronous SCSI, if you do it later, you blow away some -# data in the SCSI FIFO that the target has already sent to you. -# - mvi SXFRCTL0,0x8a # DFON|SPIOEN|CLRCHN - -# Initialize scatter-gather pointers by setting up the working copy -# in scratch RAM. -# - call sg_scb2ram - -# Initialize SCSIRATE with the appropriate value for this target. -# - call ndx_dtr - mov SCSIRATE,SINDIR ret - -# Assert that if we've been reselected, then we've seen an IDENTIFY -# message. -# -assert: - test FLAGS,RESELECTED jz return # reselected? - test FLAGS,IDENTIFY_SEEN jnz return # seen IDENTIFY? - - mvi INTSTAT,NO_IDENT ret # no - cause a kernel panic - -# Find out if disconnection is ok from the information the BIOS has left -# us. The tcl from SCBARRAY+1 should be in SINDEX; A will -# contain either 0x40 (disconnection ok) or 0x00 (disconnection not ok) -# on exit. -# -# To allow for wide or twin busses, we check the upper bit of the target ID -# and the channel ID and look at the appropriate disconnect register. -# -disconnect: - and FUNCTION1,0x70,SINDEX # strip off extra just in case - mov A,FUNCTION1 - test SINDEX, 0x88 jz disconnect_a - - test DISC_DSB_B,A jz disconnect1 # bit nonzero if DISabled - clr A ret - -disconnect_a: - test DISC_DSB_A,A jz disconnect1 # bit nonzero if DISabled - clr A ret - -disconnect1: - mvi A,0x40 ret - -# Locate the SCB matching the target ID/channel/lun in SAVED_TCL and switch -# the SCB to it. Have the kernel print a warning message if it can't be -# found, and generate an ABORT message to the target. SINDEX should be -# cleared on call. -# -findSCB: - mov A,SAVED_TCL - mov SCBPTR,SINDEX # switch to new SCB - cmp SCBARRAY+1,A jne findSCB1 # target ID/channel/lun match? - test SCBARRAY+0,0x4 jz findSCB1 # should be disconnected - test SCBARRAY+0,TAG_ENB jnz get_tag - ret - -findSCB1: - inc SINDEX - mov A,SCBCOUNT - cmp SINDEX,A jne findSCB - - mvi INTSTAT,NO_MATCH # not found - signal kernel - mvi 0x6 call mk_mesg # ABORT message - - or SINDEX,0x10,SIGSTATE # assert ATNO - call scsisig - ret - -# Make a working copy of the scatter-gather parameters in the SCB. -# -sg_scb2ram: - mov SG_COUNT,SCBARRAY+2 - - mvi DINDEX,SG_NEXT - mvi SCBARRAY+3 call bcopy_4 - - mvi SG_NOLOAD,0x80 - test SCBARRAY+0,0x10 jnz return # don't reload s/g? - clr SG_NOLOAD ret - -# Copying RAM values back to SCB, for Save Data Pointers message. -# -sg_ram2scb: - mov SCBARRAY+2,SG_COUNT - - mvi DINDEX,SCBARRAY+3 - mvi SG_NEXT call bcopy_4 - - and SCBARRAY+0,0xef,SCBARRAY+0 - test SG_NOLOAD,0x80 jz return # reload s/g? - or SCBARRAY+0,SG_LOAD ret - -# Load a struct scatter if needed and set up the data address and -# length. If the working value of the SG count is nonzero, then -# we need to load a new set of values. -# -# This, like the above DMA, assumes a little-endian host data storage. -# -sg_load: - test SG_COUNT,0xff jz return # SG being used? - test SG_NOLOAD,0x80 jnz return # don't reload s/g? - - clr HCNT+2 - clr HCNT+1 - mvi HCNT+0,SG_SIZEOF - - mvi DINDEX,HADDR - mvi SG_NEXT call bcopy_4 - - mvi DFCNTRL,0xd # HDMAEN|DIRECTION|FIFORESET - -# Wait for DMA from host memory to data FIFO to complete, then disable -# DMA and wait for it to acknowledge that it's off. -# - - call dma_finish - -# Copy data from FIFO into SCB data pointer and data count. This assumes -# that the struct scatterlist has this structure (this and sizeof(struct -# scatterlist) == 12 are asserted in aic7xxx.c): -# -# struct scatterlist { -# char *address; /* four bytes, little-endian order */ -# ... /* four bytes, ignored */ -# unsigned short length; /* two bytes, little-endian order */ -# } -# - -# Not in FreeBSD. the scatter list entry is only 8 bytes. -# -# struct ahc_dma_seg { -# physaddr addr; /* four bytes, little-endian order */ -# long len; /* four bytes, little endian order */ -# }; -# - - mvi DINDEX, SCBARRAY+19 - call bcopy_4_dfdat - -# For Linux, we must throw away four bytes since there is a 32bit gap -# in the middle of a struct scatterlist -# mov NONE,DFDAT -# mov NONE,DFDAT -# mov NONE,DFDAT -# mov NONE,DFDAT - - call bcopy_3_dfdat #Only support 24 bit length. - ret - -# Advance the scatter-gather pointers only IF NEEDED. If SG is enabled, -# and the SCSI transfer count is zero (note that this should be called -# right after a DMA finishes), then move the working copies of the SG -# pointer/length along. If the SCSI transfer count is not zero, then -# presumably the target is disconnecting - do not reload the SG values -# next time. -# -sg_advance: - test SG_COUNT,0xff jz return # s/g enabled? - - test STCNT+0,0xff jnz sg_advance1 # SCSI transfer count nonzero? - test STCNT+1,0xff jnz sg_advance1 - test STCNT+2,0xff jnz sg_advance1 - - clr SG_NOLOAD # reload s/g next time - dec SG_COUNT # one less segment to go - - clr A # add sizeof(struct scatter) - add SG_NEXT+0,SG_SIZEOF,SG_NEXT+0 - adc SG_NEXT+1,A,SG_NEXT+1 - adc SG_NEXT+2,A,SG_NEXT+2 - adc SG_NEXT+3,A,SG_NEXT+3 ret - -sg_advance1: - mvi SG_NOLOAD,0x80 ret # don't reload s/g next time - -# Add the array base SYNCNEG to the target offset (the target address -# is in SCSIID), and return the result in SINDEX. The accumulator -# contains the 3->8 decoding of the target ID on return. -# -ndx_dtr: - shr A,SCSIID,4 - test SBLKCTL,0x08 jz ndx_dtr_2 - or A,0x08 # Channel B entries add 8 -ndx_dtr_2: - add SINDEX,SYNCNEG,A - - and FUNCTION1,0x70,SCSIID # 3-bit target address decode - mov A,FUNCTION1 ret - -# If we need to negotiate transfer parameters, build the WDTR or SDTR message -# starting at the address passed in SINDEX. DINDEX is modified on return. -# The SCSI-II spec requires that Wide negotiation occur first and you can -# only negotiat one or the other at a time otherwise in the event of a message -# reject, you wouldn't be able to tell which message was the culpret. -# -mk_dtr: - test SCBARRAY+0,0xc0 jz return # NEEDWDTR|NEEDSDTR - test SCBARRAY+0,NEEDWDTR jnz mk_wdtr_16bit - or FLAGS, MAX_SYNC # Force an offset of 15 - -mk_sdtr: - mvi DINDIR,1 # extended message - mvi DINDIR,3 # extended message length = 3 - mvi DINDIR,1 # SDTR code - call sdtr_to_rate - mov DINDIR,RETURN_1 # REQ/ACK transfer period - test FLAGS, MAX_SYNC jnz mk_sdtr_max_sync - and DINDIR,0xf,SINDIR # Sync Offset - -mk_sdtr_done: - add MSG_LEN,-MSG_START+0,DINDEX ret # update message length - -mk_sdtr_max_sync: -# We're initiating sync negotiation, so request the max offset we can (15) - mvi DINDIR, 0x0f - xor FLAGS, MAX_SYNC - jmp mk_sdtr_done - -mk_wdtr_16bit: - mvi ARG_1,BUS_16_BIT -mk_wdtr: - mvi DINDIR,1 # extended message - mvi DINDIR,2 # extended message length = 2 - mvi DINDIR,3 # WDTR code - mov DINDIR,ARG_1 # bus width - - add MSG_LEN,-MSG_START+0,DINDEX ret # update message length - -# Set SCSI bus control signal state. This also saves the last-written -# value into a location where the higher-level driver can read it - if -# it has to send an ABORT or RESET message, then it needs to know this -# so it can assert ATN without upsetting SCSISIGO. The new value is -# expected in SINDEX. Change the actual state last to avoid contention -# from the driver. -# -scsisig: - mov SIGSTATE,SINDEX - mov SCSISIGO,SINDEX ret - -sdtr_to_rate: - call ndx_dtr # index scratch space for target - shr A,SINDIR,0x4 - dec SINDEX #Preserve SINDEX - and A,0x7 - clr RETURN_1 -sdtr_to_rate_loop: - test A,0x0f jz sdtr_to_rate_done - add RETURN_1,0x18 - dec A - jmp sdtr_to_rate_loop -sdtr_to_rate_done: - shr RETURN_1,0x2 - add RETURN_1,0x18 ret - -return: - ret diff --git a/sys/gnu/scsi/nic5000.c b/sys/gnu/scsi/nic5000.c deleted file mode 100644 index d4271df..0000000 --- a/sys/gnu/scsi/nic5000.c +++ /dev/null @@ -1,1476 +0,0 @@ -static char rcsid[] = "@(#)$Id: nic5000.c,v 1.1 1995/02/14 15:00:37 jkh Exp $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: nic5000.c,v $ - * Revision 1.1 1995/02/14 15:00:37 jkh - * An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces. - * EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface. - * Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and - * Juergen Krause <jkr@saarlink.de> - * - * This is only one part - the rest to follow in a couple of hours. - * This part is a benign import, since it doesn't affect anything else. - * - * - ******************************************************************************/ - -/* - * - * Copyright (c) 1994 Dietmar Friede (dietmar@friede.de) All rights reserved. - * FSF/FSAG GNU Copyright applies - * - * A low level driver for the NICCY-5000 ISDN/SCSI device - * - */ - -#include "snic.h" -#if NSNIC > 0 - -#define SPLSNIC splbio -#define ESUCCESS 0 -#define SNIC_RETRIES 8 -#include "sys/types.h" -#include "sys/param.h" -#include "sys/ioctl.h" -#include "sys/malloc.h" -#include "sys/kernel.h" - -#include "scsi/scsi_all.h" -#include "scsi/scsiconf.h" -#include "gnu/isdn/isdn_ioctl.h" -#include "gnu/i386/isa/niccyreg.h" -#include "gnu/scsi/scsi_nic.h" -/* #define NETBSD */ - -#undef SCSI_NOMASK -#define OPEN 1 -#define LOAD_HEAD 2 -#define LOAD_DATA 4 -#define LOAD_ENTITY 8 -#define IS_DIAL(p) (((p)&0x20)==0) -#define IS_LISTEN(p) ((p)&0x20) -#define CHAN(pl) (((pl)&7)-1) -#define C_CHAN(x) ((x)&1) -#define APPL(pl) ((((pl)>>6)&0x7f)-1) -#define CARD(pl) (((pl)>>13)&7) -#define MK_APPL(pl) (((pl)+1)<<6) -#define min(a,b) ((a)<(b)?(a):(b)) - -#define SNICOUTSTANDING 2 - -extern int hz; - -struct snic_data -{ - struct scsi_switch *sc_sw; /* address of scsi low level switch */ - int ctrl; /* so they know which one we want */ - int targ; /* our scsi target ID */ - int lu; /* out scsi lu */ - int cmdscount; /* cmds allowed outstanding by board*/ - int xfer_block_wait; - struct scsi_xfer *free_xfer; - struct scsi_xfer scsi_xfer[SNICOUTSTANDING]; /* XXX */ -}; - -struct snic_driver -{ - int size; - struct snic_data **snic_data; -}*snic_driver; - -static int next_snic_unit = 0; -static unsigned dnlnum = 0; - -static u_char ack_msg= 0xff; -static u_char snic_nxt_b; - -typedef enum -{ - DISCON, ISDISCON, DIAL, CALLED, CONNECT, IDLE, ACTIVE, WAITING, WAIT_ACK -} io_state; - -typedef struct -{ - char ctrl; - u_char msg_nr; - short plci; - short ncci; - short state; - Buffer o_buf; -} chan_t; - -struct snic_softc -{ - short sc_stat; - u_char sc_flags; - u_char sc_unit; - u_char sc_ctrl; - u_char sc_type; - u_short sc_istat; - struct scsi_msg sc_icmd; - Buffer sc_imsg; - Header sc_imsg0; - u_short sc_ostat; - struct scsi_msg sc_ocmd; - Buffer sc_omsg; - chan_t sc_chan[2]; - u_char sc_state_ind[8]; - u_char sc_gotack; -} snic_sc[NSNIC]; - -extern isdn_appl_t isdn_appl[]; -extern isdn_ctrl_t isdn_ctrl[]; -extern u_short isdn_state; -extern int ispy_applnr; -extern int Isdn_Appl, Isdn_Ctrl, Isdn_Typ; -extern void isdn_start_out(); - -static old_spy= 0; -static void snic_interupt(); -static int snic_get_msg(); -static void snic_start(); - -int snic_connect(), snic_listen(), snic_disconnect(), snic_accept(); -int snic_output(); - -#ifdef NETBSD -int snicattach(int ctrl, struct scsi_switch *scsi_switch, int physid, int *sunit) -{ - int targ, lu; -#else /* FreeBSD */ -int snicattach(int ctrl, int targ, int lu, struct scsi_switch *scsi_switch) -{ -#endif - int unit,i; - struct snic_data *snic, **snicrealloc; - struct snic_softc *sc; - int cn; - isdn_ctrl_t *ctrl0, *ctrl1; - -#ifdef NETBSD - targ = physid >> 3; - lu = physid & 7; -#endif - - if(next_snic_unit >= NSNIC) - return(0); - - unit = next_snic_unit; - if (next_snic_unit == 0) - { - snic_driver = - malloc(sizeof(struct snic_driver),M_DEVBUF,M_NOWAIT); - if(!snic_driver) - { - printf("snic%d: malloc failed\n",unit); - return(0); - } - bzero(snic_driver,sizeof(snic_driver)); - snic_driver->size = 0; - } - next_snic_unit++; - - if(unit >= snic_driver->size) - { - snicrealloc = - malloc(sizeof(snic_driver->snic_data) * next_snic_unit, - M_DEVBUF,M_NOWAIT); - if(!snicrealloc) - { - printf("snic%d: malloc failed\n",unit); - return(0); - } - /* Make sure we have something to copy before we copy it */ - bzero(snicrealloc,sizeof(snic_driver->snic_data) * next_snic_unit); - if(snic_driver->size) - { - bcopy(snic_driver->snic_data,snicrealloc, - sizeof(snic_driver->snic_data) * snic_driver->size); - free(snic_driver->snic_data,M_DEVBUF); - } - snic_driver->snic_data = snicrealloc; - snic_driver->snic_data[unit] = NULL; - snic_driver->size++; - } - - if(snic_driver->snic_data[unit]) - { - return(0); - } - - snic = snic_driver->snic_data[unit] = - malloc(sizeof(struct snic_data),M_DEVBUF,M_NOWAIT); - if(!snic) - { - printf("snic%d: malloc failed\n",unit); - return(0); - } -#ifdef NETBSD - *sunit= unit; -#endif - bzero(snic,sizeof(struct snic_data)); - - snic->sc_sw = scsi_switch; - snic->ctrl = ctrl; - snic->targ = targ; - snic->lu = lu; - snic->cmdscount = SNICOUTSTANDING; /* XXX (ask the board) */ - - i = snic->cmdscount; - while(i-- ) - { - snic->scsi_xfer[i].next = snic->free_xfer; - snic->free_xfer = &snic->scsi_xfer[i]; - } - - sc = &snic_sc[unit]; - sc->sc_ctrl = -1; - sc->sc_gotack= 1; - if ((cn = isdn_ctrl_attach(2)) == -1) - { - return (0); - } - sc->sc_ctrl = cn; - - sc->sc_chan[0].plci = sc->sc_chan[1].plci = -1; - - ctrl0 = &isdn_ctrl[cn]; - ctrl1 = &isdn_ctrl[cn + 1]; - sc->sc_chan[0].ctrl = ctrl0->ctrl = cn; - sc->sc_chan[1].ctrl = ctrl1->ctrl = cn + 1; - ctrl0->o_buf = &sc->sc_chan[0].o_buf.Data[5]; - ctrl1->o_buf = &sc->sc_chan[1].o_buf.Data[5]; - - ctrl0->listen = ctrl1->listen = snic_listen; - ctrl0->disconnect = ctrl1->disconnect = snic_disconnect; - ctrl0->accept = ctrl1->accept = snic_accept; - ctrl0->connect = ctrl1->connect = snic_connect; - ctrl0->output = ctrl1->output = snic_output; - ctrl0->unit = ctrl1->unit = unit; - ctrl0->appl = ctrl1->appl = -1; - ctrl0->o_len = ctrl1->o_len = -1; - sc->sc_flags= LOAD_ENTITY; - return(1); -} - -static -struct scsi_xfer *snic_get_xs(int unit) -{ - struct scsi_xfer *xs; - struct snic_data *snic; - int s; - - snic = snic_driver->snic_data[unit]; - if (xs = snic->free_xfer) - { - snic->free_xfer = xs->next; - xs->flags = 0; - } - return(xs); -} - -static void -snic_free_xs(int unit, struct scsi_xfer *xs) -{ - struct snic_data *snic; - - snic = snic_driver->snic_data[unit]; - xs->next = snic->free_xfer; - snic->free_xfer = xs; -} - -static void -snic_timout(int unit) -{ - struct snic_softc * sc= &snic_sc[unit&0xff]; - - if(sc->sc_istat&0x100) - { - snic_interupt(unit); - return; - } - if(sc->sc_istat & 2) - sc->sc_istat= sc->sc_ostat= 0; - else if((sc->sc_istat & 0x200) == 0 ) return; - if(sc->sc_ostat & 0xff) - { - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); - return; - } - if(sc->sc_gotack) snic_start(unit); - snic_get_msg(unit); -} - -static int -isdn_small_interupt(int unit, struct scsi_xfer *xs) -{ - struct snic_data *snic = snic_driver->snic_data[unit]; - struct snic_softc * sc= &snic_sc[unit]; - Header *msg = &sc->sc_imsg0; - int c; - - switch (msg->Type) - { - case 0: - if(sc->sc_istat&0x200) - break; - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); - break; - case 0xff: - sc->sc_gotack= 1; - break; - case 0xfe: -printf("f"); - sc->sc_gotack= 1; - for(c= 0; c < 2; c++) - { - chan_t *chan = &sc->sc_chan[c]; - if(chan->state == WAIT_ACK) - { - chan->state = WAITING; - sc->sc_ostat |= c?0x800:0x400; - } - } - break; - case 0xfd: -printf("fd"); - break; - default: - return(0); - } - sc->sc_istat&= ~0xff; - sc->sc_imsg0.Type= 0; - return(1); -} - -static void -snic_get_done(int unit, struct scsi_xfer *xs) -{ - struct snic_data *snic = snic_driver->snic_data[unit]; - struct snic_softc * sc= &snic_sc[unit]; - Header *msg = &sc->sc_imsg0; - int len, error; - - error= xs->error; - - switch(error) - { - case XS_NOERROR: - if(xs->datalen == 0) - sc->sc_imsg.h.Type= 0; - - if(isdn_small_interupt(unit,xs)) break; - - if(xs->datalen < (len=(msg->DataLen + 10))) - { - struct scsi_msg *scsi_cmd= &sc->sc_icmd; - /* resubmit it */ - - sc->sc_imsg.h.Type= 0xba; - scsi_cmd->len[1]= (len>>8)&0xff; - scsi_cmd->len[2]= len&0xff; - xs->retries= SNIC_RETRIES; - xs->error = XS_NOERROR; - xs->flags &= ~ITSDONE; - xs->data = (char *) &sc->sc_imsg; - xs->datalen = len; - xs->resid = len; - - if ((*(snic->sc_sw->scsi_cmd))(xs) == SUCCESSFULLY_QUEUED) - { - return; - } - error= xs->error | 0x1000; - break; - } - if(xs->datalen <= 10) - { - sc->sc_istat|= 0x400; - sc->sc_imsg.h = sc->sc_imsg0; - } - sc->sc_imsg0.Type= 0; - break; - - case XS_TIMEOUT: - case XS_BUSY: - case XS_DRIVER_STUFFUP: - break; - default: - printf("snic%d: unknown error %x\n",unit,xs->error); - } - - if(error) - { - sc->sc_imsg.h.Type= sc->sc_imsg0.Type= 0; - sc->sc_istat&= 0x200; - if((sc->sc_istat&0x200) == 0) - { - sc->sc_istat= 0x200; - timeout(snic_timout,unit,2); - } - } - - snic_free_xs(unit,xs); - if(sc->sc_istat&0x4ff == 0x400 ) - sc->sc_istat|= 1; - if(sc->sc_istat&0xff) - { - snic_interupt(unit); - return; - } - if(sc->sc_gotack) snic_start(unit); - if(sc->sc_istat & 0x200) - return; - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); -} - -static int -snic_get_msg(unit) -int unit; -{ - struct snic_data *snic = snic_driver->snic_data[unit]; - struct snic_softc * sc= &snic_sc[unit]; - struct scsi_msg *scsi_cmd= &sc->sc_icmd; - struct scsi_xfer *xs; - Header *data= &sc->sc_imsg0; - int retval; - - if(sc->sc_istat&0xff) - return(-1); - sc->sc_istat |= 1; - - data->Type= 0xbb; - sc->sc_istat &= ~0x200; - - bzero(scsi_cmd, sizeof(struct scsi_msg)); - bzero(data,10); - - scsi_cmd->op_code = GET_MSG_COMMAND; - scsi_cmd->len[2]= 10; - - xs = snic_get_xs(unit); - if(!xs) - { - sc->sc_istat&= ~0xff; - data->Type= 0; - return(EBUSY); - } - - xs->flags |= (INUSE | SCSI_DATA_IN | SCSI_NOSLEEP); - xs->adapter = snic->ctrl; - xs->targ = snic->targ; - xs->lu = snic->lu; - xs->retries = SNIC_RETRIES; - xs->timeout = 2000; - xs->cmd = (struct scsi_generic *) scsi_cmd; - xs->cmdlen = sizeof(struct scsi_msg); - xs->data = (char *) data; - xs->datalen = 10; - xs->resid = 10; - xs->when_done = snic_get_done; - xs->done_arg = unit; - xs->done_arg2 = (int)xs; - xs->bp = NULL; - xs->error = XS_NOERROR; - - if(retval = (*(snic->sc_sw->scsi_cmd))(xs)) - { - sc->sc_istat= ~0xff; - data->Type= 0; - snic_free_xs(unit,xs); - } - return (retval); -} - -static void -snic_put_done(int unit, struct scsi_xfer *xs) -{ - int retval; - struct snic_data *snic = snic_driver->snic_data[unit]; - struct snic_softc * sc= &snic_sc[unit]; - Header *b= (Header *) xs->data; - int c; - - sc->sc_ostat&= ~0xff; - if(xs->error != XS_NOERROR) - { - snic_free_xs(unit,xs); - switch(b->Type) - { - case 0: - return; - case 0xff: - sc->sc_ostat|= 0x100; - return; - case BD_DATA_B3_REQ | 0x40: - case BD_DATA_B3_REQ: - sc->sc_ostat|= 0x400; - return; - default: - sc->sc_ostat|= 0x200; - return; - } - } - - snic_free_xs(unit,xs); - - c= 0; - switch(b->Type) - { - case 0xff: break; - case BD_DATA_B3_REQ | 0x40: - c= 1; - case BD_DATA_B3_REQ: - sc->sc_chan[c].state = WAIT_ACK; - break; - default: - b->Type= 0; - } - - if(sc->sc_istat&0x100) - { - snic_interupt(unit); - return; - } - - if(sc->sc_ostat&0x100) - { - sc->sc_ostat&= ~0x100; - if(snic_put_msg(unit,&ack_msg,1,0)) - sc->sc_ostat|= 0x100; - else return; - } - - if(sc->sc_gotack) snic_start(unit); - if(sc->sc_istat&0x200) - return; - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); -} - -static void -snic_start(int unit) -{ - int retval; - struct snic_softc * sc= &snic_sc[unit]; - Header *b; - int c; - - if(sc->sc_ostat&0x200) - { - b= &sc->sc_omsg.h; - sc->sc_ostat&= ~0x200; - if(snic_put_msg(unit,b, b->DataLen+10,2)) - sc->sc_ostat|= 0x200; - else return; - } - - - for(c= 0; c<2; c++) - { - int cc= (snic_nxt_b++)&1; - u_short m= 0x400 << cc; - - if(sc->sc_ostat&m) - { - chan_t *chan= &sc->sc_chan[cc]; - b= &chan->o_buf.h; - sc->sc_ostat&= ~m; - if(chan->state == WAITING) - { - chan->state= ACTIVE; - if(snic_put_msg(unit,b, b->DataLen+10,4)) - { - chan->state= WAITING; - sc->sc_ostat|= m; - } - else return; - } - } - } -} - -int -snic_put_msg(int unit, Header *data, unsigned len, int w) -{ - struct snic_softc *sc = &snic_sc[unit]; - struct scsi_msg *scsi_cmd = &sc->sc_ocmd; - int retval; - struct scsi_xfer *xs; - struct snic_data *snic = snic_driver->snic_data[unit]; - - if(data->Type==0) - return(0); - - if(sc->sc_ostat&0xff) - return(EBUSY); - - sc->sc_ostat |= 1; - if((data->Type == 0xa8) || (data->Type == 0xe8)) - { - if(sc->sc_gotack==0) - { - sc->sc_ostat &= ~0xff; - return(EBUSY); - } - } - if(data->Type != 0xff) - sc->sc_gotack= 0; - bzero(scsi_cmd, sizeof(struct scsi_msg)); - - scsi_cmd->op_code = PUT_MSG_COMMAND; - if(len > 2063) - { - printf("snic%d: unsupported length %d\n",unit,len); - sc->sc_ostat &= ~0xff; - return(ENODEV); - } - scsi_cmd->len[1]= (len >> 8) & 0xff; - scsi_cmd->len[2]= len & 0xff; - - xs = snic_get_xs(unit); - if(!xs) - { - printf("snic pm%d: busy %d\n", unit, w); - sc->sc_ostat &= ~0xff; - return(EBUSY); - } - xs->flags |= (INUSE | SCSI_DATA_OUT | SCSI_NOSLEEP); - xs->adapter = snic->ctrl; - xs->targ = snic->targ; - xs->lu = snic->lu; - xs->retries = SNIC_RETRIES; - xs->timeout = 2000; - xs->cmd = (struct scsi_generic *) scsi_cmd; - xs->cmdlen = sizeof(struct scsi_msg); - xs->data = (char *)data; - xs->datalen = len; - xs->resid = len; - xs->when_done = snic_put_done; - xs->done_arg = unit; - xs->done_arg2 = (int)xs; - xs->bp = NULL; - xs->error = XS_NOERROR; - - if(retval = (*(snic->sc_sw->scsi_cmd))(xs)) - { - sc->sc_ostat &= ~0xff; - snic_free_xs(unit,xs); - return(EBUSY); - } - - return(0); -} - -int -snicopen(dev_t dev, int flag) -{ - struct snic_softc *sc; - u_char unit; - int x; - unsigned error; - u_char b= 0xff; - - unit = minor(dev); - /* minor number out of limits ? */ - if (unit >= next_snic_unit) - return (ENXIO); - sc = &snic_sc[unit]; - - x= splhigh(); - /* Card busy ? */ - if (sc->sc_flags & 7) - { - splx(x); - return (EBUSY); - } - sc->sc_flags |= OPEN; - - if(sc->sc_flags & LOAD_ENTITY) - { - snic_get_msg(unit); -/* - if(snic_put_msg(unit,(Header *) &ack_msg,1,5)) - sc->sc_ostat|= 0x100; -*/ - } - - splx(x); - return (0); -} - -int -snicclose(dev_t dev, int flag) -{ - struct snic_softc *sc = &snic_sc[minor(dev)]; - - sc->sc_flags &= ~7; - return (0); -} - -int -snicioctl(dev_t dev, int cmd, caddr_t data, int flag) -{ - int error; - u_char unit= minor(dev); - int i, x; - struct snic_softc *sc = &snic_sc[minor(dev)]; - Buffer *b= &sc->sc_omsg; - - error = 0; - x= splhigh(); - while(sc->sc_ostat || (sc->sc_gotack==0)) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "ioctl", 2); - if (error != EWOULDBLOCK) - { - splx(x); - return(error); - } - } - - switch (cmd) - { - case NICCY_DEBUG: - data[0]= 0x50; - bcopy(sc->sc_state_ind,data+1,8); - break; - case NICCY_LOAD: - { - struct head *head = (struct head *) data; - int len, l, off; - - bzero(b, 22); - b->h.Type = MD_DNL_MOD_REQ; - sc->sc_type = head->typ; - b->h.SubType = head->typ; - b->h.DataLen = 12; - bcopy(head->nam, b->Data, 8); - bcopy(&head->len, &b->Data[8], 4); - - sc->sc_flags |= LOAD_HEAD; - sc->sc_stat = -1; - while((error= snic_put_msg(unit,(Header *) b,22,6)) == EBUSY) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic1", 1); - if (error != EWOULDBLOCK) - break; - } - if(error == 0) - { - while (sc->sc_flags & LOAD_HEAD) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic2", 1); - if (error != EWOULDBLOCK) - break; - error= 0; - } - } - if (sc->sc_flags & 7) - sc->sc_flags = (sc->sc_flags & ~7 ) | OPEN; - if(error) - { - head->status = sc->sc_stat; - splx(x); - return (error); - } - - len= head->d_len; - off= 0; - while(len > 0) - { - while(sc->sc_ostat || (sc->sc_gotack==0)) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic7", 2); - if (error != EWOULDBLOCK) - { - splx(x); - return(error); - } - } - bzero(b,10); - b->h.Type = MD_DNL_MOD_DATA; - sc->sc_type = head->typ; - b->h.SubType = head->typ; - l= min(len,512); - len-= l; - b->h.DataLen = l + 8; - b->h.Number = dnlnum++; - b->h.MoreData= len>0; - bcopy(head->nam, b->Data, 8); - if(error= copyin(head->data+off, b->Data+8, l)) - { - splx(x); - return(error); - } - off+= l; - sc->sc_flags |= LOAD_DATA; - sc->sc_stat = -1; - - while((error= snic_put_msg(unit,(Header *) b,b->h.DataLen+10,7)) == EBUSY) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic3", 1); - if (error != EWOULDBLOCK) - break; - } - } - - if(error == 0) - { - while (sc->sc_flags & LOAD_DATA) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic4", 1); - if (error != EWOULDBLOCK) - break; - error= 0; - } - } - if (sc->sc_flags & 7) - sc->sc_flags = (sc->sc_flags & ~7 ) | OPEN; - head->status = sc->sc_stat; - splx(x); - return (error); - } - case NICCY_SET_CLOCK: - bzero(b,10); - b->h.Type = MD_SET_CLOCK_REQ; - b->h.DataLen = 14; - bcopy(data, b->Data,14); - while((error= snic_put_msg(unit,(Header *) b,24,8)) == EBUSY) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic5", 1); - if (error != EWOULDBLOCK) - break; - } - splx(x); - return (error); - case NICCY_SPY: - bzero(b,10); - b->h.Type = MD_MANUFACT_REQ; - b->h.SubType = 18; - b->h.DataLen = 1; -/* There are ilegal states. So I use them to toggle */ - if((data[0] == 0) && (old_spy == 0)) data[0]= 255; - else if(data[0] && old_spy ) data[0]= 0; - old_spy= b->Data[0]= data[0]; - while((error= snic_put_msg(unit,(Header *) b,11,9)) == EBUSY) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic6", 1); - if (error != EWOULDBLOCK) - break; - } - splx(x); - return (error); - case NICCY_RESET: - bzero(b,10); - b->h.Type = MD_RESET_REQ; - while((error= snic_put_msg(unit,(Header *) b,10,9)) == EBUSY) - { - error = tsleep((caddr_t) sc, PZERO | PCATCH, "nic6", 1); - if (error != EWOULDBLOCK) - break; - } - sc->sc_flags|= LOAD_ENTITY; - splx(x); - return (error); - - default: - error = ENODEV; - } - splx(x); - return (error); -} - -#define con_b3_req(unit,mb,pl) en_q(unit,mb|BD_CONN_B3_REQ,0,pl,0,NULL) -#define con_act_resp(unit,pl) en_q(unit,DD_CONN_ACT_RSP,0, pl,0,NULL) -#define discon_resp(sc,pl) en_q(unit,DD_DISC_RSP,0, pl,0,NULL) -#define inf_resp(unit,pl) en_q(unit,DD_INFO_RSP,0, pl,0,NULL) -#define listen_b3_req(unit,mb,pl) en_q(unit,mb|BD_LIST_B3_REQ,0,pl,0,NULL) -#define con_resp(unit,pl,rea) en_q(unit,DD_CONN_RSP,0, pl, 1,(u_char *) &rea) - -static int -en_q(int unit, int t, int st, int pl, int l, u_char *val) -{ - struct snic_softc * sc= &snic_sc[unit]; - Buffer *b= &sc->sc_omsg; - int error= 0; - - if(b->h.Type) - { - return(EBUSY); - } - bzero(b,10); -if(( t >= 0x80) && CHAN(pl) && ((t & 0x40) == 0)) -printf("?%x %x",t,pl); -if(t>=0x40) -printf("S%x %x",t,pl); - - b->h.Type = t; - b->h.SubType = st; - b->h.PLCI = pl; - if(l) - { - b->h.DataLen= l; - bcopy(val,b->Data,l); - } - - if((error= snic_put_msg(unit,(Header *) b,10+l,13)) == EBUSY) - { - sc->sc_ostat|= 0x200; - return(0); - } - return(error); -} - -static int -reset_plci(int w, chan_t * chan, short p) -{ - isdn_ctrl_t *ctrl; - - if (p == -1) - return (-1); - - if(chan == NULL) - return(p); - - ctrl = &isdn_ctrl[chan->ctrl]; - if(chan->plci == p) - { - if (ISBUSY(ctrl->appl)) - { - isdn_disconn_ind(ctrl->appl); - isdn_appl[ctrl->appl].ctrl = -1; - isdn_appl[ctrl->appl].state = 0; - } - ctrl->appl = -1; - ctrl->o_len = -1; - chan->plci = -1; - chan->ncci = -1; - chan->state = DISCON; - chan->o_buf.h.Type= 0; - } - return (p); -} - -static int -sel_b2_prot_req(int unit, int c, int pl, dlpd_t * dlpd) -{ - return(en_q(unit, (c ? 0x40 : 0)| BD_SEL_PROT_REQ, 2, pl, sizeof(dlpd_t), (u_char *) dlpd)); -} - -static int -sel_b3_prot_req(int unit, int mb, u_short pl, ncpd_t * ncpd) -{ - return(en_q(unit, mb | BD_SEL_PROT_REQ, 3, pl, sizeof(ncpd_t), (u_char *) ncpd)); -} - -static int -discon_req(int w, int unit , int pl, int rea, int err) -{ - if((pl == 0) || (pl == -1)) - return(0); - return(en_q(unit, DD_DISC_REQ,0, pl, 1, (u_char *) &rea)); -} - -static int -state_ind(int unit, int api, int spv) -{ - u_char buf[3]; - - buf[0]= unit; buf[1]= api; buf[2]= spv; - return(en_q(unit, MD_STATE_IND,0, 0, 3, buf)); -} - -static int -con_b3_resp(int unit, int mb, u_short ncci, u_short pl, u_char reject) -{ - u_char buf[32]; - int l = 4; - - bzero(buf, 32); - *(u_short *) buf = ncci; - buf[2] = reject; - buf[3] = 0; /* ncpi ??? */ - l += 15; - return(en_q(unit, mb | BD_CONN_B3_RSP,0, pl, l, buf)); -} - -int -snic_connect(int cn, int ap, int b_channel, int inf_mask, int out_serv - ,int out_serv_add, int src_subadr, unsigned ad_len - ,char *dest_addr, int spv) -{ - char buf[128]; - - if (ad_len > 118) - return (-1); - - buf[0] = spv ? 0x53 : 0; - buf[1] = b_channel; - if (spv) - inf_mask |= 0x40000000; - *(u_long *) & buf[2] = inf_mask; - buf[6] = out_serv; - buf[7] = out_serv_add; - buf[8] = src_subadr; - buf[9] = ad_len; - bcopy(dest_addr, &buf[10], ad_len); - return (en_q(isdn_ctrl[cn].unit, DD_CONN_REQ, 0, MK_APPL(ap), ad_len + 10, buf)); -} - -int -snic_listen(int cn, int ap, int inf_mask, int subadr_mask, int si_mask, int spv) -{ - u_short sbuf[4]; - - if (spv) - inf_mask |= 0x40000000; - *(u_long *) sbuf = inf_mask; - sbuf[2] = subadr_mask; - sbuf[3] = si_mask; - return (en_q(isdn_ctrl[cn].unit, DD_LISTEN_REQ, 0, MK_APPL(ap), 8, (u_char *) sbuf)); -} - -int -snic_disconnect(int cn, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - chan_t *chan = &snic_sc[ctrl->unit].sc_chan[C_CHAN(cn)]; - int p, err; - u_char buf[16]; - - if(chan->ncci != -1) - { - bzero(buf,16); - *(u_short *) buf = chan->ncci; - err= en_q(ctrl->unit, (C_CHAN(cn)?0x40:0)|BD_DISC_B3_REQ, 0 - , chan->plci, 3+sizeof(ncpi_t), buf); - if((err==0) && (ctrl->o_len == 0)) - ctrl->o_len= -1; - return(err); - } - p = chan->plci; - if ((p == 0) || (p == -1)) - return (ENODEV); - - err= en_q(ctrl->unit, DD_DISC_REQ, 0, p, 1, (u_char *) &rea); - if((err==0) && (ctrl->o_len == 0)) - ctrl->o_len= -1; - return(err); -} - -int -snic_accept(int cn, int an, int rea) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct snic_softc *sc = &snic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - isdn_appl_t *appl = &isdn_appl[an]; - - if(ISFREE(ctrl->appl)) - return(ENODEV); - - if (rea) - { - ctrl->appl= -1; - return(discon_req(1, ctrl->unit, chan->plci, rea, 0)); - } - ctrl->appl= an; - ctrl->lastact = time.tv_sec; - appl->ctrl= cn; - appl->state= 4; - - return(sel_b2_prot_req(ctrl->unit, C_CHAN(cn), chan->plci, &appl->dlpd)); -} - -int -snic_output(int cn) -{ - isdn_ctrl_t *ctrl = &isdn_ctrl[cn]; - struct snic_softc *sc = &snic_sc[ctrl->unit]; - chan_t *chan = &sc->sc_chan[C_CHAN(cn)]; - int len= ctrl->o_len; - Buffer *b= &chan->o_buf; - int error= 0; - - if (sc->sc_state_ind[1] || (chan->ncci == -1)) - return (ENODEV); - - if(chan->state != IDLE) - return(EBUSY); - chan->state= WAITING; - - bzero(b,10); - - b->h.Type = BD_DATA_B3_REQ; - if(C_CHAN(cn)) b->h.Type |= 0x40; - b->h.PLCI = chan->plci; - b->h.DataLen= len+5; - *(u_short *) b->Data = chan->ncci; - *(u_short *) &b->Data[2] = 0; - b->h.Number = b->Data[4] = chan->msg_nr++; - - chan->state = ACTIVE; - ctrl->lastact = time.tv_sec; - - if((error= snic_put_msg(ctrl->unit,(Header *) b,15+len,14)) == EBUSY) - { - sc->sc_ostat|= C_CHAN(cn)?0x800:0x400; - chan->state= WAITING; - return(0); - } - return(error); -} - -static void -badstate(Header *h, int n) -{ - int i; - u_char *p= (u_char *)h; - printf("Niccy: not implemented %x.%x len %d at %d", h->Type, - h->SubType, h->DataLen,n); - if(h->DataLen) - { - p+= 10; - for(i=0; i < h->DataLen ; i++) printf(" %x",p[i]); - } - printf("\n"); -} - -unsigned SavMsgTyp; - -static void -snic_interupt(unsigned unit) -{ - struct snic_softc * sc= &snic_sc[unit&0xff]; - Buffer *msg; - chan_t *chan; - u_short n, mb, c, pl, err = 0; - isdn_ctrl_t *ctrl; - isdn_appl_t *appl; - int error= 0; - - msg = &sc->sc_imsg; - chan= NULL; - ctrl= NULL; - appl= NULL; - -SavMsgTyp= msg->h.Type; - - if(sc->sc_istat & 2) - return; - - if(sc->sc_ostat&0xff) - { - sc->sc_istat|= 0x101; - if(sc->sc_istat&0x200) - return; - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); - return; - } - - mb= 0; - pl = msg->h.PLCI; - if(pl && (msg->h.Type >= 0x40) && (msg->h.Type < 0xfd) && (msg->h.Type != 0x47)) - { - if ((c = CHAN(pl)) < 2) - { - chan = &sc->sc_chan[c]; - ctrl = &isdn_ctrl[chan->ctrl]; - } else - { - c = 0xffff; - chan= NULL; - ctrl= NULL; - } - - if(ctrl && (ctrl->appl & 0xC0) == 0) - appl= &isdn_appl[ctrl->appl]; - else if( APPL(pl) < 0x30) - appl = &isdn_appl[APPL(pl)]; - else if( APPL(pl) < 0x40) - appl= NULL; - else goto fin; - - if(msg->h.Type >= 0x80) - { - mb= msg->h.Type & 0x40; - msg->h.Type &= 0xbf; - } - } -SavMsgTyp|= 0x100; - -if(msg->h.Type>=0x40) -printf("I%x %x %x",msg->h.Type,pl,mb); - switch (msg->h.Type) - { - case 0x01: /* INIT IND */ - case 0x15: /* POLL IND */ - error= en_q(unit,msg->h.Type|0x20,0,0,0,NULL); - break; - case 0x04: /* DNL MOD CONF */ - sc->sc_stat = msg->Data[0]; - if (sc->sc_flags & 7) - sc->sc_flags = (sc->sc_flags & ~7) | OPEN; - break; - case 0x06: /* DNL MOD IND */ - sc->sc_stat = msg->Data[0]; - error= en_q(unit,msg->h.Type|0x20,sc->sc_type,0,1, &msg->Data[1]); - if(sc->sc_flags & LOAD_ENTITY) - { - sc->sc_istat= sc->sc_ostat= 2; - timeout(snic_timout,unit,hz); - msg->h.Type= 0; - return; - } - if (sc->sc_flags) - sc->sc_flags = OPEN; - break; - case 0x0e: /* SET CLOCK CONF */ - error= state_ind(unit,1,0); - break; - case 0x16: /* STATE IND */ - if(sc->sc_flags & LOAD_ENTITY) - { - if(sc->sc_flags & 7) - sc->sc_flags = OPEN; - else sc->sc_flags= 0; - } - bcopy( msg->Data, sc->sc_state_ind, 8); - error= en_q(unit,msg->h.Type|0x20,0,0,0,NULL); - break; - case 0x17: /* STATE RESP */ - bcopy( msg->Data, sc->sc_state_ind, 8); - break; - case 0x1e: /* MANUFACT CONF */ - if(msg->h.SubType == 18) - break; - badstate(&msg->h,1); - break; - case 0x1f: /* MANUFACT IND */ - if(msg->h.SubType == 19) - { - isdn_input(ispy_applnr, msg->h.DataLen, msg->Data,0); - error= en_q(unit,msg->h.Type|0x20,msg->h.SubType,0,0,NULL); - break; - } - badstate(&msg->h,2); - break; - case 0x40: /* CONNECT CONF */ - err = *(u_short *) msg->Data; - if (err || (appl == NULL) || (chan == NULL) || (ctrl == NULL)) - { - if(chan) reset_plci(3, chan, pl); - if(appl) appl->state= 0; - break; - } - if (ISBUSY(ctrl->appl)) - { - error= discon_req(2, unit, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr = 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = APPL(pl); - appl->ctrl = chan->ctrl; - ctrl->islisten= 0; - chan->state = DIAL; - appl->state= 3; - break; - - case 0x41: /* CONNECT IND */ - if (ISBUSY(ctrl->appl)) - { - error= discon_req(3, unit, pl, 0, 0); - break; - } - chan->plci = pl; - chan->msg_nr = 0; - chan->ncci = -1; - ctrl->lastact = time.tv_sec; - ctrl->appl = 0x7f; - ctrl->islisten= 1; - chan->state = CALLED; - msg->Data[msg->Data[3] + 4] = 0; - isdn_accept_con_ind(APPL(pl), chan->ctrl, msg->Data[0], msg->Data[1] - ,msg->Data[2], msg->Data[3], (char *) &msg->Data[4]); - break; - - case 0x42: /* CONNECT ACTIVE IND */ - error= con_act_resp(unit, pl); - if (IS_LISTEN(pl)) - { - isdn_conn_ind(ctrl->appl,chan->ctrl,0); - break; - } - isdn_conn_ind(APPL(pl),chan->ctrl,1); - chan->state = CONNECT; - ctrl->appl = APPL(pl); - appl->ctrl = chan->ctrl; - break; - - case 0x43: /* DISCONNECT CONF */ - reset_plci(4, chan, pl); - break; - - case 0x44: /* DISCONNECT IND */ - error= discon_resp(unit, reset_plci(5, chan, pl)); - break; - - case 0x47: /* LISTEN CONF */ - isdn_state = *(u_short *) msg->Data; - break; - - case 0x4a: /* INFO IND */ - isdn_info(APPL(pl),*(u_short *)msg->Data, msg->Data[2], msg->Data+3); - error= inf_resp(unit, pl); - break; - case 0x80: /* SELECT PROT CONF */ - err = *(u_short *) msg->Data; - if (err) - { - error= discon_req(4, unit, pl, 0, err); - break; - } - - switch (msg->h.SubType) - { - case 2:/* SELECT B2 PROTOCOL */ - if(ISFREE(ctrl->appl)) - break; - error= sel_b3_prot_req(unit, mb, pl, &isdn_appl[ctrl->appl].ncpd); - break; - - case 3:/* SELECT B3 PROTOCOL */ - if (IS_DIAL(pl)) - error= con_b3_req(unit, mb, pl); - else - error= listen_b3_req(unit, mb, pl); - break; - } - break; - - case 0x81: /* LISTEN B3 CONF */ - err = *(u_short *) msg->Data; - if (err) - { - error= discon_req(5, unit, pl, 0, err); - break; - } - error= con_resp(unit, pl, err); - break; - - case 0x82: /* CONNECT B3 CONF */ - err = *(u_short *) (msg->Data + 2); - n = *(u_short *) msg->Data; - - if (err) - { - error= discon_req(6, unit, pl, 0, err); - break; - } - if(ISFREE(ctrl->appl)) - break; - chan->ncci = n; - chan->state = CONNECT; - break; - - case 0x83: /* CONNECT B3 IND */ - if(ISFREE(ctrl->appl)) - break; - n = *(u_short *) msg->Data; - chan->ncci = n; - chan->state = CONNECT; - error= con_b3_resp(unit, mb, n, pl, 0); - break; - - case 0x84: /* CONNECT B3 ACTIVE IND */ - if(ISFREE(ctrl->appl)) - break; - if (chan->state < IDLE) - { - chan->state = IDLE; - ctrl->o_len = 0; - timeout(isdn_start_out,chan->ctrl,hz/5); - } - break; - - case 0x85: /* DISCONNECT B3 CONF */ - if(ISBUSY(ctrl->appl)) - chan->state = ISDISCON; - err = *(u_short *) (msg->Data + 2); - if (err) - { - error= discon_req(7, unit, pl, 0, err); - break; - } - break; - case 0x86: /* DISCONNECT B3 IND */ - if(ISBUSY(ctrl->appl)) - chan->state = ISDISCON; - err = *(u_short *) (msg->Data + 2); - error= discon_req(8, unit, pl, 0, err); - break; - - case 0x88: /* DATA B3 CONF */ - if(ISFREE(ctrl->appl)) - break; - err = *(u_short *) (msg->Data + 2); - if (err) - { -printf("e%x\n",err); - ctrl->send_err++; - isdn_appl[ctrl->appl].send_err++; - } - chan->state = IDLE; - chan->o_buf.h.Type= 0; - ctrl->o_len = 0; - isdn_start_out(chan->ctrl); - break; - - case 0x89: /* DATA B3 IND */ - if(ISFREE(ctrl->appl)) - break; - if(isdn_input(ctrl->appl, msg->h.DataLen-5, msg->Data+5,ctrl->islisten)) - ctrl->lastact = time.tv_sec; - break; - - default: - badstate(&msg->h,3); - break; - } - -fin: - if(error) - { -printf("x%x %x %x %x %x\n",error,msg->h.Type,sc->sc_istat,sc->sc_ostat,sc->sc_omsg.h.Type); - sc->sc_istat|= 0x101; - if(sc->sc_istat&0x200) - return; - sc->sc_istat|= 0x200; - timeout(snic_timout,unit,2); - return; - } - - msg->h.Type= 0; - if(snic_put_msg(unit,(Header *) &ack_msg,1,15)) - sc->sc_ostat|= 0x100; - sc->sc_istat= 0x200; - snic_get_msg(unit); -} - -#endif /* NSNIC > 0 */ diff --git a/sys/gnu/scsi/scsi_nic.h b/sys/gnu/scsi/scsi_nic.h deleted file mode 100644 index 4847df8..0000000 --- a/sys/gnu/scsi/scsi_nic.h +++ /dev/null @@ -1,53 +0,0 @@ -static char rcsid[] = "@(#)$Id: scsi_nic.h,v 1.1 1995/01/25 14:06:18 jkr Exp jkr $"; -/******************************************************************************* - * II - Version 0.1 $Revision: 1.1 $ $State: Exp $ - * - * Copyright 1994 Dietmar Friede - ******************************************************************************* - * Bug reports, patches, comments, suggestions should be sent to: - * - * jkr@saarlink.de or jkrause@guug.de - * - ******************************************************************************* - * $Log: scsi_nic.h,v $ - * - ******************************************************************************/ - -/* - * This file defines the NICCY 5000 Interface. - * Copyright Dr. Neuhaus GmbH, Hamburg and Dietmar Friede - * -*/ -#define GET_MSG_COMMAND 0x08 -#define PUT_MSG_COMMAND 0x0a - -#pragma pack (1) -struct scsi_msg -{ - u_char op_code; - u_char dummy; - u_char len[3]; - u_char control; -}; - -typedef struct -{ - unsigned char Type; - unsigned char SubType; - unsigned short Number ; - unsigned char MoreData ; - unsigned char Reserved[1] ; - unsigned short DataLen ; - unsigned short PLCI; -} Header; - -#define SNIC_BUF_SIZE 2048+15 - -typedef struct -{ - Header h; - unsigned char Data[SNIC_BUF_SIZE]; -} Buffer; - -#pragma pack () - |