]> git.neil.brown.name Git - history.git/commitdiff
Import 2.4.0-test4pre5 2.4.0-test4pre5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:36:42 +0000 (15:36 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:36:42 +0000 (15:36 -0500)
71 files changed:
Documentation/DocBook/parportbook.tmpl
Documentation/kernel-parameters.txt
arch/arm/config.in
arch/i386/config.in
arch/i386/kernel/smp.c
arch/ia64/config.in
arch/m68k/config.in
arch/mips/cobalt/reset.c
arch/mips/config.in
arch/mips/dec/time.c
arch/mips/kernel/mips_ksyms.c
arch/mips/ld.script.big
arch/mips/ld.script.little
arch/mips/orion/misc.c
arch/mips/orion/setup.c
arch/mips64/config.in
arch/mips64/kernel/head.S
arch/mips64/kernel/mips64_ksyms.c
arch/mips64/kernel/process.c
arch/mips64/kernel/r4k_tlb.S
arch/mips64/kernel/signal32.c
arch/mips64/ld.script.elf32
arch/mips64/ld.script.elf64
arch/mips64/sgi-ip27/ip27-setup.c
arch/ppc/config.in
arch/s390/config.in
arch/sh/config.in
arch/sparc64/solaris/timod.c
drivers/acpi/Makefile
drivers/acpi/cpu.c [new file with mode: 0644]
drivers/acpi/driver.c [new file with mode: 0644]
drivers/acpi/driver.h [new file with mode: 0644]
drivers/acpi/ec.c [new file with mode: 0644]
drivers/acpi/os.c [new file with mode: 0644]
drivers/acpi/osd.c [deleted file]
drivers/acpi/sys.c [new file with mode: 0644]
drivers/acpi/tables.c [new file with mode: 0644]
drivers/block/ll_rw_blk.c
drivers/block/md.c
drivers/block/paride/paride.c
drivers/char/cyclades.c
drivers/char/i2c-parport.c
drivers/char/ppdev.c
drivers/mtd/Config.in
drivers/parport/ChangeLog
drivers/parport/init.c
drivers/parport/share.c
drivers/scsi/scsi_scan.c
drivers/usb/devices.c
drivers/video/Makefile
drivers/video/vga_font.c [deleted file]
fs/dcache.c
fs/inode.c
fs/jffs/inode-v23.c
fs/select.c
include/asm-mips/param.h
include/asm-mips64/dma.h
include/asm-mips64/param.h
include/asm-mips64/sn/addrs.h
include/asm-mips64/sn/agent.h
include/asm-mips64/sn/io.h
include/asm-mips64/sn/klconfig.h
include/asm-mips64/sn/kldir.h
include/asm-sparc/bitops.h
include/asm-sparc64/elf.h
include/asm-sparc64/semaphore.h
include/linux/parport.h
include/linux/pci_ids.h
kernel/sched.c
mm/slab.c
net/ipv4/tcp_ipv4.c

index 754f1a96b653303a287d4189adc72c00403f9bb0..ef8c07d337606125eae4344bbf0d6e7a092068c4 100644 (file)
     announces it.  The <function>parport_announce_port</function>
     function walks down the list of parallel port device drivers
     (<structname>struct parport_driver</structname>s) calling the
-    <function>attach</function> function of each.
+    <function>attach</function> function of each (which may block).
    </para>
 
    <para>
     registering a port with the
     <function>parport_unregister_port</function> function, and device
     drivers are notified using the <function>detach</function>
-    callback.
+    callback (which may not block).
    </para>
 
    <para>
@@ -656,9 +656,31 @@ struct parport_driver {
    to the <function>attach</function> function when it is called, or
    alternatively can be found from the list of detected parallel ports
    directly with the (now deprecated)
-   <function>parport_enumerate</function> function.
+   <function>parport_enumerate</function> function.  A better way of
+   doing this is with <function>parport_find_number</function> or
+   <function>parport_find_base</function> functions, which find ports
+   by number and by base I/O address respectively.
   </para>
 
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
+    <funcdef>struct parport *<function>parport_find_number</function></funcdef>
+    <paramdef>int <parameter>number</parameter></paramdef>
+   </funcprototype>
+  </funcsynopsis>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
+    <funcdef>struct parport *<function>parport_find_base</function></funcdef>
+    <paramdef>unsigned long <parameter>base</parameter></paramdef>
+   </funcprototype>
+  </funcsynopsis>
+
   <para>
    The next three parameters, <parameter>pf</parameter>,
    <parameter>kf</parameter>, and <parameter>irq_func</parameter>, are
@@ -2202,6 +2224,9 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
 !Fdrivers/parport/daisy.c parport_find_class
 !Fdrivers/parport/share.c parport_register_driver
 !Fdrivers/parport/share.c parport_unregister_driver
+!Fdrivers/parport/share.c parport_get_port
+!Fdrivers/parport/share.c parport_put_port
+!Fdrivers/parport/share.c parport_find_number parport_find_base
 !Fdrivers/parport/share.c parport_register_device
 !Fdrivers/parport/share.c parport_unregister_device
 !Fdrivers/parport/daisy.c parport_open
index 611d8be802cc6a9f109cb18fe479a04abe4cc9d2..072508d51048dd32dc653014683ad145e6c3430d 100644 (file)
@@ -1,4 +1,4 @@
-June 2000                Kernel Parameters                     v2.4.0
+July 2000                Kernel Parameters                     v2.4.0
                          ~~~~~~~~~~~~~~~~~
 
 The following is a consolidated list of the kernel parameters as implemented
@@ -80,6 +80,8 @@ running once the system is up.
 
        AM53C974=       [HW,SCSI]
 
+       amijoy=         [HW,JOY] Amiga joystick support 
        apm=            [APM] Advanced Power Management.
 
        applicom=       [HW]
@@ -139,6 +141,12 @@ running once the system is up.
  
        dasd=           [HW,NET]    
 
+       db9=            [HW,JOY]
+
+       db9_2=          [HW,JOY]
+
+       db9_3=          [HW,JOY]
        debug           [KNL] Enable kernel debugging (events log level).
 
        decnet=         [HW,NET]
@@ -179,6 +187,12 @@ running once the system is up.
 
        ftape=          [HW] Floppy Tape subsystem debugging options.
 
+       gc=             [HW,JOY]
+
+       gc_2=           [HW,JOY]
+        
+       gc_3=           [HW,JOY]
        gdth=           [HW,SCSI]
 
        gscd=           [HW,CD]
@@ -194,10 +208,6 @@ running once the system is up.
 
        hisax=          [HW,ISDN]
 
-       in2000=         [HW,SCSI]
-
-       init=           [KNL]
-
        ibmmcascsi=     [HW,MCA,SCSI] IBM MicroChannel SCSI adapter.
 
        icn=            [HW,ISDN]
@@ -208,40 +218,20 @@ running once the system is up.
        
        idebus=         [HW] (E)IDE subsystem : VLB/PCI bus speed.
 
+       idle=           [HW]
+       in2000=         [HW,SCSI]
+
+       init=           [KNL]
+
        ip=             [PNP]
 
        isp16=          [HW,CD]
 
        iucv=           [HW,NET] 
 
-       js_am=          [HW,JOY]
-
-       js_an=          [HW,JOY]
-
-       js_as=          [HW.JOY]
-
-       js_console=     [HW,JOY]
-
-       js_console2=    [HW,JOY]
-
-       js_console3=    [HW,JOY]
-
-       js_db9=         [HW,JOY]
-
-       js_db9_2=       [HW,JOY]
-
-       js_db9_3=       [HW,JOY]
-
-       js_l4=          [HW,JOY]
-
-       js_pci=         [HW,JOY,PCI]
+       js=             [HW,JOY] Analog joystick
  
-       js_tg=          [HW,JOY]
-
-       js_tg_2=        [HW,JOY]
-
-       js_tg_3=        [HW,JOY]
-
        kbd-reset       [VT]
 
        load_ramdisk=   [RAM] List of ramdisks to load from floppy.
@@ -354,6 +344,8 @@ running once the system is up.
 
        nosync          [HW, M68K] Disables sync negotiation for all devices.
 
+       notsc           [BUGS=ix86] Disable Time Stamp Counter
+
        nowb            [ARM]
  
        opl3=           [HW,SOUND]
@@ -484,6 +476,12 @@ running once the system is up.
 
        tdfx=           [HW,DRM]
  
+       tgfx=           [HW,JOY]
+
+       tgfx_2=         [HW,JOY]
+
+       tgfx_3=         [HW,JOY]
        tmc8xx=         [HW,SCSI]
 
        tmscsim=        [HW,SCSI]
index e270007f9f3e62cfedb8e848b05bebe693cb0c00..7e7e337b6178fd3a4d6310c10d4fb624ec353e8f 100644 (file)
@@ -15,6 +15,14 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
 
 mainmenu_option next_comment
 comment 'System Type'
@@ -157,17 +165,6 @@ else
 fi
 endmenu
 
-
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all symbols for modules' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-
 mainmenu_option next_comment
 comment 'General setup'
 source drivers/pci/Config.in
index 6557d822d908d13c0212b676c86d7d6378c7f9c7..d9fcd91db9a757a912a941fa7ae957b662daeceb 100644 (file)
@@ -15,6 +15,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Processor type and features'
 choice 'Processor family' \
@@ -145,15 +154,6 @@ if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
 fi
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 mainmenu_option next_comment
 comment 'General setup'
 
index e08418fe067583af20096fa15b3acbf0867beb2d..b11b629fe4b53eee50218d78b34af6f8a38092a3 100644 (file)
@@ -392,6 +392,8 @@ void smp_send_reschedule(int cpu)
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
 static volatile struct call_data_struct {
        void (*func) (void *info);
        void *info;
@@ -422,9 +424,8 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
 {
        struct call_data_struct data;
        int ret, cpus = smp_num_cpus-1;
-       static spinlock_t lock = SPIN_LOCK_UNLOCKED;
 
-       if(cpus == 0)
+       if (!cpus)
                return 0;
 
        data.func = func;
@@ -434,21 +435,21 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
        if (wait)
                atomic_set(&data.finished, 0);
 
-       spin_lock_bh(&lock);
+       spin_lock_bh(&call_lock);
        call_data = &data;
        /* Send a message to all other CPUs and wait for them to respond */
        send_IPI_allbutself(CALL_FUNCTION_VECTOR);
 
        /* Wait for response */
-       /* FIXME: lock-up detection, backtrace on lock-up */
-       while(atomic_read(&data.started) != cpus)
+       while (atomic_read(&data.started) != cpus)
                barrier();
 
        ret = 0;
        if (wait)
                while (atomic_read(&data.finished) != cpus)
                        barrier();
-       spin_unlock_bh(&lock);
+       spin_unlock_bh(&call_lock);
+
        return 0;
 }
 
index e17fbd6af5438b1593e87c0df34fdabd8e50cd2c..09131fac7a1448ce08234be4958babe807247ab3 100644 (file)
@@ -3,6 +3,20 @@
 #
 mainmenu_name "Kernel configuration of Linux for IA-64 machines"
 
+mainmenu_option next_comment
+ comment 'Code maturity level options'
+ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'General setup'
 
@@ -67,20 +81,6 @@ else
    define_bool CONFIG_PCMCIA n
 fi
 
-mainmenu_option next_comment
- comment 'Code maturity level options'
- bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
-endmenu
-
-mainmenu_option next_comment
- comment 'Loadable module support'
- bool 'Enable loadable module support' CONFIG_MODULES
- if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel module loader' CONFIG_KMOD
- fi
-endmenu
-
 source drivers/parport/Config.in
 
 endmenu
index bde3a370a67ec448a1048d87e2e15803051ed795..076d9107cd332caa0937fa06233f1709cfc5289b 100644 (file)
@@ -12,6 +12,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Platform dependent setup'
 
@@ -136,15 +145,6 @@ fi
 
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all symbols for modules' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 source drivers/mtd/Config.in
 
 source drivers/block/Config.in
index 6f7cb0a883e3e0a8333ac4d014ed0cde95972213..b91c51fe5a67fa8db70cb35c9ecd9cd020742c2b 100644 (file)
@@ -1,7 +1,6 @@
 /*
  *  Reset a Cobalt Qube.
  */
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <asm/io.h>
index 07ab5da4290220975742cc22832bc749094e5298..b064607cae619914cc9f5bb520665c7230f1ded4 100644 (file)
@@ -9,6 +9,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Machine selection'
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -159,12 +168,6 @@ comment 'General setup'
 
         source drivers/parport/Config.in
 
-       bool 'Enable loadable module support' CONFIG_MODULES
-       if [ "$CONFIG_MODULES" = "y" ]; then
-          bool '  Set version information on all symbols for modules' CONFIG_MODVERSIONS
-          bool '  Kernel module loader' CONFIG_KMOD
-       fi
-
        if [ "$CONFIG_DECSTATION" = "y" ]; then
             bool 'TURBOchannel support' CONFIG_TC
 #           if [ "$CONFIG_TC" = "y" ]; then
index 9f009680d648fcd3f42a87dd26db5724b664f84e..151ce507e80b20ce56ed8aac533df8093be019a7 100644 (file)
@@ -25,7 +25,8 @@
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
-extern volatile unsigned long lost_ticks;
+extern volatile unsigned long wall_jiffies;
+extern rwlock_t xtime_lock;
 
 /*
  * Change this if you have some constant time drift
@@ -47,69 +48,69 @@ static unsigned int timerhi = 0, timerlo = 0;
  */
 static unsigned long do_fast_gettimeoffset(void)
 {
-    u32 count;
-    unsigned long res, tmp;
-
-    /* Last jiffy when do_fast_gettimeoffset() was called. */
-    static unsigned long last_jiffies = 0;
-    unsigned long quotient;
-
-    /*
-     * Cached "1/(clocks per usec)*2^32" value.
-     * It has to be recalculated once each jiffy.
-     */
-    static unsigned long cached_quotient = 0;
-
-    tmp = jiffies;
-
-    quotient = cached_quotient;
-
-    if (last_jiffies != tmp) {
-       last_jiffies = tmp;
-       __asm__(".set\tnoreorder\n\t"
-               ".set\tnoat\n\t"
-               ".set\tmips3\n\t"
-               "lwu\t%0,%2\n\t"
-               "dsll32\t$1,%1,0\n\t"
-               "or\t$1,$1,%0\n\t"
-               "ddivu\t$0,$1,%3\n\t"
-               "mflo\t$1\n\t"
-               "dsll32\t%0,%4,0\n\t"
-               "nop\n\t"
-               "ddivu\t$0,%0,$1\n\t"
-               "mflo\t%0\n\t"
-               ".set\tmips0\n\t"
-               ".set\tat\n\t"
-               ".set\treorder"
-      :        "=&r"(quotient)
-      :        "r"(timerhi),
-               "m"(timerlo),
-               "r"(tmp),
-               "r"(USECS_PER_JIFFY)
-      :        "$1");
-       cached_quotient = quotient;
-    }
-    /* Get last timer tick in absolute kernel time */
-    count = read_32bit_cp0_register(CP0_COUNT);
-
-    /* .. relative to previous jiffy (32 bits is enough) */
-    count -= timerlo;
+       u32 count;
+       unsigned long res, tmp;
+
+       /* Last jiffy when do_fast_gettimeoffset() was called. */
+       static unsigned long last_jiffies = 0;
+       unsigned long quotient;
+
+       /*
+        * Cached "1/(clocks per usec)*2^32" value.
+        * It has to be recalculated once each jiffy.
+        */
+       static unsigned long cached_quotient = 0;
+
+       tmp = jiffies;
+
+       quotient = cached_quotient;
+
+       if (tmp && last_jiffies != tmp) {
+               last_jiffies = tmp;
+               __asm__(".set\tnoreorder\n\t"
+                       ".set\tnoat\n\t"
+                       ".set\tmips3\n\t"
+                       "lwu\t%0,%2\n\t"
+                       "dsll32\t$1,%1,0\n\t"
+                       "or\t$1,$1,%0\n\t"
+                       "ddivu\t$0,$1,%3\n\t"
+                       "mflo\t$1\n\t"
+                       "dsll32\t%0,%4,0\n\t"
+                       "nop\n\t"
+                       "ddivu\t$0,%0,$1\n\t"
+                       "mflo\t%0\n\t"
+                       ".set\tmips0\n\t"
+                       ".set\tat\n\t"
+                       ".set\treorder"
+                       :"=&r"(quotient)
+                       :"r"(timerhi),
+                       "m"(timerlo),
+                       "r"(tmp),
+                       "r"(USECS_PER_JIFFY)
+                       :"$1");
+               cached_quotient = quotient;
+       }
+       /* Get last timer tick in absolute kernel time */
+       count = read_32bit_cp0_register(CP0_COUNT);
+
+       /* .. relative to previous jiffy (32 bits is enough) */
+       count -= timerlo;
 //printk("count: %08lx, %08lx:%08lx\n", count, timerhi, timerlo);
 
-    __asm__("multu\t%1,%2\n\t"
-           "mfhi\t%0"
-  :        "=r"(res)
-  :        "r"(count),
-           "r"(quotient));
+       __asm__("multu\t%1,%2\n\t"
+               "mfhi\t%0"
+               :"=r"(res)
+               :"r"(count),
+               "r"(quotient));
 
-    /*
-     * Due to possible jiffies inconsistencies, we need to check 
-     * the result so that we'll get a timer that is monotonic.
-     */
-    if (res >= USECS_PER_JIFFY)
-       res = USECS_PER_JIFFY - 1;
+       /*
+        * Due to possible jiffies inconsistencies, we need to check 
+        * the result so that we'll get a timer that is monotonic.
+        */
+       if (res >= USECS_PER_JIFFY)
+               res = USECS_PER_JIFFY - 1;
 
-    return res;
+       return res;
 }
 
 /* This function must be called with interrupts disabled 
@@ -148,11 +149,11 @@ static unsigned long do_fast_gettimeoffset(void)
 
 static unsigned long do_slow_gettimeoffset(void)
 {
-    /*
-     * This is a kludge until I find a way for the
-     * DECstations without bus cycle counter. HK
-     */
-    return 0;
+       /*
+        * This is a kludge until I find a way for the
+        * DECstations without bus cycle counter. HK
+        */
+       return 0;
 }
 
 static unsigned long (*do_gettimeoffset) (void) = do_slow_gettimeoffset;
@@ -162,47 +163,47 @@ static unsigned long (*do_gettimeoffset) (void) = do_slow_gettimeoffset;
  */
 void do_gettimeofday(struct timeval *tv)
 {
-    unsigned long flags;
+       unsigned long flags;
 
-    save_and_cli(flags);
-    *tv = xtime;
-    tv->tv_usec += do_gettimeoffset();
+       read_lock_irqsave(&xtime_lock, flags);
+       *tv = xtime;
+       tv->tv_usec += do_gettimeoffset();
 
-    /*
-     * xtime is atomically updated in timer_bh. lost_ticks is
-     * nonzero if the timer bottom half hasnt executed yet.
-     */
-    if (lost_ticks)
-       tv->tv_usec += USECS_PER_JIFFY;
+       /*
+        * xtime is atomically updated in timer_bh. lost_ticks is
+        * nonzero if the timer bottom half hasnt executed yet.
+        */
+       if (jiffies - wall_jiffies)
+               tv->tv_usec += USECS_PER_JIFFY;
 
-    restore_flags(flags);
+       read_unlock_irqrestore(&xtime_lock, flags);
 
-    if (tv->tv_usec >= 1000000) {
-       tv->tv_usec -= 1000000;
-       tv->tv_sec++;
-    }
+       if (tv->tv_usec >= 1000000) {
+               tv->tv_usec -= 1000000;
+               tv->tv_sec++;
+       }
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-    cli();
-    /* This is revolting. We need to set the xtime.tv_usec
-     * correctly. However, the value in this location is
-     * is value at the last tick.
-     * Discover what correction gettimeofday
-     * would have done, and then undo it!
-     */
-    tv->tv_usec -= do_gettimeoffset();
-
-    if (tv->tv_usec < 0) {
-       tv->tv_usec += 1000000;
-       tv->tv_sec--;
-    }
-    xtime = *tv;
-    time_state = TIME_BAD;
-    time_maxerror = MAXPHASE;
-    time_esterror = MAXPHASE;
-    sti();
+       write_lock_irq(&xtime_lock);
+       /* This is revolting. We need to set the xtime.tv_usec
+        * correctly. However, the value in this location is
+        * is value at the last tick.
+        * Discover what correction gettimeofday
+        * would have done, and then undo it!
+        */
+       tv->tv_usec -= do_gettimeoffset();
+
+       if (tv->tv_usec < 0) {
+               tv->tv_usec += 1000000;
+               tv->tv_sec--;
+       }
+       xtime = *tv;
+       time_state = TIME_BAD;
+       time_maxerror = MAXPHASE;
+       time_esterror = MAXPHASE;
+       write_unlock_irq(&xtime_lock);
 }
 
 /*
@@ -214,53 +215,57 @@ void do_settimeofday(struct timeval *tv)
  */
 static int set_rtc_mmss(unsigned long nowtime)
 {
-    int retval = 0;
-    int real_seconds, real_minutes, cmos_minutes;
-    unsigned char save_control, save_freq_select;
-
-    save_control = CMOS_READ(RTC_CONTROL);     /* tell the clock it's being set */
-    CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
-
-    save_freq_select = CMOS_READ(RTC_FREQ_SELECT);     /* stop and reset prescaler */
-    CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-    cmos_minutes = CMOS_READ(RTC_MINUTES);
-    if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-       BCD_TO_BIN(cmos_minutes);
-
-    /*
-     * since we're only adjusting minutes and seconds,
-     * don't interfere with hour overflow. This avoids
-     * messing with unknown time zones but requires your
-     * RTC not to be off by more than 15 minutes
-     */
-    real_seconds = nowtime % 60;
-    real_minutes = nowtime / 60;
-    if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
-       real_minutes += 30;     /* correct for half hour time zone */
-    real_minutes %= 60;
-
-    if (abs(real_minutes - cmos_minutes) < 30) {
-       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-           BIN_TO_BCD(real_seconds);
-           BIN_TO_BCD(real_minutes);
+       int retval = 0;
+       int real_seconds, real_minutes, cmos_minutes;
+       unsigned char save_control, save_freq_select;
+
+       save_control = CMOS_READ(RTC_CONTROL);  /* tell the clock it's being set */
+       CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
+
+       save_freq_select = CMOS_READ(RTC_FREQ_SELECT);  /* stop and reset prescaler */
+       CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+       cmos_minutes = CMOS_READ(RTC_MINUTES);
+       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+               BCD_TO_BIN(cmos_minutes);
+
+       /*
+        * since we're only adjusting minutes and seconds,
+        * don't interfere with hour overflow. This avoids
+        * messing with unknown time zones but requires your
+        * RTC not to be off by more than 15 minutes
+        */
+       real_seconds = nowtime % 60;
+       real_minutes = nowtime / 60;
+       if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
+               real_minutes += 30;     /* correct for half hour time zone */
+       real_minutes %= 60;
+
+       if (abs(real_minutes - cmos_minutes) < 30) {
+               if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+                       BIN_TO_BCD(real_seconds);
+                       BIN_TO_BCD(real_minutes);
+               }
+               CMOS_WRITE(real_seconds, RTC_SECONDS);
+               CMOS_WRITE(real_minutes, RTC_MINUTES);
+       } else {
+               printk(KERN_WARNING
+                      "set_rtc_mmss: can't update from %d to %d\n",
+                      cmos_minutes, real_minutes);
+               retval = -1;
        }
-       CMOS_WRITE(real_seconds, RTC_SECONDS);
-       CMOS_WRITE(real_minutes, RTC_MINUTES);
-    } else
-       retval = -1;
-
-    /* The following flags have to be released exactly in this order,
-     * otherwise the DS12887 (popular MC146818A clone with integrated
-     * battery and quartz) will not reset the oscillator and will not
-     * update precisely 500 ms later. You won't find this mentioned in
-     * the Dallas Semiconductor data sheets, but who believes data
-     * sheets anyway ...                           -- Markus Kuhn
-     */
-    CMOS_WRITE(save_control, RTC_CONTROL);
-    CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-    return retval;
+
+       /* The following flags have to be released exactly in this order,
+        * otherwise the DS12887 (popular MC146818A clone with integrated
+        * battery and quartz) will not reset the oscillator and will not
+        * update precisely 500 ms later. You won't find this mentioned in
+        * the Dallas Semiconductor data sheets, but who believes data
+        * sheets anyway ...                           -- Markus Kuhn
+        */
+       CMOS_WRITE(save_control, RTC_CONTROL);
+       CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+       return retval;
 }
 
 /* last time the cmos clock got updated */
@@ -271,40 +276,74 @@ static long last_rtc_update = 0;
  * as well as call the "do_timer()" routine every clocktick
  */
 static void inline
- timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-    volatile unsigned char dummy;
-
-    dummy = CMOS_READ(RTC_REG_C);      /* ACK RTC Interrupt */
-    do_timer(regs);
-
-    /*
-     * If we have an externally synchronized Linux clock, then update
-     * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-     * called as close as possible to 500 ms before the new second starts.
-     */
-    if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
-       xtime.tv_usec > 500000 - (tick >> 1) &&
-       xtime.tv_usec < 500000 + (tick >> 1))
-       if (set_rtc_mmss(xtime.tv_sec) == 0)
-           last_rtc_update = xtime.tv_sec;
-       else
-           last_rtc_update = xtime.tv_sec - 600;       /* do it again in 60 s */
+       volatile unsigned char dummy;
+
+       dummy = CMOS_READ(RTC_REG_C);   /* ACK RTC Interrupt */
+
+       if (!user_mode(regs)) {
+               if (prof_buffer && current->pid) {
+                       extern int _stext;
+                       unsigned long pc = regs->cp0_epc;
+
+                       pc -= (unsigned long) &_stext;
+                       pc >>= prof_shift;
+                       /*
+                        * Dont ignore out-of-bounds pc values silently,
+                        * put them into the last histogram slot, so if
+                        * present, they will show up as a sharp peak.
+                        */
+                       if (pc > prof_len - 1)
+                               pc = prof_len - 1;
+                       atomic_inc((atomic_t *) & prof_buffer[pc]);
+               }
+       }
+       do_timer(regs);
+
+       /*
+        * If we have an externally synchronized Linux clock, then update
+        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        */
+       read_lock(&xtime_lock);
+       if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+           xtime.tv_usec > 500000 - (tick >> 1) &&
+           xtime.tv_usec < 500000 + (tick >> 1))
+               if (set_rtc_mmss(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600;   /* do it again in 60 s */
+       /* As we return to user mode fire off the other CPU schedulers.. this is
+          basically because we don't yet share IRQ's around. This message is
+          rigged to be safe on the 386 - basically it's a hack, so don't look
+          closely for now.. */
+       /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
+       read_unlock(&xtime_lock);
 }
 
 static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-    unsigned int count;
-
-    /*
-     * The cycle counter is only 32 bit which is good for about
-     * a minute at current count rates of upto 150MHz or so.
-     */
-    count = read_32bit_cp0_register(CP0_COUNT);
-    timerhi += (count < timerlo);      /* Wrap around */
-    timerlo = count;
-
-    timer_interrupt(irq, dev_id, regs);
+       unsigned int count;
+
+       /*
+        * The cycle counter is only 32 bit which is good for about
+        * a minute at current count rates of upto 150MHz or so.
+        */
+       count = read_32bit_cp0_register(CP0_COUNT);
+       timerhi += (count < timerlo);   /* Wrap around */
+       timerlo = count;
+
+       timer_interrupt(irq, dev_id, regs);
+
+       if (!jiffies) {
+               /*
+                * If jiffies has overflowed in this timer_interrupt we must
+                * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
+                * quotient calc still valid. -arca
+                */
+               timerhi = timerlo = 0;
+       }
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -326,114 +365,114 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
                                   unsigned int day, unsigned int hour,
                                   unsigned int min, unsigned int sec)
 {
-    if (0 >= (int) (mon -= 2)) {       /* 1..12 -> 11,12,1..10 */
-       mon += 12;              /* Puts Feb last since it has leap day */
-       year -= 1;
-    }
-    return (((
-                (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) +
-                year * 365 - 719499
-            ) * 24 + hour      /* now have hours */
-           ) * 60 + min        /* now have minutes */
-       ) * 60 + sec;           /* finally seconds */
+       if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
+               mon += 12;      /* Puts Feb last since it has leap day */
+               year -= 1;
+       }
+       return (((
+                        (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) +
+                        year * 365 - 719499
+                ) * 24 + hour  /* now have hours */
+               ) * 60 + min    /* now have minutes */
+           ) * 60 + sec;       /* finally seconds */
 }
 
 char cyclecounter_available;
 
 static inline void init_cycle_counter(void)
 {
-    switch (mips_cputype) {
-    case CPU_UNKNOWN:
-    case CPU_R2000:
-    case CPU_R3000:
-    case CPU_R3000A:
-    case CPU_R3041:
-    case CPU_R3051:
-    case CPU_R3052:
-    case CPU_R3081:
-    case CPU_R3081E:
-    case CPU_R6000:
-    case CPU_R6000A:
-    case CPU_R8000:            /* Not shure about that one, play safe */
-       cyclecounter_available = 0;
-       break;
-    case CPU_R4000PC:
-    case CPU_R4000SC:
-    case CPU_R4000MC:
-    case CPU_R4200:
-    case CPU_R4400PC:
-    case CPU_R4400SC:
-    case CPU_R4400MC:
-    case CPU_R4600:
-    case CPU_R10000:
-    case CPU_R4300:
-    case CPU_R4650:
-    case CPU_R4700:
-    case CPU_R5000:
-    case CPU_R5000A:
-    case CPU_R4640:
-    case CPU_NEVADA:
-       cyclecounter_available = 1;
-       break;
-    }
+       switch (mips_cputype) {
+       case CPU_UNKNOWN:
+       case CPU_R2000:
+       case CPU_R3000:
+       case CPU_R3000A:
+       case CPU_R3041:
+       case CPU_R3051:
+       case CPU_R3052:
+       case CPU_R3081:
+       case CPU_R3081E:
+       case CPU_R6000:
+       case CPU_R6000A:
+       case CPU_R8000: /* Not shure about that one, play safe */
+               cyclecounter_available = 0;
+               break;
+       case CPU_R4000PC:
+       case CPU_R4000SC:
+       case CPU_R4000MC:
+       case CPU_R4200:
+       case CPU_R4400PC:
+       case CPU_R4400SC:
+       case CPU_R4400MC:
+       case CPU_R4600:
+       case CPU_R10000:
+       case CPU_R4300:
+       case CPU_R4650:
+       case CPU_R4700:
+       case CPU_R5000:
+       case CPU_R5000A:
+       case CPU_R4640:
+       case CPU_NEVADA:
+               cyclecounter_available = 1;
+               break;
+       }
 }
 
-struct irqaction irq0 =
-{timer_interrupt, SA_INTERRUPT, 0,
- "timer", NULL, NULL};
-
+struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0,
+                        "timer", NULL, NULL};
 
 void (*board_time_init) (struct irqaction * irq);
 
 void __init time_init(void)
 {
-    unsigned int year, mon, day, hour, min, sec;
-    int i;
-
-    /* The Linux interpretation of the CMOS clock register contents:
-     * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-     * RTC registers show the second which has precisely just started.
-     * Let's hope other operating systems interpret the RTC the same way.
-     */
-    /* read RTC exactly on falling edge of update flag */
-    for (i = 0; i < 1000000; i++)      /* may take up to 1 second... */
-       if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-           break;
-    for (i = 0; i < 1000000; i++)      /* must try at least 2.228 ms */
-       if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-           break;
-    do {                       /* Isn't this overkill ? UIP above should guarantee consistency */
-       sec = CMOS_READ(RTC_SECONDS);
-       min = CMOS_READ(RTC_MINUTES);
-       hour = CMOS_READ(RTC_HOURS);
-       day = CMOS_READ(RTC_DAY_OF_MONTH);
-       mon = CMOS_READ(RTC_MONTH);
-       year = CMOS_READ(RTC_YEAR);
-    } while (sec != CMOS_READ(RTC_SECONDS));
-    if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-       BCD_TO_BIN(sec);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(hour);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(mon);
-       BCD_TO_BIN(year);
-    }
-    /*
-     * The DECstation RTC is used as a TOY (Time Of Year).
-     * The PROM will reset the year to either '70, '71 or '72.
-     * This hack will only work until Dec 31 2001.
-     */
-    year += 1927;
-
-    xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-    xtime.tv_usec = 0;
-
-    init_cycle_counter();
-
-    if (cyclecounter_available) {
-       write_32bit_cp0_register(CP0_COUNT, 0);
-       do_gettimeoffset = do_fast_gettimeoffset;
-       irq0.handler = r4k_timer_interrupt;
-    }
-    board_time_init(&irq0);
+       unsigned int year, mon, day, hour, min, sec;
+       int i;
+
+       /* The Linux interpretation of the CMOS clock register contents:
+        * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+        * RTC registers show the second which has precisely just started.
+        * Let's hope other operating systems interpret the RTC the same way.
+        */
+       /* read RTC exactly on falling edge of update flag */
+       for (i = 0; i < 1000000; i++)   /* may take up to 1 second... */
+               if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+                       break;
+       for (i = 0; i < 1000000; i++)   /* must try at least 2.228 ms */
+               if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+                       break;
+       do {                    /* Isn't this overkill ? UIP above should guarantee consistency */
+               sec = CMOS_READ(RTC_SECONDS);
+               min = CMOS_READ(RTC_MINUTES);
+               hour = CMOS_READ(RTC_HOURS);
+               day = CMOS_READ(RTC_DAY_OF_MONTH);
+               mon = CMOS_READ(RTC_MONTH);
+               year = CMOS_READ(RTC_YEAR);
+       } while (sec != CMOS_READ(RTC_SECONDS));
+       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+               BCD_TO_BIN(sec);
+               BCD_TO_BIN(min);
+               BCD_TO_BIN(hour);
+               BCD_TO_BIN(day);
+               BCD_TO_BIN(mon);
+               BCD_TO_BIN(year);
+       }
+       /*
+        * The DECstation RTC is used as a TOY (Time Of Year).
+        * The PROM will reset the year to either '70, '71 or '72.
+        * This hack will only work until Dec 31 2001.
+        */
+       year += 1928;
+
+       write_lock_irq(&xtime_lock);
+       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+       xtime.tv_usec = 0;
+       write_unlock_irq(&xtime_lock);
+
+       init_cycle_counter();
+
+       if (cyclecounter_available) {
+               write_32bit_cp0_register(CP0_COUNT, 0);
+               do_gettimeoffset = do_fast_gettimeoffset;
+               irq0.handler = r4k_timer_interrupt;
+       }
+       board_time_init(&irq0);
 }
index 1948a67c2cc6888198cad286bf95685305644e27..b58272f46f43b04d235bd063fcc166f1f2ccfff9 100644 (file)
@@ -49,6 +49,7 @@ EXPORT_SYMBOL_NOVERS(memcmp);
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL(simple_strtol);
 EXPORT_SYMBOL_NOVERS(strcat);
 EXPORT_SYMBOL_NOVERS(strchr);
 EXPORT_SYMBOL_NOVERS(strlen);
index 68ac485280a878928049cef573ebc42caf90acf6..27a5bade56ed8e1bcd695125ffb2c6ebad3a6b1c 100644 (file)
@@ -91,6 +91,15 @@ SECTIONS
   _end = . ;
   PROVIDE (end = .);
   }
+
+  /* Sections to be discarded */
+  /DISCARD/ :
+  {
+        *(.text.exit)
+        *(.data.exit)
+        *(.exitcall.exit)
+  }
+
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
   .stab 0 : { *(.stab) }
index 5ee17215d7c986fa774b2c7d6f8cde9be49526d6..48f9bc5fe6f1b161b406ba67709846e514460b47 100644 (file)
@@ -91,6 +91,15 @@ SECTIONS
   _end = . ;
   PROVIDE (end = .);
   }
+
+  /* Sections to be discarded */
+  /DISCARD/ : 
+  {
+        *(.text.exit)
+        *(.data.exit)
+        *(.exitcall.exit)
+  }
+
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
   .stab 0 : { *(.stab) }
index 1c6d9e2fa5d43ef0a4a9448e7e914875c709a2d4..0d88810581bf74b315bc4e8ab2d5ab0643e23337 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
-#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 
 char arcs_cmdline[CL_SIZE] = {0, };
index 8d4cc54f0ff6555ebd5fb2816790ad834d10ea15..c247d6b528aea756d64c011b553af1bc455e453e 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
-#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 #include <asm/orion.h>
 
index 70e375fed2e3707669e04293eec33d4dee5c67ae..162fa671ec2259f62c27f890688c597f8ca78083 100644 (file)
@@ -10,6 +10,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Machine selection'
 bool 'Support for SGI IP22' CONFIG_SGI_IP22
@@ -109,14 +118,6 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-   bool 'Kernel module loader' CONFIG_KMOD
-fi
-
 source drivers/pci/Config.in
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
index c7c4744795eb3ec3c56b10a66ad81784623874bb..4a47176aff741786b8f2e637a3ee04c199c32e8b 100644 (file)
@@ -100,10 +100,6 @@ NESTED(kernel_entry, 16, sp)                       # kernel entry point
 
        ARC64_TWIDDLE_PC
 
-       /* Note that all firmware passed argument registers still
-          have their values.  */
-       jal     prom_init                       # initialize firmware
-
        CLI                                     # disable interrupts
 
        mfc0    t0, CP0_STATUS
@@ -127,6 +123,10 @@ NESTED(kernel_entry, 16, sp)                       # kernel entry point
        dsrl32  t0, t0, 0
        mtc0    t0, CP0_WATCHHI
 #endif
+       /* Note that all firmware passed argument registers still
+          have their values.  */
+       jal     prom_init                       # initialize firmware
+
        jal     start_kernel
 1:     b       1b                              # just in case ...
        END(kernel_entry)
index c65f05865fa6e8018b5ed328b9a34f5455b7cc8a..284e831b46144d4cdb75e279d7222b3d9ba6e5ec 100644 (file)
@@ -46,6 +46,7 @@ EXPORT_SYMBOL_NOVERS(memcmp);
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL(simple_strtol);
 EXPORT_SYMBOL_NOVERS(strcat);
 EXPORT_SYMBOL_NOVERS(strchr);
 EXPORT_SYMBOL_NOVERS(strlen);
index 54c4006097217b8f4c24dc1d92f80d271c00347a..9241407197856679dfba460941025d171720ec98 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id: process.c,v 1.4 2000/01/16 01:34:01 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 1999 by Ralf Baechle and others.
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/errno.h>
 #include <linux/sched.h>
index 9089c13336c6bae3ca5622a9753c4b75f8272c99..ca0ab79dc8b9ad6877f5ea4376a851706d21ca66 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: r4k_tlb.S,v 1.3 2000/06/30 00:48:29 kanoj Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
index 39e0d99ef2120f44bb6080d05a40174297f94684..1988b681cc02b1d3ebd7d849456751593a4060c4 100644 (file)
@@ -4,8 +4,8 @@
  * for more details.
  *
  * Copyright (C) 1991, 1992  Linus Torvalds
- * Copyright (C) 1994 - 1999  Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1994 - 2000  Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
index 659e3761ae508f1e4e6f358fab7518922b32a981..a67b3449a2ec094d2bdd7dc0ff73b934c68da4e6 100644 (file)
@@ -83,6 +83,15 @@ SECTIONS
    *(COMMON)
   _end = . ;
   }
+
+  /* Sections to be discarded */
+  /DISCARD/ : 
+  {
+        *(.text.exit)
+        *(.data.exit)
+        *(.exitcall.exit)
+  }
+
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
   .stab 0 : { *(.stab) }
index 47f638b4a4dc4432f521d47e358a3a10d5b3c3ed..2b3ff38c61529c1560ad7860829154aa7dea16d8 100644 (file)
@@ -92,6 +92,15 @@ SECTIONS
    *(COMMON)
   _end = . ;
   }
+
+  /* Sections to be discarded */
+  /DISCARD/ : 
+  {
+        *(.text.exit)
+        *(.data.exit)
+        *(.exitcall.exit)
+  }
+
   /* These are needed for ELF backends which have not yet been
      converted to the new style linker.  */
   .stab 0 : { *(.stab) }
index 1525855e8ac1da1b6fae3d3c4dc7787de4bbac98..fbd8d1fa77df41dbae9592b573bcb4bfdb3942bd 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/pci/bridge.h>
 #include <asm/paccess.h>
 #include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hubio.h>
 
 /* Check against user dumbness.  */
 #ifdef CONFIG_VT
index 33f6eaa953758e95634b4a5fe11fe73ccb434b4b..2371da8e45b0e275f8850667dfa0ae5d2cc0a28b 100644 (file)
@@ -11,6 +11,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Platform support'
 define_bool CONFIG_PPC y
@@ -76,15 +85,6 @@ if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
 fi
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 mainmenu_option next_comment
 comment 'General setup'
 
index 9e946365ffeb86c329d65e991af5ad8111ff8643..7835a0162b88e39a9c6b45a8a86225753deab26a 100644 (file)
@@ -13,21 +13,21 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
-mainmenu_option next_comment
-comment 'Processor type and features'
-bool 'Symmetric multi-processing support' CONFIG_SMP
-bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION
-endmenu
-
 mainmenu_option next_comment
 comment 'Loadable module support'
 bool 'Enable loadable module support' CONFIG_MODULES
 if [ "$CONFIG_MODULES" = "y" ]; then
-  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-  bool 'Kernel module loader' CONFIG_KMOD
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
 fi
 endmenu
 
+mainmenu_option next_comment
+comment 'Processor type and features'
+bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION
+endmenu
+
 mainmenu_option next_comment
 comment 'General setup'
 bool 'Fast IRQ handling' CONFIG_FAST_IRQ
index 025e8a8ea4d81de15e87576fe8f83f6bb697da3b..0a83038dcb40e33adc29f1d906a527c5ba618e75 100644 (file)
@@ -13,6 +13,15 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Processor type and features'
 choice 'SuperH system type'                                    \
@@ -47,15 +56,6 @@ else
 fi
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-   bool 'Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 mainmenu_option next_comment
 comment 'General setup'
 
index aedb0f17d7c68d83c12941a5882748271b8782cd..946b20fae7c99d4d72cd1527cc06341308f1fb24 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: timod.c,v 1.8 2000/07/12 00:51:06 davem Exp $
+/* $Id: timod.c,v 1.9 2000/07/12 23:21:02 davem Exp $
  * timod.c: timod emulation.
  *
  * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
index c8b888ff1bfa1941b9aa8e7910cc4b04ef595c4f..2c96066632a21495fe39896911f5ca34da3f5fa8 100644 (file)
@@ -11,7 +11,7 @@ O_TARGET := acpi.o
 O_OBJS   :=
 M_OBJS   :=
 
-ACPI_OBJS := osd.o
+ACPI_OBJS := driver.o ec.o cpu.o os.o sys.o tables.o
 ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard */*.c))
 
 EXTRA_CFLAGS += -I./include -D_LINUX
diff --git a/drivers/acpi/cpu.c b/drivers/acpi/cpu.c
new file mode 100644 (file)
index 0000000..f1feeb1
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ *  cpu.c - Processor handling
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
+unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
+unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
+unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
+
+static unsigned long acpi_pblk = ACPI_INVALID;
+static int acpi_c2_tested = 0;
+static int acpi_c3_tested = 0;
+
+/*
+ * Clear busmaster activity flag
+ */
+static inline void
+acpi_clear_bm_activity(struct acpi_facp *facp)
+{
+       acpi_write_pm1_status(facp, ACPI_BM);
+}
+
+/*
+ * Returns 1 if there has been busmaster activity
+ */
+static inline int
+acpi_bm_activity(struct acpi_facp *facp)
+{
+       return acpi_read_pm1_status(facp) & ACPI_BM;
+}
+
+/*
+ * Set system to sleep through busmaster requests
+ */
+static void
+acpi_sleep_on_busmaster(struct acpi_facp *facp)
+{
+       u32 pm1_cntr = acpi_read_pm1_control(facp);
+       if (pm1_cntr & ACPI_BM_RLD) {
+               pm1_cntr &= ~ACPI_BM_RLD;
+               acpi_write_pm1_control(facp, pm1_cntr);
+       }
+}
+
+/*
+ * Set system to wake on busmaster requests
+ */
+static void
+acpi_wake_on_busmaster(struct acpi_facp *facp)
+{
+       u32 pm1_cntr = acpi_read_pm1_control(facp);
+       if (!(pm1_cntr & ACPI_BM_RLD)) {
+               pm1_cntr |= ACPI_BM_RLD;
+               acpi_write_pm1_control(facp, pm1_cntr);
+       }
+       acpi_clear_bm_activity(facp);
+}
+
+/* The ACPI timer is just the low 24 bits */
+#define TIME_BEGIN(tmr) inl(tmr)
+#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
+
+/*
+ * Idle loop (uniprocessor only)
+ */
+static void
+acpi_idle(void)
+{
+       static int sleep_level = 1;
+       struct acpi_facp *facp = &acpi_facp;
+
+       if (!facp
+           || facp->hdr.signature != ACPI_FACP_SIG
+           || !facp->pm_tmr
+           || !acpi_pblk)
+               goto not_initialized;
+
+       /*
+        * start from the previous sleep level..
+        */
+       if (sleep_level == 1)
+               goto sleep1;
+       if (sleep_level == 2)
+               goto sleep2;
+      sleep3:
+       sleep_level = 3;
+       if (!acpi_c3_tested) {
+               printk(KERN_DEBUG "ACPI C3 works\n");
+               acpi_c3_tested = 1;
+       }
+       acpi_wake_on_busmaster(facp);
+       if (facp->pm2_cnt)
+               goto sleep3_with_arbiter;
+
+       for (;;) {
+               unsigned long time;
+               unsigned int pm_tmr = facp->pm_tmr;
+
+               __cli();
+               if (current->need_resched)
+                       goto out;
+               if (acpi_bm_activity(facp))
+                       goto sleep2;
+
+               time = TIME_BEGIN(pm_tmr);
+               inb(acpi_pblk + ACPI_P_LVL3);
+               /* Dummy read, force synchronization with the PMU */
+               inl(pm_tmr);
+               time = TIME_END(pm_tmr, time);
+
+               __sti();
+               if (time < acpi_c3_exit_latency)
+                       goto sleep2;
+       }
+
+      sleep3_with_arbiter:
+       for (;;) {
+               unsigned long time;
+               u8 arbiter;
+               unsigned int pm2_cntr = facp->pm2_cnt;
+               unsigned int pm_tmr = facp->pm_tmr;
+
+               __cli();
+               if (current->need_resched)
+                       goto out;
+               if (acpi_bm_activity(facp))
+                       goto sleep2;
+
+               time = TIME_BEGIN(pm_tmr);
+               arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
+               /* Disable arbiter, park on CPU */
+               outb(arbiter | ACPI_ARB_DIS, pm2_cntr);
+               inb(acpi_pblk + ACPI_P_LVL3);
+               /* Dummy read, force synchronization with the PMU */
+               inl(pm_tmr);
+               time = TIME_END(pm_tmr, time);
+               /* Enable arbiter again.. */
+               outb(arbiter, pm2_cntr);
+
+               __sti();
+               if (time < acpi_c3_exit_latency)
+                       goto sleep2;
+       }
+
+      sleep2:
+       sleep_level = 2;
+       if (!acpi_c2_tested) {
+               printk(KERN_DEBUG "ACPI C2 works\n");
+               acpi_c2_tested = 1;
+       }
+       acpi_wake_on_busmaster(facp);   /* Required to track BM activity.. */
+       for (;;) {
+               unsigned long time;
+               unsigned int pm_tmr = facp->pm_tmr;
+
+               __cli();
+               if (current->need_resched)
+                       goto out;
+
+               time = TIME_BEGIN(pm_tmr);
+               inb(acpi_pblk + ACPI_P_LVL2);
+               /* Dummy read, force synchronization with the PMU */
+               inl(pm_tmr);
+               time = TIME_END(pm_tmr, time);
+
+               __sti();
+               if (time < acpi_c2_exit_latency)
+                       goto sleep1;
+               if (acpi_bm_activity(facp)) {
+                       acpi_clear_bm_activity(facp);
+                       continue;
+               }
+               if (time > acpi_c3_enter_latency)
+                       goto sleep3;
+       }
+
+      sleep1:
+       sleep_level = 1;
+       acpi_sleep_on_busmaster(facp);
+       for (;;) {
+               unsigned long time;
+               unsigned int pm_tmr = facp->pm_tmr;
+
+               __cli();
+               if (current->need_resched)
+                       goto out;
+               time = TIME_BEGIN(pm_tmr);
+               safe_halt();
+               time = TIME_END(pm_tmr, time);
+               if (time > acpi_c2_enter_latency)
+                       goto sleep2;
+       }
+
+      not_initialized:
+       for (;;) {
+               __cli();
+               if (current->need_resched)
+                       goto out;
+               safe_halt();
+       }
+
+      out:
+       __sti();
+}
+
+/*
+ * Get processor information
+ */
+static ACPI_STATUS
+acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
+{
+       ACPI_OBJECT obj;
+       ACPI_CX_STATE lat[4];
+       ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
+       ACPI_BUFFER buf;
+       int i, count;
+
+       buf.length = sizeof(obj);
+       buf.pointer = &obj;
+       if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
+               return AE_OK;
+
+       printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n",
+              obj.processor.proc_id,
+              obj.processor.pblk_address,
+              obj.processor.pblk_length);
+       if (acpi_pblk != ACPI_INVALID
+           || !obj.processor.pblk_address
+           || obj.processor.pblk_length != 6)
+               return AE_OK;
+
+       acpi_pblk = obj.processor.pblk_address;
+
+       buf.length = sizeof(lat);
+       buf.pointer = lat;
+       if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
+               return AE_OK;
+
+       if (lat[2].latency < MAX_CX_STATE_LATENCY) {
+               printk(KERN_INFO "ACPI: C2 supported\n");
+               acpi_c2_exit_latency = lat[2].latency;
+       }
+       if (lat[3].latency < MAX_CX_STATE_LATENCY) {
+               printk(KERN_INFO "ACPI: C3 supported\n");
+               acpi_c3_exit_latency = lat[3].latency;
+       }
+
+       memset(throttle, 0, sizeof(throttle));
+       buf.length = sizeof(throttle);
+       buf.pointer = throttle;
+
+       if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
+               return AE_OK;
+
+       for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
+               if (throttle[i].percent_of_clock)
+                       count++;
+       }
+       count--;
+       if (count > 0)
+               printk(KERN_INFO "ACPI: %d throttling states\n", count);
+
+       return AE_OK;
+}
+
+int
+acpi_cpu_init(void)
+{
+       acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+                           ACPI_ROOT_OBJECT,
+                           ACPI_INT32_MAX,
+                           acpi_find_cpu,
+                           NULL,
+                           NULL);
+
+#ifdef CONFIG_SMP
+       if (smp_num_cpus == 1)
+               pm_idle = acpi_idle;
+#else
+       pm_idle = acpi_idle;
+#endif
+
+       return 0;
+}
diff --git a/drivers/acpi/driver.c b/drivers/acpi/driver.c
new file mode 100644 (file)
index 0000000..0c668f5
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ *  driver.c - ACPI driver
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <asm/uaccess.h>
+#include "acpi.h"
+#include "driver.h"
+
+struct acpi_run_entry
+{
+       void (*callback)(void*);
+       void *context;
+       struct tq_struct task;
+};
+
+static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
+static volatile u32 acpi_event_status = 0;
+static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
+static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
+
+static volatile int acpi_thread_pid = -1;
+static DECLARE_TASK_QUEUE(acpi_thread_run);
+static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait);
+
+static struct ctl_table_header *acpi_sysctl = NULL;
+
+/*
+ * Examine/modify value
+ */
+static int 
+acpi_do_ulong(ctl_table * ctl,
+             int write,
+             struct file *file,
+             void *buffer,
+             size_t * len)
+{
+       char str[2 * sizeof(unsigned long) + 4], *strend;
+       unsigned long val;
+       int size;
+
+       if (!write) {
+               if (file->f_pos) {
+                       *len = 0;
+                       return 0;
+               }
+
+               val = *(unsigned long *) ctl->data;
+               size = sprintf(str, "0x%08lx\n", val);
+               if (*len >= size) {
+                       copy_to_user(buffer, str, size);
+                       *len = size;
+               }
+               else
+                       *len = 0;
+       }
+       else {
+               size = sizeof(str) - 1;
+               if (size > *len)
+                       size = *len;
+               copy_from_user(str, buffer, size);
+               str[size] = '\0';
+               val = simple_strtoul(str, &strend, 0);
+               if (strend == str)
+                       return -EINVAL;
+               *(unsigned long *) ctl->data = val;
+       }
+
+       file->f_pos += *len;
+       return 0;
+}
+
+/*
+ * Handle ACPI event
+ */
+static u32
+acpi_event(void *context)
+{
+       unsigned long flags;
+       int event = (int) context;
+       int mask = 0;
+
+       switch (event) {
+       case ACPI_EVENT_POWER_BUTTON: mask = ACPI_PWRBTN; break;
+       case ACPI_EVENT_SLEEP_BUTTON: mask = ACPI_SLPBTN; break;
+       default: return AE_ERROR;
+       }
+
+       if (mask) {
+               // notify process waiting on /dev/acpi
+               spin_lock_irqsave(&acpi_event_lock, flags);
+               acpi_event_status |= mask;
+               spin_unlock_irqrestore(&acpi_event_lock, flags);
+               acpi_event_state = acpi_sleep_state;
+               wake_up_interruptible(&acpi_event_wait);
+       }
+
+       return AE_OK;
+}
+
+/*
+ * Wait for next event
+ */
+static int
+acpi_do_event(ctl_table * ctl,
+             int write,
+             struct file *file,
+             void *buffer,
+             size_t * len)
+{
+       u32 event_status = 0;
+       acpi_sstate_t event_state = 0;
+       char str[27];
+       int size;
+
+       if (write)
+               return -EPERM;
+       if (*len < sizeof(str)) {
+               *len = 0;
+               return 0;
+       }
+
+       for (;;) {
+               unsigned long flags;
+
+               // we need an atomic exchange here
+               spin_lock_irqsave(&acpi_event_lock, flags);
+               event_status = acpi_event_status;
+               acpi_event_status = 0;
+               spin_unlock_irqrestore(&acpi_event_lock, flags);
+               event_state = acpi_event_state;
+
+               if (event_status)
+                       break;
+
+               // wait for an event to arrive
+               interruptible_sleep_on(&acpi_event_wait);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+       }
+
+       size = sprintf(str,
+                      "0x%08x 0x%08x 0x%01x\n",
+                      event_status,
+                      0,
+                      event_state);
+       copy_to_user(buffer, str, size);
+       *len = size;
+       file->f_pos += size;
+
+       return 0;
+}
+
+/*
+ * Enter system sleep state
+ */
+static int 
+acpi_do_sleep(ctl_table * ctl,
+             int write,
+             struct file *file,
+             void *buffer,
+             size_t * len)
+{
+       if (!write) {
+               if (file->f_pos) {
+                       *len = 0;
+                       return 0;
+               }
+       }
+       else {
+#ifdef CONFIG_ACPI_S1_SLEEP
+               int status = acpi_enter_sx(ACPI_S1);
+               if (status)
+                       return status;
+#endif
+       }
+       file->f_pos += *len;
+       return 0;
+}
+
+/*
+ * Run queued callback
+ */
+static void
+acpi_run_exec(void *context)
+{
+       struct acpi_run_entry *entry
+               = (struct acpi_run_entry*) context;
+       (*entry->callback)(entry->context);
+       kfree(entry);
+}
+
+/*
+ * Queue for execution by the ACPI thread
+ */
+int
+acpi_run(void (*callback)(void*), void *context)
+{
+       struct acpi_run_entry *entry;
+
+       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+       if (!entry)
+               return -1;
+
+       memset(entry, 0, sizeof(entry));
+       entry->callback = callback;
+       entry->context = context;
+       entry->task.routine = acpi_run_exec;
+       entry->task.data = entry;
+
+       queue_task(&entry->task, &acpi_thread_run);
+
+       if (waitqueue_active(&acpi_thread_wait))
+               wake_up(&acpi_thread_wait);
+
+       return 0;
+}
+
+static struct ctl_table acpi_table[] =
+{
+       {ACPI_P_LVL2_LAT, "c2_exit_latency",
+        &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
+        0644, NULL, &acpi_do_ulong},
+
+       {ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
+        &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
+        0644, NULL, &acpi_do_ulong},
+
+       {ACPI_P_LVL3_LAT, "c3_exit_latency",
+        &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
+        0644, NULL, &acpi_do_ulong},
+
+       {ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
+        &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
+        0644, NULL, &acpi_do_ulong},
+
+       {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
+
+       {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
+
+       {0}
+};
+
+static struct ctl_table acpi_dir_table[] =
+{
+       {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
+       {0}
+};
+
+/*
+ * Initialize and run interpreter within a kernel thread
+ */
+static int
+acpi_thread(void *context)
+{
+       /*
+        * initialize
+        */
+       exit_files(current);
+       daemonize();
+       strcpy(current->comm, "acpi");
+
+       if (!ACPI_SUCCESS(acpi_initialize(NULL))) {
+               printk(KERN_ERR "ACPI: initialize failed\n");
+               return -ENODEV;
+       }
+       
+       if (acpi_load_tables())
+               return -ENODEV;
+
+       if (PM_IS_ACTIVE()) {
+               printk(KERN_NOTICE "ACPI: APM is already active.\n");
+               acpi_terminate();
+               return -ENODEV;
+       }
+
+       pm_active = 1;
+
+       if (!ACPI_SUCCESS(acpi_enable())) {
+               printk(KERN_ERR "ACPI: enable failed\n");
+               acpi_terminate();
+               return -ENODEV;
+       }
+
+       acpi_cpu_init();
+       acpi_sys_init();
+       acpi_ec_init();
+
+       if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
+               ACPI_EVENT_POWER_BUTTON,
+               acpi_event,
+               (void *) ACPI_EVENT_POWER_BUTTON))) {
+               printk(KERN_ERR "ACPI: power button enable failed\n");
+       }
+       if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
+               ACPI_EVENT_SLEEP_BUTTON,
+               acpi_event,
+               (void *) ACPI_EVENT_SLEEP_BUTTON))) {
+               printk(KERN_ERR "ACPI: sleep button enable failed\n");
+       }
+
+       acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
+
+       /*
+        * run
+        */
+       for (;;) {
+               interruptible_sleep_on(&acpi_thread_wait);
+               if (signal_pending(current))
+                       break;
+               do {
+                       run_task_queue(&acpi_thread_run);
+               } while (acpi_thread_run);
+       }
+
+       /*
+        * terminate
+        */
+       unregister_sysctl_table(acpi_sysctl);
+       acpi_terminate();
+
+       acpi_thread_pid = -1;
+
+       return 0;
+}
+
+/*
+ * Start the interpreter
+ */
+int __init
+acpi_init(void)
+{
+       acpi_thread_pid = kernel_thread(acpi_thread,
+                                       NULL,
+                                       (CLONE_FS | CLONE_FILES
+                                        | CLONE_SIGHAND | SIGCHLD));
+       return ((acpi_thread_pid >= 0) ? 0:-ENODEV);
+}
+
+/*
+ * Terminate the interpreter
+ */
+void __exit
+acpi_exit(void)
+{
+       int count;
+
+       if (!kill_proc(acpi_thread_pid, SIGTERM, 1)) {
+               // wait until thread terminates (at most 5 seconds)
+               count = 5 * HZ;
+               while (acpi_thread_pid >= 0 && --count) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(1);
+               }
+       }
+
+       pm_idle = NULL;
+       pm_power_off = NULL;
+       pm_active = 0;
+}
+
+module_init(acpi_init);
+module_exit(acpi_exit);
diff --git a/drivers/acpi/driver.h b/drivers/acpi/driver.h
new file mode 100644 (file)
index 0000000..a26402b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  driver.h - ACPI driver
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __DRIVER_H
+#define __DRIVER_H
+
+#include <linux/tqueue.h>
+#include <linux/wait.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <asm/io.h>
+
+#define ACPI_MAX_THROTTLE 10
+#define ACPI_INVALID ~0UL
+#define ACPI_INFINITE ~0UL
+
+/*
+ * cpu.c
+ */
+int acpi_cpu_init(void);
+
+extern unsigned long acpi_c2_exit_latency;
+extern unsigned long acpi_c3_exit_latency;
+extern unsigned long acpi_c2_enter_latency;
+extern unsigned long acpi_c3_enter_latency;
+
+/*
+ * driver.c
+ */
+int acpi_run(void (*callback)(void*), void *context);
+
+/*
+ * ec.c
+ */
+int acpi_ec_init(void);
+int acpi_ec_read(int addr, int *value);
+int acpi_ec_write(int addr, int value);
+
+/*
+ * sys.c
+ */
+int acpi_sys_init(void);
+int acpi_enter_sx(acpi_sstate_t state);
+
+extern volatile acpi_sstate_t acpi_sleep_state;
+
+/*
+ * tables.c
+ */
+extern struct acpi_facp acpi_facp;
+
+int acpi_load_tables(void);
+
+/*
+ * access ACPI registers
+ */
+
+extern inline u32
+acpi_read_pm1_control(struct acpi_facp *facp)
+{
+       u32 value = 0;
+       if (facp->pm1a_cnt)
+               value = inw(facp->pm1a_cnt);
+       if (facp->pm1b_cnt)
+               value |= inw(facp->pm1b_cnt);
+       return value;
+}
+
+extern inline void 
+acpi_write_pm1_control(struct acpi_facp *facp, u32 value)
+{
+       if (facp->pm1a_cnt)
+               outw(value, facp->pm1a_cnt);
+       if (facp->pm1b_cnt)
+               outw(value, facp->pm1b_cnt);
+}
+
+extern inline u32 
+acpi_read_pm1_status(struct acpi_facp *facp)
+{
+       u32 value = 0;
+       if (facp->pm1a_evt)
+               value = inw(facp->pm1a_evt);
+       if (facp->pm1b_evt)
+               value |= inw(facp->pm1b_evt);
+       return value;
+}
+
+extern inline void 
+acpi_write_pm1_status(struct acpi_facp *facp, u32 value)
+{
+       if (facp->pm1a_evt)
+               outw(value, facp->pm1a_evt);
+       if (facp->pm1b_evt)
+               outw(value, facp->pm1b_evt);
+}
+
+#endif /* __DRIVER_H */
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
new file mode 100644 (file)
index 0000000..b6be7d8
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *  ec.c - Embedded controller support
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "acpi.h"
+#include "driver.h"
+
+enum
+{
+       ACPI_EC_HID = 0x090cd041,
+};
+
+enum
+{
+        ACPI_EC_SMI = 0x40,
+        ACPI_EC_SCI = 0x20,
+        ACPI_EC_BURST = 0x10,
+        ACPI_EC_CMD = 0x08,
+        ACPI_EC_IBF = 0x02,
+        ACPI_EC_OBF = 0x01
+};
+
+enum
+{
+        ACPI_EC_READ = 0x80,
+        ACPI_EC_WRITE = 0x81,
+        ACPI_EC_BURST_ENABLE = 0x82,
+        ACPI_EC_BURST_DISABLE = 0x83,
+        ACPI_EC_QUERY = 0x84,
+};
+
+
+static int acpi_ec_data = 0;
+static int acpi_ec_status = 0;
+static DECLARE_WAIT_QUEUE_HEAD(acpi_ec_wait);
+
+/*
+ * handle GPE
+ */
+static void
+acpi_ec_gpe(void *context)
+{
+       printk(KERN_INFO "ACPI: EC GPE\n");
+       if (waitqueue_active(&acpi_ec_wait))
+               wake_up_interruptible(&acpi_ec_wait);
+}
+
+/*
+ * wait for read/write status to clear
+ */
+static void
+acpi_ec_wait_control(void)
+{
+        udelay(1);
+        while(inb(acpi_ec_status) & ACPI_EC_IBF)
+                udelay(10);
+}
+
+/*
+ * read a byte from the EC
+ */
+int
+acpi_ec_read(int addr, int *value)
+{
+       if (!acpi_ec_data || !acpi_ec_status)
+               return -1;
+
+        outb(ACPI_EC_READ, acpi_ec_status);
+        acpi_ec_wait_control();
+        outb(addr, acpi_ec_data);
+        acpi_ec_wait_control();
+        interruptible_sleep_on(&acpi_ec_wait);
+        *value = inb(acpi_ec_data);
+
+       return 0;
+}
+
+/*
+ * write a byte to the EC
+ */
+int
+acpi_ec_write(int addr, int value)
+{
+       if (!acpi_ec_data || !acpi_ec_status)
+               return -1;
+
+        outb(ACPI_EC_WRITE, acpi_ec_status);
+        acpi_ec_wait_control();
+        outb(addr, acpi_ec_data);
+        acpi_ec_wait_control();
+        outb(value, acpi_ec_data);
+        acpi_ec_wait_control();
+        interruptible_sleep_on(&acpi_ec_wait);
+
+       return 0;
+}
+
+/*
+ * Get processor information
+ */
+static ACPI_STATUS
+acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
+{
+       ACPI_BUFFER buf;
+       ACPI_OBJECT obj;
+       RESOURCE *res;
+       int gpe;
+
+       buf.length = sizeof(obj);
+       buf.pointer = &obj;
+       if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_HID", NULL, &buf))
+           || obj.type != ACPI_TYPE_NUMBER
+           || obj.number.value != ACPI_EC_HID)
+               return AE_OK;
+
+       buf.length = 0;
+       buf.pointer = NULL;
+       if (acpi_get_current_resources(handle, &buf) != AE_BUFFER_OVERFLOW)
+               return AE_OK;
+
+       buf.pointer = kmalloc(buf.length, GFP_KERNEL);
+       if (!buf.pointer)
+               return AE_OK;
+
+       if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) {
+               kfree(buf.pointer);
+               return AE_OK;
+       }
+
+       res = (RESOURCE*) buf.pointer;
+       acpi_ec_data = (int) res->data.io.min_base_address;
+       res = (RESOURCE*)((u8*) buf.pointer + res->length);
+       acpi_ec_status = (int) res->data.io.min_base_address;
+
+       kfree(buf.pointer);
+
+       buf.length = sizeof(obj);
+       buf.pointer = &obj;
+       if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf))
+           || obj.type != ACPI_TYPE_NUMBER)
+               return AE_OK;
+       gpe = (int) obj.number.value;
+
+       printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n",
+              acpi_ec_data, acpi_ec_status, gpe);
+
+       if (!ACPI_SUCCESS(acpi_install_gpe_handler(
+               gpe,
+               (ACPI_EVENT_LEVEL_TRIGGERED
+                | ACPI_EVENT_EDGE_TRIGGERED),
+               acpi_ec_gpe,
+               NULL)))
+               return AE_OK;
+       
+       return AE_OK;
+}
+
+int
+acpi_ec_init(void)
+{
+       acpi_walk_namespace(ACPI_TYPE_DEVICE,
+                           ACPI_ROOT_OBJECT,
+                           ACPI_INT32_MAX,
+                           acpi_find_ec,
+                           NULL,
+                           NULL);
+       return 0;
+}
diff --git a/drivers/acpi/os.c b/drivers/acpi/os.c
new file mode 100644 (file)
index 0000000..d5c1142
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ *  os.c - OS-dependent functions
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include "acpi.h"
+#include "driver.h"
+
+static int acpi_irq_irq = 0;
+static OSD_HANDLER acpi_irq_handler = NULL;
+static void *acpi_irq_context = NULL;
+
+char *
+strupr(char *str)
+{
+       char *s = str;
+       while (*s) {
+               *s = TOUPPER(*s);
+               s++;
+       }
+       return str;
+}
+
+ACPI_STATUS
+acpi_os_initialize(void)
+{
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_terminate(void)
+{
+       if (acpi_irq_handler) {
+               acpi_os_remove_interrupt_handler(acpi_irq_irq,
+                                                acpi_irq_handler);
+       }
+       return AE_OK;
+}
+
+s32
+acpi_os_printf(const char *fmt,...)
+{
+       s32 size;
+       va_list args;
+       va_start(args, fmt);
+       size = acpi_os_vprintf(fmt, args);
+       va_end(args);
+       return size;
+}
+
+s32
+acpi_os_vprintf(const char *fmt, va_list args)
+{
+       static char buffer[512];
+       int size = vsprintf(buffer, fmt, args);
+       printk(KERN_DEBUG "ACPI: %s", buffer);
+       return size;
+}
+
+void *
+acpi_os_allocate(u32 size)
+{
+       return kmalloc(size, GFP_KERNEL);
+}
+
+void *
+acpi_os_callocate(u32 size)
+{
+       void *ptr = acpi_os_allocate(size);
+       if (ptr)
+               memset(ptr, 0, size);
+       return ptr;
+}
+
+void
+acpi_os_free(void *ptr)
+{
+       kfree(ptr);
+}
+
+ACPI_STATUS
+acpi_os_map_memory(void *phys, u32 size, void **virt)
+{
+       if ((unsigned long) phys < virt_to_phys(high_memory)) {
+               *virt = phys_to_virt((unsigned long) phys);
+               return AE_OK;
+       }
+
+       *virt = ioremap((unsigned long) phys, size);
+       if (!*virt)
+               return AE_ERROR;
+
+       return AE_OK;
+}
+
+void
+acpi_os_unmap_memory(void *virt, u32 size)
+{
+       if (virt >= high_memory)
+               iounmap(virt);
+}
+
+static void
+acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+       (*acpi_irq_handler)(acpi_irq_context);
+}
+
+ACPI_STATUS
+acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
+{
+       acpi_irq_irq = irq;
+       acpi_irq_handler = handler;
+       acpi_irq_context = context;
+       if (request_irq(irq,
+                       acpi_irq,
+                       SA_INTERRUPT | SA_SHIRQ,
+                       "acpi",
+                       acpi_irq)) {
+               printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);
+               return AE_ERROR;
+       }
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
+{
+       if (acpi_irq_handler) {
+               free_irq(irq, acpi_irq);
+               acpi_irq_handler = NULL;
+       }
+       return AE_OK;
+}
+
+/*
+ * Running in interpreter thread context, safe to sleep
+ */
+
+void
+acpi_os_sleep(u32 sec, u32 ms)
+{
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(HZ * sec + (ms * HZ) / 1000);
+}
+
+void
+acpi_os_sleep_usec(u32 us)
+{
+       udelay(us);
+}
+
+u8
+acpi_os_in8(ACPI_IO_ADDRESS port)
+{
+       return inb(port);
+}
+
+u16
+acpi_os_in16(ACPI_IO_ADDRESS port)
+{
+       return inw(port);
+}
+
+u32
+acpi_os_in32(ACPI_IO_ADDRESS port)
+{
+       return inl(port);
+}
+
+void
+acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
+{
+       outb(val, port);
+}
+
+void
+acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
+{
+       outw(val, port);
+}
+
+void
+acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
+{
+       outl(val, port);
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_byte(
+                                 u32 bus,
+                                 u32 func,
+                                 u32 addr,
+                                 u8 * val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!val || !dev || pci_read_config_byte(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_word(
+                                 u32 bus,
+                                 u32 func,
+                                 u32 addr,
+                                 u16 * val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!val || !dev || pci_read_config_word(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_dword(
+                                  u32 bus,
+                                  u32 func,
+                                  u32 addr,
+                                  u32 * val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!val || !dev || pci_read_config_dword(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_byte(
+                                  u32 bus,
+                                  u32 func,
+                                  u32 addr,
+                                  u8 val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!dev || pci_write_config_byte(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_word(
+                                  u32 bus,
+                                  u32 func,
+                                  u32 addr,
+                                  u16 val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!dev || pci_write_config_word(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_dword(
+                                   u32 bus,
+                                   u32 func,
+                                   u32 addr,
+                                   u32 val)
+{
+       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+       if (!dev || pci_write_config_dword(dev, addr, val))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+/*
+ * Queue for interpreter thread
+ */
+
+ACPI_STATUS
+acpi_os_queue_for_execution(
+                                   u32 priority,
+                                   OSD_EXECUTION_CALLBACK callback,
+                                   void *context)
+{
+       if (acpi_run(callback, context))
+               return AE_ERROR;
+       return AE_OK;
+}
+
+/*
+ * Semaphores are unused, interpreter access is single threaded
+ */
+
+ACPI_STATUS
+acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle)
+{
+       *handle = (ACPI_HANDLE) 0;
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_delete_semaphore(ACPI_HANDLE handle)
+{
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout)
+{
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units)
+{
+       return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_breakpoint(char *msg)
+{
+       acpi_os_printf("breakpoint: %s", msg);
+       return AE_OK;
+}
+
+void
+acpi_os_dbg_trap(char *msg)
+{
+       acpi_os_printf("trap: %s", msg);
+}
+
+void
+acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg)
+{
+       acpi_os_printf("assert: %s", msg);
+}
+
+u32
+acpi_os_get_line(char *buffer)
+{
+       return 0;
+}
+
+/*
+ * We just have to assume we're dealing with valid memory
+ */
+
+BOOLEAN
+acpi_os_readable(void *ptr, u32 len)
+{
+       return 1;
+}
+
+BOOLEAN
+acpi_os_writable(void *ptr, u32 len)
+{
+       return 1;
+}
diff --git a/drivers/acpi/osd.c b/drivers/acpi/osd.c
deleted file mode 100644 (file)
index 402df75..0000000
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- *  osd.c - Linux specific code
- *
- *  Copyright (C) 2000 Andrew Henroid
- *
- *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/pm.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include "acpi.h"
-
-#define ACPI_MAX_THROTTLE 10
-#define ACPI_INVALID ~0UL
-#define ACPI_INFINITE ~0UL
-
-static struct acpi_facp *acpi_facp = NULL;
-
-static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
-static volatile u32 acpi_event_status = 0;
-static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
-static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
-static int acpi_irq_irq = 0;
-static OSD_HANDLER acpi_irq_handler = NULL;
-static void *acpi_irq_context = NULL;
-
-static unsigned long acpi_pblk = ACPI_INVALID;
-static unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
-static unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
-static unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
-static unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
-static int acpi_c2_tested = 0;
-static int acpi_c3_tested = 0;
-
-struct acpi_intrp_entry
-{
-       int priority;
-       OSD_EXECUTION_CALLBACK callback;
-       void *context;
-       struct list_head list;
-};
-
-struct acpi_enter_sx_ctx
-{
-       wait_queue_head_t wait;
-       int state;
-};
-
-static volatile int acpi_intrp_pid = -1;
-static DECLARE_WAIT_QUEUE_HEAD(acpi_intrp_wait);
-static LIST_HEAD(acpi_intrp_exec);
-static spinlock_t acpi_intrp_exec_lock = SPIN_LOCK_UNLOCKED;
-
-#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
-#define ACPI_SLP_TYPA(value) \
-        ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
-#define ACPI_SLP_TYPB(value) \
-        ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
-
-static volatile acpi_sstate_t acpi_sleep_state = ACPI_S0;
-static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,};
-
-static struct ctl_table_header *acpi_sysctl = NULL;
-
-static int acpi_do_ulong(ctl_table * ctl,
-                        int write,
-                        struct file *file,
-                        void *buffer,
-                        size_t * len);
-static int acpi_do_sleep(ctl_table * ctl,
-                        int write,
-                        struct file *file,
-                        void *buffer,
-                        size_t * len);
-static int acpi_do_event(ctl_table * ctl,
-                        int write,
-                        struct file *file,
-                        void *buffer,
-                        size_t * len);
-
-static struct ctl_table acpi_table[] =
-{
-       {ACPI_P_LVL2_LAT, "c2_exit_latency",
-        &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
-        0644, NULL, &acpi_do_ulong},
-
-       {ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
-        &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
-        0644, NULL, &acpi_do_ulong},
-
-       {ACPI_P_LVL3_LAT, "c3_exit_latency",
-        &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
-        0644, NULL, &acpi_do_ulong},
-
-       {ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
-        &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
-        0644, NULL, &acpi_do_ulong},
-
-       {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
-
-       {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
-
-       {0}
-};
-
-static struct ctl_table acpi_dir_table[] =
-{
-       {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
-       {0}
-};
-
-static u32 FASTCALL(acpi_read_pm1_control(struct acpi_facp *));
-static u32 FASTCALL(acpi_read_pm1_status(struct acpi_facp *));
-static void FASTCALL(acpi_write_pm1_control(struct acpi_facp *, u32));
-static void FASTCALL(acpi_write_pm1_status(struct acpi_facp *, u32));
-
-/*
- * Get the value of the PM1 control register (ACPI_SCI_EN, ...)
- */
-static u32
-acpi_read_pm1_control(struct acpi_facp *facp)
-{
-       u32 value = 0;
-       if (facp->pm1a_cnt)
-               value = inw(facp->pm1a_cnt);
-       if (facp->pm1b_cnt)
-               value |= inw(facp->pm1b_cnt);
-       return value;
-}
-
-/*
- * Set the value of the PM1 control register (ACPI_BM_RLD, ...)
- */
-static void 
-acpi_write_pm1_control(struct acpi_facp *facp, u32 value)
-{
-       if (facp->pm1a_cnt)
-               outw(value, facp->pm1a_cnt);
-       if (facp->pm1b_cnt)
-               outw(value, facp->pm1b_cnt);
-}
-
-/*
- * Get the value of the fixed event status register
- */
-static u32 
-acpi_read_pm1_status(struct acpi_facp *facp)
-{
-       u32 value = 0;
-       if (facp->pm1a_evt)
-               value = inw(facp->pm1a_evt);
-       if (facp->pm1b_evt)
-               value |= inw(facp->pm1b_evt);
-       return value;
-}
-
-/*
- * Set the value of the fixed event status register (clear events)
- */
-static void 
-acpi_write_pm1_status(struct acpi_facp *facp, u32 value)
-{
-       if (facp->pm1a_evt)
-               outw(value, facp->pm1a_evt);
-       if (facp->pm1b_evt)
-               outw(value, facp->pm1b_evt);
-}
-
-/*
- * Examine/modify value
- */
-static int 
-acpi_do_ulong(ctl_table * ctl,
-             int write,
-             struct file *file,
-             void *buffer,
-             size_t * len)
-{
-       char str[2 * sizeof(unsigned long) + 4], *strend;
-       unsigned long val;
-       int size;
-
-       if (!write) {
-               if (file->f_pos) {
-                       *len = 0;
-                       return 0;
-               }
-
-               val = *(unsigned long *) ctl->data;
-               size = sprintf(str, "0x%08lx\n", val);
-               if (*len >= size) {
-                       copy_to_user(buffer, str, size);
-                       *len = size;
-               }
-               else
-                       *len = 0;
-       }
-       else {
-               size = sizeof(str) - 1;
-               if (size > *len)
-                       size = *len;
-               copy_from_user(str, buffer, size);
-               str[size] = '\0';
-               val = simple_strtoul(str, &strend, 0);
-               if (strend == str)
-                       return -EINVAL;
-               *(unsigned long *) ctl->data = val;
-       }
-
-       file->f_pos += *len;
-       return 0;
-}
-
-/*
- * Handle ACPI event
- */
-u32
-acpi_event(void *context)
-{
-       unsigned long flags;
-       int event = (int) context;
-       int mask = 0;
-
-       switch (event) {
-       case ACPI_EVENT_POWER_BUTTON:
-               mask = ACPI_PWRBTN;
-               break;
-       case ACPI_EVENT_SLEEP_BUTTON:
-               mask = ACPI_SLPBTN;
-               break;
-       }
-
-       if (mask) {
-               // notify process waiting on /dev/acpi
-               spin_lock_irqsave(&acpi_event_lock, flags);
-               acpi_event_status |= mask;
-               spin_unlock_irqrestore(&acpi_event_lock, flags);
-               acpi_event_state = acpi_sleep_state;
-               wake_up_interruptible(&acpi_event_wait);
-       }
-
-       return AE_OK;
-}
-
-/*
- * Wait for next event
- */
-int
-acpi_do_event(ctl_table * ctl,
-             int write,
-             struct file *file,
-             void *buffer,
-             size_t * len)
-{
-       u32 event_status = 0;
-       acpi_sstate_t event_state = 0;
-       char str[27];
-       int size;
-
-       if (write)
-               return -EPERM;
-       if (*len < sizeof(str)) {
-               *len = 0;
-               return 0;
-       }
-
-       for (;;) {
-               unsigned long flags;
-
-               // we need an atomic exchange here
-               spin_lock_irqsave(&acpi_event_lock, flags);
-               event_status = acpi_event_status;
-               acpi_event_status = 0;
-               spin_unlock_irqrestore(&acpi_event_lock, flags);
-               event_state = acpi_event_state;
-
-               if (event_status)
-                       break;
-
-               // wait for an event to arrive
-               interruptible_sleep_on(&acpi_event_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-       }
-
-       size = sprintf(str,
-                      "0x%08x 0x%08x 0x%01x\n",
-                      event_status,
-                      0,
-                      event_state);
-       copy_to_user(buffer, str, size);
-       *len = size;
-       file->f_pos += size;
-
-       return 0;
-}
-
-/*
- * Enter system sleep state
- */
-static void
-acpi_enter_sx(void *context)
-{
-       struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context;
-       struct acpi_facp *facp = acpi_facp;
-       ACPI_OBJECT_LIST arg_list;
-       ACPI_OBJECT arg;
-       u16 value;
-
-       /*
-         * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
-        */
-
-       // run the _PTS method
-       memset(&arg_list, 0, sizeof(arg_list));
-       arg_list.count = 1;
-       arg_list.pointer = &arg;
-
-       memset(&arg, 0, sizeof(arg));
-       arg.type = ACPI_TYPE_NUMBER;
-       arg.number.value = ctx->state;
-
-       acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
-       
-       // clear wake status
-       acpi_write_pm1_status(facp, ACPI_WAK);
-       
-       acpi_sleep_state = ctx->state;
-
-       // set ACPI_SLP_TYPA/b and ACPI_SLP_EN
-       __cli();
-       if (facp->pm1a_cnt) {
-               value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
-               value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state])
-                         | ACPI_SLP_EN);
-               outw(value, facp->pm1a_cnt);
-       }
-       if (facp->pm1b_cnt) {
-               value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK;
-               value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state])
-                         | ACPI_SLP_EN);
-               outw(value, facp->pm1b_cnt);
-       }
-       __sti();
-       
-       if (ctx->state != ACPI_S1) {
-               printk(KERN_ERR "ACPI: S%d failed\n", ctx->state);
-               goto out;
-       }
-
-       // wait until S1 is entered
-       while (!(acpi_read_pm1_status(facp) & ACPI_WAK))
-               safe_halt();
-
-       // run the _WAK method
-       memset(&arg_list, 0, sizeof(arg_list));
-       arg_list.count = 1;
-       arg_list.pointer = &arg;
-
-       memset(&arg, 0, sizeof(arg));
-       arg.type = ACPI_TYPE_NUMBER;
-       arg.number.value = ctx->state;
-
-       acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
-
- out:
-       acpi_sleep_state = ACPI_S0;
-
-       if (waitqueue_active(&ctx->wait))
-               wake_up_interruptible(&ctx->wait);
-}
-
-/*
- * Enter system sleep state and wait for completion
- */
-static int
-acpi_enter_sx_and_wait(acpi_sstate_t state)
-{
-       struct acpi_enter_sx_ctx ctx;
-
-       if (!acpi_facp
-           || acpi_facp->hdr.signature != ACPI_FACP_SIG
-           || acpi_slptyp[state] == ACPI_INVALID)
-               return -EINVAL;
-       
-       init_waitqueue_head(&ctx.wait);
-       ctx.state = state;
-
-       if (acpi_os_queue_for_execution(0, acpi_enter_sx, &ctx))
-               return -1;
-
-       interruptible_sleep_on(&ctx.wait);
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-
-       return 0;
-}
-
-/*
- * Enter system sleep state
- */
-static int 
-acpi_do_sleep(ctl_table * ctl,
-             int write,
-             struct file *file,
-             void *buffer,
-             size_t * len)
-{
-       if (!write) {
-               if (file->f_pos) {
-                       *len = 0;
-                       return 0;
-               }
-       }
-       else {
-#ifdef CONFIG_ACPI_S1_SLEEP
-               int status = acpi_enter_sx_and_wait(ACPI_S1);
-               if (status)
-                       return status;
-#endif
-       }
-       file->f_pos += *len;
-       return 0;
-}
-
-/*
- * Clear busmaster activity flag
- */
-static inline void
-acpi_clear_bm_activity(struct acpi_facp *facp)
-{
-       acpi_write_pm1_status(facp, ACPI_BM);
-}
-
-/*
- * Returns 1 if there has been busmaster activity
- */
-static inline int
-acpi_bm_activity(struct acpi_facp *facp)
-{
-       return acpi_read_pm1_status(facp) & ACPI_BM;
-}
-
-/*
- * Set system to sleep through busmaster requests
- */
-static void
-acpi_sleep_on_busmaster(struct acpi_facp *facp)
-{
-       u32 pm1_cntr = acpi_read_pm1_control(facp);
-       if (pm1_cntr & ACPI_BM_RLD) {
-               pm1_cntr &= ~ACPI_BM_RLD;
-               acpi_write_pm1_control(facp, pm1_cntr);
-       }
-}
-
-/*
- * Set system to wake on busmaster requests
- */
-static void
-acpi_wake_on_busmaster(struct acpi_facp *facp)
-{
-       u32 pm1_cntr = acpi_read_pm1_control(facp);
-       if (!(pm1_cntr & ACPI_BM_RLD)) {
-               pm1_cntr |= ACPI_BM_RLD;
-               acpi_write_pm1_control(facp, pm1_cntr);
-       }
-       acpi_clear_bm_activity(facp);
-}
-
-/* The ACPI timer is just the low 24 bits */
-#define TIME_BEGIN(tmr) inl(tmr)
-#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
-
-/*
- * Idle loop (uniprocessor only)
- */
-void
-acpi_idle(void)
-{
-       static int sleep_level = 1;
-       struct acpi_facp *facp = acpi_facp;
-
-       if (!facp
-           || facp->hdr.signature != ACPI_FACP_SIG
-           || !facp->pm_tmr
-           || !acpi_pblk)
-               goto not_initialized;
-
-       /*
-        * start from the previous sleep level..
-        */
-       if (sleep_level == 1)
-               goto sleep1;
-       if (sleep_level == 2)
-               goto sleep2;
-      sleep3:
-       sleep_level = 3;
-       if (!acpi_c3_tested) {
-               printk(KERN_DEBUG "ACPI C3 works\n");
-               acpi_c3_tested = 1;
-       }
-       acpi_wake_on_busmaster(facp);
-       if (facp->pm2_cnt)
-               goto sleep3_with_arbiter;
-
-       for (;;) {
-               unsigned long time;
-               unsigned int pm_tmr = facp->pm_tmr;
-
-               __cli();
-               if (current->need_resched)
-                       goto out;
-               if (acpi_bm_activity(facp))
-                       goto sleep2;
-
-               time = TIME_BEGIN(pm_tmr);
-               inb(acpi_pblk + ACPI_P_LVL3);
-               /* Dummy read, force synchronization with the PMU */
-               inl(pm_tmr);
-               time = TIME_END(pm_tmr, time);
-
-               __sti();
-               if (time < acpi_c3_exit_latency)
-                       goto sleep2;
-       }
-
-      sleep3_with_arbiter:
-       for (;;) {
-               unsigned long time;
-               u8 arbiter;
-               unsigned int pm2_cntr = facp->pm2_cnt;
-               unsigned int pm_tmr = facp->pm_tmr;
-
-               __cli();
-               if (current->need_resched)
-                       goto out;
-               if (acpi_bm_activity(facp))
-                       goto sleep2;
-
-               time = TIME_BEGIN(pm_tmr);
-               arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
-               /* Disable arbiter, park on CPU */
-               outb(arbiter | ACPI_ARB_DIS, pm2_cntr);
-               inb(acpi_pblk + ACPI_P_LVL3);
-               /* Dummy read, force synchronization with the PMU */
-               inl(pm_tmr);
-               time = TIME_END(pm_tmr, time);
-               /* Enable arbiter again.. */
-               outb(arbiter, pm2_cntr);
-
-               __sti();
-               if (time < acpi_c3_exit_latency)
-                       goto sleep2;
-       }
-
-      sleep2:
-       sleep_level = 2;
-       if (!acpi_c2_tested) {
-               printk(KERN_DEBUG "ACPI C2 works\n");
-               acpi_c2_tested = 1;
-       }
-       acpi_wake_on_busmaster(facp);   /* Required to track BM activity.. */
-       for (;;) {
-               unsigned long time;
-               unsigned int pm_tmr = facp->pm_tmr;
-
-               __cli();
-               if (current->need_resched)
-                       goto out;
-
-               time = TIME_BEGIN(pm_tmr);
-               inb(acpi_pblk + ACPI_P_LVL2);
-               /* Dummy read, force synchronization with the PMU */
-               inl(pm_tmr);
-               time = TIME_END(pm_tmr, time);
-
-               __sti();
-               if (time < acpi_c2_exit_latency)
-                       goto sleep1;
-               if (acpi_bm_activity(facp)) {
-                       acpi_clear_bm_activity(facp);
-                       continue;
-               }
-               if (time > acpi_c3_enter_latency)
-                       goto sleep3;
-       }
-
-      sleep1:
-       sleep_level = 1;
-       acpi_sleep_on_busmaster(facp);
-       for (;;) {
-               unsigned long time;
-               unsigned int pm_tmr = facp->pm_tmr;
-
-               __cli();
-               if (current->need_resched)
-                       goto out;
-               time = TIME_BEGIN(pm_tmr);
-               safe_halt();
-               time = TIME_END(pm_tmr, time);
-               if (time > acpi_c2_enter_latency)
-                       goto sleep2;
-       }
-
-      not_initialized:
-       for (;;) {
-               __cli();
-               if (current->need_resched)
-                       goto out;
-               safe_halt();
-       }
-
-      out:
-       __sti();
-}
-
-/*
- * Enter soft-off (S5)
- */
-static void
-acpi_power_off(void)
-{
-       struct acpi_enter_sx_ctx ctx;
-
-       if (!acpi_facp
-           || acpi_facp->hdr.signature != ACPI_FACP_SIG
-           || acpi_slptyp[ACPI_S5] == ACPI_INVALID)
-               return;
-       
-       init_waitqueue_head(&ctx.wait);
-       ctx.state = ACPI_S5;
-       acpi_enter_sx(&ctx);
-}
-
-/*
- * Get processor information
- */
-static ACPI_STATUS
-acpi_get_cpu_info(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
-       ACPI_OBJECT obj;
-       ACPI_CX_STATE lat[4];
-       ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
-       ACPI_BUFFER buf;
-       int i, count;
-
-       buf.length = sizeof(obj);
-       buf.pointer = &obj;
-       if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
-               return AE_OK;
-
-       printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n",
-              obj.processor.proc_id,
-              obj.processor.pblk_address,
-              obj.processor.pblk_length);
-       if (acpi_pblk != ACPI_INVALID
-           || !obj.processor.pblk_address
-           || obj.processor.pblk_length != 6)
-               return AE_OK;
-
-       acpi_pblk = obj.processor.pblk_address;
-
-       buf.length = sizeof(lat);
-       buf.pointer = lat;
-       if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
-               return AE_OK;
-
-       if (lat[2].latency < MAX_CX_STATE_LATENCY) {
-               printk(KERN_INFO "ACPI: C2 supported\n");
-               acpi_c2_exit_latency = lat[2].latency;
-       }
-       if (lat[3].latency < MAX_CX_STATE_LATENCY) {
-               printk(KERN_INFO "ACPI: C3 supported\n");
-               acpi_c3_exit_latency = lat[3].latency;
-       }
-
-       memset(throttle, 0, sizeof(throttle));
-       buf.length = sizeof(throttle);
-       buf.pointer = throttle;
-
-       if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
-               return AE_OK;
-
-       for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
-               if (throttle[i].percent_of_clock)
-                       count++;
-       }
-       count--;
-       if (count > 0)
-               printk(KERN_INFO "ACPI: %d throttling states\n", count);
-
-       return AE_OK;
-}
-
-/*
- * Fetch the FACP information
- */
-static int
-acpi_fetch_facp(void)
-{
-       ACPI_BUFFER buffer;
-
-       buffer.pointer = acpi_facp;
-       buffer.length = sizeof(*acpi_facp);
-       if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
-               printk(KERN_ERR "ACPI: no FACP\n");
-               kfree(acpi_facp);
-               return -ENODEV;
-       }
-
-       if (acpi_facp->p_lvl2_lat
-           && acpi_facp->p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
-               acpi_c2_exit_latency
-                       = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl2_lat);
-               acpi_c2_enter_latency
-                       = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
-       }
-       if (acpi_facp->p_lvl3_lat
-           && acpi_facp->p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
-               acpi_c3_exit_latency
-                       = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat);
-               acpi_c3_enter_latency
-                       = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat * 5);
-       }
-
-       return 0;
-}
-
-/*
- * Execute callbacks (interpret methods)
- */
-static void
-acpi_intrp_run(void)
-{
-       for (;;) {
-               struct acpi_intrp_entry *entry;
-               unsigned long flags;
-
-               interruptible_sleep_on(&acpi_intrp_wait);
-               if (signal_pending(current))
-                       return;
-
-               for (;;) {
-                       entry = NULL;
-
-                       spin_lock_irqsave(&acpi_intrp_exec_lock, flags);
-                       if (!list_empty(&acpi_intrp_exec)) {
-                               entry = list_entry(acpi_intrp_exec.next,
-                                                  struct acpi_intrp_entry,
-                                                  list);
-                               list_del(&entry->list);
-                       }
-                       spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags);
-
-                       if (!entry)
-                               break;
-
-                       (*entry->callback)(entry->context);
-
-                       kfree(entry);
-               }
-       }
-}
-
-/*
- * Initialize and run interpreter within a kernel thread
- */
-static int
-acpi_intrp_thread(void *context)
-{
-       ACPI_STATUS status;
-       u8 sx, typa, typb;
-
-       /*
-        * initialize interpreter
-        */
-       exit_files(current);
-       daemonize();
-       strcpy(current->comm, "acpi");
-
-       if (!ACPI_SUCCESS(acpi_initialize(NULL))) {
-               printk(KERN_ERR "ACPI: initialize failed\n");
-               return -ENODEV;
-       }
-
-       if (!ACPI_SUCCESS(acpi_load_firmware_tables())) {
-               printk(KERN_ERR "ACPI: table load failed\n");
-               acpi_terminate();
-               return -ENODEV;
-       }
-
-       if (acpi_fetch_facp()) {
-               acpi_terminate();
-               return -ENODEV;
-       }
-
-       status = acpi_load_namespace();
-       if (!ACPI_SUCCESS(status) && status != AE_CTRL_PENDING) {
-               printk(KERN_ERR "ACPI: namespace load failed\n");
-               acpi_terminate();
-               return -ENODEV;
-       }
-
-       printk(KERN_INFO "ACPI: ACPI support found\n");
-
-       acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_INT32_MAX,
-                           acpi_get_cpu_info,
-                           NULL,
-                           NULL);
-
-       for (sx = ACPI_S0; sx <= ACPI_S5; sx++) {
-               int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1);
-               if (ACPI_SUCCESS(
-                          acpi_hw_obtain_sleep_type_register_data(ca_sx,
-                                                                  &typa,
-                                                                  &typb)))
-                       acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb);
-               else
-                       acpi_slptyp[sx] = ACPI_INVALID;
-       }
-       if (acpi_slptyp[ACPI_S1] != ACPI_INVALID)
-               printk(KERN_INFO "ACPI: S1 supported\n");
-       if (acpi_slptyp[ACPI_S5] != ACPI_INVALID)
-               printk(KERN_INFO "ACPI: S5 supported\n");
-
-       if (!ACPI_SUCCESS(acpi_enable())) {
-               printk(KERN_ERR "ACPI: enable failed\n");
-               acpi_terminate();
-               return -ENODEV;
-       }
-
-       if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
-               ACPI_EVENT_POWER_BUTTON,
-               acpi_event,
-               (void *) ACPI_EVENT_POWER_BUTTON))) {
-               printk(KERN_ERR "ACPI: power button enable failed\n");
-       }
-       if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
-               ACPI_EVENT_SLEEP_BUTTON,
-               acpi_event,
-               (void *) ACPI_EVENT_SLEEP_BUTTON))) {
-               printk(KERN_ERR "ACPI: sleep button enable failed\n");
-       }
-
-#ifdef CONFIG_SMP
-       if (smp_num_cpus == 1)
-               pm_idle = acpi_idle;
-#else
-       pm_idle = acpi_idle;
-#endif
-       pm_power_off = acpi_power_off;
-
-       acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
-
-       /*
-        * run interpreter
-        */
-       acpi_intrp_run();
-
-       /*
-        * terminate interpreter
-        */
-       unregister_sysctl_table(acpi_sysctl);
-       acpi_terminate();
-
-       acpi_intrp_pid = -1;
-
-       return 0;
-}
-
-/*
- * Start the interpreter
- */
-int __init
-acpi_init(void)
-{
-       acpi_facp = kmalloc(sizeof(*acpi_facp), GFP_KERNEL);
-       if (!acpi_facp)
-               return -ENOMEM;
-       memset(acpi_facp, 0, sizeof(*acpi_facp));
-
-       acpi_intrp_pid = kernel_thread(acpi_intrp_thread,
-                                      NULL,
-                                      (CLONE_FS | CLONE_FILES
-                                       | CLONE_SIGHAND | SIGCHLD));
-       return ((acpi_intrp_pid >= 0) ? 0:-ENODEV);
-}
-
-/*
- * Terminate the interpreter
- */
-void __exit
-acpi_exit(void)
-{
-       int count;
-
-       if (!kill_proc(acpi_intrp_pid, SIGTERM, 1)) {
-               // wait until interpreter thread terminates (at most 5 seconds)
-               count = 5 * HZ;
-               while (acpi_intrp_pid >= 0 && --count) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(1);
-               }
-       }
-
-       // clean up after the interpreter
-
-       if (acpi_irq_handler) {
-               acpi_os_remove_interrupt_handler(acpi_irq_irq,
-                                                 acpi_irq_handler);
-       }
-
-       if (pm_power_off == acpi_power_off)
-               pm_power_off = NULL;
-       if (pm_idle == acpi_idle)
-               pm_idle = NULL;
-
-       kfree(acpi_facp);
-}
-
-module_init(acpi_init);
-module_exit(acpi_exit);
-
-/*
- * OS-dependent functions
- *
- */
-
-char *
-strupr(char *str)
-{
-       char *s = str;
-       while (*s) {
-               *s = TOUPPER(*s);
-               s++;
-       }
-       return str;
-}
-
-ACPI_STATUS
-acpi_os_initialize(void)
-{
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_terminate(void)
-{
-       return AE_OK;
-}
-
-s32
-acpi_os_printf(const char *fmt,...)
-{
-       s32 size;
-       va_list args;
-       va_start(args, fmt);
-       size = acpi_os_vprintf(fmt, args);
-       va_end(args);
-       return size;
-}
-
-s32
-acpi_os_vprintf(const char *fmt, va_list args)
-{
-       static char buffer[512];
-       int size = vsprintf(buffer, fmt, args);
-       printk(KERN_DEBUG "%s", buffer);
-       return size;
-}
-
-void *
-acpi_os_allocate(u32 size)
-{
-       return kmalloc(size, GFP_KERNEL);
-}
-
-void *
-acpi_os_callocate(u32 size)
-{
-       void *ptr = acpi_os_allocate(size);
-       if (ptr)
-               memset(ptr, 0, size);
-       return ptr;
-}
-
-void
-acpi_os_free(void *ptr)
-{
-       kfree(ptr);
-}
-
-ACPI_STATUS
-acpi_os_map_memory(void *phys, u32 size, void **virt)
-{
-       if ((unsigned long) phys < virt_to_phys(high_memory)) {
-               *virt = phys_to_virt((unsigned long) phys);
-               return AE_OK;
-       }
-
-       *virt = ioremap((unsigned long) phys, size);
-       if (!*virt)
-               return AE_ERROR;
-
-       return AE_OK;
-}
-
-void
-acpi_os_unmap_memory(void *virt, u32 size)
-{
-       if (virt >= high_memory)
-               iounmap(virt);
-}
-
-static void
-acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-       (*acpi_irq_handler)(acpi_irq_context);
-}
-
-ACPI_STATUS
-acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
-{
-       acpi_irq_irq = irq;
-       acpi_irq_handler = handler;
-       acpi_irq_context = context;
-       if (request_irq(irq,
-                       acpi_irq,
-                       SA_INTERRUPT | SA_SHIRQ,
-                       "acpi",
-                       acpi_irq)) {
-               printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);
-               return AE_ERROR;
-       }
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
-{
-       if (acpi_irq_handler) {
-               free_irq(irq, acpi_irq);
-               acpi_irq_handler = NULL;
-       }
-       return AE_OK;
-}
-
-/*
- * Running in interpreter thread context, safe to sleep
- */
-
-void
-acpi_os_sleep(u32 sec, u32 ms)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(HZ * sec + (ms * HZ) / 1000);
-}
-
-void
-acpi_os_sleep_usec(u32 us)
-{
-       udelay(us);
-}
-
-u8
-acpi_os_in8(ACPI_IO_ADDRESS port)
-{
-       return inb(port);
-}
-
-u16
-acpi_os_in16(ACPI_IO_ADDRESS port)
-{
-       return inw(port);
-}
-
-u32
-acpi_os_in32(ACPI_IO_ADDRESS port)
-{
-       return inl(port);
-}
-
-void
-acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
-{
-       outb(val, port);
-}
-
-void
-acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
-{
-       outw(val, port);
-}
-
-void
-acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
-{
-       outl(val, port);
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_byte(
-                                 u32 bus,
-                                 u32 func,
-                                 u32 addr,
-                                 u8 * val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!val || !dev || pci_read_config_byte(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_word(
-                                 u32 bus,
-                                 u32 func,
-                                 u32 addr,
-                                 u16 * val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!val || !dev || pci_read_config_word(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_dword(
-                                  u32 bus,
-                                  u32 func,
-                                  u32 addr,
-                                  u32 * val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!val || !dev || pci_read_config_dword(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_byte(
-                                  u32 bus,
-                                  u32 func,
-                                  u32 addr,
-                                  u8 val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!dev || pci_write_config_byte(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_word(
-                                  u32 bus,
-                                  u32 func,
-                                  u32 addr,
-                                  u16 val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!dev || pci_write_config_word(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_dword(
-                                   u32 bus,
-                                   u32 func,
-                                   u32 addr,
-                                   u32 val)
-{
-       int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
-       struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
-       if (!dev || pci_write_config_dword(dev, addr, val))
-               return AE_ERROR;
-       return AE_OK;
-}
-
-/*
- * Queue for interpreter thread
- */
-
-ACPI_STATUS
-acpi_os_queue_for_execution(
-                                   u32 priority,
-                                   OSD_EXECUTION_CALLBACK callback,
-                                   void *context)
-{
-       struct acpi_intrp_entry *entry;
-       unsigned long flags;
-
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       if (!entry)
-               return AE_ERROR;
-
-       memset(entry, 0, sizeof(entry));
-       entry->priority = priority;
-       entry->callback = callback;
-       entry->context = context;
-       INIT_LIST_HEAD(&entry->list);
-
-       if (!waitqueue_active(&acpi_intrp_wait)) {
-               kfree(entry);
-               return AE_ERROR;
-       }
-
-       spin_lock_irqsave(&acpi_intrp_exec_lock, flags);
-       list_add(&entry->list, &acpi_intrp_exec);
-       wake_up(&acpi_intrp_wait);
-       spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags);
-
-       return AE_OK;
-}
-
-/*
- * Semaphores are unused, interpreter access is single threaded
- */
-
-ACPI_STATUS
-acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle)
-{
-       *handle = (ACPI_HANDLE) 0;
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_delete_semaphore(ACPI_HANDLE handle)
-{
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout)
-{
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units)
-{
-       return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_breakpoint(char *msg)
-{
-       acpi_os_printf("breakpoint: %s", msg);
-       return AE_OK;
-}
-
-void
-acpi_os_dbg_trap(char *msg)
-{
-       acpi_os_printf("trap: %s", msg);
-}
-
-void
-acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg)
-{
-       acpi_os_printf("assert: %s", msg);
-}
-
-u32
-acpi_os_get_line(char *buffer)
-{
-       return 0;
-}
-
-/*
- * We just have to assume we're dealing with valid memory
- */
-
-BOOLEAN
-acpi_os_readable(void *ptr, u32 len)
-{
-       return 1;
-}
-
-BOOLEAN
-acpi_os_writable(void *ptr, u32 len)
-{
-       return 1;
-}
diff --git a/drivers/acpi/sys.c b/drivers/acpi/sys.c
new file mode 100644 (file)
index 0000000..40ce078
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ *  sys.c - System management (suspend, ...)
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
+#define ACPI_SLP_TYPA(value) \
+        ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
+#define ACPI_SLP_TYPB(value) \
+        ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
+
+struct acpi_enter_sx_ctx
+{
+       wait_queue_head_t wait;
+       int state;
+};
+
+volatile acpi_sstate_t acpi_sleep_state = ACPI_S0;
+static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,};
+
+/*
+ * Enter system sleep state
+ */
+static void
+acpi_enter_sx_async(void *context)
+{
+       struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context;
+       struct acpi_facp *facp = &acpi_facp;
+       ACPI_OBJECT_LIST arg_list;
+       ACPI_OBJECT arg;
+       u16 value;
+
+       /*
+         * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
+        */
+
+       // run the _PTS method
+       memset(&arg_list, 0, sizeof(arg_list));
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+
+       memset(&arg, 0, sizeof(arg));
+       arg.type = ACPI_TYPE_NUMBER;
+       arg.number.value = ctx->state;
+
+       acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
+       
+       // clear wake status
+       acpi_write_pm1_status(facp, ACPI_WAK);
+       
+       acpi_sleep_state = ctx->state;
+
+       // set ACPI_SLP_TYPA/b and ACPI_SLP_EN
+       __cli();
+       if (facp->pm1a_cnt) {
+               value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
+               value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state])
+                         | ACPI_SLP_EN);
+               outw(value, facp->pm1a_cnt);
+       }
+       if (facp->pm1b_cnt) {
+               value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK;
+               value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state])
+                         | ACPI_SLP_EN);
+               outw(value, facp->pm1b_cnt);
+       }
+       __sti();
+       
+       if (ctx->state != ACPI_S1) {
+               printk(KERN_ERR "ACPI: S%d failed\n", ctx->state);
+               goto out;
+       }
+
+       // wait until S1 is entered
+       while (!(acpi_read_pm1_status(facp) & ACPI_WAK))
+               safe_halt();
+
+       // run the _WAK method
+       memset(&arg_list, 0, sizeof(arg_list));
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+
+       memset(&arg, 0, sizeof(arg));
+       arg.type = ACPI_TYPE_NUMBER;
+       arg.number.value = ctx->state;
+
+       acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
+
+ out:
+       acpi_sleep_state = ACPI_S0;
+
+       if (waitqueue_active(&ctx->wait))
+               wake_up_interruptible(&ctx->wait);
+}
+
+/*
+ * Enter soft-off (S5)
+ */
+static void
+acpi_power_off(void)
+{
+       struct acpi_enter_sx_ctx ctx;
+
+       if (acpi_facp.hdr.signature != ACPI_FACP_SIG
+           || acpi_slptyp[ACPI_S5] == ACPI_INVALID)
+               return;
+       
+       init_waitqueue_head(&ctx.wait);
+       ctx.state = ACPI_S5;
+       acpi_enter_sx_async(&ctx);
+}
+
+/*
+ * Enter system sleep state and wait for completion
+ */
+int
+acpi_enter_sx(acpi_sstate_t state)
+{
+       struct acpi_enter_sx_ctx ctx;
+
+       if (acpi_facp.hdr.signature != ACPI_FACP_SIG
+           || acpi_slptyp[state] == ACPI_INVALID)
+               return -EINVAL;
+       
+       init_waitqueue_head(&ctx.wait);
+       ctx.state = state;
+
+       if (acpi_os_queue_for_execution(0, acpi_enter_sx_async, &ctx))
+               return -1;
+
+       interruptible_sleep_on(&ctx.wait);
+       if (signal_pending(current))
+               return -ERESTARTSYS;
+
+       return 0;
+}
+
+int
+acpi_sys_init(void)
+{
+       u8 sx, typa, typb;
+
+       for (sx = ACPI_S0; sx <= ACPI_S5; sx++) {
+               int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1);
+               if (ACPI_SUCCESS(
+                          acpi_hw_obtain_sleep_type_register_data(ca_sx,
+                                                                  &typa,
+                                                                  &typb)))
+                       acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb);
+               else
+                       acpi_slptyp[sx] = ACPI_INVALID;
+       }
+       if (acpi_slptyp[ACPI_S1] != ACPI_INVALID)
+               printk(KERN_INFO "ACPI: S1 supported\n");
+       if (acpi_slptyp[ACPI_S5] != ACPI_INVALID)
+               printk(KERN_INFO "ACPI: S5 supported\n");
+
+       pm_power_off = acpi_power_off;
+
+       return 0;
+}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
new file mode 100644 (file)
index 0000000..9621490
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ *  tables.c - ACPI tables, chipset, and errata handling
+ *
+ *  Copyright (C) 2000 Andrew Henroid
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+struct acpi_facp acpi_facp;
+
+#define ACPI_DUMMY_CHECKSUM 9
+#define ACPI_DUMMY_PBLK 51
+
+static u8 acpi_dummy_dsdt[] =
+{
+       0x44, 0x53, 0x44, 0x54,                         // "DSDT"
+       0x38, 0x00, 0x00, 0x00,                         // length
+       0x01,                                           // revision
+       0x00,                                           // checksum
+       0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00,             // "LINUX"
+       0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY"
+       0x01, 0x00, 0x00, 0x00,                         // OEM rev
+       0x4c, 0x4e, 0x55, 0x58,                         // "LNUX"
+       0x01, 0x00, 0x00, 0x00,                         // creator rev
+       0x10,                                           // Scope
+       0x13,                                           //   PkgLength
+       0x5c, 0x5f, 0x50, 0x52, 0x5f,                   //   \_PR_
+       0x5b, 0x83,                                     //   Processor
+       0x0b,                                           //     PkgLength
+       0x43, 0x50, 0x55, 0x30,                         //     CPU0
+       0x00,                                           //     ID
+       0x00, 0x00, 0x00, 0x00,                         //     PBLK
+       0x06                                            //     PBLK size
+};
+
+/*
+ * Calculate and set ACPI table checksum
+ */
+static void
+acpi_set_checksum(u8 *table, int size)
+{
+       int i, sum = 0;
+       for (i = 0; i < size; i++)
+               sum += (int) table[i];
+       sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff));
+       table[ACPI_DUMMY_CHECKSUM] = sum;
+}
+
+/*
+ * Init PIIX4 device, create a fake FACP
+ */
+static int
+acpi_init_piix4(struct pci_dev *dev)
+{
+       u32 base, pblk;
+       u16 cmd;
+       u8 pmregmisc;
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (!(cmd & PCI_COMMAND_IO))
+               return -ENODEV;
+       
+       pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc);
+       if (!(pmregmisc & ACPI_PIIX4_PMIOSE))
+               return -ENODEV;
+       
+       base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES);
+       if (!base)
+               return -ENODEV;
+
+       printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+       memset(&acpi_facp, 0, sizeof(acpi_facp));
+       acpi_facp.hdr.signature = ACPI_FACP_SIG;
+       acpi_facp.hdr.length = sizeof(acpi_facp);
+       acpi_facp.int_model = ACPI_PIIX4_INT_MODEL;
+       acpi_facp.sci_int = ACPI_PIIX4_SCI_INT;
+       acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD;
+       acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE;
+       acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE;
+       acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ;
+       acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
+       acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
+       acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT;
+       acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR;
+       acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0;
+       acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN;
+       acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN;
+       acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN;
+       acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN;
+       acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN;
+       acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+       acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+       acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+       acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+       pblk = base + ACPI_PIIX4_P_BLK;
+       memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+       acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+       acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+       return 0;
+}
+
+/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int
+acpi_init_via(struct pci_dev *dev)
+{
+       u32 base, pblk;
+       u8 tmp, irq;
+
+       pci_read_config_byte(dev, 0x41, &tmp);
+       if (!(tmp & 0x80))
+               return -ENODEV;
+
+       base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES);
+       if (!base) {
+               base = pci_resource_start(dev, PCI_BASE_ADDRESS_4);
+               if (!base)
+                       return -ENODEV;
+       }
+
+       pci_read_config_byte(dev, 0x42, &irq);
+
+       printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+       memset(&acpi_facp, 0, sizeof(acpi_facp));
+       acpi_facp.hdr.signature = ACPI_FACP_SIG;
+       acpi_facp.hdr.length = sizeof(acpi_facp);
+       acpi_facp.int_model = ACPI_VIA_INT_MODEL;
+       acpi_facp.sci_int = irq;
+       acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD;
+       acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE;
+       acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE;
+       acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT;
+       acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT;
+       acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR;
+       acpi_facp.gpe0 = base + ACPI_VIA_GPE0;
+
+       acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+       acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+       acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN;
+       acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN;
+       acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+       acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+       acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET;
+       acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH;
+
+       acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM;
+       acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM;
+       acpi_facp.century = ACPI_VIA_CENTURY;
+
+       acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+       acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+       pblk = base + ACPI_VIA_P_BLK;
+       memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+       acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+       acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+       return 0;
+}
+
+typedef enum
+{
+        CH_UNKNOWN = 0,
+        CH_INTEL_PIIX4,
+        CH_VIA_586,
+        CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct
+{
+        int (*chip_init)(struct pci_dev *dev);
+} acpi_chip_info[] =
+{
+        {NULL,},
+        {acpi_init_piix4},
+        {acpi_init_via},
+        {acpi_init_via},
+};
+
+static struct pci_device_id acpi_pci_tbl[] =
+{
+        {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4},
+        {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586},
+        {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A},
+        {0,} /* terminate list */
+};
+
+static int
+acpi_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+        return acpi_chip_info[id->driver_data].chip_init(dev);
+}
+
+static struct pci_driver acpi_driver =
+{
+        name:           "acpi",
+        id_table:       acpi_pci_tbl,
+        probe:          acpi_probe,
+};
+static int acpi_driver_registered = 0;
+
+/*
+ * Locate a known ACPI chipset
+ */
+static int
+acpi_find_chipset(void)
+{
+        if (pci_register_driver(&acpi_driver) < 1)
+                return -ENODEV;
+        acpi_driver_registered = 1;
+        return 0;
+}
+
+/*
+ * Fetch the FACP information
+ */
+static int
+acpi_fetch_facp(void)
+{
+       ACPI_BUFFER buffer;
+
+       memset(&acpi_facp, 0, sizeof(acpi_facp));
+       buffer.pointer = &acpi_facp;
+       buffer.length = sizeof(acpi_facp);
+       if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
+               printk(KERN_ERR "ACPI: missing FACP\n");
+               return -ENODEV;
+       }
+
+       if (acpi_facp.p_lvl2_lat
+           && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
+               acpi_c2_exit_latency
+                       = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat);
+               acpi_c2_enter_latency
+                       = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
+       }
+       if (acpi_facp.p_lvl3_lat
+           && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
+               acpi_c3_exit_latency
+                       = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat);
+               acpi_c3_enter_latency
+                       = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5);
+       }
+
+       return 0;
+}
+
+/*
+ * Find and load ACPI tables
+ */
+int
+acpi_load_tables(void)
+{
+       if (ACPI_SUCCESS(acpi_load_firmware_tables()))
+       {
+               printk(KERN_INFO "ACPI: support found\n");
+       }
+       else if (acpi_find_chipset()) {
+               acpi_terminate();
+               return -1;
+       }
+
+       if (acpi_fetch_facp()) {
+               acpi_terminate();
+               return -1;
+       }
+
+       if (!ACPI_SUCCESS(acpi_load_namespace())) {
+               printk(KERN_ERR "ACPI: namespace load failed\n");
+               acpi_terminate();
+               return -1;
+       }
+
+       return 0;
+}
index 37e50dbcdaef1b7500e5db8c0ad9b8285fae2906..47cf8c69efcac77f25f7787de34b68bd0fc48ac6 100644 (file)
@@ -792,8 +792,7 @@ int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
    device. Currently the only restriction is that all buffers must belong to
    the same device */
 
-static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[],
-                                                               int haslock)
+void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
 {
        struct buffer_head *bh;
        request_queue_t *q;
@@ -840,13 +839,9 @@ static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[],
                bh = bhs[i];
 
                /* Only one thread can actually submit the I/O. */
-               if (haslock) {
-                       if (!buffer_locked(bh))
-                               BUG();
-               } else {
-                       if (test_and_set_bit(BH_Lock, &bh->b_state))
-                               continue;
-               }
+               if (test_and_set_bit(BH_Lock, &bh->b_state))
+                       continue;
+
                set_bit(BH_Req, &bh->b_state);
 
                /*
@@ -865,15 +860,6 @@ sorry:
                buffer_IO_error(bhs[i]);
 }
 
-void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
-{
-       __ll_rw_block(rw, nr, bh, 0);
-}
-
-void ll_rw_block_locked(int rw, int nr, struct buffer_head * bh[])
-{
-       __ll_rw_block(rw, nr, bh, 1);
-}
 
 #ifdef CONFIG_STRAM_SWAP
 extern int stram_device_init (void);
index 651c3dd6dfedc191c40b78423cd234fc5598257f..087b5aee180da677e0d1e2aa1ba51d33b615948f 100644 (file)
@@ -3412,7 +3412,7 @@ repeat:
                currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1;
 
                if (currspeed > sysctl_speed_limit_min) {
-                       current->priority = 19;
+                       current->nice = 19;
 
                        if ((currspeed > sysctl_speed_limit_max) ||
                                        !is_mddev_idle(mddev)) {
@@ -3422,7 +3422,7 @@ repeat:
                                        goto repeat;
                        }
                } else
-                       current->priority = -20;
+                       current->nice = -20;
        }
        fsync_dev(read_disk);
        printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
index 2315e1d300c0cc866b12a9be0c0dfae3c89dc278..b36fdab112076c72bf5074be5b8281eac5f0bf5b 100644 (file)
        1.02    GRG 1998.05.05  init_proto, release_proto, ktti
        1.03    GRG 1998.08.15  eliminate compiler warning
        1.04    GRG 1998.11.28  added support for FRIQ 
-
+       1.05    TMW 2000.06.06  use parport_find_number instead of
+                               parport_enumerate
 */
 
-#define PI_VERSION      "1.04"
+#define PI_VERSION      "1.05"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -238,22 +239,25 @@ static void pi_register_parport( PIA *pi, int verbose)
 {
 #ifdef CONFIG_PARPORT
 
-       struct parport  *pp;
-
-       pp = parport_enumerate();
+       struct parport *port;
 
-       while((pp)&&(pp->base != pi->port)) pp = pp->next;
+       port = parport_find_base (pi->port);
+       if (!port) return;
 
-       if (!pp) return;
+       pi->pardev = parport_register_device(port,
+                                            pi->device,NULL,
+                                            pi_wake_up,NULL,
+                                            0,(void *)pi);
+       parport_put_port (port);
+       if (!pi->pardev) return;
 
-       pi->pardev = (void *) parport_register_device(
-             pp,pi->device,NULL,pi_wake_up,NULL,0,(void *)pi);
 
        init_waitqueue_head(&pi->parq);
 
-       if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name);
+       if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,
+                           port->name);
        
-       pi->parname = (char *)pp->name;
+       pi->parname = (char *)port->name;
 
 #endif
 }
@@ -406,6 +410,7 @@ int init_module(void)
 {      int k;
 
        for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
+
        printk("paride: version %s installed\n",PI_VERSION);
        return 0;
 }
index cf4bb1f8381a70c38307891bdc74b43270a25762..d0e8011807b8b6624634af79dab05ebb63e755cd 100644 (file)
@@ -2,7 +2,7 @@
 #define        Z_WAKE
 #undef Z_EXT_CHARS_IN_BUFFER
 static char rcsid[] =
-"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $";
+"$Revision: 2.3.2.8 $$Date: 2000/07/06 18:14:16 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -25,6 +25,11 @@ static char rcsid[] =
  * This version supports shared IRQ's (only for PCI boards).
  *
  * $Log: cyclades.c,v $
+ * Revision 2.3.2.8   2000/07/06 18:14:16 ivan
+ * Fixed the PCI detection function to work properly on Alpha systems.
+ * Implemented support for TIOCSERGETLSR ioctl.
+ * Implemented full support for non-standard baud rates.
+ *
  * Revision 2.3.2.7   2000/06/01 18:26:34 ivan
  * Request PLX I/O region, although driver doesn't use it, to avoid
  * problems with other drivers accessing it.
@@ -1363,9 +1368,16 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                     while (char_count-- > 0){
                        if (!info->xmit_cnt){
-                            cy_writeb((u_long)base_addr+(CySRER<<index),
-                               cy_readb(base_addr+(CySRER<<index)) & 
-                                       ~CyTxRdy);
+                           if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
+                               cy_writeb((u_long)base_addr+(CySRER<<index),
+                                         cy_readb(base_addr+(CySRER<<index)) &
+                                         ~CyTxMpty);
+                           } else {
+                               cy_writeb((u_long)base_addr+(CySRER<<index),
+                                         ((cy_readb(base_addr+(CySRER<<index))
+                                           & ~CyTxRdy)
+                                          | CyTxMpty));
+                           }
                            goto txdone;
                        }
                        if (info->xmit_buf == 0){
@@ -3176,6 +3188,30 @@ cy_chars_in_buffer(struct tty_struct *tty)
  * ------------------------------------------------------------
  */
 
+static void
+cyy_baud_calc(struct cyclades_port *info, uclong baud)
+{
+    int co, co_val, bpr;
+    uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000);
+
+    if (baud == 0) {
+       info->tbpr = info->tco = info->rbpr = info->rco = 0;
+       return;
+    }
+
+    /* determine which prescaler to use */
+    for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
+       if (cy_clock / co_val / baud > 63)
+           break;
+    }
+
+    bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
+    if (bpr > 255)
+       bpr = 255;
+
+    info->tbpr = info->rbpr = bpr;
+    info->tco = info->rco = co;
+}
 
 /*
  * This routine finds or computes the various line characteristics.
@@ -3189,7 +3225,7 @@ set_line_char(struct cyclades_port * info)
   int card,chip,channel,index;
   unsigned cflag, iflag;
   unsigned short chip_number;
-  int baud;
+  int baud, baud_rate = 0;
   int   i;
 
 
@@ -3225,12 +3261,14 @@ set_line_char(struct cyclades_port * info)
        index = cy_card[card].bus_index;
 
        /* baud rate */
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
-           baud = info->baud;
-       } else {
-           baud = tty_get_baud_rate(info->tty);
-       }
-       if (baud > CD1400_MAX_SPEED) {
+       baud = tty_get_baud_rate(info->tty);
+       if ((baud == 38400) &&
+           ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+           if (info->custom_divisor)
+               baud_rate = info->baud / info->custom_divisor;
+           else
+               baud_rate = info->baud;
+       } else if (baud > CD1400_MAX_SPEED) {
            baud = CD1400_MAX_SPEED;
        }
        /* find the baud index */
@@ -3243,22 +3281,29 @@ set_line_char(struct cyclades_port * info)
            i = 19; /* CD1400_MAX_SPEED */
        } 
 
-
-       if(info->chip_rev >= CD1400_REV_J) {
-           /* It is a CD1400 rev. J or later */
-           info->tbpr = baud_bpr_60[i]; /* Tx BPR */
-           info->tco = baud_co_60[i]; /* Tx CO */
-           info->rbpr = baud_bpr_60[i]; /* Rx BPR */
-           info->rco = baud_co_60[i]; /* Rx CO */
+       if ((baud == 38400) &&
+           ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+           cyy_baud_calc(info, baud_rate);
        } else {
-           info->tbpr = baud_bpr_25[i]; /* Tx BPR */
-           info->tco = baud_co_25[i]; /* Tx CO */
-           info->rbpr = baud_bpr_25[i]; /* Rx BPR */
-           info->rco = baud_co_25[i]; /* Rx CO */
+           if(info->chip_rev >= CD1400_REV_J) {
+               /* It is a CD1400 rev. J or later */
+               info->tbpr = baud_bpr_60[i]; /* Tx BPR */
+               info->tco = baud_co_60[i]; /* Tx CO */
+               info->rbpr = baud_bpr_60[i]; /* Rx BPR */
+               info->rco = baud_co_60[i]; /* Rx CO */
+           } else {
+               info->tbpr = baud_bpr_25[i]; /* Tx BPR */
+               info->tco = baud_co_25[i]; /* Tx CO */
+               info->rbpr = baud_bpr_25[i]; /* Rx BPR */
+               info->rco = baud_co_25[i]; /* Rx CO */
+           }
        }
        if (baud_table[i] == 134) {
-           info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
            /* get it right for 134.5 baud */
+           info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+       } else if ((baud == 38400) &&
+                  ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+           info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
        } else if (baud_table[i]) {
            info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
            /* this needs to be propagated into the card info */
@@ -3447,19 +3492,24 @@ set_line_char(struct cyclades_port * info)
        buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
 
        /* baud rate */
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
-           baud = info->baud;
-       } else {
-           baud = tty_get_baud_rate(info->tty);
-       }
-       if (baud > CYZ_MAX_SPEED) {
+       baud = tty_get_baud_rate(info->tty);
+       if ((baud == 38400) &&
+           ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+           if (info->custom_divisor)
+               baud_rate = info->baud / info->custom_divisor;
+           else
+               baud_rate = info->baud;
+       } else if (baud > CYZ_MAX_SPEED) {
            baud = CYZ_MAX_SPEED;
        }
        cy_writel(&ch_ctrl->comm_baud , baud);
 
        if (baud == 134) {
-           info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
            /* get it right for 134.5 baud */
+           info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+       } else if ((baud == 38400) &&
+                  ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+           info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
        } else if (baud) {
            info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
            /* this needs to be propagated into the card info */
@@ -3549,8 +3599,6 @@ set_line_char(struct cyclades_port * info)
            clear_bit(TTY_IO_ERROR, &info->tty->flags);
        }
     }
-
-
 } /* set_line_char */
 
 
@@ -3571,7 +3619,7 @@ get_serial_info(struct cyclades_port * info,
     tmp.flags = info->flags;
     tmp.close_delay = info->close_delay;
     tmp.baud_base = info->baud;
-    tmp.custom_divisor = 0;     /*!!!*/
+    tmp.custom_divisor = info->custom_divisor;
     tmp.hub6 = 0;               /*!!!*/
     return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
 } /* get_serial_info */
@@ -3597,6 +3645,7 @@ set_serial_info(struct cyclades_port * info,
             info->flags = ((info->flags & ~ASYNC_USR_MASK) |
                            (new_serial.flags & ASYNC_USR_MASK));
             info->baud = new_serial.baud_base;
+           info->custom_divisor = new_serial.custom_divisor;
             goto check_and_exit;
     }
 
@@ -3607,6 +3656,7 @@ set_serial_info(struct cyclades_port * info,
      */
 
     info->baud = new_serial.baud_base;
+    info->custom_divisor = new_serial.custom_divisor;
     info->flags = ((info->flags & ~ASYNC_FLAGS) |
                     (new_serial.flags & ASYNC_FLAGS));
     info->close_delay = new_serial.close_delay * HZ/100;
@@ -3621,6 +3671,43 @@ check_and_exit:
     }
 } /* set_serial_info */
 
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *         is emptied.  On bus types like RS485, the transmitter must
+ *         release the bus after transmitting. This must be done when
+ *         the transmit shift register is empty, not be done when the
+ *         transmit holding register is empty.  This functionality
+ *         allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
+{
+    int card, chip, channel, index;
+    unsigned char status;
+    unsigned int result;
+    unsigned long flags;
+    unsigned char *base_addr;
+
+    card = info->card;
+    channel = (info->line) - (cy_card[card].first_line);
+    if (!IS_CYC_Z(cy_card[card])) {
+       chip = channel>>2;
+       channel &= 0x03;
+       index = cy_card[card].bus_index;
+       base_addr = (unsigned char *)
+                    (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
+
+       CY_LOCK(info, flags);
+       status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty);
+       CY_UNLOCK(info, flags);
+       result = (status ? 0 : TIOCSER_TEMT);
+    } else {
+       /* Not supported yet */
+       return -EINVAL;
+    }
+    return cy_put_user(result, (unsigned long *) value);
+}
 
 static int
 get_modem_info(struct cyclades_port * info, unsigned int *value)
@@ -4247,6 +4334,9 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
         case TIOCSSERIAL:
             ret_val = set_serial_info(info, (struct serial_struct *) arg);
             break;
+       case TIOCSERGETLSR: /* Get line status register */
+           ret_val = get_lsr_info(info, (unsigned int *) arg);
+           break;
        /*
         * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
         * - mask passed in arg for lines of interest
@@ -4937,10 +5027,9 @@ cy_detect_pci(void)
                    i--;
                    continue;
                 }
-#else
+#endif
                cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Yctl);
                cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ywin);
-#endif
 
 #ifdef CY_PCI_DEBUG
             printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
@@ -5048,9 +5137,7 @@ cy_detect_pci(void)
             printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
                 (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
 #endif
-#if !defined(__alpha__)
-                cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
-#endif
+               cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
 
                /* Disable interrupts on the PLX before resetting it */
                cy_writew(cy_pci_addr0+0x68,
@@ -5078,9 +5165,7 @@ cy_detect_pci(void)
                request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z");
 
                if (mailbox == ZE_V1) {
-#if !defined(__alpha__)
-                           cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
-#endif
+                   cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
                    if (ZeIndex == NR_CARDS) {
                        printk("Cyclades-Ze/PCI found at 0x%lx ",
                                (ulong)cy_pci_phys2);
@@ -5097,9 +5182,7 @@ cy_detect_pci(void)
                    i--;
                    continue;
                } else {
-#if !defined(__alpha__)
-                    cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
-#endif
+                   cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
                }
 
 #ifdef CY_PCI_DEBUG
@@ -5538,6 +5621,7 @@ cy_init(void)
                     info->tco = 0;
                     info->rbpr = 0;
                     info->rco = 0;
+                   info->custom_divisor = 0;
                     info->close_delay = 5*HZ/10;
                    info->closing_wait = CLOSING_WAIT_DELAY;
                    info->icount.cts = info->icount.dsr = 
@@ -5596,6 +5680,7 @@ cy_init(void)
                     info->cor3 = 0x08; /* _very_ small rcv threshold */
                     info->cor4 = 0;
                     info->cor5 = 0;
+                   info->custom_divisor = 0;
                     info->close_delay = 5*HZ/10;
                    info->closing_wait = CLOSING_WAIT_DELAY;
                    info->icount.cts = info->icount.dsr = 
index 8304a6ab5f470f8c7a60ed9779fe35aadcc02679..00b574f60b9c9d64e345fdac9b0ab7dd939a841a 100644 (file)
@@ -75,7 +75,7 @@ static void i2c_parport_attach(struct parport *port)
   struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus), 
                                      GFP_KERNEL);
   b->i2c = parport_i2c_bus_template;
-  b->i2c.data = port;
+  b->i2c.data = parport_get_port (port);
   strncpy(b->i2c.name, port->name, 32);
   spin_lock(&bus_list_lock);
   b->next = bus_list;
index 4e2be3c8b32498230dbf0101cd80c926eab54cd6..1f0b9fddcddff94ba7a50f655bc0fb07a6b8a27f 100644 (file)
@@ -83,64 +83,6 @@ struct pp_struct {
 /* ROUND_UP macro from fs/select.c */
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
-struct pp_port_list_struct {
-       struct parport *port;
-       struct pp_port_list_struct *next;
-};
-static struct pp_port_list_struct *pp_port_list;
-static DECLARE_MUTEX(pp_port_list_lock);
-
-/* pp_attach and pp_detach are for keeping a list of currently
- * available ports, held under a mutex.  We do this rather than
- * using parport_enumerate because it stops a load of races.
- */
-
-static void pp_attach (struct parport *port)
-{
-       struct pp_port_list_struct *add;
-
-       add = kmalloc (sizeof (struct pp_port_list_struct), GFP_KERNEL);
-       if (!add) {
-               printk (KERN_WARNING CHRDEV ": memory squeeze\n");
-               return;
-       }
-
-       add->port = port;
-       down (&pp_port_list_lock);
-       add->next = pp_port_list;
-       pp_port_list = add;
-       up (&pp_port_list_lock);
-}
-
-static void pp_detach (struct parport *port)
-{
-       struct pp_port_list_struct *del;
-
-       down (&pp_port_list_lock);
-       del = pp_port_list;
-       if (del->port == port)
-               pp_port_list = del->next;
-       else {
-               struct pp_port_list_struct *prev;
-               do {
-                       prev = del;
-                       del = del->next;
-               } while (del && del->port != port);
-               if (del)
-                       prev->next = del->next;
-       }
-       up (&pp_port_list_lock);
-
-       if (del)
-               kfree (del);
-}
-
-static struct parport_driver ppdev_driver = {
-       name:   CHRDEV,
-       attach: pp_attach,
-       detach: pp_detach
-};
-
 static inline void pp_enable_irq (struct pp_struct *pp)
 {
        struct parport *port = pp->pdev->port;
@@ -274,7 +216,7 @@ static void pp_irq (int irq, void * private, struct pt_regs * unused)
 
 static int register_device (int minor, struct pp_struct *pp)
 {
-       struct pp_port_list_struct *ports;
+       struct parport *port;
        struct pardevice * pdev = NULL;
        char *name;
        int fl;
@@ -285,23 +227,17 @@ static int register_device (int minor, struct pp_struct *pp)
 
        sprintf (name, CHRDEV "%x", minor);
 
-       down (&pp_port_list_lock);
-       ports = pp_port_list;
-       while (ports && ports->port->number != minor)
-               ports = ports->next;
-       if (ports->port) {
-               fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
-               pdev = parport_register_device (ports->port, name, NULL,
-                                               NULL, pp_irq, fl, pp);
-       }
-       up (&pp_port_list_lock);
-
-       if (!ports->port) {
+       port = parport_find_number (minor);
+       if (!port) {
                printk (KERN_WARNING "%s: no associated port!\n", name);
                kfree (name);
                return -ENXIO;
        }
 
+       fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+       pdev = parport_register_device (port, name, NULL,
+                                       NULL, pp_irq, fl, pp);
+       parport_put_port (port);
 
        if (!pdev) {
                printk (KERN_WARNING "%s: failed to register device!\n", name);
@@ -654,10 +590,6 @@ static devfs_handle_t devfs_handle = NULL;
 
 static int __init ppdev_init (void)
 {
-       if (parport_register_driver (&ppdev_driver)) {
-               printk (KERN_WARNING CHRDEV ": unable to register driver\n");
-               return -EIO;
-       }
        if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
                printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
                        PP_MAJOR);
@@ -678,7 +610,6 @@ static void __exit ppdev_cleanup (void)
        /* Clean up all parport stuff */
        devfs_unregister (devfs_handle);
        devfs_unregister_chrdev (PP_MAJOR, CHRDEV);
-       parport_unregister_driver (&ppdev_driver);
 }
 
 module_init(ppdev_init);
index e2af3489a4158e1c33290b2e9d715b48f03f4770..450405fa3e250898caad1d84d6f7900b1bd8461d 100644 (file)
@@ -1,59 +1,61 @@
+
+# $Id: Config.in,v 1.18 2000/07/12 13:43:24 dwmw2 Exp $
+
 mainmenu_option next_comment
 comment 'Memory Technology Devices (MTD)'
 
 tristate 'Memory Technology Device (MTD) support' CONFIG_MTD
 
 if [ "$CONFIG_MTD" != "n" ]; then
-       dep_tristate 'M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD
-       dep_tristate 'M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD
-       dep_tristate 'M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD
-       if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
-               define_bool CONFIG_MTD_DOCPROBE y
-       else
-         if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
-               define_bool CONFIG_MTD_DOCPROBE m
-         else
-               define_bool CONFIG_MTD_DOCPROBE n
-         fi
-       fi
-       dep_tristate 'Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD
-       dep_tristate 'Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD
-       if [ "$CONFIG_MTD_PMC551" != "n" ]; then
-         bool 'PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
-       fi
-       dep_tristate 'Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD
+   dep_tristate '  M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD
+   dep_tristate '  M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD
+   dep_tristate '  M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD
+   if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
+      define_tristate CONFIG_MTD_DOCPROBE y
+   else
+      if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
+        define_tristate CONFIG_MTD_DOCPROBE m
+      else
+        define_tristate CONFIG_MTD_DOCPROBE n
+      fi
+   fi
+   dep_tristate '  Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD
+   dep_tristate '  Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD
+   if [ "$CONFIG_MTD_PMC551" != "n" ]; then
+      bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
+   fi
+   dep_tristate '  Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD
 
-mainmenu_option next_comment
 comment 'MTD drivers for mapped chips'
+   dep_tristate '  Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
+   dep_tristate '    CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
 
-       dep_tristate 'Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
-       dep_tristate 'CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_CFI
-       define_bool CONFIG_MTD_JEDEC n
-       define_bool CONFIG_MTD_RAM n
-       define_bool CONFIG_MTD_ROM n
-mainmenu_option next_comment
-comment 'Drivers for chip mappings'
+# These will later become config-options
+define_bool CONFIG_MTD_JEDEC n
+define_bool CONFIG_MTD_RAM n
+define_bool CONFIG_MTD_ROM n
 
-       dep_tristate 'Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
-       if [ "$CONFIG_MTD_PHYSMAP" != "n" ]; then
-               hex '        Physical start location of flash chip mapping (0x8000000)' CONFIG_MTD_PHYSMAP_START 0x8000000
-               hex '        Physical length of flash chip mapping         (0x4000000)' CONFIG_MTD_PHYSMAP_LEN 0x4000000
-       fi
-       dep_tristate 'Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
-       dep_tristate 'Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
-       dep_tristate 'Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
-       dep_tristate 'Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
-       dep_tristate 'Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
+   dep_tristate '    Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
+   if [ "$CONFIG_MTD_PHYSMAP" != "n" ]; then
+      hex 'Physical start location of flash chip mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
+      hex 'Physical length of flash chip mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
+   fi
+
+comment 'Drivers for chip mappings'
+   dep_tristate '  Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
+   dep_tristate '  Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
+   dep_tristate '  Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
+   dep_tristate '  Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
+   dep_tristate '  Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
 
-mainmenu_option next_comment
 comment 'User modules and translation layers for MTD devices'
-       dep_tristate 'Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
-       dep_tristate 'Pseudo-blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
-       dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
-       dep_tristate 'NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
-       if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then
-         bool 'Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW
-       fi
+   dep_tristate '  Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
+   dep_tristate '  Pseudo-blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
+   dep_tristate '  FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
+   dep_tristate '  NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
+   if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then
+      bool '    Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW
+   fi
 fi
 
 endmenu
index d408c879690218f39918fe4682fbfda234049f8d..34446db013b52177ef40b6dd098a4f21a7a9b219 100644 (file)
@@ -1,4 +1,40 @@
-2000-06-30  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c: Documentation for parport_{get,port}_port,
+       parport_find_{number,base}.
+
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c (parport_unregister_device): Remove unneeded locking
+       (test cad==dev).
+       (parport_claim): Likewise.
+       (parport_find_number): New function.
+
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c (parport_register_port): Hold the parportlist_lock while
+       looking for a free parport number.
+       (parport_register_driver): Make sure that attach can block.
+       (attach_driver_chain): Likewise.
+
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c (call_driver_chain): Do reference counting things.
+       (parport_get_port): New function.
+       (parport_put_port): New function.
+       (parport_register_port): Initialise reference count to zero.
+       (parport_unregister_port): Check reference count rather than
+       driver list to see if we can free the port.
+
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c: Clarifications in doc comments.
+
+2000-07-12  Tim Waugh  <twaugh@redhat.com>
+
+       * share.c (parport_unregister_port): Fix typo in comment.
+
+2000-07-11  Gunther Mayer  <gunther.mayer@braunschweig.okersurf.de>
 
        * parport_pc.c: Support for the full range of Timedia cards.
 
index 416ca51cb72ef9c813f0d58af868c5ee9e20b81b..90280e37176c8490c57fc3dcc74a2d134a9be7ea 100644 (file)
@@ -180,6 +180,10 @@ EXPORT_SYMBOL(parport_unregister_driver);
 EXPORT_SYMBOL(parport_register_device);
 EXPORT_SYMBOL(parport_unregister_device);
 EXPORT_SYMBOL(parport_enumerate);
+EXPORT_SYMBOL(parport_get_port);
+EXPORT_SYMBOL(parport_put_port);
+EXPORT_SYMBOL(parport_find_number);
+EXPORT_SYMBOL(parport_find_base);
 EXPORT_SYMBOL(parport_negotiate);
 EXPORT_SYMBOL(parport_write);
 EXPORT_SYMBOL(parport_read);
index 9fe0bb4be1c84aa59337cae3d68c9c3134e3b59b..50eb808429c8d0f0f1517503ce6ee1f11d548df1 100644 (file)
@@ -88,17 +88,57 @@ static struct parport_operations dead_ops = {
        dead_read               /* byte */
 };
 
-static void call_driver_chain(int attach, struct parport *port)
+/* Call attach(port) for each registered driver. */
+static void attach_driver_chain(struct parport *port)
 {
        struct parport_driver *drv;
+       void (**attach) (struct parport *);
+       int count = 0, i;
+
+       /* This is complicated because attach() must be able to block,
+        * but we can't let it do that while we're holding a
+        * spinlock. */
 
        spin_lock (&driverlist_lock);
-       for (drv = driver_chain; drv; drv = drv->next) {
-               if (attach)
-                       drv->attach (port);
-               else
-                       drv->detach (port);
+       for (drv = driver_chain; drv; drv = drv->next)
+               count++;
+       spin_unlock (&driverlist_lock);
+
+       /* Drivers can unregister here; that's okay.  If they register
+        * they'll be given an attach during parport_register_driver,
+        * so that's okay too.  The only worry is that someone might
+        * get given an attach twice if they registered just before
+        * this function gets called. */
+
+       /* Hmm, this could be fixed with a generation number..
+        * FIXME */
+
+       attach = kmalloc (sizeof (void(*)(struct parport *)) * count,
+                         GFP_KERNEL);
+       if (!attach) {
+               printk (KERN_WARNING "parport: not enough memory to attach\n");
+               return;
        }
+
+       spin_lock (&driverlist_lock);
+       for (i = 0, drv = driver_chain; drv && i < count; drv = drv->next)
+               attach[i] = drv->attach;
+       spin_unlock (&driverlist_lock);
+
+       for (count = 0; count < i; count++)
+               (*attach[i]) (port);
+
+       kfree (attach);
+}
+
+/* Call detach(port) for each registered driver. */
+static void detach_driver_chain(struct parport *port)
+{
+       struct parport_driver *drv;
+
+       spin_lock (&driverlist_lock);
+       for (drv = driver_chain; drv; drv = drv->next)
+               drv->detach (port);
        spin_unlock (&driverlist_lock);
 }
 
@@ -121,28 +161,63 @@ static void get_lowlevel_driver (void)
  *     The @drv structure is allocated by the caller and must not be
  *     deallocated until after calling parport_unregister_driver().
  *
+ *     The driver's attach() function may block.  The port that
+ *     attach() is given will be valid for the duration of the
+ *     callback, but if the driver wants to take a copy of the
+ *     pointer it must call parport_get_port() to do so.  Calling
+ *     parport_register_device() on that port will do this for you.
+ *
+ *     The driver's detach() function may not block.  The port that
+ *     detach() is given will be valid for the duration of the
+ *     callback, but if the driver wants to take a copy of the
+ *     pointer it must call parport_get_port() to do so.
+ *
  *     Returns 0 on success.  Currently it always succeeds.
  **/
 
 int parport_register_driver (struct parport_driver *drv)
 {
        struct parport *port;
-
-       spin_lock (&driverlist_lock);
-       drv->next = driver_chain;
-       driver_chain = drv;
-       spin_unlock (&driverlist_lock);
+       struct parport **ports;
+       int count = 0, i;
 
        /* We have to take the portlist lock for this to be sure
         * that port is valid for the duration of the callback. */
+
+       /* This is complicated by the fact that attach must be allowed
+        * to block, so we can't be holding any spinlocks when we call
+        * it.  But we need to hold a spinlock to iterate over the
+        * list of ports.. */
+
        spin_lock (&parportlist_lock);
        for (port = portlist; port; port = port->next)
-               drv->attach (port);
+               count++;
        spin_unlock (&parportlist_lock);
 
+       ports = kmalloc (sizeof (struct parport *) * count, GFP_KERNEL);
+       if (!ports)
+               printk (KERN_WARNING "parport: not enough memory to attach\n");
+       else {
+               spin_lock (&parportlist_lock);
+               for (i = 0, port = portlist; port && i < count;
+                    port = port->next)
+                       ports[i] = port;
+               spin_unlock (&parportlist_lock);
+
+               for (count = 0; count < i; count++)
+                       drv->attach (ports[count]);
+
+               kfree (ports);
+       }
+
        if (!portlist)
                get_lowlevel_driver ();
 
+       spin_lock (&driverlist_lock);
+       drv->next = driver_chain;
+       driver_chain = drv;
+       spin_unlock (&driverlist_lock);
+
        return 0;
 }
 
@@ -162,6 +237,11 @@ int parport_register_driver (struct parport_driver *drv)
  *     If the caller's attach() function can block, it is their
  *     responsibility to make sure to wait for it to exit before
  *     unloading.
+ *
+ *     All the driver's detach() calls are guaranteed to have
+ *     finished by the time this function returns.
+ *
+ *     The driver's detach() call is not allowed to block.
  **/
 
 void parport_unregister_driver (struct parport_driver *arg)
@@ -194,6 +274,57 @@ void parport_unregister_driver (struct parport_driver *arg)
        }
 }
 
+static void free_port (struct parport *port)
+{
+       int d;
+       for (d = 0; d < 5; d++) {
+               if (port->probe_info[d].class_name)
+                       kfree (port->probe_info[d].class_name);
+               if (port->probe_info[d].mfr)
+                       kfree (port->probe_info[d].mfr);
+               if (port->probe_info[d].model)
+                       kfree (port->probe_info[d].model);
+               if (port->probe_info[d].cmdset)
+                       kfree (port->probe_info[d].cmdset);
+               if (port->probe_info[d].description)
+                       kfree (port->probe_info[d].description);
+       }
+
+       kfree(port->name);
+       kfree(port);
+}
+
+/**
+ *     parport_get_port - increment a port's reference count
+ *     @port: the port
+ *
+ *     This ensure's that a struct parport pointer remains valid
+ *     until the matching parport_put_port() call.
+ **/
+
+struct parport *parport_get_port (struct parport *port)
+{
+       atomic_inc (&port->ref_count);
+       return port;
+}
+
+/**
+ *     parport_put_port - decrement a port's reference count
+ *     @port: the port
+ *
+ *     This should be called once for each call to parport_get_port(),
+ *     once the port is no longer needed.
+ **/
+
+void parport_put_port (struct parport *port)
+{
+       if (atomic_dec_and_test (&port->ref_count))
+               /* Can destroy it now. */
+               free_port (port);
+
+       return;
+}
+
 /**
  *     parport_enumerate - return a list of the system's parallel ports
  *
@@ -260,6 +391,8 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
        }
 
        /* Search for the lowest free parport number. */
+
+       spin_lock_irq (&parportlist_lock);
        for (portnum = 0; ; portnum++) {
                struct parport *itr = portlist;
                while (itr) {
@@ -274,6 +407,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
                        /* Got to the end of the list. */
                        break;
        }
+       spin_unlock_irq (&parportlist_lock);
        
        /* Init our structure */
        memset(tmp, 0, sizeof(struct parport));
@@ -296,6 +430,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
        tmp->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
        init_MUTEX_LOCKED (&tmp->ieee1284.irq); /* actually a semaphore at 0 */
        tmp->spintime = parport_default_spintime;
+       atomic_set (&tmp->ref_count, 1);
 
        name = kmalloc(15, GFP_KERNEL);
        if (!name) {
@@ -372,27 +507,7 @@ void parport_announce_port (struct parport *port)
 #endif
 
        /* Let drivers know that a new port has arrived. */
-       call_driver_chain (1, port);
-}
-
-static void free_port (struct parport *port)
-{
-       int d;
-       for (d = 0; d < 5; d++) {
-               if (port->probe_info[d].class_name)
-                       kfree (port->probe_info[d].class_name);
-               if (port->probe_info[d].mfr)
-                       kfree (port->probe_info[d].mfr);
-               if (port->probe_info[d].model)
-                       kfree (port->probe_info[d].model);
-               if (port->probe_info[d].cmdset)
-                       kfree (port->probe_info[d].cmdset);
-               if (port->probe_info[d].description)
-                       kfree (port->probe_info[d].description);
-       }
-
-       kfree(port->name);
-       kfree(port);
+       attach_driver_chain (port);
 }
 
 /**
@@ -421,7 +536,7 @@ void parport_unregister_port(struct parport *port)
        port->ops = &dead_ops;
 
        /* Spread the word. */
-       call_driver_chain (0, port);
+       detach_driver_chain (port);
 
 #ifdef CONFIG_PARPORT_1284
        /* Forget the IEEE1284.3 topology of the port. */
@@ -431,7 +546,7 @@ void parport_unregister_port(struct parport *port)
        spin_lock(&parportlist_lock);
 
        /* We are protected from other people changing the list, but
-        * they can see see it (using parport_enumerate).  So be
+        * they can still see it (using parport_enumerate).  So be
         * careful about the order of writes.. */
        if (portlist == port) {
                if ((portlist = port->next) == NULL)
@@ -449,8 +564,7 @@ void parport_unregister_port(struct parport *port)
        spin_unlock(&parportlist_lock);
 
        /* Yes, parport_enumerate _is_ unsafe.  Don't use it. */
-       if (!port->devices)
-               free_port (port);
+       parport_put_port (port);
 }
 
 /**
@@ -552,6 +666,7 @@ parport_register_device(struct parport *port, const char *name,
            parport_register_device.. */
        inc_parport_count();
        port->ops->inc_use_count();
+       parport_get_port (port);
 
        tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL);
        if (tmp == NULL) {
@@ -623,6 +738,7 @@ parport_register_device(struct parport *port, const char *name,
  out:
        dec_parport_count();
        port->ops->dec_use_count();
+       parport_put_port (port);
        return NULL;
 }
 
@@ -636,7 +752,6 @@ parport_register_device(struct parport *port, const char *name,
 void parport_unregister_device(struct pardevice *dev)
 {
        struct parport *port;
-       unsigned long flags;
 
 #ifdef PARPORT_PARANOID
        if (dev == NULL) {
@@ -649,14 +764,11 @@ void parport_unregister_device(struct pardevice *dev)
 
        port = dev->port->physport;
 
-       read_lock_irqsave (&port->cad_lock, flags);
        if (port->cad == dev) {
-               read_unlock_irqrestore (&port->cad_lock, flags);
                printk(KERN_DEBUG "%s: %s forgot to release port\n",
                       port->name, dev->name);
                parport_release (dev);
        }
-       read_unlock_irqrestore (&port->cad_lock, flags);
 
        spin_lock(&port->pardevice_lock);
        if (dev->next)
@@ -676,11 +788,7 @@ void parport_unregister_device(struct pardevice *dev)
 
        dec_parport_count();
        port->ops->dec_use_count();
-
-       /* If this was the last device on a port that's already gone away,
-        * free up the resources. */
-       if (port->ops == &dead_ops && !port->devices)
-               free_port (port);
+       parport_put_port (port);
 
        /* Yes, that's right, someone _could_ still have a pointer to
         * port, if they used parport_enumerate.  That's why they
@@ -688,6 +796,56 @@ void parport_unregister_device(struct pardevice *dev)
         */
 }
 
+/**
+ *     parport_find_number - find a parallel port by number
+ *     @number: parallel port number
+ *
+ *     This returns the parallel port with the specified number, or
+ *     %NULL if there is none.
+ *
+ *     There is an implicit parport_get_port() done already; to throw
+ *     away the reference to the port that parport_find_number()
+ *     gives you, use parport_put_port().
+ */
+
+struct parport *parport_find_number (int number)
+{
+       struct parport *port, *result = NULL;
+       spin_lock (&parportlist_lock);
+       for (port = portlist; port; port = port->next)
+               if (port->number == number) {
+                       result = parport_get_port (port);
+                       break;
+               }
+       spin_unlock (&parportlist_lock);
+       return result;
+}
+
+/**
+ *     parport_find_base - find a parallel port by base address
+ *     @base: base I/O address
+ *
+ *     This returns the parallel port with the specified base
+ *     address, or %NULL if there is none.
+ *
+ *     There is an implicit parport_get_port() done already; to throw
+ *     away the reference to the port that parport_find_base()
+ *     gives you, use parport_put_port().
+ */
+
+struct parport *parport_find_base (unsigned long base)
+{
+       struct parport *port, *result = NULL;
+       spin_lock (&parportlist_lock);
+       for (port = portlist; port; port = port->next)
+               if (port->base == base) {
+                       result = parport_get_port (port);
+                       break;
+               }
+       spin_unlock (&parportlist_lock);
+       return result;
+}
+
 /**
  *     parport_claim - claim access to a parallel port device
  *     @dev: pointer to structure representing a device on the port
@@ -706,14 +864,11 @@ int parport_claim(struct pardevice *dev)
        struct parport *port = dev->port->physport;
        unsigned long flags;
 
-       read_lock_irqsave (&port->cad_lock, flags);
        if (port->cad == dev) {
-               read_unlock_irqrestore (&port->cad_lock, flags);
                printk(KERN_INFO "%s: %s already owner\n",
                       dev->port->name,dev->name);
                return 0;
        }
-       read_unlock_irqrestore (&port->cad_lock, flags);
 
        /* Preempt any current device */
        write_lock_irqsave (&port->cad_lock, flags);
index 056b2f1b50ee8e950edc144fd7e4445df00ab4f9..fd705d425f44154a0174e1feb1571693745813e9 100644 (file)
@@ -138,6 +138,10 @@ static struct dev_info device_list[] =
        {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
        {"TOSHIBA","CDROM","*", BLIST_ISROM},
        {"MegaRAID", "LD", "*", BLIST_FORCELUN},
+       {"DGC",  "RAID",      "*", BLIST_SPARSELUN}, // Dell PV 650F (tgt @ LUN 0)
+       {"DGC",  "DISK",      "*", BLIST_SPARSELUN}, // Dell PV 650F (no tgt @ LUN 0) 
+       {"DELL", "PV530F",    "*", BLIST_SPARSELUN}, // Dell PV 530F
+       {"SONY", "TSL",       "*", BLIST_FORCELUN},  // DDS3 & DDS4 autoloaders
 
        /*
         * Must be at end of list...
index c99f869732788a053666825284bc388657260444..df02bcf2a80769d25d88508cd0f73e7720e18137 100644 (file)
@@ -45,6 +45,9 @@
  *   up an eventual usbd
  * 2000-01-04: Thomas Sailer <sailer@ife.ee.ethz.ch>
  *   Turned into its own filesystem
+ * 2000-07-05: Ashley Montanaro <ashley@compsoc.man.ac.uk>
+ *   Converted file reading routine to dump to buffer once
+ *   per device, not per bus
  *
  * $Id: devices.c,v 1.5 2000/01/11 13:58:21 tom Exp $
  */
@@ -367,23 +370,40 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de
 
 /*****************************************************************/
 
-static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev,
-                            struct usb_bus *bus, int level, int index, int count)
+/* This is a recursive function. Parameters:
+ * buffer - the user-space buffer to write data into
+ * nbytes - the maximum number of bytes to write
+ * skip_bytes - the number of bytes to skip before writing anything
+ * file_offset - the offset into the devices file on completion
+ */
+static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
+                               struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
 {
        int chix;
-       int cnt = 0;
+       int ret, cnt = 0;
        int parent_devnum = 0;
-
+       char *pages_start, *data_end;
+       unsigned int length;
+       ssize_t total_written = 0;
+       
+       /* don't bother with anything else if we're not writing any data */
+       if (*nbytes <= 0)
+               return 0;
+       
        if (level > MAX_TOPO_LEVEL)
-               return start;
+               return total_written;
+       /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
+        if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
+                return -ENOMEM;
+               
        if (usbdev->parent && usbdev->parent->devnum != -1)
                parent_devnum = usbdev->parent->devnum;
        /*
         * So the root hub's parent is 0 and any device that is
         * plugged into the root hub has a parent of 0.
         */
-       start += sprintf(start, format_topo, bus->busnum, level, parent_devnum, index, count,
-                        usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
+       data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, index, count,
+                                       usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
        /*
         * level = topology-tier level;
         * parent_devnum = parent device number;
@@ -392,30 +412,58 @@ static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev,
         */
        /* If this is the root hub, display the bandwidth information */
        if (level == 0)
-               start += sprintf(start, format_bandwidth, bus->bandwidth_allocated, 
+               data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
                                FRAME_TIME_MAX_USECS_ALLOC,
                                (100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC,
                                 bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs);
-       start = usb_dump_desc(start, end, usbdev);
-       if (start > end)
-               return start + sprintf(start, "(truncated)\n");
+       
+       data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
+       
+       if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
+               data_end += sprintf(data_end, "(truncated)\n");
+       
+       length = data_end - pages_start;
+       /* if we can start copying some data to the user */
+       if (length > *skip_bytes) {
+               length -= *skip_bytes;
+               if (length > *nbytes)
+                       length = *nbytes;
+               if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) {
+                       free_pages((unsigned long)pages_start, 1);
+                       
+                       if (total_written == 0)
+                               return -EFAULT;
+                       return total_written;
+               }
+               *nbytes -= length;
+               *file_offset += length;
+               total_written += length;
+               *buffer += length;
+               *skip_bytes = 0;
+       } else
+               *skip_bytes -= length;
+       
+       free_pages((unsigned long)pages_start, 1);
+       
        /* Now look at all of this device's children. */
        for (chix = 0; chix < usbdev->maxchild; chix++) {
-               if (start > end)
-                       return start;
-               if (usbdev->children[chix])
-                       start = usb_device_dump(start, end, usbdev->children[chix], bus, level + 1, chix, ++cnt);
+               if (usbdev->children[chix]) {
+                       ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, usbdev->children[chix],
+                                       bus, level + 1, chix, ++cnt);
+                       if (ret == -EFAULT)
+                               return total_written;
+                       total_written += ret;
+               }
        }
-       return start;
+       return total_written;
 }
 
 static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
        struct list_head *buslist;
        struct usb_bus *bus;
-       char *page, *end;
-       ssize_t ret = 0;
-       unsigned int pos, len;
+       ssize_t ret, total_written = 0;
+       loff_t skip_bytes = *ppos;
 
        if (*ppos < 0)
                return -EINVAL;
@@ -423,34 +471,18 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff
                return 0;
        if (!access_ok(VERIFY_WRITE, buf, nbytes))
                return -EFAULT;
-        if (!(page = (char*) __get_free_pages(GFP_KERNEL,1)))
-                return -ENOMEM;
-       pos = *ppos;
+
        /* enumerate busses */
        for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {
                /* print devices for this bus */
                bus = list_entry(buslist, struct usb_bus, bus_list);
-               end = usb_device_dump(page, page + (2*PAGE_SIZE - 256), bus->root_hub, bus, 0, 0, 0);
-               len = end - page;
-               if (len > pos) {
-                       len -= pos;
-                       if (len > nbytes)
-                               len = nbytes;
-                       if (copy_to_user(buf, page + pos, len)) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
-                       nbytes -= len;
-                       buf += len;
-                       ret += len;
-                       pos = 0;
-                       *ppos += len;
-               } else
-                       pos -= len;
+               /* recurse through all children of the root hub */
+               ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
+               if (ret < 0)
+                       return ret;
+               total_written += ret;
        }
-       free_pages((unsigned long)page, 1);
-       return ret;
+       return total_written;
 }
 
 /* Kernel lock for "lastev" protection */
index 940d47f52e79dbff14670062d1bd1ce2e0e235e5..886229370e781b1e3a491802af96881192e1818d 100644 (file)
@@ -33,7 +33,7 @@ obj-           :=
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
-obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o vga_font.o
+obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
 obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
diff --git a/drivers/video/vga_font.c b/drivers/video/vga_font.c
deleted file mode 100644 (file)
index d6683ee..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/modversions.h>
-
-
-#define cmapsz 8192
-
-unsigned char vga_font[cmapsz] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
-0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
-0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
-0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
-0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
-0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
-0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
-0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
-0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
-0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
-0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
-0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
-0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
-0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
-0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
-0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
-0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
-0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
-0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
-0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
-0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
-0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
-0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
-0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
-0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
-0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
-0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
-0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
-0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
-0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
-0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
-0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
-0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
-0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 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, 0xff, 0x00, 0x00, 
-0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
-0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
-0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
-0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
-0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
-0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
-0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
-0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
-0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
-0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
-0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
-0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
-0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
-0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
-0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
-0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
-0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
-0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
-0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
-0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
-0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
-0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
-0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
-0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
-0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 
-0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
-0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
-0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
-0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 
-0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
-0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
-0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
-0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
-0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
-0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
-0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 
-0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 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, 
-};
-
index 0f9c59c6c5c4ba05272e274707f56afd974f1715..8c27b5f94a77e913aa6f95fbc8bf474bd870a46b 100644 (file)
@@ -933,6 +933,9 @@ void d_move(struct dentry * dentry, struct dentry * target)
 /**
  * d_path - return the path of a dentry
  * @dentry: dentry to report
+ * @vfsmnt: vfsmnt to which the dentry belongs
+ * @root: root dentry
+ * @rootmnt: vfsmnt to which the root dentry belongs
  * @buffer: buffer to return value in
  * @buflen: buffer length
  *
index 28fbd00985f3baa5f73e0447cadd82b7d24ac89c..62acffd58bce87b2528a35c15787072d58004d4e 100644 (file)
@@ -261,6 +261,7 @@ static void sync_all_inodes(void)
 /**
  *     write_inode_now -       write an inode to disk
  *     @inode: inode to write to disk
+ *     @sync: whether the write should be synchronous or not
  *
  *     This function commits an inode to disk immediately if it is
  *     dirty. This is primarily needed by knfsd.
index e088d7fba7736f2c7839f489885db54ca816e39d..01500eeee993ef5d552aa8a75496160025cabe93 100644 (file)
@@ -8,7 +8,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: inode-v23.c,v 1.16 2000/07/06 14:38:10 dwmw2 Exp $
+ * $Id: inode-v23.c,v 1.17 2000/07/06 20:35:19 prumpf Exp $
  *
  *
  * Ported to Linux 2.3.x and MTD:
@@ -24,7 +24,6 @@
  * maybe other stuff do to.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -1453,7 +1452,6 @@ static struct inode_operations jffs_file_inode_operations =
 
 static struct file_operations jffs_dir_operations =
 {
-       read:           generic_read_dir,
        readdir:        jffs_readdir,
 };
 
@@ -1533,16 +1531,19 @@ jffs_delete_inode(struct inode *inode)
        
        inode->i_size = 0;
 
-       unlock_kernel();
        clear_inode(inode);
 
+       unlock_kernel();
 }
 
 void
 jffs_write_super(struct super_block *sb)
 {
 #ifdef USE_GC
-       jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
+       struct jffs_control *c = (struct jffs_control *)sb->u.generic_sbp;
+       
+       if(!c->fmc->no_call_gc)
+               jffs_garbage_collect(c);
 #endif
 }
 
index 427e7f0f77271d548f15bb4ac12b66cf21d195b0..be09afdd7b6186e16b866eac997d021efedf3450 100644 (file)
@@ -164,6 +164,8 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
 
        poll_initwait(&table);
        wait = &table;
+       if (!__timeout)
+               wait = NULL;
        retval = 0;
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
@@ -385,7 +387,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
 {
        int i, j, fdcount, err;
        struct pollfd **fds;
-       poll_table table;
+       poll_table table, *wait;
        int nchunks, nleft;
 
        /* Do a sanity check on nfds ... */
@@ -401,8 +403,11 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
        }
 
        poll_initwait(&table);
-       err = -ENOMEM;
+       wait = &table;
+       if (!timeout)
+               wait = NULL;
 
+       err = -ENOMEM;
        fds = NULL;
        if (nfds != 0) {
                fds = (struct pollfd **)kmalloc(
@@ -437,7 +442,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
                        goto out_fds1;
        }
 
-       fdcount = do_poll(nfds, nchunks, nleft, fds, &table, timeout);
+       fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout);
 
        /* OK, now copy the revents fields back to user space. */
        for(i=0; i < nchunks; i++)
index 82110a4e00745191fda570925b3d668d09c84563..5487778ca7b90eb06515adc304e0e293d7f5e353 100644 (file)
@@ -1,37 +1,56 @@
-#ifndef __ASM_MIPS_PARAM_H
-#define __ASM_MIPS_PARAM_H
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
 
 #ifndef HZ
 
+#ifdef __KERNEL__
+
+/* Safeguard against user stupidity  */
+#ifdef _SYS_PARAM_H
+#error Do not include <asm/param.h> with __KERNEL__ defined!
+#endif
+
 #include <linux/config.h>
 
 #ifdef CONFIG_DECSTATION
    /*
-    * log2(HZ), change this here if you want another
-    * HZ value. This is also used in dec_time_init.
-    * Minimum is 1, Maximum is 15.
+    * log2(HZ), change this here if you want another HZ value. This is also
+    * used in dec_time_init.  Minimum is 1, Maximum is 15.
     */
 #  define LOG_2_HZ 7
 #  define HZ (1 << LOG_2_HZ)
    /*
     * Ye olde division-by-multiplication trick.
-    *
     * This works only if 100 / HZ <= 1
     */
 #  define QUOTIENT ((1UL << (32 - LOG_2_HZ)) * 100)
-#  define HZ_TO_STD(a)                            \
+#  define hz_to_std(a)                            \
    ({ unsigned int __res;                        \
-      unsigned long lo;                                  \
+      unsigned long __lo;                        \
         __asm__("multu\t%2,%3\n\t"               \
-               :"=h" (__res), "=l" (lo)          \
+               :"=h" (__res), "=l" (__lo)        \
                :"r" (a),"r" (QUOTIENT));         \
         (__typeof__(a)) __res;})
-#else
+
+#else /* Not a DECstation  */
+
+/* This is the internal value of HZ, that is the rate at which the jiffies
+   counter is increasing.  This value is independent from the external value
+   and can be changed in order to suit the hardware and application
+   requirements.  */
 #  define HZ 100
-#  define HZ_TO_STD(a) (a)
-#endif
+#  define hz_to_std(a) (a)
 
-#endif
+#endif /* Not a DECstation */
+
+#else /* defined(__KERNEL__)  */
+
+/* This is the external value of HZ as seen by user programs.  Don't change
+   unless you know what you're doing - changing breaks binary compatibility.  */
+#define HZ 100
+
+#endif /* defined(__KERNEL__)  */
+#endif /* defined(HZ)  */
 
 #define EXEC_PAGESIZE  4096
 
@@ -45,4 +64,4 @@
 
 #define MAXHOSTNAMELEN 64      /* max length of hostname */
 
-#endif /* __ASM_MIPS_PARAM_H */
+#endif /* _ASM_PARAM_H */
index e1caa024a71c768375f21a337ba7ce81ccd767ca..2a0753dd2da906bc246ab6797ebb037e75bed1c1 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: dma.h,v 1.5 2000/03/07 15:45:42 ralf Exp $
- *
+/*
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
  * High DMA channel support & info by Hannu Savolainen
index f958c4d8acdbf2d5a20b4d1800f697b56bed4fb1..5354eeb7df6ee2dbcc9e28dd63ecf5b5fc8874bc 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: param.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright 1994 - 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright 1994 - 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright 2000 Silicon Graphics, Inc.
  */
 #ifndef _ASM_PARAM_H
 #define _ASM_PARAM_H
@@ -13,7 +13,7 @@
 #define HZ 100
 #  define HZ 100
 #ifdef __KERNEL__
-#  define HZ_TO_STD(a) (a)
+#  define hz_to_std(a) (a)
 #endif
 #endif
 
index e51ce04da258b782dad0b3551d21056c2eeb2154..66c57ab288031ee68b43c85ed8af1508cc1acc1d 100644 (file)
@@ -1,16 +1,16 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
- * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
  */
 #ifndef _ASM_SN_ADDRS_H
 #define _ASM_SN_ADDRS_H
 
 #include <linux/config.h>
+
 #if _LANGUAGE_C
 #include <linux/types.h>
 #endif /* _LANGUAGE_C */
index 76004336a241537c15daf221dc8d9cc7486bcab7..2502069c2a358e5afd494890bbb096c7f3ff15a2 100644 (file)
@@ -1,13 +1,12 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * This file has definitions for the hub and snac interfaces.
  *
- * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
- * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silcon Graphics, Inc.
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SGI_SN_AGENT_H
 #define _ASM_SGI_SN_AGENT_H
index b0f7a215193cbb326f5b07e93a031e8e239a5f1d..c8ff3c3c07c2473fc0ee6348a5efaebb382bcaab 100644 (file)
@@ -1,6 +1,4 @@
-
-/* $Id: io.h,v 1.2 2000/02/02 16:35:57 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -12,6 +10,7 @@
 #define _ASM_SN_IO_H
 
 #include <linux/config.h>
+
 #if !defined(CONFIG_SGI_IO)
 #include <asm/sn/sn0/addrs.h>
 
index 4c5fa57e509b3d6b5c6f08d33c38627d872000b0..493582fc5075c45f0878ca8f6be99035191b813b 100644 (file)
@@ -1,20 +1,17 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Derived from IRIX <sys/SN/klconfig.h>.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
- * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
  */
 #ifndef        _ASM_SN_KLCONFIG_H
 #define        _ASM_SN_KLCONFIG_H
 
-/*
- * klconfig.h
- */
+#include <linux/config.h>
 
 /*
  * The KLCONFIG structures store info about the various BOARDs found
  *      that offsets of existing fields do not change.
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <asm/sn/types.h>
-#if defined(CONFIG_SGI_IP27) || defined(CONFIG_SGI_IP35)
-#include <asm/sn/agent.h>
-#include <asm/arc/types.h>
-#include <asm/arc/hinv.h>
-#endif /* CONFIG_SGI_IP27 || CONFIG_SGI_IP35 */
 #if defined(CONFIG_SGI_IP27)
 #include <asm/sn/sn0/addrs.h>
 //#include <sys/SN/router.h>
 // XXX Stolen from <sys/SN/router.h>:
 #define MAX_ROUTER_PORTS (6)    /* Max. number of ports on a router */
 #include <asm/sn/sn0/sn0_fru.h>
+#include <asm/sn/agent.h>
 //#include <sys/graph.h>
+#include <asm/arc/types.h>
+#include <asm/arc/hinv.h>
 //#include <sys/xtalk/xbow.h>
+#if defined(CONFIG_SGI_IO)
+// The hack file has to be before vector and after sn0_fru....
+#include <asm/hack.h>
+#include <asm/sn/vector.h>
+#include <asm/xtalk/xtalk.h>
+#endif  /* CONFIG_SGI_IO */
 #elif defined(CONFIG_SGI_IP35)
+#include <asm/hack.h>
 #include <asm/sn/sn1/addrs.h>
+#include <asm/sn/vector.h>
 #include <sys/sn/router.h>
+#include <asm/sn/agent.h>
 #include <sys/graph.h>
+#include <asm/arc/types.h>
+#include <asm/arc/hinv.h>
 #include <asm/xtalk/xbow.h>
-#endif  /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
-#if (defined(CONFIG_SGI_IP27)&&defined(CONFIG_SGI_IO))||defined(CONFIG_SGI_IP35)
-// The hack file has to be before vector and after sn0_fru....
-#include <asm/hack.h>
-#include <asm/sn/vector.h>
 #include <asm/xtalk/xtalk.h>
-#endif  /* (CONFIG_SGI_IP27 && CONFIG_SGI_IO) || CONFIG_SGI_IP35 */
+#endif  /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
 
 #define KLCFGINFO_MAGIC        0xbeedbabe
 
index 3ca24005693a899f9e0b31d6730838557296dfc7..b979205c2115521ed64275ea892c046fc7d0c000 100644 (file)
@@ -1,18 +1,18 @@
-/* $Id$
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
  *
- * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
- * Copyright (C) 1999 by Ralf Baechle
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
  */
 #ifndef _ASM_SN_KLDIR_H
 #define _ASM_SN_KLDIR_H
 
 #include <linux/config.h>
+
 #if defined(CONFIG_SGI_IO)
 #include <asm/hack.h>
 #endif
index af8d4a2d4c7cc31702e95cc10ef57561974085bc..59a57452c33aceb5566eccf1622e3e19002b5eb3 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef _SPARC_BITOPS_H
 #define _SPARC_BITOPS_H
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/byteorder.h>
 
index 8a5404930b140ab02052dd15005117eb1d00b5aa..7e3adf02f44ab97becb9f6ddffe73dd19e674ac0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.24 2000/04/14 09:59:04 davem Exp $ */
+/* $Id: elf.h,v 1.25 2000/07/12 01:27:08 davem Exp $ */
 #ifndef __ASM_SPARC64_ELF_H
 #define __ASM_SPARC64_ELF_H
 
index 85ae21c9d9a97ab7dfa566805b8cd30fda609372..5a53d342debeeb83bd3ee10de5490e3f64fafd4a 100644 (file)
@@ -7,6 +7,7 @@
 #include <asm/atomic.h>
 #include <asm/bitops.h>
 #include <asm/system.h>
+#include <linux/wait.h>
 
 struct semaphore {
        atomic_t count;
index 294464b657a833198e03c28355946e81ca14645c..27d813e9db10723578e33d95441876419fdd8b12 100644 (file)
@@ -309,6 +309,7 @@ struct parport {
        rwlock_t cad_lock;
 
        int spintime;
+       atomic_t ref_count;
 };
 
 #define DEFAULT_SPIN_TIME 500 /* us */
@@ -337,12 +338,9 @@ void parport_announce_port (struct parport *port);
 /* Unregister a port. */
 extern void parport_unregister_port(struct parport *port);
 
-/* parport_in_use returns nonzero if there are devices attached to a
-   port. */
-#define parport_in_use(x)  ((x)->devices != NULL)
-
 /* parport_enumerate returns a pointer to the linked list of all the
-   ports in this machine. */
+   ports in this machine.  DON'T USE THIS.  Use
+   parport_register_driver instead. */
 struct parport *parport_enumerate(void);
 
 /* Register a new high-level driver. */
@@ -351,6 +349,15 @@ extern int parport_register_driver (struct parport_driver *);
 /* Unregister a high-level driver. */
 extern void parport_unregister_driver (struct parport_driver *);
 
+/* If parport_register_driver doesn't fit your needs, perhaps
+ * parport_find_xxx does. */
+extern struct parport *parport_find_number (int);
+extern struct parport *parport_find_base (unsigned long);
+
+/* Reference counting for ports. */
+extern struct parport *parport_get_port (struct parport *);
+extern void parport_put_port (struct parport *);
+
 /* parport_register_device declares that a device is connected to a
    port, and tells the kernel all it needs to know.
    - pf is the preemption function (may be NULL for no callback)
index 04ae938be5b995161a931bf4d00e1b5bbdc1c724..a53a165b1ae9940c69d0a74d6bbf371065c54f87 100644 (file)
 #define PCI_DEVICE_ID_LAVA_SSERIAL     0x0500 /* 1x 16550 */
 #define PCI_DEVICE_ID_LAVA_PORT_650    0x0600 /* 1x 16650 */
 
+#define PCI_VENDOR_ID_SYBA             0x1592
+#define PCI_DEVICE_ID_SYBA_2P_EPP      0x0782
+#define PCI_DEVICE_ID_SYBA_1P_ECP      0x0783
+
 #define PCI_DEVICE_ID_LAVA_PARALLEL    0x8000
 #define PCI_DEVICE_ID_LAVA_DUAL_PAR_A  0x8002 /* The Lava Dual Parallel is */
 #define PCI_DEVICE_ID_LAVA_DUAL_PAR_B  0x8003 /* two PCI devices on a card */
index 38e79216700fd0eb747d6bec100108c417647786..5208de0c3d6f6d72c1d7975bff208864efc59a40 100644 (file)
@@ -233,7 +233,7 @@ static void reschedule_idle(struct task_struct * p, unsigned long flags)
                 * its preferred CPU. (this is a shortcut):
                 */
                tsk = cpu_curr(best_cpu);
-               if (preemption_goodness(tsk, p, best_cpu) > 1)
+               if (preemption_goodness(tsk, p, best_cpu) > 0)
                        goto preempt_now;
        }
 
@@ -290,7 +290,7 @@ send_now_idle:
         * altogether, tsk->need_resched is actively watched by the
         * idle thread.
         */
-       if (!tsk->need_resched)
+       if ((tsk->processor != current->processor) && !tsk->need_resched)
                smp_send_reschedule(tsk->processor);
        tsk->need_resched = 1;
        spin_unlock_irqrestore(&runqueue_lock, flags);
index a24e465825cb50ecc62bfd46e52d57ae900f4dc7..a31f0f7e78b59afbccc49e34f563a2de3e3ac6ca 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1966,7 +1966,7 @@ int slabinfo_read_proc (char *page, char **start, off_t off,
 #define MAX_SLABINFO_WRITE 128
 /**
  * slabinfo_write_proc - SMP tuning for the slab allocator
- * @file:
+ * @file: unused
  * @buffer: user buffer
  * @count: data len
  * @data: unused
index 282024cc92a1ea4701532946418d239ad4cbe059..46f5e57e826ebb4e52661e074bd0e433cf3bd108 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.208 2000/05/03 06:37:06 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.209 2000/07/12 03:49:30 davem Exp $
  *
  *             IPv4 specific functions
  *
@@ -69,8 +69,8 @@ extern int sysctl_ip_dynaddr;
 #define ICMP_MIN_LENGTH 8
 
 /* Socket used for sending RSTs */     
-struct inode tcp_inode;
-struct socket *tcp_socket=&tcp_inode.u.socket_i;
+static struct inode tcp_inode;
+static struct socket *tcp_socket=&tcp_inode.u.socket_i;
 
 void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, 
                       struct sk_buff *skb);