!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/s390/char/   drwxr-xr-x
Free 318.32 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     tapechar.c (21.12 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |

/***************************************************************************
 *
 *  drivers/s390/char/tapechar.c
 *    character device frontend for tape device driver
 *
 *  S390 and zSeries version
 *    Copyright (C) 2001 IBM Corporation
 *    Author(s): Carsten Otte <cotte@de.ibm.com>
 *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
 *
 *
 ****************************************************************************
 */

#include "tapedefs.h"
#include <linux/config.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <asm/ccwcache.h>    /* CCW allocations      */
#include <asm/s390dyn.h>
#include <asm/debug.h>
#include <linux/mtio.h>
#include <asm/uaccess.h>
#include <linux/compatmac.h>
#ifdef MODULE
#define __NO_VERSION__
#include <linux/module.h>
#endif
#include "tape.h"
#include "tapechar.h"

#define PRINTK_HEADER "TCHAR:"

/*
 * file operation structure for tape devices
 */
static struct file_operations tape_fops =
{
    //    owner   : THIS_MODULE,
    llseek:NULL,        /* lseek - default */
    read:tape_read,        /* read  */
    write:tape_write,    /* write */
    readdir:NULL,        /* readdir - bad */
    poll:NULL,        /* poll */
    ioctl:tape_ioctl,    /* ioctl */
    mmap:NULL,        /* mmap */
    open:tape_open,        /* open */
    flush:NULL,        /* flush */
    release:tape_release,    /* release */
    fsync:NULL,        /* fsync */
    fasync:NULL,        /* fasync */
    lock:NULL,
};

int tape_major = TAPE_MAJOR;

#ifdef CONFIG_DEVFS_FS
void
tapechar_mkdevfstree (tape_info_t* ti) {
    ti->devfs_char_dir=devfs_mk_dir (ti->devfs_dir, "char", ti);
    ti->devfs_nonrewinding=devfs_register(ti->devfs_char_dir, "nonrewinding",
                        DEVFS_FL_DEFAULT,tape_major, 
                        ti->nor_minor, TAPECHAR_DEFAULTMODE, 
                        &tape_fops, ti);
    ti->devfs_rewinding=devfs_register(ti->devfs_char_dir, "rewinding",
                     DEVFS_FL_DEFAULT, tape_major, ti->rew_minor,
                     TAPECHAR_DEFAULTMODE, &tape_fops, ti);
}

void
tapechar_rmdevfstree (tape_info_t* ti) {
    devfs_unregister(ti->devfs_nonrewinding);
    devfs_unregister(ti->devfs_rewinding);
    devfs_unregister(ti->devfs_char_dir);
}
#endif

void
tapechar_setup (tape_info_t * ti)
{
#ifdef CONFIG_DEVFS_FS
    tapechar_mkdevfstree(ti);
#endif
}

void
tapechar_init (void)
{
    int result;
    tape_frontend_t *charfront,*temp;
    tape_info_t* ti;

    tape_init();

    /* Register the tape major number to the kernel */
#ifdef CONFIG_DEVFS_FS
    result = devfs_register_chrdev (tape_major, "tape", &tape_fops);
#else
    result = register_chrdev (tape_major, "tape", &tape_fops);
#endif

    if (result < 0) {
        PRINT_WARN (KERN_ERR "tape: can't get major %d\n", tape_major);
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,3,"c:initfail");
        debug_text_event (tape_debug_area,3,"regchrfail");
#endif /* TAPE_DEBUG */
        panic ("no major number available for tape char device");
    }
    if (tape_major == 0)
        tape_major = result;    /* accept dynamic major number */
    PRINT_WARN (KERN_ERR " tape gets major %d for character device\n", result);
    charfront = kmalloc (sizeof (tape_frontend_t), GFP_KERNEL);
    if (charfront == NULL) {
#ifdef TAPE_DEBUG
                debug_text_event (tape_debug_area,3,"c:initfail");
        debug_text_event (tape_debug_area,3,"no mem");
#endif /* TAPE_DEBUG */
        panic ("no major number available for tape char device");        
    }
    charfront->device_setup = tapechar_setup;
#ifdef CONFIG_DEVFS_FS
    charfront->mkdevfstree = tapechar_mkdevfstree;
    charfront->rmdevfstree = tapechar_rmdevfstree;
#endif
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,3,"c:init ok");
#endif /* TAPE_DEBUG */
    charfront->next=NULL;
    if (first_frontend==NULL) {
        first_frontend=charfront;
    } else {
        temp=first_frontend;
        while (temp->next!=NULL)
        temp=temp->next;
        temp->next=charfront;
    }
    ti=first_tape_info;
    while (ti!=NULL) {
        tapechar_setup(ti);
        ti=ti->next;
    }
}

void
tapechar_uninit (void)
{
    unregister_chrdev (tape_major, "tape");
}

/*
 * Tape device read function
 */
ssize_t
tape_read (struct file *filp, char *data, size_t count, loff_t * ppos)
{
    long lockflags;
    tape_info_t *ti;
    size_t block_size;
    ccw_req_t *cqr;
    int rc;
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:read");
#endif /* TAPE_DEBUG */
    ti = first_tape_info;
    while ((ti != NULL) && (ti->rew_filp != filp) && (ti->nor_filp != filp))
        ti = (tape_info_t *) ti->next;
    if (ti == NULL) {
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:nodev");
#endif /* TAPE_DEBUG */
        return -ENODEV;
    }
    if (ppos != &filp->f_pos) {
        /* "A request was outside the capabilities of the device." */
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:ppos wrong");
#endif /* TAPE_DEBUG */
        return -EOVERFLOW;    /* errno=75 Value too large for def. data type */
    }
    if (ti->block_size == 0) {
        block_size = count;
    } else {
        block_size = ti->block_size;
    }
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:nbytes:");
    debug_int_event (tape_debug_area,6,block_size);
#endif
    cqr = ti->discipline->read_block (data, block_size, ti);
    if (!cqr) {
        return -ENOBUFS;
    }
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    ti->cqr = cqr;
    ti->wanna_wakeup=0;
    rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
    if (rc) {
        tapestate_set(ti,TS_IDLE);
        kfree (cqr);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        return rc;
    }
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
    wait_event (ti->wq,ti->wanna_wakeup);
    ti->cqr = NULL;
    ti->discipline->free_read_block (cqr, ti);
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    if (tapestate_get (ti) == TS_FAILED) {
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        return ti->rc;
    }
    if (tapestate_get (ti) == TS_NOT_OPER) {
        ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
        ti->devinfo.irq=-1;
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
        return -ENODEV;
    }
    if (tapestate_get (ti) != TS_DONE) {
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        return -EIO;
    }
    tapestate_set (ti, TS_IDLE);
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:rbytes:");
    debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
#endif    /* TAPE_DEBUG */
    filp->f_pos += block_size - ti->devstat.rescnt;
    return block_size - ti->devstat.rescnt;
}

/*
 * Tape device write function
 */
ssize_t
tape_write (struct file *filp, const char *data, size_t count, loff_t * ppos)
{
    long lockflags;
    tape_info_t *ti;
    size_t block_size;
    ccw_req_t *cqr;
    int nblocks, i, rc;
    size_t written = 0;
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:write");
#endif
    ti = first_tape_info;
    while ((ti != NULL) && (ti->nor_filp != filp) && (ti->rew_filp != filp))
        ti = (tape_info_t *) ti->next;
    if (ti == NULL)
        return -ENODEV;
    if (ppos != &filp->f_pos) {
        /* "A request was outside the capabilities of the device." */
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:ppos wrong");
#endif
        return -EOVERFLOW;    /* errno=75 Value too large for def. data type */
    }
    if ((ti->block_size != 0) && (count % ti->block_size != 0))
        return -EIO;
    if (ti->block_size == 0) {
        block_size = count;
        nblocks = 1;
    } else {
        block_size = ti->block_size;
        nblocks = count / (ti->block_size);
    }
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:nbytes:");
        debug_int_event (tape_debug_area,6,block_size);
            debug_text_event (tape_debug_area,6,"c:nblocks:");
            debug_int_event (tape_debug_area,6,nblocks);
#endif
    for (i = 0; i < nblocks; i++) {
        cqr = ti->discipline->write_block (data + i * block_size, block_size, ti);
        if (!cqr) {
            return -ENOBUFS;
        }
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        ti->cqr = cqr;
        ti->wanna_wakeup=0;
        rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        wait_event_interruptible (ti->wq,ti->wanna_wakeup);
        ti->cqr = NULL;
        ti->discipline->free_write_block (cqr, ti);
        if (signal_pending (current)) {
            tapestate_set (ti, TS_IDLE);
            return -ERESTARTSYS;
        }
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        if (tapestate_get (ti) == TS_FAILED) {
            tapestate_set (ti, TS_IDLE);
            s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
                        if ((ti->rc==-ENOSPC) && (i!=0))
              return i*block_size;
            return ti->rc;
        }
        if (tapestate_get (ti) == TS_NOT_OPER) {
            ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
            ti->devinfo.irq=-1;
            s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
            return -ENODEV;
        }
        if (tapestate_get (ti) != TS_DONE) {
            tapestate_set (ti, TS_IDLE);
            s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
            return -EIO;
        }
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:wbytes:"); 
        debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
#endif
        filp->f_pos += block_size - ti->devstat.rescnt;
        written += block_size - ti->devstat.rescnt;
        if (ti->devstat.rescnt > 0)
            return written;
    }
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:wtotal:");
    debug_int_event (tape_debug_area,6,written);
#endif
    return written;
}

static int
tape_mtioctop (struct file *filp, short mt_op, int mt_count)
{
    tape_info_t *ti;
    ccw_req_t *cqr = NULL;
    int rc;
    long lockflags;
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:mtio");
    debug_text_event (tape_debug_area,6,"c:ioop:");
    debug_int_event (tape_debug_area,6,mt_op); 
    debug_text_event (tape_debug_area,6,"c:arg:");
    debug_int_event (tape_debug_area,6,mt_count);
#endif
    ti = first_tape_info;
    while ((ti != NULL) && (ti->rew_filp != filp) && (ti->nor_filp != filp))
        ti = (tape_info_t *) ti->next;
    if (ti == NULL)
        return -ENODEV;
    switch (mt_op) {
    case MTREW:        // rewind

        cqr = ti->discipline->mtrew (ti, mt_count);
        break;
    case MTOFFL:        // put drive offline

        cqr = ti->discipline->mtoffl (ti, mt_count);
        break;
    case MTUNLOAD:        // unload the tape

        cqr = ti->discipline->mtunload (ti, mt_count);
        break;
    case MTWEOF:        // write tapemark

        cqr = ti->discipline->mtweof (ti, mt_count);
        break;
    case MTFSF:        // forward space file

        cqr = ti->discipline->mtfsf (ti, mt_count);
        break;
    case MTBSF:        // backward space file

        cqr = ti->discipline->mtbsf (ti, mt_count);
        break;
    case MTFSFM:        // forward space file, stop at BOT side

        cqr = ti->discipline->mtfsfm (ti, mt_count);
        break;
    case MTBSFM:        // backward space file, stop at BOT side

        cqr = ti->discipline->mtbsfm (ti, mt_count);
        break;
    case MTFSR:        // forward space file

        cqr = ti->discipline->mtfsr (ti, mt_count);
        break;
    case MTBSR:        // backward space file

        cqr = ti->discipline->mtbsr (ti, mt_count);
        break;
    case MTNOP:
        cqr = ti->discipline->mtnop (ti, mt_count);
        break;
    case MTEOM:        // postion at the end of portion

    case MTRETEN:        // retension the tape

        cqr = ti->discipline->mteom (ti, mt_count);
        break;
    case MTERASE:
        cqr = ti->discipline->mterase (ti, mt_count);
        break;
    case MTSETDENSITY:
        cqr = ti->discipline->mtsetdensity (ti, mt_count);
        break;
    case MTSEEK:
        cqr = ti->discipline->mtseek (ti, mt_count);
        break;
    case MTSETDRVBUFFER:
        cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
        break;
    case MTLOCK:
        cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
        break;
    case MTUNLOCK:
        cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
        break;
    case MTLOAD:
        cqr = ti->discipline->mtload (ti, mt_count);
        if (cqr!=NULL) break; // if backend driver has an load function ->use it
        // if no medium is in, wait until it gets inserted
        if (ti->medium_is_unloaded) {
            wait_event_interruptible (ti->wq,ti->medium_is_unloaded==0);
        }
        return 0;
    case MTCOMPRESSION:
        cqr = ti->discipline->mtcompression (ti, mt_count);
        break;
    case MTSETPART:
        cqr = ti->discipline->mtsetpart (ti, mt_count);
        break;
    case MTMKPART:
        cqr = ti->discipline->mtmkpart (ti, mt_count);
        break;
    case MTTELL:        // return number of block relative to current file

        cqr = ti->discipline->mttell (ti, mt_count);
        break;
    case MTSETBLK:
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        ti->block_size = mt_count;
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:setblk:");
            debug_int_event (tape_debug_area,6,mt_count);
#endif
        return 0;
    case MTRESET:
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        ti->kernbuf = ti->userbuf = NULL;
        tapestate_set (ti, TS_IDLE);
        ti->block_size = 0;
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:devreset:");
        debug_int_event (tape_debug_area,6,ti->blk_minor);
#endif
        return 0;
    default:
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:inv.mtio");
#endif
        return -EINVAL;
    }
    if (cqr == NULL) {
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:ccwg fail");
#endif
        return -ENOSPC;
    }
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    ti->cqr = cqr;
    ti->wanna_wakeup=0;
    rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
    wait_event_interruptible (ti->wq,ti->wanna_wakeup);
    ti->cqr = NULL;
    if (ti->kernbuf != NULL) {
        kfree (ti->kernbuf);
        ti->kernbuf = NULL;
    }
    tape_free_request (cqr);
    // if medium was unloaded, update the corresponding variable.
    switch (mt_op) {
    case MTOFFL:
    case MTUNLOAD:
        ti->medium_is_unloaded=1;
    }
    if (signal_pending (current)) {
        tapestate_set (ti, TS_IDLE);
        return -ERESTARTSYS;
    }
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    if (((mt_op == MTEOM) || (mt_op == MTRETEN)) && (tapestate_get (ti) == TS_FAILED))
        tapestate_set (ti, TS_DONE);
    if (tapestate_get (ti) == TS_FAILED) {
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        return ti->rc;
    }
    if (tapestate_get (ti) == TS_NOT_OPER) {
        ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
        ti->devinfo.irq=-1;
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
        return -ENODEV;
    }
    if (tapestate_get (ti) != TS_DONE) {
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        return -EIO;
    }
    tapestate_set (ti, TS_IDLE);
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
    switch (mt_op) {
    case MTRETEN:        //need to rewind the tape after moving to eom

        return tape_mtioctop (filp, MTREW, 1);
    case MTFSFM:        //need to skip back over the filemark

        return tape_mtioctop (filp, MTBSFM, 1);
    case MTBSF:        //need to skip forward over the filemark

        return tape_mtioctop (filp, MTFSF, 1);
    }
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:mtio done");
#endif
    return 0;
}

/*
 * Tape device io controls.
 */
int
tape_ioctl (struct inode *inode, struct file *filp,
        unsigned int cmd, unsigned long arg)
{
    long lockflags;
    tape_info_t *ti;
    ccw_req_t *cqr;
    struct mtop op;        /* structure for MTIOCTOP */
    struct mtpos pos;    /* structure for MTIOCPOS */
    struct mtget get;

    int rc;
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:ioct");
#endif
    ti = first_tape_info;
    while ((ti != NULL) &&
           (ti->rew_minor != MINOR (inode->i_rdev)) &&
           (ti->nor_minor != MINOR (inode->i_rdev)))
        ti = (tape_info_t *) ti->next;
    if (ti == NULL) {
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,6,"c:nodev");
#endif
        return -ENODEV;
    }
    // check for discipline ioctl overloading
    if ((rc = ti->discipline->discipline_ioctl_overload (inode, filp, cmd, arg))
        != -EINVAL) {
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:ioverloa");
#endif
        return rc;
    }

    switch (cmd) {
    case MTIOCTOP:        /* tape op command */
        if (copy_from_user (&op, (char *) arg, sizeof (struct mtop))) {
             return -EFAULT;
        }
        return (tape_mtioctop (filp, op.mt_op, op.mt_count));
    case MTIOCPOS:        /* query tape position */
        cqr = ti->discipline->mttell (ti, 0);
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        ti->cqr = cqr;
        ti->wanna_wakeup=0;
        do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        wait_event_interruptible (ti->wq,ti->wanna_wakeup);
        pos.mt_blkno = ti->rc;
        ti->cqr = NULL;
        if (ti->kernbuf != NULL) {
            kfree (ti->kernbuf);
            ti->kernbuf = NULL;
        }
        tape_free_request (cqr);
        if (signal_pending (current)) {
            tapestate_set (ti, TS_IDLE);
            return -ERESTARTSYS;
        }
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        if (copy_to_user ((char *) arg, &pos, sizeof (struct mtpos)))
             return -EFAULT;
        return 0;
    case MTIOCGET:
        get.mt_erreg = ti->rc;
        cqr = ti->discipline->mttell (ti, 0);
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        ti->cqr = cqr;
        ti->wanna_wakeup=0;
        do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        wait_event_interruptible (ti->wq,ti->wanna_wakeup);
        get.mt_blkno = ti->rc;
        get.mt_fileno = 0;
        get.mt_type = MT_ISUNKNOWN;
        get.mt_resid = ti->devstat.rescnt;
        get.mt_dsreg = ti->devstat.ii.sense.data[3];
        get.mt_gstat = 0;
        if (ti->devstat.ii.sense.data[1] & 0x08)
            get.mt_gstat &= GMT_BOT (1);    // BOT

        if (ti->devstat.ii.sense.data[1] & 0x02)
            get.mt_gstat &= GMT_WR_PROT (1);    // write protected

        if (ti->devstat.ii.sense.data[1] & 0x40)
            get.mt_gstat &= GMT_ONLINE (1);        //drive online

        ti->cqr = NULL;
        if (ti->kernbuf != NULL) {
            kfree (ti->kernbuf);
            ti->kernbuf = NULL;
        }
        tape_free_request (cqr);
        if (signal_pending (current)) {
            tapestate_set (ti, TS_IDLE);
            return -ERESTARTSYS;
        }
        s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
        tapestate_set (ti, TS_IDLE);
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
        if (copy_to_user ((char *) arg, &get, sizeof (struct mtget)))
             return -EFAULT;
        return 0;
    default:
#ifdef TAPE_DEBUG
            debug_text_event (tape_debug_area,3,"c:ioct inv");
#endif        
        return -EINVAL;
    }
}

/*
 * Tape device open function.
 */
int
tape_open (struct inode *inode, struct file *filp)
{
    tape_info_t *ti;
    kdev_t dev;
    long lockflags;

    inode = filp->f_dentry->d_inode;
    ti = first_tape_info;
    while ((ti != NULL) &&
           (ti->rew_minor != MINOR (inode->i_rdev)) &&
           (ti->nor_minor != MINOR (inode->i_rdev)))
        ti = (tape_info_t *) ti->next;
    if (ti == NULL)
        return -ENODEV;
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:open:");
    debug_int_event (tape_debug_area,6,ti->blk_minor);
#endif
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    if (tapestate_get (ti) != TS_UNUSED) {
        s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
#ifdef TAPE_DEBUG
        debug_text_event (tape_debug_area,6,"c:dbusy");
#endif
        return -EBUSY;
    }
    tapestate_set (ti, TS_IDLE);
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);

    dev = MKDEV (tape_major, MINOR (inode->i_rdev));    /* Get the device */
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    if (ti->rew_minor == MINOR (inode->i_rdev))
        ti->rew_filp = filp;    /* save for later reference     */
    else
        ti->nor_filp = filp;
    filp->private_data = ti;    /* save the dev.info for later reference */
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);

#ifdef MODULE
    MOD_INC_USE_COUNT;
#endif                /* MODULE */
    return 0;
}

/*
 * Tape device release function.
 */
int
tape_release (struct inode *inode, struct file *filp)
{
    long lockflags;
    tape_info_t *ti,*lastti;
    ccw_req_t *cqr = NULL;
    int rc = 0;

    ti = first_tape_info;
    while ((ti != NULL) && (ti->rew_minor != MINOR (inode->i_rdev)) && (ti->nor_minor != MINOR (inode->i_rdev)))
        ti = (tape_info_t *) ti->next;
    if ((ti != NULL) && (tapestate_get (ti) == TS_NOT_OPER)) {
        if (ti==first_tape_info) {
        first_tape_info=ti->next;
        } else {
        lastti=first_tape_info;
        while (lastti->next!=ti) lastti=lastti->next;
        lastti->next=ti->next;
        }
        kfree(ti);    
        goto out;
    }
    if ((ti == NULL) || (tapestate_get (ti) != TS_IDLE)) {
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:notidle!");
#endif
        rc = -ENXIO;    /* error in tape_release */
        goto out;
    }
#ifdef TAPE_DEBUG
    debug_text_event (tape_debug_area,6,"c:release:");
    debug_int_event (tape_debug_area,6,ti->blk_minor);
#endif
    if (ti->rew_minor == MINOR (inode->i_rdev)) {
        cqr = ti->discipline->mtrew (ti, 1);
        if (cqr != NULL) {
#ifdef TAPE_DEBUG
                debug_text_event (tape_debug_area,6,"c:rewrelea");
#endif
            s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
            tapestate_set (ti, TS_REW_RELEASE_INIT);
            ti->cqr = cqr;
            ti->wanna_wakeup=0;
            rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
            s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
            wait_event (ti->wq,ti->wanna_wakeup);
            ti->cqr = NULL;
            tape_free_request (cqr);
        }
    }
    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
    tapestate_set (ti, TS_UNUSED);
    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
out:
#ifdef MODULE
    MOD_DEC_USE_COUNT;
#endif                /* MODULE */
    return rc;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0268 ]--