!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/sbus/   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:     sbus.c (13.53 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* $Id: sbus.c,v 1.95.2.3 2002/01/05 01:12:31 davem Exp $
 * sbus.c:  SBus support routines.
 *
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/pci.h>

#include <asm/system.h>
#include <asm/sbus.h>
#include <asm/dma.h>
#include <asm/oplib.h>
#include <asm/bpp.h>
#include <asm/irq.h>

struct sbus_bus *sbus_root = NULL;

static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } };

/* Perhaps when I figure out more about the iommu we'll put a
 * device registration routine here that probe_sbus() calls to
 * setup the iommu for each Sbus.
 */

/* We call this for each SBus device, and fill the structure based
 * upon the prom device tree.  We return the start of memory after
 * the things we have allocated.
 */

/* #define DEBUG_FILL */

static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
{
    unsigned long address, base;
    int len;

    sdev->prom_node = prom_node;
    prom_getstring(prom_node, "name",
               sdev->prom_name, sizeof(sdev->prom_name));
    address = prom_getint(prom_node, "address");
    len = prom_getproperty(prom_node, "reg",
                   (char *) sdev->reg_addrs,
                   sizeof(sdev->reg_addrs));
    if (len == -1) {
        sdev->num_registers = 0;
        goto no_regs;
    }

    if (len % sizeof(struct linux_prom_registers)) {
        prom_printf("fill_sbus_device: proplen for regs of %s "
                " was %d, need multiple of %d\n",
                sdev->prom_name, len,
                (int) sizeof(struct linux_prom_registers));
        prom_halt();
    }
    if (len > (sizeof(struct linux_prom_registers) * PROMREG_MAX)) {
        prom_printf("fill_sbus_device: Too many register properties "
                "for device %s, len=%d\n",
                sdev->prom_name, len);
        prom_halt();
    }
    sdev->num_registers = len / sizeof(struct linux_prom_registers);
    sdev->ranges_applied = 0;

    base = (unsigned long) sdev->reg_addrs[0].phys_addr;

    /* Compute the slot number. */
    if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) {
        sdev->slot = sbus_dev_slot(base);
    } else {
        sdev->slot = sdev->reg_addrs[0].which_io;
    }

no_regs:
    len = prom_getproperty(prom_node, "ranges",
                   (char *)sdev->device_ranges,
                   sizeof(sdev->device_ranges));
    if (len == -1) {
        sdev->num_device_ranges = 0;
        goto no_ranges;
    }
    if (len % sizeof(struct linux_prom_ranges)) {
        prom_printf("fill_sbus_device: proplen for ranges of %s "
                " was %d, need multiple of %d\n",
                sdev->prom_name, len,
                (int) sizeof(struct linux_prom_ranges));
        prom_halt();
    }
    if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) {
        prom_printf("fill_sbus_device: Too many range properties "
                "for device %s, len=%d\n",
                sdev->prom_name, len);
        prom_halt();
    }
    sdev->num_device_ranges =
        len / sizeof(struct linux_prom_ranges);

no_ranges:
    /* XXX Unfortunately, IRQ issues are very arch specific.
     * XXX Pull this crud out into an arch specific area
     * XXX at some point. -DaveM
     */
#ifdef __sparc_v9__
    len = prom_getproperty(prom_node, "interrupts",
                   (char *) irqs, sizeof(irqs));
    if (len == -1 || len == 0) {
        sdev->irqs[0] = 0;
        sdev->num_irqs = 0;
    } else {
        unsigned int pri = irqs[0].pri;

        sdev->num_irqs = 1;
        if (pri < 0x20)
            pri += sdev->slot * 8;

        sdev->irqs[0] =    sbus_build_irq(sdev->bus, pri);
    }
#else
    len = prom_getproperty(prom_node, "intr",
                   (char *)irqs, sizeof(irqs));
    if (len == -1)
        len = 0;
    sdev->num_irqs = len / 8;
    if (sdev->num_irqs == 0) {
        sdev->irqs[0] = 0;
    } else if (sparc_cpu_model == sun4d) {
        extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);

        for (len = 0; len < sdev->num_irqs; len++)
            sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri);
    } else {
        for (len = 0; len < sdev->num_irqs; len++)
            sdev->irqs[len] = irqs[len].pri;
    }
#endif /* !__sparc_v9__ */
}

/* This routine gets called from whoever needs the sbus first, to scan
 * the SBus device tree.  Currently it just prints out the devices
 * found on the bus and builds trees of SBUS structs and attached
 * devices.
 */

extern void iommu_init(int iommu_node, struct sbus_bus *sbus);
extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus);
void sun4_init(void);
#ifdef CONFIG_SUN_AUXIO
extern void auxio_probe(void);
#endif

static void __init sbus_do_child_siblings(int start_node,
                      struct sbus_dev *child,
                      struct sbus_dev *parent,
                      struct sbus_bus *sbus)
{
    struct sbus_dev *this_dev = child;
    int this_node = start_node;

    /* Child already filled in, just need to traverse siblings. */
    child->child = NULL;
    child->parent = parent;
    while((this_node = prom_getsibling(this_node)) != 0) {
        this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
        this_dev = this_dev->next;
        this_dev->next = 0;
        this_dev->parent = parent;

        this_dev->bus = sbus;
        fill_sbus_device(this_node, this_dev);

        if(prom_getchild(this_node)) {
            this_dev->child = kmalloc(sizeof(struct sbus_dev),
                          GFP_ATOMIC);
            this_dev->child->bus = sbus;
            this_dev->child->next = 0;
            fill_sbus_device(prom_getchild(this_node), this_dev->child);
            sbus_do_child_siblings(prom_getchild(this_node),
                           this_dev->child, this_dev, sbus);
        } else {
            this_dev->child = NULL;
        }
    }
}

/*
 * XXX This functions appears to be a distorted version of
 * prom_sbus_ranges_init(), with all sun4d stuff cut away.
 * Ask DaveM what is going on here, how is sun4d supposed to work... XXX
 */
static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus)
{
    int len;

    len = prom_getproperty(sbus->prom_node, "ranges",
                   (char *) sbus->sbus_ranges,
                   sizeof(sbus->sbus_ranges));
    if (len == -1 || len == 0) {
        sbus->num_sbus_ranges = 0;
        return;
    }
    sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges);
}

static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
                      int num_ranges,
                      struct linux_prom_registers *regs,
                      int num_regs)
{
    if (num_ranges) {
        int regnum;

        for (regnum = 0; regnum < num_regs; regnum++) {
            int rngnum;

            for (rngnum = 0; rngnum < num_ranges; rngnum++) {
                if (regs[regnum].which_io == ranges[rngnum].ot_child_space)
                    break;
            }
            if (rngnum == num_ranges) {
                /* We used to flag this as an error.  Actually
                 * some devices do not report the regs as we expect.
                 * For example, see SUNW,pln device.  In that case
                 * the reg property is in a format internal to that
                 * node, ie. it is not in the SBUS register space
                 * per se. -DaveM
                 */
                return;
            }
            regs[regnum].which_io = ranges[rngnum].ot_parent_space;
            regs[regnum].phys_addr -= ranges[rngnum].ot_child_base;
            regs[regnum].phys_addr += ranges[rngnum].ot_parent_base;
        }
    }
}

static void __init __fixup_regs_sdev(struct sbus_dev *sdev)
{
    if (sdev->num_registers != 0) {
        struct sbus_dev *parent = sdev->parent;
        int i;

        while (parent != NULL) {
            __apply_ranges_to_regs(parent->device_ranges,
                           parent->num_device_ranges,
                           sdev->reg_addrs,
                           sdev->num_registers);

            parent = parent->parent;
        }

        __apply_ranges_to_regs(sdev->bus->sbus_ranges,
                       sdev->bus->num_sbus_ranges,
                       sdev->reg_addrs,
                       sdev->num_registers);

        for (i = 0; i < sdev->num_registers; i++) {
            struct resource *res = &sdev->resource[i];

            res->start = sdev->reg_addrs[i].phys_addr;
            res->end = (res->start +
                    (unsigned long)sdev->reg_addrs[i].reg_size - 1UL);
            res->flags = IORESOURCE_IO |
                (sdev->reg_addrs[i].which_io & 0xff);
        }
    }
}

static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev)
{
    struct sbus_dev *sdev;

    for (sdev = first_sdev; sdev; sdev = sdev->next) {
        if (sdev->child)
            sbus_fixup_all_regs(sdev->child);
        __fixup_regs_sdev(sdev);
    }
}

extern void register_proc_sparc_ioport(void);
extern void firetruck_init(void);
extern void rs_init(void);

void __init sbus_init(void)
{
    int nd, this_sbus, sbus_devs, topnd, iommund;
    unsigned int sbus_clock;
    struct sbus_bus *sbus;
    struct sbus_dev *this_dev;
    int num_sbus = 0;  /* How many did we find? */

#ifndef __sparc_v9__
    register_proc_sparc_ioport();
#endif

#ifdef CONFIG_SUN4
    return sun4_dvma_init();
#endif

    topnd = prom_getchild(prom_root_node);
    
    /* Finding the first sbus is a special case... */
    iommund = 0;
    if(sparc_cpu_model == sun4u) {
        nd = prom_searchsiblings(topnd, "sbus");
        if(nd == 0) {
#ifdef CONFIG_PCI
            if (!pcibios_present()) {    
                prom_printf("Neither SBUS nor PCI found.\n");
                prom_halt();
            } else {
#ifdef __sparc_v9__
                firetruck_init();
#endif
            }
            return;
#else
            prom_printf("YEEE, UltraSparc sbus not found\n");
            prom_halt();
#endif
        }
    } else if(sparc_cpu_model == sun4d) {
        if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 ||
           (nd = prom_getchild(iommund)) == 0 ||
           (nd = prom_searchsiblings(nd, "sbi")) == 0) {
               panic("sbi not found");
        }
    } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) {
        if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 ||
           (nd = prom_getchild(iommund)) == 0 ||
           (nd = prom_searchsiblings(nd, "sbus")) == 0) {
#ifdef CONFIG_PCI
                        if (!pcibios_present()) {       
                                prom_printf("Neither SBUS nor PCI found.\n");
                                prom_halt();
                        }
                        return;
#else
            /* No reason to run further - the data access trap will occur. */
            panic("sbus not found");
#endif
        }
    }

    /* Ok, we've found the first one, allocate first SBus struct
     * and place in chain.
     */
    sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
    sbus->next = NULL;
    sbus->prom_node = nd;
    this_sbus = nd;

    if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d)
        iommu_init(iommund, sbus);

    /* Loop until we find no more SBUS's */
    while(this_sbus) {
#ifdef __sparc_v9__                          
        /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */
        if(sparc_cpu_model == sun4u) {
            extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus);

            sbus_iommu_init(this_sbus, sbus);
        }
#endif
#ifndef __sparc_v9__                          
        if (sparc_cpu_model == sun4d)
            iounit_init(this_sbus, iommund, sbus);
#endif                           
        printk("sbus%d: ", num_sbus);
        sbus_clock = prom_getint(this_sbus, "clock-frequency");
        if(sbus_clock == -1)
            sbus_clock = (25*1000*1000);
        printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
               (int) (((sbus_clock/1000)%1000 != 0) ? 
                  (((sbus_clock/1000)%1000) + 1000) : 0));

        prom_getstring(this_sbus, "name",
                   sbus->prom_name, sizeof(sbus->prom_name));
        sbus->clock_freq = sbus_clock;
#ifndef __sparc_v9__        
        if (sparc_cpu_model == sun4d) {
            sbus->devid = prom_getint(iommund, "device-id");
            sbus->board = prom_getint(iommund, "board#");
        }
#endif
        
        sbus_bus_ranges_init(iommund, sbus);

        sbus_devs = prom_getchild(this_sbus);

        sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);

        this_dev = sbus->devices;
        this_dev->next = NULL;

        this_dev->bus = sbus;
        this_dev->parent = NULL;
        fill_sbus_device(sbus_devs, this_dev);

        /* Should we traverse for children? */
        if(prom_getchild(sbus_devs)) {
            /* Allocate device node */
            this_dev->child = kmalloc(sizeof(struct sbus_dev),
                          GFP_ATOMIC);
            /* Fill it */
            this_dev->child->bus = sbus;
            this_dev->child->next = 0;
            fill_sbus_device(prom_getchild(sbus_devs),
                     this_dev->child);
            sbus_do_child_siblings(prom_getchild(sbus_devs),
                           this_dev->child,
                           this_dev,
                           sbus);
        } else {
            this_dev->child = NULL;
        }

        while((sbus_devs = prom_getsibling(sbus_devs)) != 0) {
            /* Allocate device node */
            this_dev->next = kmalloc(sizeof(struct sbus_dev),
                         GFP_ATOMIC);
            this_dev = this_dev->next;
            this_dev->next = NULL;

            /* Fill it */
            this_dev->bus = sbus;
            this_dev->parent = NULL;
            fill_sbus_device(sbus_devs, this_dev);

            /* Is there a child node hanging off of us? */
            if(prom_getchild(sbus_devs)) {
                /* Get new device struct */
                this_dev->child = kmalloc(sizeof(struct sbus_dev),
                              GFP_ATOMIC);
                /* Fill it */
                this_dev->child->bus = sbus;
                this_dev->child->next = 0;
                fill_sbus_device(prom_getchild(sbus_devs),
                         this_dev->child);
                sbus_do_child_siblings(prom_getchild(sbus_devs),
                               this_dev->child,
                               this_dev,
                               sbus);
            } else {
                this_dev->child = NULL;
            }
        }

        /* Walk all devices and apply parent ranges. */
        sbus_fixup_all_regs(sbus->devices);

        dvma_init(sbus);

        num_sbus++;
        if(sparc_cpu_model == sun4u) {
            this_sbus = prom_getsibling(this_sbus);
            if(!this_sbus)
                break;
            this_sbus = prom_searchsiblings(this_sbus, "sbus");
        } else if(sparc_cpu_model == sun4d) {
            iommund = prom_getsibling(iommund);
            if(!iommund)
                break;
            iommund = prom_searchsiblings(iommund, "io-unit");
            if(!iommund)
                break;
            this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi");
        } else {
            this_sbus = prom_getsibling(this_sbus);
            if(!this_sbus)
                break;
            this_sbus = prom_searchsiblings(this_sbus, "sbus");
        }
        if(this_sbus) {
            sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
            sbus = sbus->next;
            sbus->next = NULL;
            sbus->prom_node = this_sbus;
        } else {
            break;
        }
    } /* while(this_sbus) */

    if (sparc_cpu_model == sun4d) {
        extern void sun4d_init_sbi_irq(void);
        sun4d_init_sbi_irq();
    }
    
    rs_init();

#ifdef __sparc_v9__
    if (sparc_cpu_model == sun4u) {
        firetruck_init();
    }
#endif
#ifdef CONFIG_SUN_AUXIO
    if (sparc_cpu_model == sun4u)
        auxio_probe ();
#endif
#ifdef __sparc_v9__
    if (sparc_cpu_model == sun4u) {
        extern void clock_probe(void);

        clock_probe();
    }
#endif
}

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