!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/parport/   drwxr-xr-x
Free 318.35 GB of 458.09 GB (69.5%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     parport_gsc.c (14.04 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *      Low-level parallel-support for PC-style hardware integrated in the 
 *    LASI-Controller (on GSC-Bus) for HP-PARISC Workstations
 *
 *    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.
 *
 *    by Helge Deller <deller@gmx.de>
 *
 * 
 * based on parport_pc.c by 
 *         Grant Guenther <grant@torque.net>
 *         Phil Blundell <Philip.Blundell@pobox.com>
 *          Tim Waugh <tim@cyberelk.demon.co.uk>
 *        Jose Renau <renau@acm.org>
 *          David Campbell <campbell@torque.net>
 *          Andrea Arcangeli
 */

#undef DEBUG    /* undef for production */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/sysctl.h>

#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>

#include <linux/parport.h>
#include <asm/gsc.h>
#include <asm/pdc.h>
#include <asm/hardware.h>
#include <asm/parport_gsc.h>


MODULE_AUTHOR("Helge Deller <deller@gmx.de>");
MODULE_DESCRIPTION("HP-PARISC PC-style parallel port driver");
MODULE_SUPPORTED_DEVICE("integrated PC-style parallel port");


/*
 * Clear TIMEOUT BIT in EPP MODE
 *
 * This is also used in SPP detection.
 */
static int clear_epp_timeout(struct parport *pb)
{
    unsigned char r;

    if (!(parport_gsc_read_status(pb) & 0x01))
        return 1;

    /* To clear timeout some chips require double read */
    parport_gsc_read_status(pb);
    r = parport_gsc_read_status(pb);
    parport_writeb (r | 0x01, STATUS (pb)); /* Some reset by writing 1 */
    parport_writeb (r & 0xfe, STATUS (pb)); /* Others by writing 0 */
    r = parport_gsc_read_status(pb);

    return !(r & 0x01);
}

/*
 * Access functions.
 *
 * Most of these aren't static because they may be used by the
 * parport_xxx_yyy macros.  extern __inline__ versions of several
 * of these are in parport_gsc.h.
 */

static void parport_gsc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    parport_generic_irq(irq, (struct parport *) dev_id, regs);
}

void parport_gsc_write_data(struct parport *p, unsigned char d)
{
    parport_writeb (d, DATA (p));
}

unsigned char parport_gsc_read_data(struct parport *p)
{
    unsigned char c = parport_readb (DATA (p));
    return c;
}

void parport_gsc_write_control(struct parport *p, unsigned char d)
{
    const unsigned char wm = (PARPORT_CONTROL_STROBE |
                  PARPORT_CONTROL_AUTOFD |
                  PARPORT_CONTROL_INIT |
                  PARPORT_CONTROL_SELECT);

    /* Take this out when drivers have adapted to the newer interface. */
    if (d & 0x20) {
        pr_debug("%s (%s): use data_reverse for this!\n",
                p->name, p->cad->name);
        parport_gsc_data_reverse (p);
    }

    __parport_gsc_frob_control (p, wm, d & wm);
}

unsigned char parport_gsc_read_control(struct parport *p)
{
    const unsigned char wm = (PARPORT_CONTROL_STROBE |
                  PARPORT_CONTROL_AUTOFD |
                  PARPORT_CONTROL_INIT |
                  PARPORT_CONTROL_SELECT);
    const struct parport_gsc_private *priv = p->physport->private_data;
    return priv->ctr & wm; /* Use soft copy */
}

unsigned char parport_gsc_frob_control (struct parport *p, unsigned char mask,
                       unsigned char val)
{
    const unsigned char wm = (PARPORT_CONTROL_STROBE |
                  PARPORT_CONTROL_AUTOFD |
                  PARPORT_CONTROL_INIT |
                  PARPORT_CONTROL_SELECT);

    /* Take this out when drivers have adapted to the newer interface. */
    if (mask & 0x20) {
        pr_debug("%s (%s): use data_%s for this!\n",
            p->name, p->cad->name,
            (val & 0x20) ? "reverse" : "forward");
        if (val & 0x20)
            parport_gsc_data_reverse (p);
        else
            parport_gsc_data_forward (p);
    }

    /* Restrict mask and val to control lines. */
    mask &= wm;
    val &= wm;

    return __parport_gsc_frob_control (p, mask, val);
}

unsigned char parport_gsc_read_status(struct parport *p)
{
    return parport_readb (STATUS (p));
}

void parport_gsc_disable_irq(struct parport *p)
{
    __parport_gsc_frob_control (p, 0x10, 0);
}

void parport_gsc_enable_irq(struct parport *p)
{
    __parport_gsc_frob_control (p, 0x10, 0x10);
}

void parport_gsc_data_forward (struct parport *p)
{
    __parport_gsc_frob_control (p, 0x20, 0);
}

void parport_gsc_data_reverse (struct parport *p)
{
    __parport_gsc_frob_control (p, 0x20, 0x20);
}

void parport_gsc_init_state(struct pardevice *dev, struct parport_state *s)
{
    s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
}

void parport_gsc_save_state(struct parport *p, struct parport_state *s)
{
    s->u.pc.ctr = parport_readb (CONTROL (p));
}

void parport_gsc_restore_state(struct parport *p, struct parport_state *s)
{
    parport_writeb (s->u.pc.ctr, CONTROL (p));
}

void parport_gsc_inc_use_count(void)
{
    MOD_INC_USE_COUNT;
}

void parport_gsc_dec_use_count(void)
{
    MOD_DEC_USE_COUNT;
}


struct parport_operations parport_gsc_ops = 
{
    write_data:    parport_gsc_write_data,
    read_data:    parport_gsc_read_data,

    write_control:    parport_gsc_write_control,
    read_control:    parport_gsc_read_control,
    frob_control:    parport_gsc_frob_control,

    read_status:    parport_gsc_read_status,

    enable_irq:    parport_gsc_enable_irq,
    disable_irq:    parport_gsc_disable_irq,

    data_forward:    parport_gsc_data_forward,
    data_reverse:    parport_gsc_data_reverse,

    init_state:    parport_gsc_init_state,
    save_state:    parport_gsc_save_state,
    restore_state:    parport_gsc_restore_state,

    inc_use_count:    parport_gsc_inc_use_count,
    dec_use_count:    parport_gsc_dec_use_count,

    epp_write_data:    parport_ieee1284_epp_write_data,
    epp_read_data:    parport_ieee1284_epp_read_data,
    epp_write_addr:    parport_ieee1284_epp_write_addr,
    epp_read_addr:    parport_ieee1284_epp_read_addr,

    ecp_write_data:    parport_ieee1284_ecp_write_data,
    ecp_read_data:    parport_ieee1284_ecp_read_data,
    ecp_write_addr:    parport_ieee1284_ecp_write_addr,

    compat_write_data:     parport_ieee1284_write_compat,
    nibble_read_data:    parport_ieee1284_read_nibble,
    byte_read_data:        parport_ieee1284_read_byte,
};

/* --- Mode detection ------------------------------------- */

/*
 * Checks for port existence, all ports support SPP MODE
 */
static int __devinit parport_SPP_supported(struct parport *pb)
{
    unsigned char r, w;

    /*
     * first clear an eventually pending EPP timeout 
     * I (sailer@ife.ee.ethz.ch) have an SMSC chipset
     * that does not even respond to SPP cycles if an EPP
     * timeout is pending
     */
    clear_epp_timeout(pb);

    /* Do a simple read-write test to make sure the port exists. */
    w = 0xc;
    parport_writeb (w, CONTROL (pb));

    /* Is there a control register that we can read from?  Some
     * ports don't allow reads, so read_control just returns a
     * software copy. Some ports _do_ allow reads, so bypass the
     * software copy here.  In addition, some bits aren't
     * writable. */
    r = parport_readb (CONTROL (pb));
    if ((r & 0xf) == w) {
        w = 0xe;
        parport_writeb (w, CONTROL (pb));
        r = parport_readb (CONTROL (pb));
        parport_writeb (0xc, CONTROL (pb));
        if ((r & 0xf) == w)
            return PARPORT_MODE_PCSPP;
    }

    /* Try the data register.  The data lines aren't tri-stated at
     * this stage, so we expect back what we wrote. */
    w = 0xaa;
    parport_gsc_write_data (pb, w);
    r = parport_gsc_read_data (pb);
    if (r == w) {
        w = 0x55;
        parport_gsc_write_data (pb, w);
        r = parport_gsc_read_data (pb);
        if (r == w)
            return PARPORT_MODE_PCSPP;
    }

    return 0;
}

/* Detect PS/2 support.
 *
 * Bit 5 (0x20) sets the PS/2 data direction; setting this high
 * allows us to read data from the data lines.  In theory we would get back
 * 0xff but any peripheral attached to the port may drag some or all of the
 * lines down to zero.  So if we get back anything that isn't the contents
 * of the data register we deem PS/2 support to be present. 
 *
 * Some SPP ports have "half PS/2" ability - you can't turn off the line
 * drivers, but an external peripheral with sufficiently beefy drivers of
 * its own can overpower them and assert its own levels onto the bus, from
 * where they can then be read back as normal.  Ports with this property
 * and the right type of device attached are likely to fail the SPP test,
 * (as they will appear to have stuck bits) and so the fact that they might
 * be misdetected here is rather academic. 
 */

static int __devinit parport_PS2_supported(struct parport *pb)
{
    int ok = 0;
  
    clear_epp_timeout(pb);

    /* try to tri-state the buffer */
    parport_gsc_data_reverse (pb);
    
    parport_gsc_write_data(pb, 0x55);
    if (parport_gsc_read_data(pb) != 0x55) ok++;

    parport_gsc_write_data(pb, 0xaa);
    if (parport_gsc_read_data(pb) != 0xaa) ok++;

    /* cancel input mode */
    parport_gsc_data_forward (pb);

    if (ok) {
        pb->modes |= PARPORT_MODE_TRISTATE;
    } else {
        struct parport_gsc_private *priv = pb->private_data;
        priv->ctr_writable &= ~0x20;
    }

    return ok;
}


/* --- Initialisation code -------------------------------- */

struct parport *__devinit parport_gsc_probe_port (unsigned long base,
                         unsigned long base_hi,
                         int irq, int dma,
                         struct pci_dev *dev)
{
    struct parport_gsc_private *priv;
    struct parport_operations *ops;
    struct parport tmp;
    struct parport *p = &tmp;

#if 1
#warning Take this out when region handling works again, <deller@gmx,de>
#else
    if (check_region(base, 3)) 
        return NULL;
#endif
        
    priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL);
    if (!priv) {
        printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
        return NULL;
    }
    ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
    if (!ops) {
        printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
            base);
        kfree (priv);
        return NULL;
    }
    memcpy (ops, &parport_gsc_ops, sizeof (struct parport_operations));
    priv->ctr = 0xc;
    priv->ctr_writable = 0xff;
    priv->dma_buf = 0;
    priv->dma_handle = 0;
    priv->dev = dev;
    p->base = base;
    p->base_hi = base_hi;
    p->irq = irq;
    p->dma = dma;
    p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
    p->ops = ops;
    p->private_data = priv;
    p->physport = p;
    if (!parport_SPP_supported (p)) {
        /* No port. */
        kfree (priv);
        return NULL;
    }
    parport_PS2_supported (p);

    if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
                    PARPORT_DMA_NONE, ops))) {
        kfree (priv);
        kfree (ops);
        return NULL;
    }

    p->base_hi = base_hi;
    p->modes = tmp.modes;
    p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
    p->private_data = priv;

    printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
    p->irq = irq;
    if (p->irq == PARPORT_IRQ_AUTO) {
        p->irq = PARPORT_IRQ_NONE;
    }
    if (p->irq != PARPORT_IRQ_NONE) {
        printk(", irq %d", p->irq);

        if (p->dma == PARPORT_DMA_AUTO) {
            p->dma = PARPORT_DMA_NONE;
        }
    }
    if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq
                                           is mandatory (see above) */
        p->dma = PARPORT_DMA_NONE;

    printk(" [");
#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}}
    {
        int f = 0;
        printmode(PCSPP);
        printmode(TRISTATE);
        printmode(COMPAT)
        printmode(EPP);
//        printmode(ECP);
//        printmode(DMA);
    }
#undef printmode
    printk("]\n");
    parport_proc_register(p);

    request_region (p->base, 3, p->name);
    if (p->size > 3)
        request_region (p->base + 3, p->size - 3, p->name);
    if (p->modes & PARPORT_MODE_ECP)
        request_region (p->base_hi, 3, p->name);

    if (p->irq != PARPORT_IRQ_NONE) {
        if (request_irq (p->irq, parport_gsc_interrupt,
                 0, p->name, p)) {
            printk (KERN_WARNING "%s: irq %d in use, "
                "resorting to polled operation\n",
                p->name, p->irq);
            p->irq = PARPORT_IRQ_NONE;
            p->dma = PARPORT_DMA_NONE;
        }
    }

    /* Done probing.  Now put the port into a sensible start-up state. */

    parport_gsc_write_data(p, 0);
    parport_gsc_data_forward (p);

    /* Now that we've told the sharing engine about the port, and
       found out its characteristics, let the high-level drivers
       know about it. */
    parport_announce_port (p);

    return p;
}


#define PARPORT_GSC_OFFSET 0x800

static int __initdata parport_count;

static int __init parport_init_chip(struct hp_device *d, struct pa_iodc_driver *dri)
{
    unsigned long port;
    int irq;

    irq = busdevice_alloc_irq(d); 

    if (!irq) {
        printk(KERN_DEBUG "IRQ not found for parallel device at 0x%p\n", d->hpa);
        return -ENODEV;
    }

    port = ((unsigned long) d->hpa) + PARPORT_GSC_OFFSET;
    
    /* 
        some older machines with ASP-chip don't support the enhanced parport modes 
    */
    if (!pdc_add_valid( (void *)(port+4))) {
        /* Initialize bidirectional-mode (0x10) & data-tranfer-mode #1 (0x20) */
        printk(KERN_DEBUG "%s: initialize bidirectional-mode.\n", __FUNCTION__);
        parport_writeb ( (0x10 + 0x20), port + 4);
    } else {
        printk(KERN_DEBUG "%s: enhanced parport-modes not supported.\n", __FUNCTION__);
    }
    
    if (parport_gsc_probe_port(port, 0, 
            irq, /* PARPORT_IRQ_NONE */
            PARPORT_DMA_NONE, NULL))
        parport_count++;

    return 0;
}

static struct pa_iodc_driver parport_drivers_for[] __initdata = {
  {HPHW_FIO, 0x0, 0x0, 0x74, 0x0, 0,            /* 715/64 */
    DRIVER_CHECK_SVERSION + DRIVER_CHECK_HWTYPE,
    "parallel device", "HP 7xx - Series", (void *) parport_init_chip},
  { 0 }
};

int __init parport_gsc_init(void)
{
    parport_count = 0;
    
    register_driver(parport_drivers_for);

    return 0;
}


static int __init parport_gsc_init_module(void)
{    
    return !parport_gsc_init();
}

static void __exit parport_gsc_exit_module(void)
{
    struct parport *p = parport_enumerate(), *tmp;
    while (p) {
        tmp = p->next;
        if (p->modes & PARPORT_MODE_PCSPP) { 
            struct parport_gsc_private *priv = p->private_data;
            struct parport_operations *ops = p->ops;
            if (p->dma != PARPORT_DMA_NONE)
                free_dma(p->dma);
            if (p->irq != PARPORT_IRQ_NONE)
                free_irq(p->irq, p);
            release_region(p->base, 3);
            if (p->size > 3)
                release_region(p->base + 3, p->size - 3);
            if (p->modes & PARPORT_MODE_ECP)
                release_region(p->base_hi, 3);
            parport_proc_unregister(p);
            if (priv->dma_buf)
                pci_free_consistent(priv->dev, PAGE_SIZE,
                            priv->dma_buf,
                            priv->dma_handle);
            kfree (p->private_data);
            parport_unregister_port(p);
            kfree (ops); /* hope no-one cached it */
        }
        p = tmp;
    }
}

EXPORT_NO_SYMBOLS;

module_init(parport_gsc_init_module);
module_exit(parport_gsc_exit_module);

:: 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.0304 ]--