]> git.neil.brown.name Git - history.git/commitdiff
v2.4.9.2 -> v2.4.9.3
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:11:43 +0000 (20:11 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:11:43 +0000 (20:11 -0800)
  - Johannes Erdfelt, Oliver Neukum: USB printer driver race fix
  - John Byrne: fix stupid i386-SMP irq stack layout bug
  - Andreas Bombe, me: yenta IO window fix
  - Neil Brown: raid1 buffer state fix
  - David Miller, Paul Mackerras: fix up sparc and ppc respectively for kmap/kbd_rate
  - Matija Nalis: umsdos fixes, and make it possible to boot up with umsdos
  - Francois Romieu: fix bugs in dscc4 driver
  - Andy Grover: new PCI config space access functions (eventually for ACPI)
  - Albert Cranford: fix incorrect e2fsprog data from ver_linux script
  - Dave Jones: re-sync x86 setup code, fix macsonic kmalloc use
  - Johannes Erdfelt: remove obsolete plusb USB driver
  - Andries Brouwer: fix USB compact flash version info, add blksize ioctls

56 files changed:
Documentation/Configure.help
Makefile
arch/i386/defconfig
arch/i386/kernel/bluesmoke.c
arch/i386/kernel/mtrr.c
arch/i386/kernel/pci-pc.c
arch/i386/kernel/setup.c
arch/mips64/kernel/ioctl32.c
arch/ppc/kernel/chrp_setup.c
arch/ppc/kernel/head_8xx.S
arch/ppc/kernel/pmac_setup.c
arch/ppc/kernel/prep_setup.c
arch/sparc64/kernel/ioctl32.c
drivers/acpi/include/platform/acgcc.h
drivers/block/DAC960.c
drivers/block/blkpg.c
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/loop.c
drivers/block/ps2esdi.c
drivers/ide/ide.c
drivers/macintosh/Makefile
drivers/macintosh/via-pmu.c
drivers/md/md.c
drivers/md/raid1.c
drivers/net/macsonic.c
drivers/net/wan/dscc4.c
drivers/pci/pci.c
drivers/pcmcia/yenta.c
drivers/scsi/sd.c
drivers/usb/Config.in
drivers/usb/Makefile
drivers/usb/plusb.c [deleted file]
drivers/usb/printer.c
drivers/usb/storage/unusual_devs.h
drivers/video/vga16fb.c
fs/Makefile
fs/umsdos/README-WIP.txt
fs/umsdos/dir.c
fs/umsdos/emd.c
fs/umsdos/inode.c
fs/umsdos/namei.c
fs/umsdos/rdir.c
include/asm-i386/hw_irq.h
include/asm-i386/msr.h
include/asm-i386/system.h
include/asm-i386/timex.h
include/asm-ppc/keyboard.h
include/asm-ppc/kmap_types.h
include/asm-ppc/machdep.h
include/asm-sparc/kmap_types.h
include/linux/fs.h
include/linux/pmu.h
include/linux/skbuff.h
mm/vmscan.c
scripts/ver_linux

index 364ac608b6c0180f014bbe6cfa0e54c7f1f61db2..9a457df6bfdc5dda92ee0f5940f16cb52db36b54 100644 (file)
@@ -11690,19 +11690,6 @@ CONFIG_USB_USBNET
   The module will be called usbnet.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-PLUSB driver
-CONFIG_USB_PLUSB
-  A driver for the Prolific PL-2302 USB-to-USB network device. This
-  'USB cable' connects two hosts via a point-to-point network with
-  bandwidth of 5 Mbit/s. Configure this driver after connecting the
-  USB cable via ifconfig plusb0 10.0.0.1 pointopoint 10.0.0.2 (and
-  vice versa on the other host).
-
-  This code is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module will be called plusb.o. If you want to compile it as a
-  module, say M here and read Documentation/modules.txt.
-
 USB Diamond Rio500 support
 CONFIG_USB_RIO500
   Say Y here if you want to connect a USB Rio500 mp3 player to your
index a9754f318748d2b9603f821d9795fedca67c60bf..16857718ac8b50fffdf356820cf840cdcece5d3d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 10
-EXTRAVERSION =-pre2
+EXTRAVERSION =-pre3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
index 1083b11aab48003f4ae36a74dcb3e3d59e5f2c46..6e5153049c9483c4e753efa62b70477f669bd5dd 100644 (file)
@@ -742,7 +742,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_USBNET is not set
 
 #
 # USB port drivers
index 5ae7f060efc447f16164d317b8219c1249c9991b..7c6e59aa6e3cc6de238c9a6e042abf65c8f1feba 100644 (file)
@@ -19,7 +19,7 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
        u32 mcgstl, mcgsth;
        int i;
        
-       rdmsr(0x17a, mcgstl, mcgsth);
+       rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
        if(mcgstl&(1<<0))       /* Recoverable ? */
                recover=0;
 
@@ -27,7 +27,7 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
        
        for(i=0;i<banks;i++)
        {
-               rdmsr(0x401+i*4,low, high);
+               rdmsr(MSR_IA32_MC0_STATUS+i*4,low, high);
                if(high&(1<<31))
                {
                        if(high&(1<<29))
@@ -38,18 +38,18 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
                        high&=~(1<<31);
                        if(high&(1<<27))
                        {
-                               rdmsr(0x402+i*4, alow, ahigh);
+                               rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
                                printk("[%08x%08x]", alow, ahigh);
                        }
                        if(high&(1<<26))
                        {
-                               rdmsr(0x402+i*4, alow, ahigh);
+                               rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
                                printk(" at %08x%08x", 
                                        high, low);
                        }
                        printk("\n");
                        /* Clear it */
-                       wrmsr(0x401+i*4, 0UL, 0UL);
+                       wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
                        /* Serialize */
                        wmb();
                }
@@ -61,7 +61,7 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
                panic("Unable to continue");
        printk(KERN_EMERG "Attempting to continue.\n");
        mcgstl&=~(1<<2);
-       wrmsr(0x17a,mcgstl, mcgsth);
+       wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
 }
 
 /*
@@ -71,8 +71,8 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
 static void pentium_machine_check(struct pt_regs * regs, long error_code)
 {
        u32 loaddr, hi, lotype;
-       rdmsr(0x0, loaddr, hi);
-       rdmsr(0x1, lotype, hi);
+       rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi);
+       rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi);
        printk(KERN_EMERG "CPU#%d: Machine Check Exception:  0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype);
        if(lotype&(1<<5))
                printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id());
@@ -133,8 +133,8 @@ void __init intel_mcheck_init(struct cpuinfo_x86 *c)
                machine_check_vector = pentium_machine_check;
                wmb();
                /* Read registers before enabling */
-               rdmsr(0x0, l, h);
-               rdmsr(0x1, l, h);
+               rdmsr(MSR_IA32_P5_MC_ADDR, l, h);
+               rdmsr(MSR_IA32_P5_MC_TYPE, l, h);
                if(done==0)
                        printk(KERN_INFO "Intel old style machine check architecture supported.\n");
                /* Enable MCE */                
@@ -161,17 +161,17 @@ void __init intel_mcheck_init(struct cpuinfo_x86 *c)
        
        if(done==0)
                printk(KERN_INFO "Intel machine check architecture supported.\n");
-       rdmsr(0x179, l, h);
+       rdmsr(MSR_IA32_MCG_CAP, l, h);
        if(l&(1<<8))
-               wrmsr(0x17b, 0xffffffff, 0xffffffff);
+               wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
        banks = l&0xff;
        for(i=1;i<banks;i++)
        {
-               wrmsr(0x400+4*i, 0xffffffff, 0xffffffff); 
+               wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
        }
        for(i=0;i<banks;i++)
        {
-               wrmsr(0x401+4*i, 0x0, 0x0); 
+               wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
        }
        set_in_cr4(X86_CR4_MCE);
        printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
@@ -191,10 +191,10 @@ static void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
        /* Winchip C6 */
        machine_check_vector = winchip_machine_check;
        wmb();
-       rdmsr(0x107, lo, hi);
+       rdmsr(MSR_IDT_FCR1, lo, hi);
        lo|= (1<<2);    /* Enable EIERRINT (int 18 MCE) */
        lo&= ~(1<<4);   /* Enable MCE */
-       wrmsr(0x107, lo, hi);
+       wrmsr(MSR_IDT_FCR1, lo, hi);
        __asm__ __volatile__ (
                "movl %%cr4, %%eax\n\t"
                "orl $0x40, %%eax\n\t"
@@ -236,6 +236,6 @@ void __init mcheck_init(struct cpuinfo_x86 *c)
 static int __init mcheck_disable(char *str)
 {
        mce_disabled = 1;
-       return 1;
+       return 0;
 }
 __setup("nomce", mcheck_disable);
index fa815a804220bc5f5d51b9adb039663abb497cc8..afaa4b2db31ab7813560df204355563a0fc9a1e7 100644 (file)
@@ -389,21 +389,19 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
         return;
 
     /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-    if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
-       asm volatile ("movl  %%cr4, %0\n\t"
-                     "movl  %0, %1\n\t"
-                     "andb  $0x7f, %b1\n\t"
-                     "movl  %1, %%cr4\n\t"
-                     : "=r" (ctxt->cr4val), "=q" (tmp) : : "memory");
+    if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) ) {
+       ctxt->cr4val = read_cr4();
+       write_cr4(ctxt->cr4val & (unsigned char) ~(1<<7));
+    }
 
     /*  Disable and flush caches. Note that wbinvd flushes the TLBs as
        a side-effect  */
-    asm volatile ("movl  %%cr0, %0\n\t"
-                 "orl   $0x40000000, %0\n\t"
-                 "wbinvd\n\t"
-                 "movl  %0, %%cr0\n\t"
-                 "wbinvd\n\t"
-                 : "=r" (tmp) : : "memory");
+    {
+       unsigned int cr0 = read_cr0() | 0x40000000;
+       wbinvd();
+       write_cr0( cr0 );
+       wbinvd();
+    }
 
     if ( mtrr_if == MTRR_IF_INTEL ) {
        /*  Disable MTRRs, and set the default type to uncached  */
@@ -420,15 +418,13 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
 /*  Restore the processor after a set_mtrr_prepare  */
 static void set_mtrr_done (struct set_mtrr_context *ctxt)
 {
-    unsigned long tmp;
-
     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR ) {
         __restore_flags (ctxt->flags);
         return;
     }
 
     /*  Flush caches and TLBs  */
-    asm volatile ("wbinvd" : : : "memory" );
+    wbinvd();
 
     /*  Restore MTRRdefType  */
     if ( mtrr_if == MTRR_IF_INTEL ) {
@@ -440,15 +436,11 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
     }
 
     /*  Enable caches  */
-    asm volatile ("movl  %%cr0, %0\n\t"
-                 "andl  $0xbfffffff, %0\n\t"
-                 "movl  %0, %%cr0\n\t"
-                 : "=r" (tmp) : : "memory");
+    write_cr0( read_cr0() & 0xbfffffff );
 
     /*  Restore value of CR4  */
     if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
-       asm volatile ("movl  %0, %%cr4"
-                     : : "r" (ctxt->cr4val) : "memory");
+       write_cr4(ctxt->cr4val);
 
     /*  Re-enable interrupts locally (if enabled previously)  */
     __restore_flags (ctxt->flags);
@@ -607,7 +599,7 @@ static void amd_get_mtrr (unsigned int reg, unsigned long *base,
 {
     unsigned long low, high;
 
-    rdmsr (0xC0000085, low, high);
+    rdmsr (MSR_K6_UWCCR, low, high);
     /*  Upper dword is region 1, lower is region 0  */
     if (reg == 1) low = high;
     /*  The base masks off on the right alignment  */
@@ -771,7 +763,7 @@ static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
     /*
      * Low is MTRR0 , High MTRR 1
      */
-    rdmsr (0xC0000085, regs[0], regs[1]);
+    rdmsr (MSR_K6_UWCCR, regs[0], regs[1]);
     /*
      * Blank to disable
      */
@@ -792,8 +784,8 @@ static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
      * The writeback rule is quite specific. See the manual. Its
      * disable local interrupts, write back the cache, set the mtrr
      */
-    __asm__ __volatile__ ("wbinvd" : : : "memory");
-    wrmsr (0xC0000085, regs[0], regs[1]);
+       wbinvd();
+       wrmsr (MSR_K6_UWCCR, regs[0], regs[1]);
     if (do_safe) set_mtrr_done (&ctxt);
 }   /*  End Function amd_set_mtrr_up  */
 
@@ -826,7 +818,7 @@ static void centaur_set_mcr_up (unsigned int reg, unsigned long base,
     }
     centaur_mcr[reg].high = high;
     centaur_mcr[reg].low = low;
-    wrmsr (0x110 + reg, low, high);
+    wrmsr (MSR_IDT_MCR0 + reg, low, high);
     if (do_safe) set_mtrr_done( &ctxt );
 }   /*  End Function centaur_set_mtrr_up  */
 
@@ -2012,12 +2004,12 @@ static void __init centaur_mcr1_init(void)
      * find out what the bios might have done.
      */
      
-    rdmsr(0x120, lo, hi);
+    rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
     if(((lo>>17)&7)==1)                /* Type 1 Winchip2 MCR */
     {
        lo&= ~0x1C0;            /* clear key */
        lo|= 0x040;             /* set key to 1 */
-       wrmsr(0x120, lo, hi);   /* unlock MCR */
+       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);        /* unlock MCR */
     }    
     
     centaur_mcr_type = 1;
@@ -2031,7 +2023,7 @@ static void __init centaur_mcr1_init(void)
        if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
        {
                if(!(lo & (1<<(9+i))))
-                       wrmsr (0x110 + i , 0, 0);
+                       wrmsr (MSR_IDT_MCR0 + i , 0, 0);
                else
                        /*
                         *      If the BIOS set up an MCR we cannot see it
@@ -2047,7 +2039,7 @@ static void __init centaur_mcr1_init(void)
      */
 
     lo |= 15;                  /* Write combine enables */
-    wrmsr(0x120, lo, hi);
+    wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 }   /*  End Function centaur_mcr1_init  */
 
 /*
@@ -2071,10 +2063,10 @@ static void __init centaur_mcr0_init(void)
     for (i = 0; i < 8; ++i)
     {
        if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
-               wrmsr (0x110 + i , 0, 0);
+               wrmsr (MSR_IDT_MCR0 + i , 0, 0);
     }
 
-    wrmsr(0x120, 0x01F0001F, 0);       /* Write only */
+    wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);    /* Write only */
 }   /*  End Function centaur_mcr0_init  */
 
 /*
@@ -2231,6 +2223,8 @@ void __init mtrr_init_secondary_cpu(void)
         */
        cyrix_arr_init_secondary ();
        break;
+    case MTRR_IF_NONE:
+       break;
     default:
        /* I see no MTRRs I can support in SMP mode... */
        printk ("mtrr: SMP support incomplete for this vendor\n");
index ef3c7c35af013841184b35204047f134005c1d61..a0aa4f46b887fb25b7f22083d78bcc5686e2acf8 100644 (file)
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
 
 int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus;
-struct pci_ops *pci_root_ops;
+struct pci_bus *pci_root_bus = NULL;
+struct pci_ops *pci_root_ops = NULL;
+
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
 
 /*
- * Direct access to PCI hardware...
+ * This interrupt-safe spinlock protects all accesses to PCI
+ * configuration space.
  */
+spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef CONFIG_PCI_DIRECT
 
 /*
  * Functions for accessing PCI configuration space with type 1 accesses
  */
 
-#define CONFIG_CMD(dev, where)   (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+#ifdef CONFIG_PCI_DIRECT
+
+#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
+       (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
+
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+       unsigned long flags;
+
+       if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+       switch (len) {
+       case 1:
+               *value = inb(0xCFC + (reg & 3));
+               break;
+       case 2:
+               *value = inw(0xCFC + (reg & 2));
+               break;
+       case 4:
+               *value = inl(0xCFC);
+               break;
+       }
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return 0;
+}
+
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+       unsigned long flags;
+
+       if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
+
+       switch (len) {
+       case 1:
+               outb((u8)value, 0xCFC + (reg & 3));
+               break;
+       case 2:
+               outw((u16)value, 0xCFC + (reg & 2));
+               break;
+       case 4:
+               outl((u32)value, 0xCFC);
+               break;
+       }
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return 0;
+}
+
+#undef PCI_CONF1_ADDRESS
 
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);
-       *value = inb(0xCFC + (where&3));
-       return PCIBIOS_SUCCESSFUL;
+       int result; 
+       u32 data;
+
+       if (!value) 
+               return -EINVAL;
+
+       result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, &data);
+
+       *value = (u8)data;
+
+       return result;
 }
 
 static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);    
-       *value = inw(0xCFC + (where&2));
-       return PCIBIOS_SUCCESSFUL;    
+       int result; 
+       u32 data;
+
+       if (!value) 
+               return -EINVAL;
+
+       result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, &data);
+
+       *value = (u16)data;
+
+       return result;
 }
 
 static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);
-       *value = inl(0xCFC);
-       return PCIBIOS_SUCCESSFUL;    
+       if (!value) 
+               return -EINVAL;
+
+       return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);    
-       outb(value, 0xCFC + (where&3));
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);
-       outw(value, 0xCFC + (where&2));
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-       outl(CONFIG_CMD(dev,where), 0xCF8);
-       outl(value, 0xCFC);
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-#undef CONFIG_CMD
-
 static struct pci_ops pci_direct_conf1 = {
        pci_conf1_read_config_byte,
        pci_conf1_read_config_word,
@@ -88,68 +168,131 @@ static struct pci_ops pci_direct_conf1 = {
        pci_conf1_write_config_dword
 };
 
+
 /*
  * Functions for accessing PCI configuration space with type 2 accesses
  */
 
-#define IOADDR(devfn, where)   ((0xC000 | ((devfn & 0x78) << 5)) + where)
-#define FUNC(devfn)            (((devfn & 7) << 1) | 0xf0)
-#define SET(dev)               if (dev->devfn & 0x80) return PCIBIOS_DEVICE_NOT_FOUND;         \
-                               outb(FUNC(dev->devfn), 0xCF8);                                  \
-                               outb(dev->bus->number, 0xCFA);
+#define PCI_CONF2_ADDRESS(dev, reg)    (u16)(0xC000 | (dev << 8) | reg)
 
-static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
 {
-       SET(dev);
-       *value = inb(IOADDR(dev->devfn,where));
+       unsigned long flags;
+
+       if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+               return -EINVAL;
+
+       if (dev & 0x10) 
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+       outb((u8)bus, 0xCFA);
+
+       switch (len) {
+       case 1:
+               *value = inb(PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       case 2:
+               *value = inw(PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       case 4:
+               *value = inl(PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       }
+
        outb (0, 0xCF8);
-       return PCIBIOS_SUCCESSFUL;
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return 0;
+}
+
+static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+       unsigned long flags;
+
+       if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+               return -EINVAL;
+
+       if (dev & 0x10) 
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       outb((u8)(0xF0 | (fn << 1)), 0xCF8);
+       outb((u8)bus, 0xCFA);
+
+       switch (len) {
+       case 1:
+               outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       case 2:
+               outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       case 4:
+               outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg));
+               break;
+       }
+
+       outb (0, 0xCF8);    
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return 0;
+}
+
+#undef PCI_CONF2_ADDRESS
+
+static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+       int result; 
+       u32 data;
+       result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, &data);
+       *value = (u8)data;
+       return result;
 }
 
 static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-       SET(dev);
-       *value = inw(IOADDR(dev->devfn,where));
-       outb (0, 0xCF8);
-       return PCIBIOS_SUCCESSFUL;
+       int result; 
+       u32 data;
+       result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, &data);
+       *value = (u8)data;
+       return result;
 }
 
 static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-       SET(dev);
-       *value = inl (IOADDR(dev->devfn,where));    
-       outb (0, 0xCF8);    
-       return PCIBIOS_SUCCESSFUL;
+       int result; 
+       u32 data;
+       result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, &data);
+       *value = (u8)data;
+       return result;
 }
 
 static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-       SET(dev);
-       outb (value, IOADDR(dev->devfn,where));
-       outb (0, 0xCF8);    
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-       SET(dev);
-       outw (value, IOADDR(dev->devfn,where));
-       outb (0, 0xCF8);    
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-       SET(dev);
-       outl (value, IOADDR(dev->devfn,where));    
-       outb (0, 0xCF8);    
-       return PCIBIOS_SUCCESSFUL;
+       return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-#undef SET
-#undef IOADDR
-#undef FUNC
-
 static struct pci_ops pci_direct_conf2 = {
        pci_conf2_read_config_byte,
        pci_conf2_read_config_word,
@@ -159,6 +302,7 @@ static struct pci_ops pci_direct_conf2 = {
        pci_conf2_write_config_dword
 };
 
+
 /*
  * Before we decide to use direct hardware access mechanisms, we try to do some
  * trivial checks to ensure it at least _seems_ to be working -- we just test
@@ -420,114 +564,176 @@ static int __init pci_bios_find_device (unsigned short vendor, unsigned short de
        return (int) (ret & 0xff00) >> 8;
 }
 
+static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+       unsigned long result = 0;
+       unsigned long flags;
+       unsigned long bx = ((bus << 8) | (dev << 3) | fn);
+
+       if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       switch (len) {
+       case 1:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=c" (*value),
+                         "=a" (result)
+                       : "1" (PCIBIOS_READ_CONFIG_BYTE),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       case 2:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=c" (*value),
+                         "=a" (result)
+                       : "1" (PCIBIOS_READ_CONFIG_WORD),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       case 4:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=c" (*value),
+                         "=a" (result)
+                       : "1" (PCIBIOS_READ_CONFIG_DWORD),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       }
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return (int)((result & 0xff00) >> 8);
+}
+
+static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+{
+       unsigned long result = 0;
+       unsigned long flags;
+       unsigned long bx = ((bus << 8) | (dev << 3) | fn);
+
+       if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+               return -EINVAL;
+
+       spin_lock_irqsave(&pci_config_lock, flags);
+
+       switch (len) {
+       case 1:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=a" (result)
+                       : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
+                         "c" (value),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       case 2:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=a" (result)
+                       : "0" (PCIBIOS_WRITE_CONFIG_WORD),
+                         "c" (value),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       case 4:
+               __asm__("lcall (%%esi); cld\n\t"
+                       "jc 1f\n\t"
+                       "xor %%ah, %%ah\n"
+                       "1:"
+                       : "=a" (result)
+                       : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
+                         "c" (value),
+                         "b" (bx),
+                         "D" ((long)reg),
+                         "S" (&pci_indirect));
+               break;
+       }
+
+       spin_unlock_irqrestore(&pci_config_lock, flags);
+
+       return (int)((result & 0xff00) >> 8);
+}
+
 static int pci_bios_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
+       int result; 
+       u32 data;
 
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=c" (*value),
-                 "=a" (ret)
-               : "1" (PCIBIOS_READ_CONFIG_BYTE),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       if (!value) 
+               return -EINVAL;
+
+       result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, &data);
+
+       *value = (u8)data;
+
+       return result;
 }
 
 static int pci_bios_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
+       int result; 
+       u32 data;
 
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=c" (*value),
-                 "=a" (ret)
-               : "1" (PCIBIOS_READ_CONFIG_WORD),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       if (!value) 
+               return -EINVAL;
+
+       result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, &data);
+
+       *value = (u16)data;
+
+       return result;
 }
 
 static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=c" (*value),
-                 "=a" (ret)
-               : "1" (PCIBIOS_READ_CONFIG_DWORD),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       if (!value) 
+               return -EINVAL;
+       
+       return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int pci_bios_write_config_byte(struct pci_dev *dev, int where, u8 value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
-                 "c" (value),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int pci_bios_write_config_word(struct pci_dev *dev, int where, u16 value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_WORD),
-                 "c" (value),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int pci_bios_write_config_dword(struct pci_dev *dev, int where, u32 value)
 {
-       unsigned long ret;
-       unsigned long bx = (dev->bus->number << 8) | dev->devfn;
-
-       __asm__("lcall (%%esi); cld\n\t"
-               "jc 1f\n\t"
-               "xor %%ah, %%ah\n"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
-                 "c" (value),
-                 "b" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       return (int) (ret & 0xff00) >> 8;
+       return pci_bios_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+               PCI_FUNC(dev->devfn), where, 4, value);
 }
 
+
 /*
  * Function table for BIOS32 access
  */
@@ -981,34 +1187,47 @@ void __init pcibios_fixup_bus(struct pci_bus *b)
        pci_read_bridge_bases(b);
 }
 
-/*
- * Initialization. Try all known PCI access methods. Note that we support
- * using both PCI BIOS and direct access: in such cases, we use I/O ports
- * to access config space, but we still keep BIOS order of cards to be
- * compatible with 2.0.X. This should go away some day.
- */
 
-void __init pcibios_init(void)
+void __init pcibios_config_init(void)
 {
-       struct pci_ops *bios = NULL;
-       struct pci_ops *dir = NULL;
+       /*
+        * Try all known PCI access methods. Note that we support using 
+        * both PCI BIOS and direct access, with a preference for direct.
+        */
 
 #ifdef CONFIG_PCI_BIOS
-       if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
+       if ((pci_probe & PCI_PROBE_BIOS) 
+               && ((pci_root_ops = pci_find_bios()))) {
                pci_probe |= PCI_BIOS_SORT;
                pci_bios_present = 1;
+               pci_config_read = pci_bios_read;
+               pci_config_write = pci_bios_write;
        }
 #endif
+
 #ifdef CONFIG_PCI_DIRECT
-       if (pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2))
-               dir = pci_check_direct();
+       if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
+               && (pci_root_ops = pci_check_direct())) {
+               if (pci_root_ops == &pci_direct_conf1) {
+                       pci_config_read = pci_conf1_read;
+                       pci_config_write = pci_conf1_write;
+               }
+               else {
+                       pci_config_read = pci_conf2_read;
+                       pci_config_write = pci_conf2_write;
+               }
+       }
 #endif
-       if (dir)
-               pci_root_ops = dir;
-       else if (bios)
-               pci_root_ops = bios;
-       else {
-               printk("PCI: No PCI bus detected\n");
+
+       return;
+}
+
+void __init pcibios_init(void)
+{
+       if (!pci_root_ops)
+               pcibios_config_init();
+       if (!pci_root_ops) {
+               printk("PCI: System does not support PCI\n");
                return;
        }
 
index 4cbe6e15b4fbe6babdb443764ee3a89012b89957..3ab1b3a931cff0b6bce78ea8cb2083a8b8a5cbd0 100644 (file)
@@ -64,6 +64,9 @@
  *
  *  VIA C3 Support.
  *  Dave Jones <davej@suse.de>, March 2001
+ *
+ *  AMD Athlon/Duron/Thunderbird bluesmoke support.
+ *  Dave Jones <davej@suse.de>, April 2001.
  */
 
 /*
@@ -93,6 +96,7 @@
 #include <linux/bootmem.h>
 #include <asm/processor.h>
 #include <linux/console.h>
+#include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -145,9 +149,9 @@ struct e820map e820;
 
 unsigned char aux_device_present;
 
+extern void mcheck_init(struct cpuinfo_x86 *c);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
-extern unsigned long cpu_khz;
 
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
@@ -1088,11 +1092,18 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
        l2size = ecx >> 16;
 
        /* AMD errata T13 (order #21922) */
-       if (c->x86_vendor == X86_VENDOR_AMD &&
-           c->x86 == 6 &&
-           c->x86_model == 3 &&
-           c->x86_mask == 0) {
-               l2size = 64;
+       if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
+               if (c->x86_model == 3 && c->x86_mask == 0)      /* Duron Rev A0 */
+                       l2size = 64;
+               if (c->x86_model == 4 &&
+                       (c->x86_mask==0 || c->x86_mask==1))     /* Tbird rev A1/A2 */
+                       l2size = 256;
+       }
+
+       /* VIA C3 CPUs (670-68F) need further shifting. */
+       if (c->x86_vendor == X86_VENDOR_CENTAUR && (c->x86 == 6) &&
+               ((c->x86_model == 7) || (c->x86_model == 8))) {
+               l2size = l2size >> 8;
        }
 
        if ( l2size == 0 )
@@ -1109,7 +1120,7 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
  *     misexecution of code under Linux. Owners of such processors should
  *     contact AMD for precise details and a CPU swap.
  *
- *     See     http://www.mygale.com/~poulot/k6bug.html
+ *     See     http://www.multimania.com/poulot/k6bug.html
  *             http://www.amd.com/K6/k6docs/revgd.html
  *
  *     The following test is erm.. interesting. AMD neglected to up
@@ -1126,6 +1137,12 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        int mbytes = max_mapnr >> (20-PAGE_SHIFT);
        int r;
 
+       /*
+        *      FIXME: We should handle the K5 here. Set up the write
+        *      range and also turn on MSR 83 bits 4 and 31 (write alloc,
+        *      no bus pipeline)
+        */
+
        /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
        clear_bit(0*32+31, &c->x86_capability);
@@ -1185,13 +1202,13 @@ static int __init init_amd(struct cpuinfo_x86 *c)
                                if(mbytes>508)
                                        mbytes=508;
                                        
-                               rdmsr(0xC0000082, l, h);
+                               rdmsr(MSR_K6_WHCR, l, h);
                                if ((l&0x0000FFFF)==0) {
                                        unsigned long flags;
                                        l=(1<<0)|((mbytes/4)<<1);
                                        local_irq_save(flags);
-                                       __asm__ __volatile__ ("wbinvd": : :"memory");
-                                       wrmsr(0xC0000082, l, h);
+                                       wbinvd();
+                                       wrmsr(MSR_K6_WHCR, l, h);
                                        local_irq_restore(flags);
                                        printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
                                                mbytes);
@@ -1206,13 +1223,13 @@ static int __init init_amd(struct cpuinfo_x86 *c)
                                if(mbytes>4092)
                                        mbytes=4092;
 
-                               rdmsr(0xC0000082, l, h);
+                               rdmsr(MSR_K6_WHCR, l, h);
                                if ((l&0xFFFF0000)==0) {
                                        unsigned long flags;
                                        l=((mbytes>>2)<<22)|(1<<16);
                                        local_irq_save(flags);
-                                       __asm__ __volatile__ ("wbinvd": : :"memory");
-                                       wrmsr(0xC0000082, l, h);
+                                       wbinvd();
+                                       wrmsr(MSR_K6_WHCR, l, h);
                                        local_irq_restore(flags);
                                        printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
                                                mbytes);
@@ -1226,10 +1243,10 @@ static int __init init_amd(struct cpuinfo_x86 *c)
                                        set_bit(X86_FEATURE_K6_MTRR, &c->x86_capability);
                                break;
                        }
-
                        break;
 
                case 6: /* An Athlon/Duron. We can trust the BIOS probably */
+                       mcheck_init(c);
                        break;          
        }
 
@@ -1312,9 +1329,10 @@ extern void calibrate_delay(void) __init;
 
 static void __init check_cx686_slop(struct cpuinfo_x86 *c)
 {
+       unsigned long flags;
+
        if (Cx86_dir0_msb == 3) {
                unsigned char ccr3, ccr5;
-               unsigned long flags;
 
                local_irq_save(flags);
                ccr3 = getCx86(CX86_CCR3);
@@ -1551,14 +1569,12 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
                                name="??";
                        }
 
-                       /* get FCR  */
-                       rdmsr(0x107, lo, hi);
-
+                       rdmsr(MSR_IDT_FCR1, lo, hi);
                        newlo=(lo|fcr_set) & (~fcr_clr);
 
                        if (newlo!=lo) {
                                printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo );
-                               wrmsr(0x107, newlo, hi );
+                               wrmsr(MSR_IDT_FCR1, newlo, hi );
                        } else {
                                printk(KERN_INFO "Centaur FCR is 0x%X\n",lo);
                        }
@@ -1577,14 +1593,15 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
                                c->x86_cache_size = (cc>>24)+(dd>>24);
                        }
                        sprintf( c->x86_model_id, "WinChip %s", name );
+                       mcheck_init(c);
                        break;
 
                case 6:
                        switch (c->x86_model) {
                                case 6 ... 7:           /* Cyrix III or C3 */
-                                       rdmsr (0x1107, lo, hi);
+                                       rdmsr (MSR_VIA_FCR, lo, hi);
                                        lo |= (1<<1 | 1<<7);    /* Report CX8 & enable PGE */
-                                       wrmsr (0x1107, lo, hi);
+                                       wrmsr (MSR_VIA_FCR, lo, hi);
 
                                        set_bit(X86_FEATURE_CX8, &c->x86_capability);
                                        set_bit(X86_FEATURE_3DNOW, &c->x86_capability);
@@ -1595,7 +1612,6 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
                        }
                        break;
        }
-
 }
 
 
@@ -1668,7 +1684,6 @@ static void __init init_rise(struct cpuinfo_x86 *c)
        if (c->x86_model > 2)
                printk(" II");
        printk("\n");
-       printk("If you have one of these please email davej@suse.de\n");
 
        /* Unhide possibly hidden capability flags
           The mp6 iDragon family don't have MSRs.
@@ -1694,7 +1709,6 @@ static void __init init_intel(struct cpuinfo_x86 *c)
 #ifndef CONFIG_M686
        static int f00f_workaround_enabled = 0;
 #endif
-       extern void mcheck_init(struct cpuinfo_x86 *c);
        char *p = NULL;
        unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 
@@ -1989,9 +2003,9 @@ static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
            disable_x86_serial_nr ) {
                /* Disable processor serial number */
                unsigned long lo,hi;
-               rdmsr(0x119,lo,hi);
+               rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
                lo |= 0x200000;
-               wrmsr(0x119,lo,hi);
+               wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
                printk(KERN_NOTICE "CPU serial number disabled.\n");
                clear_bit(X86_FEATURE_PN, &c->x86_capability);
 
index 9402aaaff8b0fbb084ca99b8cd162268157ffa5c..3490c0c54cda928c03136327b5e96e3c5c74d826 100644 (file)
@@ -770,6 +770,8 @@ static struct ioctl32_list ioctl32_handler_table[] = {
        IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
        IOCTL32_DEFAULT(BLKELVGET),
        IOCTL32_DEFAULT(BLKELVSET),
+       IOCTL32_DEFAULT(BLKBSZGET),
+       IOCTL32_DEFAULT(BLKBSZSET),
 
 #ifdef CONFIG_MD
        /* status */
index 0f47bd29c6ea5296d5b2ac0baa88a0fbbd2b98d4..1d3702d21fe34737f5906dd8902bbf290e4e86de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.chrp_setup.c 1.32 08/20/01 22:58:32 paulus
+ * BK Id: SCCS/s.chrp_setup.c 1.34 08/29/01 10:07:29 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -78,7 +78,6 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
                           char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
-extern int pckbd_rate(struct kbd_repeat *rep);
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 extern void select_adb_keyboard(void);
@@ -546,7 +545,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.kbd_translate     = pckbd_translate;
        ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
        ppc_md.kbd_leds          = pckbd_leds;
-       ppc_md.kbd_rate_fn       = pckbd_rate;
        ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
        ppc_md.ppc_kbd_sysrq_xlate       = pckbd_sysrq_xlate;
index e038a6f2102937f0d4d3868ed7760f3e03fbb5c7..dfdcd728d2323ae7b13b2f76ab33588d28f4d733 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.head_8xx.S 1.19 08/16/01 23:00:17 paulus
+ * BK Id: SCCS/s.head_8xx.S 1.21 08/28/01 16:27:27 trini
  */
 /*
  *  arch/ppc/kernel/except_8xx.S
@@ -823,8 +823,8 @@ initial_mmu:
        mtspr   DC_CST, r8
        lis     r8, IDC_ENABLE@h
        mtspr   DC_CST, r8
-       blr
 #endif
+       blr
 
 
 /*
index 0d72073c58e5f18c353da45781f4a801e13cb278..cd2a265d4b4e86ffe97d34d406be15f63d54fa4b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.pmac_setup.c 1.35 08/20/01 22:37:37 paulus
+ * BK Id: SCCS/s.pmac_setup.c 1.37 08/29/01 10:07:29 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -728,7 +728,6 @@ select_adb_keyboard(void)
        ppc_md.kbd_setkeycode    = 0;
        ppc_md.kbd_getkeycode    = 0;
        ppc_md.kbd_leds          = 0;
-       ppc_md.kbd_rate_fn       = 0;
 #ifdef CONFIG_MAGIC_SYSRQ
 #ifdef CONFIG_MAC_ADBKEYCODES
        if (!keyboard_sends_linux_keycodes) {
@@ -747,7 +746,6 @@ select_adb_keyboard(void)
        ppc_md.kbd_translate        = mackbd_translate;
        ppc_md.kbd_unexpected_up    = mackbd_unexpected_up;
        ppc_md.kbd_leds             = mackbd_leds;
-       ppc_md.kbd_rate_fn          = NULL;
        ppc_md.kbd_init_hw          = mackbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
        ppc_md.ppc_kbd_sysrq_xlate  = mackbd_sysrq_xlate;
index 9ee811f21f9a26dbdd8fcdc4c37709afcb9537e2..feb7db27386f2b04562cd87cfd488910186eb0c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.prep_setup.c 1.32 08/20/01 15:06:15 paulus
+ * BK Id: SCCS/s.prep_setup.c 1.34 08/29/01 10:07:29 paulus
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -89,7 +89,6 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
                           char raw_mode);
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
-extern int pckbd_rate(struct kbd_repeat *rep);
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 
@@ -955,7 +954,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.kbd_translate     = pckbd_translate;
        ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
        ppc_md.kbd_leds          = pckbd_leds;
-       ppc_md.kbd_rate_fn       = pckbd_rate;
        ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
        ppc_md.ppc_kbd_sysrq_xlate       = pckbd_sysrq_xlate;
index 85548b4d41dfdf90d654e7a30497e2d9b974adc2..21e02899a5fafed2199f789de924d456dc4fabba 100644 (file)
@@ -3691,6 +3691,8 @@ COMPATIBLE_IOCTL(BLKRASET)
 COMPATIBLE_IOCTL(BLKFRASET)
 COMPATIBLE_IOCTL(BLKSECTSET)
 COMPATIBLE_IOCTL(BLKSSZGET)
+COMPATIBLE_IOCTL(BLKBSZGET)
+COMPATIBLE_IOCTL(BLKBSZSET)
 
 /* RAID */
 COMPATIBLE_IOCTL(RAID_VERSION)
index 4d8d34811047bdad38d31d86ec95f741e2610d5d..8c62e903addf807ab169302de2cfae6a5d3ea27a 100644 (file)
@@ -39,7 +39,6 @@
 #define BREAKPOINT3
 #define disable() __cli()
 #define enable()  __sti()
-#define wbinvd()
 
 /*! [Begin] no source code translation */
 
 #define disable() __cli()
 #define enable()  __sti()
 #define halt()    __asm__ __volatile__ ("sti; hlt":::"memory")
-#define wbinvd()
 
 /*! [Begin] no source code translation
  *
index fb39eb06a4540d508cab50eb5825faa5ceb86cf2..f510b00e2c2633a5f1c8c1bb537d80ac6ee3b56f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
+#include <linux/blkpg.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/locks.h>
@@ -5094,21 +5095,12 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
                                                 .nr_sects,
                      (long *) Argument);
     case BLKRAGET:
-      /* Get Read-Ahead. */
-      if ((long *) Argument == NULL) return -EINVAL;
-      return put_user(read_ahead[MAJOR(Inode->i_rdev)], (long *) Argument);
     case BLKRASET:
-      /* Set Read-Ahead. */
-      if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-      if (Argument > 256) return -EINVAL;
-      read_ahead[MAJOR(Inode->i_rdev)] = Argument;
-      return 0;
     case BLKFLSBUF:
-      /* Flush Buffers. */
-      if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-      fsync_dev(Inode->i_rdev);
-      invalidate_buffers(Inode->i_rdev);
-      return 0;
+    case BLKBSZGET:
+    case BLKBSZSET:
+      return blk_ioctl (Inode->i_rdev, Request, Argument);
+
     case BLKRRPART:
       /* Re-Read Partition Table. */
       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
index 68240f8731e5ce15e0b854407ae02a75733875bc..43f42cb659174f2bbf7e737492c6b6ab53416318 100644 (file)
@@ -274,6 +274,29 @@ int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
                        return blkelvset_ioctl(&blk_get_queue(dev)->elevator,
                                               (blkelv_ioctl_arg_t *) arg);
 
+               case BLKBSZGET:
+                       /* get the logical block size (cf. BLKSSZGET) */
+                       intval = BLOCK_SIZE;
+                       if (blksize_size[MAJOR(dev)])
+                               intval = blksize_size[MAJOR(dev)][MINOR(dev)];
+                       return put_user (intval, (int *) arg);
+
+               case BLKBSZSET:
+                       /* set the logical block size */
+                       if (!capable (CAP_SYS_ADMIN))
+                               return -EACCES;
+                       if (!dev || !arg)
+                               return -EINVAL;
+                       if (get_user (intval, (int *) arg))
+                               return -EFAULT;
+                       if (intval > PAGE_SIZE || intval < 512 ||
+                           (intval & (intval - 1)))
+                               return -EINVAL;
+                       if (is_mounted (dev) || is_swap_partition (dev))
+                               return -EBUSY;
+                       set_blocksize (dev, intval);
+                       return 0;
+
                default:
                        return -EINVAL;
        }
index 800debe3b4165b956f4d3fa7382dad35788686a2..0c1a044f41725b5aa52dcb3fdf90be3c30d68041 100644 (file)
@@ -406,6 +406,8 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
        case BLKRRPART:
                return revalidate_logvol(inode->i_rdev, 1);
        case BLKFLSBUF:
+       case BLKBSZSET:
+       case BLKBSZGET:
        case BLKROSET:
        case BLKROGET:
        case BLKRASET:
index 340dc7e65ee6e458b839d9c72d58d9993d071eb7..dc2287324a7e5fa8a1a4269dd88606bd5acd314c 100644 (file)
@@ -1266,6 +1266,8 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
        }       
 
        case BLKFLSBUF:
+       case BLKBSZSET:
+       case BLKBSZGET:
        case BLKROSET:
        case BLKROGET:
        case BLKRASET:
index 26d06cd8177a246a4ba625bd8f0adacff9365050..8b4d168a5dec6b9acc9806073a5a4692d761eff1 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/major.h>
 #include <linux/wait.h>
 #include <linux/blk.h>
+#include <linux/blkpg.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/smp_lock.h>
@@ -854,6 +855,10 @@ static int lo_ioctl(struct inode * inode, struct file * file,
                }
                err = put_user(loop_sizes[lo->lo_number] << 1, (long *) arg);
                break;
+       case BLKBSZGET:
+       case BLKBSZSET:
+               err = blk_ioctl(inode->i_rdev, cmd, arg);
+               break;
        default:
                err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
        }
index 0fdeccda15263a103cd005a39a5be54067b94f79..3050ba13cd7ace429b3c84ea291fedcfd6ab4953 100644 (file)
@@ -1127,6 +1127,8 @@ static int ps2esdi_ioctl(struct inode *inode,
                case BLKRASET:
                case BLKRAGET:
                case BLKFLSBUF:
+               case BLKBSZGET:
+               case BLKBSZSET:
                case BLKPG:
                        return blk_ioctl(inode->i_rdev, cmd, arg);
                }
index aaf5fd51d804d9213851f82e62265106d40dafce..4a1b3fce70a29b6e9dc508621cf4ce7448de920c 100644 (file)
@@ -2788,6 +2788,8 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                case BLKPG:
                case BLKELVGET:
                case BLKELVSET:
+               case BLKBSZGET:
+               case BLKBSZSET:
                        return blk_ioctl(inode->i_rdev, cmd, arg);
 
                case HDIO_GET_BUSSTATE:
index 6451d2ed63162cb5e48ced07373740558ba07078..55465e4b7f8963bc84c5a3098a5e820bb9d53e83 100644 (file)
@@ -15,7 +15,7 @@ O_TARGET      := macintosh.o
 
 # Objects that export symbols.
 
-export-objs    := adb.o rtc.o mac_hid.o
+export-objs    := adb.o rtc.o mac_hid.o via-pmu.o
 
 # Object file lists.
 
index 6e7cff42614d6948e09da3d27e66b360630e6d26..504167fe5166a9a72d0fa7a3adb379ec220609aa 100644 (file)
 #include <linux/pmu.h>
 #include <linux/cuda.h>
 #include <linux/smp_lock.h>
+#include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/init.h>
 #include <asm/irq.h>
 #include <asm/hardirq.h>
 #include <asm/feature.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
+#include <asm/cputable.h>
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
 
 /* Some compile options */
 #undef SUSPEND_USES_PMU
+#define DEBUG_SLEEP
 
 /* Misc minor number allocated for /dev/pmu */
 #define PMU_MINOR      154
@@ -102,13 +107,11 @@ static volatile enum pmu_state {
 static struct adb_request *current_req;
 static struct adb_request *last_req;
 static struct adb_request *req_awaiting_reply;
-static unsigned char interrupt_data[256]; /* Made bigger: I've been told that might happen */
+static unsigned char interrupt_data[32];
 static unsigned char *reply_ptr;
 static int data_index;
 static int data_len;
 static volatile int adb_int_pending;
-static int pmu_adb_flags;
-static int adb_dev_map = 0;
 static struct adb_request bright_req_1, bright_req_2, bright_req_3;
 static struct device_node *vias;
 static int pmu_kind = PMU_UNKNOWN;
@@ -118,11 +121,20 @@ static unsigned char *gpio_reg = NULL;
 static int gpio_irq = -1;
 static volatile int pmu_suspended = 0;
 static spinlock_t pmu_lock;
+static u8 pmu_intr_mask;
+static int pmu_version;
+static int drop_interrupts;
+#ifdef CONFIG_PMAC_PBOOK
+static int sleep_in_progress;
+#endif /* CONFIG_PMAC_PBOOK */
 
 int asleep;
 struct notifier_block *sleep_notifier_list;
 
 #ifdef CONFIG_ADB
+static int adb_dev_map = 0;
+static int pmu_adb_flags;
+
 static int pmu_probe(void);
 static int pmu_init(void);
 static int pmu_send_request(struct adb_request *req, int sync);
@@ -163,8 +175,25 @@ struct adb_driver via_pmu_driver = {
 #endif /* CONFIG_ADB */
 
 extern void low_sleep_handler(void);
-extern void sleep_save_intrs(int);
-extern void sleep_restore_intrs(void);
+extern void pmac_sleep_save_intrs(int);
+extern void pmac_sleep_restore_intrs(void);
+extern void openpic_sleep_save_intrs(void);
+extern void openpic_sleep_restore_intrs(void);
+extern void enable_kernel_altivec(void);
+extern void enable_kernel_fp(void);
+
+#ifdef DEBUG_SLEEP
+int pmu_polled_request(struct adb_request *req);
+int pmu_wink(struct adb_request *req);
+#endif
+
+#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM)
+static int generic_notify_sleep(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier generic_sleep_notifier = {
+       generic_notify_sleep,
+       SLEEP_LEVEL_MISC,
+};
+#endif /* defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM) */
 
 /*
  * This table indicates for each PMU opcode:
@@ -246,6 +275,11 @@ find_via_pmu()
 
        pmu_has_adb = 1;
 
+       pmu_intr_mask = PMU_INT_PCEJECT |
+                       PMU_INT_SNDBRT |
+                       PMU_INT_ADB |
+                       PMU_INT_TICK;
+       
        if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
            || device_is_compatible(vias->parent, "ohare")))
                pmu_kind = PMU_OHARE_BASED;
@@ -258,7 +292,12 @@ find_via_pmu()
 
                pmu_kind = PMU_KEYLARGO_BASED;
                pmu_has_adb = (find_type_devices("adb") != NULL);
-
+               pmu_intr_mask = PMU_INT_PCEJECT |
+                               PMU_INT_SNDBRT |
+                               PMU_INT_ADB |
+                               PMU_INT_TICK |
+                               PMU_INT_ENVIRONMENT;
+               
                gpiop = find_devices("gpio");
                if (gpiop && gpiop->n_addrs) {
                        gpio_reg = ioremap(gpiop->addrs->address, 0x10);
@@ -281,11 +320,16 @@ find_via_pmu()
                return 0;
        }
 
-       printk(KERN_INFO "PMU driver initialized for %s\n",
-              pbook_type[pmu_kind]);
+       printk(KERN_INFO "PMU driver %d initialized for %s, firmware: %02x\n",
+              PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version);
               
        sys_ctrler = SYS_CTRLER_PMU;
        
+#if defined(CONFIG_PMAC_PBOOK) && defined(CONFIG_PM)
+       pmu_register_sleep_notifier(&generic_sleep_notifier);
+       pm_active = 1;
+#endif 
+
        return 1;
 }
 
@@ -367,7 +411,7 @@ init_pmu()
        out_8(&via[B], via[B] | TREQ);                  /* negate TREQ */
        out_8(&via[DIRB], (via[DIRB] | TREQ) & ~TACK);  /* TACK in, TREQ out */
 
-       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
        timeout =  100000;
        while (!req.complete) {
                if (--timeout < 0) {
@@ -392,13 +436,20 @@ init_pmu()
                udelay(10);
        }
 
-       /* Tell PMU we are ready. Which PMU support this ? */
+       /* Tell PMU we are ready.  */
        if (pmu_kind == PMU_KEYLARGO_BASED) {
                pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
                while (!req.complete)
                        pmu_poll();
        }
-               
+
+       /* Read PMU version */
+       pmu_request(&req, NULL, 1, PMU_GET_VERSION);
+       while (!req.complete)
+               pmu_poll();
+       if (req.reply_len > 1)
+               pmu_version = req.reply[1];
+
        return 1;
 }
 
@@ -529,7 +580,7 @@ pmu_adb_reset_bus(void)
        req.done = NULL;
        req.data[0] = PMU_ADB_CMD;
        req.data[1] = 0;
-       req.data[2] = ADB_BUSRESET; /* 3 ??? */
+       req.data[2] = ADB_BUSRESET;
        req.data[3] = 0;
        req.data[4] = 0;
        req.reply_len = 0;
@@ -759,7 +810,7 @@ pmu_resume(void)
        }
        adb_int_pending = 1;
 #ifdef SUSPEND_USES_PMU
-       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
        spin_unlock_irqrestore(&pmu_lock, flags);
        while(!req.complete)
                pmu_poll();
@@ -789,16 +840,11 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
                               "intr=%x pmu_state=%d\n", intr, pmu_state);
                        break;
                }
+               out_8(&via[IFR], intr);
                if (intr & SR_INT)
                        pmu_sr_intr(regs);
-               else if (intr & CB1_INT) {
+               else if (intr & CB1_INT)
                        adb_int_pending = 1;
-                       out_8(&via[IFR], CB1_INT);
-               }
-               intr &= ~(SR_INT | CB1_INT);
-               if (intr != 0) {
-                       out_8(&via[IFR], intr);
-               }
        }
        /* This is not necessary except if synchronous ADB requests are done
         * with interrupts off, which should not happen. Since I'm not sure
@@ -846,23 +892,17 @@ pmu_sr_intr(struct pt_regs *regs)
                out_8(&via[IFR], SR_INT);
                return;
        }
-       /* This one seems to appear with PMU99. According to OF methods,
-        * the protocol didn't change...
-        */
-       if (via[B] & TACK) {
-               while ((in_8(&via[B]) & TACK) != 0)
+       /* The ack may not yet be low when we get the interrupt */
+       while ((in_8(&via[B]) & TACK) != 0)
                        ;
-       }
-
-       /* reset TREQ and wait for TACK to go high */
-       out_8(&via[B], in_8(&via[B]) | TREQ);
-       wait_for_ack();
 
        /* if reading grab the byte, and reset the interrupt */
        if (pmu_state == reading || pmu_state == reading_intr)
                bite = in_8(&via[SR]);
 
-       out_8(&via[IFR], SR_INT);
+       /* reset TREQ and wait for TACK to go high */
+       out_8(&via[B], in_8(&via[B]) | TREQ);
+       wait_for_ack();
 
        switch (pmu_state) {
        case sending:
@@ -909,9 +949,8 @@ pmu_sr_intr(struct pt_regs *regs)
                if (data_len == -1) {
                        data_len = bite;
                        if (bite > 32)
-                               printk(KERN_ERR "PMU: bad reply len %d\n",
-                                      bite);
-               } else {
+                               printk(KERN_ERR "PMU: bad reply len %d\n", bite);
+               } else if (data_index < 32) {
                        reply_ptr[data_index++] = bite;
                }
                if (data_index < data_len) {
@@ -954,11 +993,14 @@ static void __openfirmware
 pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
 {
        asleep = 0;
-       if (len < 1) {
-//             xmon_printk("empty ADB\n");
+       if (drop_interrupts || len < 1) {
                adb_int_pending = 0;
                return;
        }
+       /* Note: for some reason, we get an interrupt with len=1,
+        * data[0]==0 after each normal ADB interrupt, at least
+        * on the Pismo. Still investigating...  --BenH
+        */
        if (data[0] & PMU_INT_ADB) {
                if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
                        struct adb_request *req = req_awaiting_reply;
@@ -1085,10 +1127,14 @@ pmu_restart(void)
 
        cli();
 
-       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
-                                       PMU_INT_TICK );
-       while(!req.complete)
-               pmu_poll();
+       drop_interrupts = 1;
+       
+       if (pmu_kind != PMU_KEYLARGO_BASED) {
+               pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
+                                               PMU_INT_TICK );
+               while(!req.complete)
+                       pmu_poll();
+       }
 
        pmu_request(&req, NULL, 1, PMU_RESET);
        while(!req.complete || (pmu_state != idle))
@@ -1104,10 +1150,14 @@ pmu_shutdown(void)
 
        cli();
 
-       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
-                                       PMU_INT_TICK );
-       while(!req.complete)
-               pmu_poll();
+       drop_interrupts = 1;
+
+       if (pmu_kind != PMU_KEYLARGO_BASED) {
+               pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
+                                               PMU_INT_TICK );
+               while(!req.complete)
+                       pmu_poll();
+       }
 
        pmu_request(&req, NULL, 5, PMU_SHUTDOWN,
                    'M', 'A', 'T', 'T');
@@ -1127,6 +1177,22 @@ pmu_present(void)
 
 static LIST_HEAD(sleep_notifiers);
 
+#ifdef CONFIG_PM
+static int
+generic_notify_sleep(struct pmu_sleep_notifier *self, int when)
+{
+       switch (when) {
+               case PBOOK_SLEEP_NOW:
+                       if (pm_send_all(PM_SUSPEND, (void *)3))
+                               return PBOOK_SLEEP_REJECT;
+                       break;
+               case PBOOK_WAKE:
+                       (void) pm_send_all(PM_RESUME, (void *)0);
+       }
+       return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PM */
+
 int
 pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
 {
@@ -1268,23 +1334,42 @@ pbook_pci_restore(void)
        }
 }
 
-#if 0
+#ifdef DEBUG_SLEEP
 /* N.B. This doesn't work on the 3400 */
-void pmu_blink(int n)
+void
+pmu_blink(int n)
 {
        struct adb_request req;
 
+       memset(&req, 0, sizeof(req));
+
        for (; n > 0; --n) {
-               pmu_request(&req, NULL, 4, 0xee, 4, 0, 1);
-               while (!req.complete) pmu_poll();
-               udelay(50000);
-               pmu_request(&req, NULL, 4, 0xee, 4, 0, 0);
-               while (!req.complete) pmu_poll();
-               udelay(50000);
+               req.nbytes = 4;
+               req.done = NULL;
+               req.data[0] = 0xee;
+               req.data[1] = 4;
+               req.data[2] = 0;
+               req.data[3] = 1;
+               req.reply[0] = ADB_RET_OK;
+               req.reply_len = 1;
+               req.reply_expected = 0;
+               pmu_polled_request(&req);
+               mdelay(50);
+               req.nbytes = 4;
+               req.done = NULL;
+               req.data[0] = 0xee;
+               req.data[1] = 4;
+               req.data[2] = 0;
+               req.data[3] = 0;
+               req.reply[0] = ADB_RET_OK;
+               req.reply_len = 1;
+               req.reply_expected = 0;
+               pmu_polled_request(&req);
+               mdelay(50);
        }
-       udelay(150000);
+       mdelay(50);
 }
-#endif
+#endif /* DEBUG_SLEEP */
 
 /*
  * Put the powerbook to sleep.
@@ -1317,7 +1402,6 @@ static void restore_via_state(void)
        out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
 }
 
-#define FEATURE_CTRL(base)     ((unsigned int *)(base + 0x38))
 #define        GRACKLE_PM      (1<<7)
 #define GRACKLE_DOZE   (1<<5)
 #define        GRACKLE_NAP     (1<<4)
@@ -1363,7 +1447,8 @@ int __openfirmware powerbook_sleep_G3(void)
                mb();
 
        /* Wait for completion of async backlight requests */
-       while (!bright_req_1.complete || !bright_req_2.complete || !bright_req_3.complete)
+       while (!bright_req_1.complete || !bright_req_2.complete ||
+               !bright_req_3.complete)
                pmu_poll();
        
        /* Turn off various things. Darwin does some retry tests here... */
@@ -1375,8 +1460,8 @@ int __openfirmware powerbook_sleep_G3(void)
        while (!req.complete)
                pmu_poll();
 
-       /* Disable all interrupts except pmu */
-       sleep_save_intrs(vias->intrs[0].line);
+       /* Disable all interrupts */
+       pmac_sleep_save_intrs(-1);
 
        /* Make sure the PMU is idle */
        while (pmu_state != idle)
@@ -1393,6 +1478,9 @@ int __openfirmware powerbook_sleep_G3(void)
        if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
                giveup_fpu(current);
 
+       /* We can now disable MSR_EE */
+       cli();
+
        /* For 750, save backside cache setting and disable it */
        save_l2cr = _get_L2CR();        /* (returns 0 if not 750) */
        if (save_l2cr)
@@ -1431,7 +1519,7 @@ int __openfirmware powerbook_sleep_G3(void)
                _set_L2CR(save_l2cr);
        
        /* Restore userland MMU context */
-       set_context(current->mm->context);
+       set_context(current->active_mm->context, current->active_mm->pgd);
 
        /* Re-enable DEC interrupts and kick DEC */
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
@@ -1464,26 +1552,29 @@ int __openfirmware powerbook_sleep_G3(void)
        }
 
        /* reenable interrupt controller */
-       sleep_restore_intrs();
+       pmac_sleep_restore_intrs();
 
        /* Leave some time for HW to settle down */
        mdelay(100);
 
        /* Notify drivers */
-       mdelay(10);
        broadcast_wake();
 
        return 0;
 }
 
-/* Not finished yet */
 int __openfirmware powerbook_sleep_Core99(void)
 {
-       int ret;
        unsigned long save_l2cr;
        unsigned long wait;
        struct adb_request req;
-
+       int ret, timeout;
+       
+       if (!feature_can_sleep()) {
+               printk(KERN_ERR "Sleep mode not supported on this machine\n");
+               return -ENOSYS;
+       }
+       
        /* Notify device drivers */
        ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
        if (ret != PBOOK_SLEEP_OK) {
@@ -1507,81 +1598,140 @@ int __openfirmware powerbook_sleep_Core99(void)
        }
 
        /* Give the disks a little time to actually finish writing */
-       for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
+       for (wait = jiffies + HZ; time_before(jiffies, wait); )
                mb();
 
+       /* Wait for completion of async backlight requests */
+       while (!bright_req_1.complete || !bright_req_2.complete ||
+               !bright_req_3.complete)
+               pmu_poll();
+
        /* Tell PMU what events will wake us up */
        pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
                0xff, 0xff);
        while (!req.complete)
                pmu_poll();
+
        pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_SET_WAKEUP_EVENTS,
                0, PMU_PWR_WAKEUP_KEY | PMU_PWR_WAKEUP_LID_OPEN);
        while (!req.complete)
                pmu_poll();
                
-       /* Disable all interrupts except pmu */
-       sleep_save_intrs(vias->intrs[0].line);
+       /* Save & disable all interrupts */
+       openpic_sleep_save_intrs();
+
+       /* Make sure the PMU is idle */
+       while (pmu_state != idle)
+               pmu_poll();
 
        /* Make sure the decrementer won't interrupt us */
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
+       /* Make sure any pending DEC interrupt occuring while we did
+        * the above didn't re-enable the DEC */
+       mb();
+       asm volatile("mtdec %0" : : "r" (0x7fffffff));
 
-       /* Save the state of PCI config space for some slots */
-       pbook_pci_save();
+       /* Giveup the FPU & vec */
+       enable_kernel_fp();
 
-       feature_prepare_for_sleep();
+#ifdef CONFIG_ALTIVEC
+       if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
+               enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+       /* We can now disable MSR_EE */
+       cli();
 
        /* For 750, save backside cache setting and disable it */
        save_l2cr = _get_L2CR();        /* (returns 0 if not 750) */
        if (save_l2cr)
-               _set_L2CR(0);
+               _set_L2CR(save_l2cr & 0x7fffffff);
 
-       if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
-               giveup_fpu(current);
+       /* Save the state of PCI config space for some slots */
+       //pbook_pci_save();
 
        /* Ask the PMU to put us to sleep */
        pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
-       while (!req.complete)
-               mb();
-
-       cli();
-       while (pmu_state != idle)
+       while (!req.complete && pmu_state != idle)
                pmu_poll();
 
-       /* Call low-level ASM sleep handler */
-       low_sleep_handler();
+       out_8(&via[B], in_8(&via[B]) | TREQ);
+       wait_for_ack();
 
-       /* Make sure the PMU is idle */
-       while (pmu_state != idle)
-               pmu_poll();
+       /* The VIA is supposed not to be restored correctly*/
+       save_via_state();
 
-       sti();
+       /* Shut down various ASICs. There's a chance that we can no longer
+        * talk to the PMU after this, so I moved it to _after_ sending the
+        * sleep command to it. Still need to be checked.
+        */
+       feature_prepare_for_sleep();
 
+       /* Call low-level ASM sleep handler */
+       low_sleep_handler();
+
+       /* Restore Apple core ASICs state */
        feature_wake_up();
-       pbook_pci_restore();
 
-       set_context(current->mm->context);
+       /* Restore VIA */
+       restore_via_state();
+
+       /* Restore PCI config space. This should be overridable by PCI device
+        * drivers as some of them may need special restore code. That's yet
+        * another issue that should be handled by the common code properly,
+        * maybe one day ?
+        */
+       /* Don't restore PCI for now, it crashes. Maybe unnecessary on pbook */
+       //pbook_pci_restore();
 
+       pmu_blink(2);
+               
        /* Restore L2 cache */
        if (save_l2cr)
-               _set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
+               _set_L2CR(save_l2cr);
+       
+       /* Restore userland MMU context */
+       set_context(current->active_mm->context, current->active_mm->pgd);
 
-       /* reenable interrupts */
-       sleep_restore_intrs();
+       /* Re-enable DEC interrupts and kick DEC */
+       asm volatile("mtdec %0" : : "r" (0x7fffffff));
+       sti();
+       asm volatile("mtdec %0" : : "r" (0x10000000));
 
        /* Tell PMU we are ready */
        pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+       while (!req.complete)
+               pmu_poll();
+       pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
        while (!req.complete)
                pmu_poll();
                
+       /* ack all pending interrupts */
+       timeout = 100000;
+       interrupt_data[0] = 1;
+       while (interrupt_data[0] || pmu_state != idle) {
+               if (--timeout < 0)
+                       break;
+               if (pmu_state == idle)
+                       adb_int_pending = 1;
+               via_pmu_interrupt(0, 0, 0);
+               udelay(10);
+       }
+
+       /* reenable interrupt controller */
+       openpic_sleep_restore_intrs();
+
+       /* Leave some time for HW to settle down */
+       mdelay(100);
+
        /* Notify drivers */
-       mdelay(10);
        broadcast_wake();
 
        return 0;
 }
 
-#define PB3400_MEM_CTRL                ((unsigned int *)0xf8000070)
+#define PB3400_MEM_CTRL                0xf8000000
+#define PB3400_MEM_CTRL_SLEEP  0x70
 
 int __openfirmware powerbook_sleep_3400(void)
 {
@@ -1590,6 +1740,16 @@ int __openfirmware powerbook_sleep_3400(void)
        unsigned int hid0;
        unsigned long p, wait;
        struct adb_request sleep_req;
+       char *mem_ctrl;
+       unsigned int *mem_ctrl_sleep;
+
+       /* first map in the memory controller registers */
+       mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
+       if (mem_ctrl == NULL) {
+               printk("powerbook_sleep_3400: ioremap failed\n");
+               return -ENOMEM;
+       }
+       mem_ctrl_sleep = (unsigned int *) (mem_ctrl + PB3400_MEM_CTRL_SLEEP);
 
        /* Notify device drivers */
        ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
@@ -1617,11 +1777,20 @@ int __openfirmware powerbook_sleep_3400(void)
        for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
                mb();
 
+       /* Wait for completion of async backlight requests */
+       while (!bright_req_1.complete || !bright_req_2.complete ||
+               !bright_req_3.complete)
+               pmu_poll();
+
        /* Disable all interrupts except pmu */
-       sleep_save_intrs(vias->intrs[0].line);
+       pmac_sleep_save_intrs(vias->intrs[0].line);
 
        /* Make sure the decrementer won't interrupt us */
        asm volatile("mtdec %0" : : "r" (0x7fffffff));
+       /* Make sure any pending DEC interrupt occuring while we did
+        * the above didn't re-enable the DEC */
+       mb();
+       asm volatile("mtdec %0" : : "r" (0x7fffffff));
 
        /* Save the state of PCI config space for some slots */
        pbook_pci_save();
@@ -1629,9 +1798,9 @@ int __openfirmware powerbook_sleep_3400(void)
        /* Set the memory controller to keep the memory refreshed
           while we're asleep */
        for (i = 0x403f; i >= 0x4000; --i) {
-               out_be32(PB3400_MEM_CTRL, i);
+               out_be32(mem_ctrl_sleep, i);
                do {
-                       x = (in_be32(PB3400_MEM_CTRL) >> 16) & 0x3ff;
+                       x = (in_be32(mem_ctrl_sleep) >> 16) & 0x3ff;
                } while (x == 0);
                if (x >= 0x100)
                        break;
@@ -1651,32 +1820,36 @@ int __openfirmware powerbook_sleep_3400(void)
        asm volatile("mfspr %0,1008" : "=r" (hid0) :);
        hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
        asm volatile("mtspr 1008,%0" : : "r" (hid0));
-       save_flags(msr);
-       msr |= MSR_POW | MSR_EE;
-       restore_flags(msr);
+       _nmask_and_or_msr(0, MSR_POW | MSR_EE);
        udelay(10);
 
        /* OK, we're awake again, start restoring things */
-       out_be32(PB3400_MEM_CTRL, 0x3f);
+       out_be32(mem_ctrl_sleep, 0x3f);
        pbook_pci_restore();
 
        /* wait for the PMU interrupt sequence to complete */
        while (asleep)
                mb();
 
+       /* Re-enable DEC interrupts and kick DEC */
+       asm volatile("mtdec %0" : : "r" (0x7fffffff));
+       sti();
+       asm volatile("mtdec %0" : : "r" (0x10000000));
+
        /* reenable interrupts */
-       sleep_restore_intrs();
+       pmac_sleep_restore_intrs();
 
        /* Notify drivers */
        broadcast_wake();
 
+       iounmap(mem_ctrl);
        return 0;
 }
 
 /*
  * Support for /dev/pmu device
  */
-#define RB_SIZE                10
+#define RB_SIZE                0x10
 struct pmu_private {
        struct list_head list;
        int     rb_get;
@@ -1830,6 +2003,11 @@ static int pmu_ioctl(struct inode * inode, struct file *filp,
 
        switch (cmd) {
        case PMU_IOC_SLEEP:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EACCES;
+               if (sleep_in_progress)
+                       return -EBUSY;
+               sleep_in_progress = 1;
                switch (pmu_kind) {
                case PMU_OHARE_BASED:
                        error = powerbook_sleep_3400();
@@ -1838,20 +2016,24 @@ static int pmu_ioctl(struct inode * inode, struct file *filp,
                case PMU_PADDINGTON_BASED:
                        error = powerbook_sleep_G3();
                        break;
-#if 0 /* Not ready yet */
                case PMU_KEYLARGO_BASED:
                        error = powerbook_sleep_Core99();
                        break;
-#endif                 
                default:
                        error = -ENOSYS;
                }
+               sleep_in_progress = 0;
                return error;
+       case PMU_IOC_CAN_SLEEP:
+               return put_user(feature_can_sleep(), (__u32 *)arg);
+
 #ifdef CONFIG_PMAC_BACKLIGHT
        /* Backlight should have its own device or go via
         * the fbdev
         */
        case PMU_IOC_GET_BACKLIGHT:
+               if (sleep_in_progress)
+                       return -EBUSY;
                error = get_backlight_level();
                if (error < 0)
                        return error;
@@ -1859,6 +2041,8 @@ static int pmu_ioctl(struct inode * inode, struct file *filp,
        case PMU_IOC_SET_BACKLIGHT:
        {
                __u32 value;
+               if (sleep_in_progress)
+                       return -EBUSY;
                error = get_user(value, (__u32 *)arg);
                if (!error)
                        error = set_backlight_level(value);
@@ -1893,7 +2077,7 @@ void pmu_device_init(void)
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
-#if 0
+#ifdef DEBUG_SLEEP
 static inline void polled_handshake(volatile unsigned char *via)
 {
        via[B] &= ~TREQ; eieio();
@@ -1939,6 +2123,8 @@ pmu_polled_request(struct adb_request *req)
        while (pmu_state != idle)
                pmu_poll();
 
+       while ((via[B] & TACK) == 0)
+               ;
        polled_send_byte(v, c);
        if (l < 0) {
                l = req->nbytes - 1;
@@ -1959,4 +2145,15 @@ pmu_polled_request(struct adb_request *req)
        restore_flags(flags);
        return 0;
 }
-#endif /* 0 */
+#endif /* DEBUG_SLEEP */
+
+EXPORT_SYMBOL(pmu_request);
+EXPORT_SYMBOL(pmu_poll);
+EXPORT_SYMBOL(pmu_suspend);
+EXPORT_SYMBOL(pmu_resume);
+#ifdef CONFIG_PMAC_PBOOK
+EXPORT_SYMBOL(pmu_register_sleep_notifier);
+EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
+EXPORT_SYMBOL(pmu_enable_irled);
+#endif /* CONFIG_PMAC_PBOOK */
+
index 3a4daf75543d09a96df33fff9ee1937218a13fb4..5b97e8c61911372be20b25c10c30f3cb8a4d6cbe 100644 (file)
@@ -921,17 +921,19 @@ static int write_disk_sb(mdk_rdev_t * rdev)
        dev = rdev->dev;
        sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
        if (rdev->sb_offset != sb_offset) {
-               printk("%s's sb offset has changed from %ld to %ld, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
+               printk("%s's sb offset has changed from %ld to %ld, skipping\n",
+                      partition_name(dev), rdev->sb_offset, sb_offset);
                goto skip;
        }
        /*
         * If the disk went offline meanwhile and it's just a spare, then
-        * it's size has changed to zero silently, and the MD code does
+        * its size has changed to zero silently, and the MD code does
         * not yet know that it's faulty.
         */
        size = calc_dev_size(dev, rdev->mddev, 1);
        if (size != rdev->size) {
-               printk("%s's size has changed from %ld to %ld since import, skipping\n", partition_name(dev), rdev->size, size);
+               printk("%s's size has changed from %ld to %ld since import, skipping\n",
+                      partition_name(dev), rdev->size, size);
                goto skip;
        }
 
@@ -2488,27 +2490,14 @@ static int md_ioctl (struct inode *inode, struct file *file,
                                                (long *) arg);
                        goto done;
 
-               case BLKFLSBUF:
-                       fsync_dev(dev);
-                       invalidate_buffers(dev);
-                       goto done;
-
+               case BLKRAGET:
                case BLKRASET:
-                       if (arg > 0xff) {
-                               err = -EINVAL;
-                               goto abort;
-                       }
-                       read_ahead[MAJOR(dev)] = arg;
-                       goto done;
+               case BLKFLSBUF:
+               case BLKBSZGET:
+               case BLKBSZSET:
+                       err = blk_ioctl (dev, cmd, arg);
+                       goto abort;
 
-               case BLKRAGET:
-                       if (!arg) {
-                               err = -EINVAL;
-                               goto abort;
-                       }
-                       err = md_put_user (read_ahead[
-                               MAJOR(dev)], (long *) arg);
-                       goto done;
                default:;
        }
 
index bceacf91017c825a471ab37a441cb3b5c26161ec..41fb53ca07c2b06acc7f0d9b867287dd912c0107 100644 (file)
@@ -162,7 +162,7 @@ static struct raid1_bh *raid1_alloc_r1bh(raid1_conf_t *conf)
                        conf->freer1 = r1_bh->next_r1;
                        conf->freer1_cnt--;
                        r1_bh->next_r1 = NULL;
-                       r1_bh->state = 0;
+                       r1_bh->state = (1 << R1BH_PreAlloc);
                        r1_bh->bh_req.b_state = 0;
                }
                md_spin_unlock_irq(&conf->device_lock);
index b37fa410cfeb14a0af2d03491785fe78dede8e00..dea26603a4710a0888f14f2de7255426514c6aaa 100644 (file)
@@ -135,8 +135,9 @@ int __init macsonic_init(struct net_device* dev)
                unsigned long desc_base, desc_top;
                if ((lp->sonic_desc = 
                     kmalloc(SIZEOF_SONIC_DESC
-                            * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_DMA)) == NULL) {
+                            * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_KERNEL | GFP_DMA)) == NULL) {
                        printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
+                       return -ENOMEM;
                }
                desc_base = (unsigned long) lp->sonic_desc;
                desc_top = desc_base + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode);
@@ -165,7 +166,7 @@ int __init macsonic_init(struct net_device* dev)
 
        /* FIXME, maybe we should use skbs */
        if ((lp->rba = (char *)
-            kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_DMA)) == NULL) {
+            kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
                printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
                return -ENOMEM;
        }
index bd559edd79824228b7bf95f1b786d8baad9b6167..60bd3f33695f591448cea8f6762479be4e27340a 100644 (file)
@@ -348,7 +348,7 @@ void inline try_get_rx_skb(struct dscc4_dev_priv *priv, int cur, struct net_devi
 {
        struct sk_buff *skb;
 
-       skb = dev_alloc_skb(RX_MAX(dev->mtu+2));
+       skb = dev_alloc_skb(RX_MAX(HDLC_MAX_MRU+2));
        priv->rx_skbuff[cur] = skb;
        if (!skb) {
                priv->rx_fd[cur--].data = (u32) NULL;
@@ -428,9 +428,9 @@ static __inline__ void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, int cur,
        int pkt_len;
 
        skb = dpriv->rx_skbuff[cur];
-       pkt_len = TO_SIZE(rx_fd->state2);
-       pci_dma_sync_single(pdev, rx_fd->data, pkt_len, PCI_DMA_FROMDEVICE);
-       if((skb->data[pkt_len - 1] & FrameOk) == FrameOk) {
+       pkt_len = TO_SIZE(rx_fd->state2) - 1;
+       pci_dma_sync_single(pdev, rx_fd->data, pkt_len + 1, PCI_DMA_FROMDEVICE);
+       if((skb->data[pkt_len] & FrameOk) == FrameOk) {
                pci_unmap_single(pdev, rx_fd->data, skb->len, PCI_DMA_FROMDEVICE);
                dpriv->stats.rx_packets++;
                dpriv->stats.rx_bytes += pkt_len;
@@ -442,11 +442,11 @@ static __inline__ void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, int cur,
                        netif_rx(skb);
                try_get_rx_skb(dpriv, cur, dev);
        } else {
-               if(skb->data[pkt_len - 1] & FrameRdo)
+               if(skb->data[pkt_len] & FrameRdo)
                        dpriv->stats.rx_fifo_errors++;
-               else if(!(skb->data[pkt_len - 1] | ~FrameCrc))
+               else if(!(skb->data[pkt_len] | ~FrameCrc))
                        dpriv->stats.rx_crc_errors++;
-               else if(!(skb->data[pkt_len - 1] | ~FrameVfr))
+               else if(!(skb->data[pkt_len] | ~FrameVfr))
                        dpriv->stats.rx_length_errors++;
                else
                        dpriv->stats.rx_errors++;
@@ -760,7 +760,7 @@ static int dscc4_open(struct net_device *dev)
        /* FIXME: VIS */
        writel(readl(ioaddr + CCR0) | 0x80001000, ioaddr + CCR0);
 
-       writel(LengthCheck | (dev->mtu >> 5), ioaddr + RLCR);
+       writel(LengthCheck | (HDLC_MAX_MRU >> 5), ioaddr + RLCR);
 
        /* no address recognition/crc-CCITT/cts enabled */
        writel(readl(ioaddr + CCR1) | 0x021c8000, ioaddr + CCR1);
@@ -1224,7 +1224,7 @@ try:
                       dev->name, SOURCE_ID(state), state );
                return;
        }
-       if (state & 0x0df80c01) {
+       if (state & 0x0df80c00) {
                printk(KERN_DEBUG "%s (Tx): state=%08x (UFO alert)\n",
                       dev->name, state);
                return;
@@ -1377,7 +1377,7 @@ try:
                       dev->name, SOURCE_ID(state), state);
                goto try;
        }
-       if (state & 0x0df80c01) {
+       if (state & 0x0df80c00) {
                printk(KERN_DEBUG "%s (Rx): state=%08x (UFO alert)\n",
                       dev->name, state);
                goto try;
@@ -1609,7 +1609,7 @@ static int dscc4_init_ring(struct net_device *dev)
                rx_fd->state1 = HiDesc; /* Hi, no Hold */
                rx_fd->state2 = 0x00000000;
                rx_fd->end = 0xbabeface;
-               rx_fd->state1 |= ((u32)(dev->mtu & RxSizeMax)) << 16;
+               rx_fd->state1 |= ((u32)(HDLC_MAX_MRU & RxSizeMax)) << 16;
                try_get_rx_skb(dpriv, i, dev);
                i++;
                rx_fd->next = (u32)(dpriv->rx_fd_dma + i*sizeof(struct RxFD));
@@ -1720,7 +1720,7 @@ static int dscc4_attach_hdlc_device(struct net_device *dev)
        hdlc = &dpriv->hdlc;
        /* XXX: Don't look at the next line */
        hdlc->netdev.base_addr = (unsigned long)dev;
-       // FIXME: set hdlc->set_mode ?
+       hdlc->set_mode = NULL;
        hdlc->open = dscc4_hdlc_open;
        hdlc->close = dscc4_hdlc_close;
        hdlc->ioctl = dscc4_hdlc_ioctl;
index a8b1377f51605276651d67cdf1cc6070f7298e4e..f8fcbe5b5a038fe35a6c8874d73a44e0b41064f8 100644 (file)
@@ -307,8 +307,8 @@ pci_set_power_state(struct pci_dev *dev, int state)
 
 /**
  * pci_save_state - save the PCI configuration space of a device before suspending
- * @dev - PCI device that we're dealing with
- * @buffer - buffer to hold config space context
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - buffer to hold config space context
  *
  * @buffer must be large enough to hold the entire PCI 2.2 config space 
  * (>= 64 bytes).
@@ -327,8 +327,8 @@ pci_save_state(struct pci_dev *dev, u32 *buffer)
 
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
- * @dev - PCI device that we're dealing with
- * @buffer - saved PCI config space
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - saved PCI config space
  *
  */
 int 
@@ -489,6 +489,7 @@ void pci_release_regions(struct pci_dev *pdev)
 /**
  *     pci_request_regions - Reserved PCI I/O and memory resources
  *     @pdev: PCI device whose resources are to be reserved
+ *     @res_name: Name to be associated with resource.
  *
  *     Mark all PCI regions associated with PCI device @pdev as
  *     being reserved by owner @res_name.  Do not access any
index 6303192b2b8109c2a101117e4e9a8ac808ec3335..c72c4ca43b0f95550953ce44b404ef9c9476dafd 100644 (file)
@@ -702,6 +702,12 @@ static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
        u32 start, end;
        u32 align, size, min, max;
        unsigned offset;
+       unsigned mask;
+
+       /* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
+       mask = ~0xfff;
+       if (type & IORESOURCE_IO)
+               mask = ~3;
 
        offset = 0x1c + 8*nr;
        bus = socket->dev->subordinate;
@@ -715,8 +721,8 @@ static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
        if (!root)
                return;
 
-       start = config_readl(socket, offset);
-       end = config_readl(socket, offset+4) | 0xfff;
+       start = config_readl(socket, offset) & mask;
+       end = config_readl(socket, offset+4) | ~mask;
        if (start && end > start) {
                res->start = start;
                res->end = end;
index 57f1817c1443ac0002e93a42064d2af3667222c7..0e1e0ab1f8d633afe29c9293f270287957387e5d 100644 (file)
@@ -238,8 +238,10 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
                case BLKFLSBUF:
                case BLKSSZGET:
                case BLKPG:
-                case BLKELVGET:
-                case BLKELVSET:
+               case BLKELVGET:
+               case BLKELVSET:
+               case BLKBSZGET:
+               case BLKBSZSET:
                        return blk_ioctl(inode->i_rdev, cmd, arg);
 
                case BLKRRPART: /* Re-read partition tables */
index e085396c7fc9a345eb772c6a028c27afcdf0bed5..d2c623a50e9de6493bec31bb0125f633c7b262f0 100644 (file)
@@ -64,7 +64,6 @@ comment 'USB Controllers'
    dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
 
    comment 'USB Network adaptors'
-   dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB CATC NetMate-based Ethernet driver (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
index 3789e22a08ba258bcb388358f54b849d741faae1..ddb549b0c34682febc62b6797a19a1a9cc9013cb 100644 (file)
@@ -60,7 +60,6 @@ obj-$(CONFIG_USB_DC2XX)               += dc2xx.o
 obj-$(CONFIG_USB_MDC800)       += mdc800.o
 obj-$(CONFIG_USB_USS720)       += uss720.o
 obj-$(CONFIG_USB_DABUSB)       += dabusb.o
-obj-$(CONFIG_USB_PLUSB)                += plusb.o
 obj-$(CONFIG_USB_OV511)                += ov511.o
 obj-$(CONFIG_USB_SE401)                += se401.o
 obj-$(CONFIG_USB_PEGASUS)      += pegasus.o
diff --git a/drivers/usb/plusb.c b/drivers/usb/plusb.c
deleted file mode 100644 (file)
index 6d92d5d..0000000
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      plusb.c  --  prolific pl-2301/pl-2302 driver.
- *
- *      Copyright (C) 2000  Deti Fliegl (deti@fliegl.de)
- *      Copyright (C) 2000  Pavel Machek (pavel@suse.cz)
- *      Copyright (C) 2000  Eric Z. Ayers (eric@compgen.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- *  This driver creates a network interface (plusb0, plusb1, ...) that will
- *  send messages over a USB host-host cable based on the Prolific ASIC.
- *  It works a lot like plip or PP over an RS-232C null modem cable.
- *
- *  Expect speeds of around 330Kbytes/second over a UHCI host controller.
- *  OHCI should be faster.  Increase the MTU for faster transfers of large
- *  files (up-to 800Kbytes/second).  (16384 is a good size)
- *
- *  $Id: plusb.c,v 1.18 2000/02/14 10:38:58 fliegl Exp $
- *
- *  Changelog:
- *
- *    v0.1                deti
- *        Original Version of driver.
- *    v0.2     15 Sep 2000  pavel
- *        Patches to decrease latency by rescheduling the bottom half of
- *          interrupt code.
- *    v0.3     10 Oct 2000  eric
- *        Patches to work in v2.2 backport (v2.4 changes the way net_dev.name
- *          is allocated)
- *    v0.4     19 Oct 2000  eric
- *        Some more performance fixes.  Lock re-submitting urbs.
- *          Lower the number of sk_buff's to queue.
- *    v0.5     25 Oct 2000 eric
- *        Removed use of usb_bulk_msg() all together.  This caused
- *          the driver to block in an interrupt context.
- *        Consolidate read urb submission into read_urb_submit().
- *        Performance is the same as v0.4.
- *    v0.5.1   27 Oct 2000 eric
- *        Extra debugging messages to help diagnose problem with uchi.o stack.
- *    v0.5.2   27 Oct 2000 eric
- *        Set the 'start' flag for the network device in plusb_net_start()
- *         and plusb_net_stop() (doesn't help)
- *    v0.5.3   27 Oct 2000 pavel
- *        Commented out handlers when -EPIPE is received,
- *         (remove calls to usb_clear_halt()) Since the callback is in
- *         an interrupt context, it doesn't help, it just panics
- *         the kernel. (what do we do?)
- *        Under high load, dev_alloc_skb() fails, the read URB must
- *         be re-submitted.
- *        Added plusb_change_mtu() and increased the size of _BULK_DATA_LEN
- *    v0.5.4   31 Oct 2000 eric
- *        Fix race between plusb_net_xmit() and plusb_bulk_write_complete()
- *    v0.5.5    1 Nov 2000 eric
- *        Remove dev->start field, otherwise, it won't compile in 2.4
- *        Use dev_kfree_skb_any(). (important in 2.4 kernel)
- *    v0.5.6   2 Nov 2000 pavel,eric
- *        Add calls to netif_stop_queue() and netif_start_queue()
- *        Drop packets that come in while the free list is empty.
- *        (This version is being submitted after the release of 2.4-test10)
- *    v0.5.7   6 Nov 2000
- *        Fix to not re-submit the urb on error to help when cables
- *          are yanked (not tested)
- *
- *
- * KNOWN PROBLEMS: (Any suggestions greatfully accepted!)
- *
- *     2 Nov 2000
- *      - The shutdown for this may not be entirely clean.  Sometimes, the
- *         kernel will Oops when the cable is unplugged, or
- *         if the plusb module is removed.
- *      - If you ifdown a device and then ifup it again, the link will not
- *         always work.  You have to 'rmmod plusb ; modprobe plusb' on
- *         both machines to get it to work again.  Something must be wrong with
- *         plusb_net_open() and plusb_net_start() ?  Maybe
- *         the 'suspend' and 'resume' entry points need to be
- *         implemented?
- *      - Needs to handle -EPIPE correctly in bulk complete handlers.
- *         (replace usb_clear_halt() function with async urbs?)
- *      - I think this code relies too much on one spinlock and does
- *         too much in the interrupt handler.  The net1080 code is
- *         much more elegant, and should work for this chip.  Its
- *         only drawback is that it is going to be tough to backport
- *         it to v2.2.
- *      - Occasionally the device will hang under the 'uhci.o'
- *         driver.   The workaround is to ifdown the device and
- *         remove the modules, then re-insert them.  You may have
- *         better luck with the 'usb-uhci.o' driver.
- *      - After using ifconfig down ; ifconfig up, sometimes packets
- *         continue to be received, but there is a framing problem.
- *
- * FUTURE DIRECTIONS:
- *
- *     - Fix the known problems.
- *     - There isn't much functional difference between the net1080
- *        driver and this one.  It would be neat if the same driver
- *        could handle both types of chips.  Or if both drivers
- *        could handle both types of chips - this one is easier to
- *        backport to the 2.2 kernel.
- *     - Get rid of plusb_add_buf_tail and the single spinlock.
- *        Use a separate spinlock for the 2 lists, and use atomic
- *        operators for writeurb_submitted and readurb_submitted members.
- *
- *
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/socket.h>
-#include <linux/miscdevice.h>
-#include <linux/list.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-//#define DEBUG 1
-#include <linux/usb.h>
-
-#if (LINUX_VERSION_CODE < 0x020300)
-#define dev_kfree_skb_any dev_kfree_skb
-#endif
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.5.7"
-#define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de"
-#define DRIVER_DESC "PL-2302 USB Interface Driver for Linux (c)2000"
-
-/* Definitions formerly in plusb.h relocated. No need to export them -EZA */
-
-#define _PLUSB_INTPIPE         0x1
-#define _PLUSB_BULKOUTPIPE     0x2
-#define _PLUSB_BULKINPIPE      0x3
-
-#define _SKB_NUM               32
-
-/* increase size of BULK_DATA_LEN so we can use bigger MTU's*/
-#define _BULK_DATA_LEN         32768
-
-
-typedef struct
-{
-       int connected;   /* indicates if this structure is active */
-       struct usb_device *usbdev;
-                                        /* keep track of USB structure */
-       int status;      /* Prolific status byte returned from interrupt */
-       int in_bh;       /* flag to indicate that we are in the bulk handler */
-       int opened;      /* flag to indicate that network dev is open    */
-
-       spinlock_t lock; /* Lock for the buffer list. re-used for
-                                               locking around submitting the readurb member.
-                                        */
-       urb_t *inturb;   /* Read buffer for the interrupt callback */
-       unsigned char *         interrupt_in_buffer;
-                        /* holds data for the inturb*/
-       urb_t *readurb;  /* Read buffer for the bulk data callback */
-       unsigned char *         bulk_in_buffer;
-                                        /* kmalloc'ed data for the readurb */
-       int readurb_submitted;
-                                        /* Flag to indicate that readurb already sent */
-       urb_t *writeurb; /* Write buffer for the bulk data callback */
-       int writeurb_submitted;
-                                        /* Flag to indicate that writeurb already sent */
-       
-       struct list_head tx_skb_list;
-                                        /* sk_buff's read from net device */
-       struct list_head free_skb_list;
-                                       /* free sk_buff list */
-       struct net_device net_dev;
-                                       /* handle to linux network device */
-       struct net_device_stats net_stats;
-                                       /* stats to return for ifconfig output */
-} plusb_t,*pplusb_t;
-
-/*
- * skb_list - queue of packets from the network driver to be delivered to USB
- */
-typedef struct
-{
-       struct list_head skb_list;
-       struct sk_buff *skb;
-       int state;
-       plusb_t *s;
-} skb_list_t,*pskb_list_t;
-
-
-/* --------------------------------------------------------------------- */
-
-#define NRPLUSB 4
-
-/*
- * Interrupt endpoint status byte, from Prolific PL-2301 docs
- * Check the 'download' link at www.prolifictech.com
- */
-#define _PL_INT_RES1    0x80 /* reserved              */
-#define _PL_INT_RES2    0x40 /* reserved              */
-#define _PL_INT_RXD    _PL_INT_RES2  /* Read data ready - Not documented by Prolific, but seems to work! */
-#define _PL_INT_TX_RDY 0x20 /* OK to transmit data   */
-#define _PL_INT_RESET_O        0x10 /* reset output pipe     */
-#define _PL_INT_RESET_I 0x08 /* reset input pipe      */
-#define _PL_INT_TX_C    0x04 /* transmission complete */
-#define _PL_INT_TX_REQ  0x02 /* transmission received */
-#define _PL_INT_PEER_E  0x01 /* peer exists           */
-
-/*-------------------------------------------------------------------*/
-
-static plusb_t plusb[NRPLUSB];
-
-static void plusb_write_bulk_complete(urb_t *purb);
-static void plusb_read_bulk_complete(urb_t *purb);
-static void plusb_int_complete(urb_t *purb);
-
-/* --------------------------------------------------------------------- */
-
-/*
- * plusb_add_buf_tail - Take the head of the src list and append it to
- *                      the tail of the dest list
- */
-static int plusb_add_buf_tail (plusb_t *s, struct list_head *dst, struct list_head *src)
-{
-       unsigned long flags = 0;
-       struct list_head *tmp;
-       int ret = 0;
-
-       spin_lock_irqsave (&s->lock, flags);
-
-       if (list_empty (src)) {
-               // no elements in source buffer
-               ret = -1;
-               goto err;
-       }
-       tmp = src->next;
-       list_del (tmp);
-       list_add_tail (tmp, dst);
-
-  err: spin_unlock_irqrestore (&s->lock, flags);
-       return ret;
-}
-/*-------------------------------------------------------------------*/
-
-/*
- * dequeue_next_skb - submit the first thing on the tx_skb_list to the
- * USB stack.  This function should be called each time we get a new
- * message to send to the other host, or each time a message is successfully
- * sent.
- */
-static void dequeue_next_skb(char * func, plusb_t * s)
-{
-       skb_list_t * skb_list;
-       unsigned long flags = 0;
-
-       if (!s->connected)
-               return;
-       
-       spin_lock_irqsave (&s->lock, flags);
-       
-       if (!list_empty (&s->tx_skb_list) && !s->writeurb_submitted) {
-               int submit_ret;
-               skb_list = list_entry (s->tx_skb_list.next, skb_list_t, skb_list);
-
-               if (skb_list->skb) {
-                       s->writeurb_submitted = 1;
-               
-                       /* Use the buffer inside the sk_buff directly. why copy? */
-                       FILL_BULK_URB_TO(s->writeurb, s->usbdev,
-                                                        usb_sndbulkpipe(s->usbdev, _PLUSB_BULKOUTPIPE),
-                                                        skb_list->skb->data, skb_list->skb->len,
-                                                        plusb_write_bulk_complete, skb_list, 500);
-                       
-                       dbg ("%s: %s: submitting urb. skb_list %p", s->net_dev.name, func, skb_list);
-               
-                       submit_ret = usb_submit_urb(s->writeurb);
-                       if (submit_ret) {
-                               s->writeurb_submitted = 0;
-                               printk (KERN_CRIT "%s: %s: can't submit writeurb: %d\n",
-                                               s->net_dev.name, func, submit_ret);
-                       }
-               } /* end if the skb value has been filled in */
-       }
-       
-       spin_unlock_irqrestore (&s->lock, flags);       
-}
-
-/*
- * submit_read_urb - re-submit the read URB to the stack
- */
-void submit_read_urb(char * func, plusb_t * s)
-{
-       unsigned long flags=0;
-
-       if (!s->connected)
-               return;
-       
-       spin_lock_irqsave (&s->lock, flags);
-       
-       if (!s->readurb_submitted) {
-               int ret;
-               s->readurb_submitted=1;
-               s->readurb->dev=s->usbdev;
-               ret = usb_submit_urb(s->readurb);
-               if (ret) {
-                       printk (KERN_CRIT "%s: %s: error %d submitting read URB\n",
-                                  s->net_dev.name, func, ret);
-                       s->readurb_submitted=0;
-               }
-       }
-
-       spin_unlock_irqrestore (&s->lock, flags);
-       
-}
-/* --------------------------------------------------------------------- */
-
-/*
- * plusb_net_xmit - callback from the network device driver for outgoing data
- *
- * Data has arrived to the network device from the local machine and needs
- * to be sent over the USB cable.  This is in an interrupt, so we don't
- * want to spend too much time in this function.
- *
- */
-static int plusb_net_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       plusb_t *s=dev->priv;
-       skb_list_t *skb_list;
-       unsigned int flags;
-
-       dbg("plusb_net_xmit: len:%d i:%d",skb->len,in_interrupt());
-
-       if(!s->connected || !s->opened) {
-               /*
-                 NOTE: If we get to this point, you'll return the error
-                 kernel: virtual device plusb0 asks to queue packet
-
-                 Other things we could do:
-                 1) just drop this packet
-                 2) drop other packets in the queue
-               */
-               return 1;
-       }
-
-       spin_lock_irqsave (&s->lock, flags);
-
-       if  (list_empty(&s->free_skb_list)
-       || plusb_add_buf_tail (s, &s->tx_skb_list, &s->free_skb_list)) {
-               /* The buffers on this side are full. DROP the packet
-                  I think that this shouldn't happen with the correct
-                  use of the netif_XXX functions -EZA
-                */
-               dbg ("plusb: Free list is empty.");
-               kfree_skb(skb);
-               s->net_stats.tx_dropped++;
-               spin_unlock_irqrestore (&s->lock, flags);
-               return 0;
-       }
-       
-       skb_list = list_entry (s->tx_skb_list.prev, skb_list_t, skb_list);
-       skb_list->skb=skb;
-       skb_list->state=1;
-       skb_list->s=s;
-
-       if (list_empty(&s->free_skb_list)) {
-               /* apply "backpressure". Tell the net layer to stop sending
-                  the driver packets.
-               */
-               netif_stop_queue(dev);
-       }
-       
-       spin_unlock_irqrestore (&s->lock, flags);
-       
-       /* If there is no write urb outstanding, pull the first thing
-          off of the list and submit it to the USB stack
-       */
-       dequeue_next_skb("plusb_net_xmit", s);
-       
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * plusb_write_bulk_complete () - callback after the data has been
- *   sent to the USB device, or a timeout occurred.
- */
-static void plusb_write_bulk_complete(urb_t *purb)
-{
-       skb_list_t * skb_list=purb->context;
-       plusb_t *s=skb_list->s;
-
-       dbg ("%s: plusb_write_bulk_complete: status:%d skb_list:%p\n",
-                s->net_dev.name, purb->status, skb_list);
-
-       skb_list->state=0;
-
-       if( purb->status == -EPIPE )
-               printk(KERN_CRIT "%s: plusb_write_bulk_complete: got -EPIPE and don't know what to do!\n",
-                    s->net_dev.name);
-               
-       if(!purb->status) {
-               s->net_stats.tx_packets++;
-               s->net_stats.tx_bytes+=skb_list->skb->len;
-       }
-       else {
-               err ("%s: plusb_write_bulk_complete: returned ERROR status:%d\n",
-                        s->net_dev.name, purb->status);
-
-               s->net_stats.tx_errors++;
-               s->net_stats.tx_aborted_errors++;
-       }
-       
-       dbg("plusb_bh: dev_kfree_skb");
-
-       /* NOTE: In 2.4 it's a problem to call dev_kfree_skb() in a hard IRQ:
-          Oct 28 23:42:14 bug kernel: Warning: kfree_skb on hard IRQ c023329a
-       */
-       dev_kfree_skb_any(skb_list->skb);
-       
-       skb_list->skb = NULL;
-       if (plusb_add_buf_tail (s, &s->free_skb_list, &s->tx_skb_list)) {
-               err ("plusb: tx list empty. This shouldn't happen.");
-       }
-
-       purb->status = 0;
-       s->writeurb_submitted = 0;
-       
-    netif_wake_queue((&s->net_dev));
-       
-       dequeue_next_skb("plusb_write_bulk_complete", s);
-
-       
-}
-
-/*
- * plusb_read_bulk_complete - Callback for data arriving from the USB device
- *
- * This gets called back when a full 'urb' is received from the remote system.
- * This urb was allocated by this driver and is kept in the member: s->readurb
- *
- */
-static void plusb_read_bulk_complete(urb_t *purb)
-{
-       
-       plusb_t *s=purb->context;
-
-       dbg("plusb_read_bulk_complete: status:%d length:%d", purb->status,purb->actual_length);
-       
-       if(!s->connected)
-               return;
-
-       if( purb->status == -EPIPE )
-               printk(KERN_CRIT "%s: plusb_read_bulk_complete: got -EPIPE and I don't know what to do!\n",
-                    s->net_dev.name);
-       else if (!purb->status) {
-               struct sk_buff *skb;
-               unsigned char *dst;
-               int len=purb->transfer_buffer_length;
-               struct net_device_stats *stats=&s->net_stats;
-
-               skb=dev_alloc_skb(len);
-
-               if(!skb) {
-                       printk (KERN_CRIT "%s: plusb_read_bulk_complete: dev_alloc_skb(%d)=NULL, dropping frame\n", s->net_dev.name, len);
-                       stats->rx_dropped++;
-               } else {
-                       dst=(char *)skb_put(skb, len);
-                       memcpy( dst, purb->transfer_buffer, len);
-                       
-                       skb->dev=&s->net_dev;
-                       skb->protocol=eth_type_trans(skb, skb->dev);
-                       stats->rx_packets++;
-                       stats->rx_bytes+=len;
-                       netif_rx(skb);
-               }
-               
-       }
-       
-       s->readurb_submitted = 0;
-       
-       if (purb->status) {
-               /* Give the system a chance to "catch its breath". Shortcut
-                  re-submitting the read URB>  It will be re-submitted if
-                  another interrupt comes back.  The problem scenario is that
-                  the plub is pulled and the read returns an error.
-                  You don't want to resumbit in this case.
-               */
-               err ("%s: plusb_read_bulk_complete: returned status %d\n",
-                        s->net_dev.name, purb->status);
-               return;
-       }
-
-
-       purb->status=0;
-
-       /* Keep it coming! resubmit the URB for reading.. Make sure
-          we aren't in contention with the interrupt callback.
-       */
-       submit_read_urb("plusb_read_bulk_complete", s);
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * plusb_int_complete - USB driver callback for interrupt msg from the device
- *
- * Interrupts are scheduled to go off on a periodic basis (see FILL_INT_URB)
- * For the prolific device, this is basically just returning a register
- * filled with bits.  See the macro definitions for _PL_INT_XXX above.
- * Most of these bits are for implementing a machine-machine protocol
- * and can be set with a special message (described as the "Quicklink"
- * feature in the prolific documentation.)
- *
- * I don't think we need any of that to work as a network device. If a
- * message is lost, big deal - that's what UNIX networking expects from
- * the physical layer.
- *
- */
-static void plusb_int_complete(urb_t *purb)
-{
-       plusb_t *s=purb->context;
-       s->status=((unsigned char*)purb->transfer_buffer)[0]&255;
-       
-#if 0
-       /* This isn't right because 0x20 is TX_RDY and
-          sometimes will not be set
-       */
-       if((s->status&0x3f)!=0x20) {
-               warn("invalid device status %02X", s->status);
-               return;
-       }
-#endif 
-       if(!s->connected)
-               return;
-
-       /* Don't turn this on unless you want to see the log flooded. */
-#if 0
-       printk("plusb_int_complete: PEER_E:%d TX_REQ:%d TX_C:%d RESET_IN:%d RESET_O: %d TX_RDY:%d RES1:%d RES2:%d\n",
-           s->status & _PL_INT_PEER_E  ? 1 : 0,
-           s->status & _PL_INT_TX_REQ  ? 1 : 0,
-           s->status & _PL_INT_TX_C    ? 1 : 0,
-           s->status & _PL_INT_RESET_I ? 1 : 0,
-           s->status & _PL_INT_RESET_O ? 1 : 0,
-           s->status & _PL_INT_TX_RDY  ? 1 : 0,
-           s->status & _PL_INT_RES1    ? 1 : 0,
-           s->status & _PL_INT_RES2    ? 1 : 0);
-#endif
-
-#if 1
-       /* At first glance, this logic appears to not really be needed, but
-          it can help recover from intermittent problems where the
-          usb_submit_urb() fails in the read callback. -EZA
-       */
-       
-       /* Try to submit the read URB again. Make sure
-          we aren't in contention with the bulk read callback
-       */
-       submit_read_urb ("plusb_int_complete", s);
-       
-       /* While we are at it, why not check to see if the
-          write urb should be re-submitted?
-       */
-       dequeue_next_skb("plusb_int_complete", s);      
-       
-#endif
-
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * plusb_free_all - deallocate all memory kept for an instance of the device.
- */
-static void plusb_free_all(plusb_t *s)
-{
-       struct list_head *skb;
-       skb_list_t *skb_list;
-       
-       dbg("plusb_free_all");
-       
-       /* set a flag to tell all callbacks to cease and desist */
-       s->connected = 0;
-
-       /* If the interrupt handler is about to fire, let it finish up */
-       run_task_queue(&tq_immediate);  
-
-       if(s->inturb) {
-               dbg("unlink inturb");
-               usb_unlink_urb(s->inturb);
-               dbg("free_urb inturb");
-               usb_free_urb(s->inturb);
-               s->inturb=NULL;
-       }
-       
-       if(s->interrupt_in_buffer) {
-               dbg("kfree s->interrupt_in_buffer");
-               kfree(s->interrupt_in_buffer);
-               s->interrupt_in_buffer=NULL;
-       }
-
-       if(s->readurb) {
-               dbg("unlink readurb");
-               usb_unlink_urb(s->readurb);
-               dbg("free_urb readurb:");
-               usb_free_urb(s->readurb);
-               s->readurb=NULL;
-       }
-
-       if(s->bulk_in_buffer) {
-               dbg("kfree s->bulk_in_buffer");
-               kfree(s->bulk_in_buffer);
-               s->bulk_in_buffer=NULL;
-       }
-       
-       s->readurb_submitted = 0;
-       
-       if(s->writeurb) {
-               dbg("unlink writeurb");
-               usb_unlink_urb(s->writeurb);
-               dbg("free_urb writeurb:");
-               usb_free_urb(s->writeurb);
-               s->writeurb=NULL;
-       }
-
-       s->writeurb_submitted = 0;
-       
-       while(!list_empty(&s->free_skb_list)) {
-               skb=s->free_skb_list.next;
-               list_del(skb);
-               skb_list = list_entry (skb, skb_list_t, skb_list);
-               kfree(skb_list);
-       }
-
-       while(!list_empty(&s->tx_skb_list)) {
-               skb=s->tx_skb_list.next;
-               list_del(skb);
-               skb_list = list_entry (skb, skb_list_t, skb_list);
-               if (skb_list->skb) {
-                       dbg ("Freeing SKB in queue");
-                       dev_kfree_skb_any(skb_list->skb);
-                       skb_list->skb = NULL;
-               }
-               kfree(skb_list);
-       }
-       
-       s->in_bh=0;
-       
-       dbg("plusb_free_all: finished");        
-}
-
-/*-------------------------------------------------------------------*/
-/*
- * plusb_alloc - allocate memory associated with one instance of the device
- */
-static int plusb_alloc(plusb_t *s)
-{
-       int i;
-       skb_list_t *skb;
-
-       dbg("plusb_alloc");
-
-       for(i=0 ; i < _SKB_NUM ; i++) {
-               skb=kmalloc(sizeof(skb_list_t), GFP_KERNEL);
-               if(!skb) {
-                       err("kmalloc for skb_list failed");
-                       goto reject;
-               }
-               memset(skb, 0, sizeof(skb_list_t));
-               list_add(&skb->skb_list, &s->free_skb_list);
-       }
-
-       dbg("inturb allocation:");
-       s->inturb=usb_alloc_urb(0);
-       if(!s->inturb) {
-               err("alloc_urb failed");
-               goto reject;
-       }
-
-       dbg("bulk read urb allocation:");
-       s->readurb=usb_alloc_urb(0);
-       if(!s->readurb) {
-               err("alloc_urb failed");
-               goto reject;
-       }
-       
-       dbg("bulk write urb allocation:");
-       s->writeurb=usb_alloc_urb(0);
-       if(!s->writeurb) {
-               err("alloc_urb for writeurb failed");
-               goto reject;
-       }
-       
-       dbg("readurb/inturb init:");
-       s->interrupt_in_buffer=kmalloc(64, GFP_KERNEL);
-       if(!s->interrupt_in_buffer) {
-               err("kmalloc failed");
-               goto reject;
-       }
-
-       /* The original value of '10' makes this interrupt fire off a LOT.
-          It was set so low because the callback determined when to
-          sumbit the buld read URB. I've lowered it to 100 - the driver
-          doesn't depend on that logic anymore. -EZA
-       */
-       FILL_INT_URB(s->inturb, s->usbdev,
-                    usb_rcvintpipe (s->usbdev, _PLUSB_INTPIPE),
-                    s->interrupt_in_buffer, 1,
-                    plusb_int_complete, s, HZ);
-
-       dbg("inturb submission:");
-       if(usb_submit_urb(s->inturb)<0) {
-               err("usb_submit_urb failed");
-               goto reject;
-       }
-       
-       dbg("readurb init:");
-       s->bulk_in_buffer = kmalloc(_BULK_DATA_LEN, GFP_KERNEL);
-       if (!s->bulk_in_buffer) {
-               err("kmalloc %d bytes for bulk in buffer failed", _BULK_DATA_LEN);
-       }
-
-       FILL_BULK_URB(s->readurb, s->usbdev,
-                     usb_rcvbulkpipe(s->usbdev, _PLUSB_BULKINPIPE),
-                     s->bulk_in_buffer, _BULK_DATA_LEN,
-                     plusb_read_bulk_complete, s);
-
-       /* The write urb will be initialized inside the network
-          interrupt.
-       */
-
-       /* get the bulk read going */
-       submit_read_urb("plusb_alloc", s);
-
-       dbg ("plusb_alloc: finished. readurb=%p writeurb=%p inturb=%p",
-               s->readurb, s->writeurb, s->inturb);
-       
-       return 0;
-
-  reject:
-       dbg("plusb_alloc: failed");
-       
-       plusb_free_all(s);
-       return -ENOMEM;
-}
-
-/*-------------------------------------------------------------------*/
-
-static int plusb_net_open(struct net_device *dev)
-{
-       plusb_t *s=dev->priv;
-       
-       dbg("plusb_net_open");
-       
-       if(plusb_alloc(s))
-               return -ENOMEM;
-
-       s->opened=1;
-       
-       MOD_INC_USE_COUNT;
-
-       netif_start_queue(dev);
-
-       dbg("plusb_net_open: success");
-       
-       return 0;
-       
-}
-
-/* --------------------------------------------------------------------- */
-
-static int plusb_net_stop(struct net_device *dev)
-{
-       plusb_t *s=dev->priv;
-
-       netif_stop_queue(dev);
-       
-       dbg("plusb_net_stop");  
-       
-       s->opened=0;
-       plusb_free_all(s);
-
-       MOD_DEC_USE_COUNT;
-       dbg("plusb_net_stop:finished");
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static struct net_device_stats *plusb_net_get_stats(struct net_device *dev)
-{
-       plusb_t *s=dev->priv;
-       
-       dbg("net_device_stats");
-       
-       return &s->net_stats;
-}
-
-/* --------------------------------------------------------------------- */
-
-static plusb_t *plusb_find_struct (void)
-{
-       int u;
-
-       for (u = 0; u < NRPLUSB; u++) {
-               plusb_t *s = &plusb[u];
-               if (!s->connected)
-                       return s;
-       }
-       return NULL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void plusb_disconnect (struct usb_device *usbdev, void *ptr)
-{
-       plusb_t *s = ptr;
-
-       dbg("plusb_disconnect");
-       
-       plusb_free_all(s);
-
-       if(!s->opened && s->net_dev.name) {
-               dbg("unregistering netdev: %s",s->net_dev.name);
-               unregister_netdev(&s->net_dev);
-               s->net_dev.name[0] = '\0';
-#if (LINUX_VERSION_CODE < 0x020300)
-               dbg("plusb_disconnect: About to free name");
-               kfree (s->net_dev.name);
-               s->net_dev.name = NULL;
-#endif 
-       }
-       
-       dbg("plusb_disconnect: finished");
-       MOD_DEC_USE_COUNT;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int plusb_change_mtu(struct net_device *dev, int new_mtu)
-{
-       if ((new_mtu < 68) || (new_mtu > _BULK_DATA_LEN))
-               return -EINVAL;
-
-       printk("plusb: changing mtu to %d\n", new_mtu);
-       dev->mtu = new_mtu;
-       
-       /* NOTE: Could we change the size of the READ URB here dynamically
-          to save kernel memory?
-       */
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-int plusb_net_init(struct net_device *dev)
-{
-       dbg("plusb_net_init");
-       
-       dev->open=plusb_net_open;
-       dev->stop=plusb_net_stop;
-       dev->hard_start_xmit=plusb_net_xmit;
-       dev->get_stats  = plusb_net_get_stats;
-       ether_setup(dev);
-       dev->change_mtu = plusb_change_mtu;
-       /* Setting the default MTU to 16K gives good performance for
-          me, and keeps the ping latency low too.  Setting it up
-          to 32K made performance go down. -EZA
-          Pavel says it would be best not to do this...
-       */
-       /*dev->mtu=16384; */
-       dev->tx_queue_len = 0;  
-       dev->flags = IFF_POINTOPOINT|IFF_NOARP;
-
-       
-       dbg("plusb_net_init: finished");
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void *plusb_probe (struct usb_device *usbdev, unsigned int ifnum, const struct usb_device_id *id)
-{
-       plusb_t *s;
-
-       dbg("plusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
-         usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
-
-       if (usbdev->descriptor.idVendor != 0x067b || usbdev->descriptor.idProduct > 0x1)
-               return NULL;
-
-       /* We don't handle multiple configurations */
-       if (usbdev->descriptor.bNumConfigurations != 1)
-               return NULL;
-
-       s = plusb_find_struct ();
-       if (!s)
-               return NULL;
-
-       s->usbdev = usbdev;
-
-       if (usb_set_configuration (s->usbdev, usbdev->config[0].bConfigurationValue) < 0) {
-               err("set_configuration failed");
-               return NULL;
-       }
-
-       if (usb_set_interface (s->usbdev, 0, 0) < 0) {
-               err("set_interface failed");
-               return NULL;
-       }
-
-#if (LINUX_VERSION_CODE < 0x020300)
-       {
-               int i;
-               
-               /* For Kernel version 2.2, the driver is responsible for
-                  allocating this memory. For version 2.4, the rules
-                  have apparently changed, but there is a nifty function
-                  'init_netdev' that might make this easier...  It's in 
-                  ../net/net_init.c - but can we get there from here?  (no)
-                  -EZA
-               */
-               
-               /* Find the device number... we seem to have lost it... -EZA */
-               for (i=0; i<NRPLUSB; i++) {
-                       if (&plusb[i] == s)
-                               break;
-               }
-       
-               if(!s->net_dev.name) {
-                       s->net_dev.name = kmalloc(strlen("plusbXXXX"), GFP_KERNEL);
-                       sprintf (s->net_dev.name, "plusb%d", i);
-                       s->net_dev.init=plusb_net_init;
-                       s->net_dev.priv=s;
-                       
-                       printk ("plusb_probe: Registering Device\n");   
-                       if(!register_netdev(&s->net_dev))
-                               info("registered: %s", s->net_dev.name);
-                       else {
-                               err("register_netdev failed");
-                               s->net_dev.name[0] = '\0';
-                       }
-                       dbg ("plusb_probe: Connected!");
-               }
-       }
-#else
-       /* Kernel version 2.3+ works a little bit differently than 2.2 */
-       if(!s->net_dev.name[0]) {
-               strcpy(s->net_dev.name, "plusb%d");
-               s->net_dev.init=plusb_net_init;
-               s->net_dev.priv=s;
-               if(!register_netdev(&s->net_dev))
-                       info("registered: %s", s->net_dev.name);
-               else {
-                       err("register_netdev failed");
-                       s->net_dev.name[0] = '\0';
-               }
-       }
-#endif
-       
-       s->connected = 1;
-
-       if(s->opened) {
-               dbg("net device already allocated, restarting USB transfers");
-               plusb_alloc(s);
-       }
-
-       info("bound to interface: %d dev: %p", ifnum, usbdev);
-       MOD_INC_USE_COUNT;
-       return s;
-}
-/* --------------------------------------------------------------------- */
-
-static struct usb_driver plusb_driver =
-{
-       name: "plusb",
-       probe: plusb_probe,
-       disconnect: plusb_disconnect,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int __init plusb_init (void)
-{
-       unsigned u;
-       dbg("plusb_init");
-       
-       /* initialize struct */
-       for (u = 0; u < NRPLUSB; u++) {
-               plusb_t *s = &plusb[u];
-               memset (s, 0, sizeof (plusb_t));
-               INIT_LIST_HEAD (&s->tx_skb_list);
-               INIT_LIST_HEAD (&s->free_skb_list);
-               spin_lock_init (&s->lock);
-       }
-
-       /* register misc device */
-       usb_register (&plusb_driver);
-
-       dbg("plusb_init: driver registered");
-
-       info(DRIVER_VERSION ":" DRIVER_DESC);
-
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void __exit plusb_cleanup (void)
-{
-       unsigned u;
-
-       dbg("plusb_cleanup");
-       for (u = 0; u < NRPLUSB; u++) {
-               plusb_t *s = &plusb[u];
-#if (LINUX_VERSION_CODE < 0x020300)
-               if(s->net_dev.name) {
-                       dbg("unregistering netdev: %s",s->net_dev.name);
-                       unregister_netdev(&s->net_dev);
-                       s->net_dev.name[0] = '\0';
-                       kfree (s->net_dev.name);
-                       s->net_dev.name = NULL;         
-               }               
-#else
-               if(s->net_dev.name[0]) {
-                       dbg("unregistering netdev: %s",s->net_dev.name);
-                       unregister_netdev(&s->net_dev);
-                       s->net_dev.name[0] = '\0';
-               }
-#endif
-       }
-       usb_deregister (&plusb_driver);
-       dbg("plusb_cleanup: finished");
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-
-
-module_init (plusb_init);
-module_exit (plusb_cleanup);
-
-/* --------------------------------------------------------------------- */
index b8271eca56c9a8cc7d559893752272d3fee4a3dd..b691bcd059567edf3fc7c235e74a33aacf289701 100644 (file)
@@ -269,6 +269,7 @@ static int usblp_release(struct inode *inode, struct file *file)
        struct usblp *usblp = file->private_data;
 
        down (&usblp->sem);
+       lock_kernel();
        usblp->used = 0;
        if (usblp->dev) {
                if (usblp->bidir)
@@ -277,6 +278,7 @@ static int usblp_release(struct inode *inode, struct file *file)
                up(&usblp->sem);
        } else          /* finish cleanup from disconnect */
                usblp_cleanup (usblp);
+       unlock_kernel();
        return 0;
 }
 
@@ -685,11 +687,9 @@ static void usblp_disconnect(struct usb_device *dev, void *ptr)
                BUG ();
        }
 
-
        down (&usblp->sem);
        lock_kernel();
        usblp->dev = NULL;
-       unlock_kernel();
 
        usb_unlink_urb(&usblp->writeurb);
        if (usblp->bidir)
@@ -699,6 +699,7 @@ static void usblp_disconnect(struct usb_device *dev, void *ptr)
                usblp_cleanup (usblp);
        else    /* cleanup later, on close */
                up (&usblp->sem);
+       unlock_kernel();
 }
 
 static struct usb_device_id usblp_ids [] = {
index 9bacf95547fe4db2a7e785af8109e5c8d7732e81..8a6a731cfab2177c868a46407e03b08a9a77761b 100644 (file)
@@ -96,7 +96,7 @@ UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999,
 #endif
 
 /* This entry is from Andries.Brouwer@cwi.nl */
-UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0205, 
+UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
                "SCM Microsystems",
                "eUSB SmartMedia / CompactFlash Adapter",
                US_SC_SCSI, US_PR_DPCM_USB, NULL, 
index d388ac1a3a8338cc8e2632e63df2502063b82ede..3e63e5d730565ee27bbedbd660244a0918317e17 100644 (file)
@@ -33,7 +33,7 @@
 #define dac_val        (0x3c9)
 
 #define VGA_FB_PHYS 0xA0000
-#define VGA_FB_PHYS_LEN 65535
+#define VGA_FB_PHYS_LEN 65536
 
 /* --------------------------------------------------------------------- */
 
index 41265f21614f02700ff29a389dd72003b77d50c3..d704109137024c428e1c8539ef56780fc95c60d3 100644 (file)
@@ -32,6 +32,7 @@ subdir-$(CONFIG_RAMFS)                += ramfs
 subdir-$(CONFIG_CODA_FS)       += coda
 subdir-$(CONFIG_MINIX_FS)      += minix
 subdir-$(CONFIG_FAT_FS)                += fat
+subdir-$(CONFIG_UMSDOS_FS)     += umsdos
 subdir-$(CONFIG_MSDOS_FS)      += msdos
 subdir-$(CONFIG_VFAT_FS)       += vfat
 subdir-$(CONFIG_BFS_FS)                += bfs
@@ -43,7 +44,6 @@ subdir-$(CONFIG_NFS_FS)               += nfs
 subdir-$(CONFIG_NFSD)          += nfsd
 subdir-$(CONFIG_LOCKD)         += lockd
 subdir-$(CONFIG_NLS)           += nls
-subdir-$(CONFIG_UMSDOS_FS)     += umsdos
 subdir-$(CONFIG_SYSV_FS)       += sysv
 subdir-$(CONFIG_SMB_FS)                += smbfs
 subdir-$(CONFIG_NCP_FS)                += ncpfs
index 9c09891de727555380fae3e32697dec105e87d84..14643c738f6e410a7874b5541e8f12b7f88f8d3e 100644 (file)
@@ -5,18 +5,11 @@ Changes by Matija Nalis (mnalis@jagor.srce.hr) on umsdos dentry fixing
 There is no warning any more.
 Both read-only and read-write stuff is fixed, both in
 msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-There are still few hardlink nuisances, but those are not fatal.
-
-I'd call it pre-release, and ask for as many people as possible to
-come and test it! See notes below for some more information, or if
-you are trying to use UMSDOS as root partition.
 
 Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x kernels and glibc based systems may be found
-at http://cvs.linux.hr/
-
-Also look at the quick-hack "homepage" for umsdos filesystem at 
-http://www.voyager.hr/~mnalis/umsdos
+will compile and work on 2.2.x+ kernels and glibc based systems, as well as
+kernel patches and other umsdos related information may be found at
+http://linux.voyager.hr/umsdos/
 
 Information below is getting outdated slowly -- I'll fix it one day when I
 get enough time - there are more important things to fix right now.
@@ -24,7 +17,7 @@ get enough time - there are more important things to fix right now.
 Legend: those lines marked with '+' on the beggining of line indicates it
 passed all of my tests, and performed perfect in all of them.
 
-Current status (990202) - UMSDOS 0.85:
+Current status (010125) - UMSDOS 0.86j:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -35,7 +28,7 @@ READ:
 
 WRITE:
 + creat file                   - works
-+ delete file                  - works
++ unlink file                  - works
 + write file                   - works
 + rename file (same dir)       - works
 + rename file (dif. dir)       - works
@@ -66,21 +59,22 @@ READ:
 
 WRITE:
 + create symlink               - works
-- create hardlink              - works
++ create hardlink              - works
 + create file                  - works
 + create special file          - works
 + write to file                        - works
 + rename file (same dir)       - works
 + rename file (dif. dir)       - works
-- rename hardlink (same dir)   -
-- rename hardlink (dif. dir)   -
++ rename hardlink (same dir)   - works
+- rename hardlink (dif. dir)   - works, but see notes below.
 + rename symlink (same dir)    - works
 + rename symlink (dif. dir)    - works
 + rename dir (same dir)                - works
 + rename dir (dif. dir)                - works
-+ delete file                  - works
++ unlink file                  - works
 + notify_change (chown,perms)  - works
-+ delete hardlink              - works
++ notify_change for hardlinks  - works
++ unlink hardlink              - works
 + mkdir                                - works
 + rmdir                        - works
 + umssyncing (many ioctls)     - works
@@ -99,24 +93,11 @@ in filesystems that might be externally modified like umsdos. There is
 example is specs file about it. Specifically, moving directory which
 contains hardlinks will break them.
 
-Note: (about pseudoroot) If you are currently trying to use UMSDOS as root
-partition (with linux installed in c:\linux) it will boot, but there may be
-some problems. Volunteers ready to test pseudoroot are needed (preferably
-ones with working backups or unimportant data).  For example, '/DOS' pseudo
-directory is only partially re-implemented and buggy. It works most of the
-time, though. Update: should work ok in 0.84, although it still does not
-work correctly in combination with initrd featere. Working on this!
-
 Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
 pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
 versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-
-Warning: (about hardlinks) - modifying hardlinks (esp. if they are in
-different directories) are currently somewhat broken, I'm working on it.
-Problem seems to be that code uses and updates EMD of directory where 'real
-hardlink' is stored, not EMD of directory where our pseudo-hardlink is
-located! I'm looking for ideas how to work around this in clean way, since
-without it modifying hardlinks in any but most simple ways is broken!
+See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
+procedure if you used broken versions...
 
 ------------------------------------------------------------------------------
 
@@ -130,6 +111,4 @@ or panics which force you to reboot etc.)
 I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
 check for messages having "UMSDOS" in the subject, and read them.  I might
 miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.  You can try
-mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable.
-
+in few days.  If I don't, probably I never got your message.
index 50a9459b62682e5bcfc130a82d9df140806346ee..b2a140ce01271f1c061f91554b44f9f3a588df36 100644 (file)
@@ -651,13 +651,13 @@ char * umsdos_d_path(struct dentry *dentry, char * buffer, int len)
        old_root = dget(current->fs->root);
        read_unlock(&current->fs->lock);
        spin_lock(&dcache_lock);
-       path = __d_path(dentry, NULL, dentry->d_sb->s_root, NULL, buffer, len);
+       path = __d_path(dentry, current->fs->rootmnt, dentry->d_sb->s_root, current->fs->rootmnt, buffer, len); /* FIXME: current->fs->rootmnt */
        spin_unlock(&dcache_lock);
 
        if (*path == '/')
                path++; /* skip leading '/' */
 
-       if (old_root->d_inode == pseudo_root)
+       if (current->fs->root->d_inode == pseudo_root)
        {
                *(path-1) = '/';
                path -= (UMSDOS_PSDROOT_LEN+1);
index c1bf4e1dd2cee18f0d378c1fa6aea73cc10be428..51d76ca240091371aaad9b9372300fc7c5d2fa84 100644 (file)
 #include <linux/pagemap.h>
 #include <linux/delay.h>
 
-static void copy_entry(struct umsdos_dirent *p, struct umsdos_dirent *q)
+void put_entry (struct umsdos_dirent *p, struct umsdos_dirent *q)
+{
+       p->name_len = q->name_len;
+       p->flags = q->flags;
+       p->nlink = cpu_to_le16(q->nlink);
+       p->uid = cpu_to_le16(q->uid);
+       p->gid = cpu_to_le16(q->gid);
+       p->atime = cpu_to_le32(q->atime);
+       p->mtime = cpu_to_le32(q->mtime);
+       p->ctime = cpu_to_le32(q->ctime);
+       p->rdev = cpu_to_le16(q->rdev);
+       p->mode = cpu_to_le16(q->mode);
+}
+
+static void get_entry(struct umsdos_dirent *p, struct umsdos_dirent *q)
 {
        p->name_len = q->name_len;
        p->name[p->name_len]='\0';
@@ -136,6 +150,7 @@ int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_di
                printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
                p->name_len = 0; 
                ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
+               /* FIXME: does not work if we did 'ls -l' before 'udosctl uls' ?! */
        }
 
        recsize = umsdos_evalrecsize(p->name_len);
@@ -163,7 +178,7 @@ int umsdos_emd_dir_readentry (struct dentry *demd, loff_t *pos, struct umsdos_di
                page_cache_release(page2);
        } else
                memcpy(entry->spare,p->spare,((char*)p+recsize)-p->spare);
-       copy_entry(entry, p);
+       get_entry(entry, p);
        kunmap(page);
        page_cache_release(page);
        *pos += recsize;
@@ -249,16 +264,7 @@ int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
                                        offs+info->recsize-PAGE_CACHE_SIZE);
                if (ret)
                        goto out_unlock3;
-               p->name_len = entry->name_len;
-               p->flags = entry->flags;
-               p->nlink = cpu_to_le16(entry->nlink);
-               p->uid = cpu_to_le16(entry->uid);
-               p->gid = cpu_to_le16(entry->gid);
-               p->atime = cpu_to_le32(entry->atime);
-               p->mtime = cpu_to_le32(entry->mtime);
-               p->ctime = cpu_to_le32(entry->ctime);
-               p->rdev = cpu_to_le16(entry->rdev);
-               p->mode = cpu_to_le16(entry->mode);
+               put_entry (p, entry);
                memcpy(p->spare,entry->spare,
                        (char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare);
                memcpy(page_address(page2),
@@ -279,16 +285,7 @@ int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
                                        offs + info->recsize);
                if (ret)
                        goto out_unlock;
-               p->name_len = entry->name_len;
-               p->flags = entry->flags;
-               p->nlink = cpu_to_le16(entry->nlink);
-               p->uid = cpu_to_le16(entry->uid);
-               p->gid = cpu_to_le16(entry->gid);
-               p->atime = cpu_to_le32(entry->atime);
-               p->mtime = cpu_to_le32(entry->mtime);
-               p->ctime = cpu_to_le32(entry->ctime);
-               p->rdev = cpu_to_le16(entry->rdev);
-               p->mode = cpu_to_le16(entry->mode);
+               put_entry (p, entry);
                memcpy(p->spare,entry->spare,((char*)p+info->recsize)-p->spare);
                ret = mapping->a_ops->commit_write(NULL,page,offs,
                                        offs + info->recsize);
@@ -463,7 +460,7 @@ static int umsdos_find (struct dentry *demd, struct umsdos_info *info)
                        goto skip_it;
 
                info->f_pos = pos;
-               copy_entry(entry, rentry);
+               get_entry(entry, rentry);
                ret = 0;
                break;
 skip_it:
index ff765811c9f306330def28bd1bcbbac64b67f08f..9a47f8cd388e923dd1ee80b9a521573460c1965a 100644 (file)
@@ -38,7 +38,7 @@ void UMSDOS_put_inode (struct inode *inode)
                 ,atomic_read(&inode->i_count)));
 
        if (inode == pseudo_root) {
-               printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, atomic_read(&inode->i_count));
+               Printk ((KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, atomic_read(&inode->i_count)));
        }
 
        if (atomic_read(&inode->i_count) == 1)
@@ -49,7 +49,7 @@ void UMSDOS_put_inode (struct inode *inode)
 void UMSDOS_put_super (struct super_block *sb)
 {
        Printk ((KERN_DEBUG "UMSDOS_put_super: entering\n"));
-       if (saved_root) {
+       if (saved_root && pseudo_root && sb->s_dev == ROOT_DEV) {
                shrink_dcache_parent(saved_root);
                dput(saved_root);
                saved_root = NULL;
@@ -153,16 +153,56 @@ dentry, f_pos));
 }
 
 
-int umsdos_notify_change_locked(struct dentry *, struct iattr *);
 /*
  * lock the parent dir before starting ...
+ * also handles hardlink converting
  */
 int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
 {
-       struct inode *dir = dentry->d_parent->d_inode;
-       struct inode *inode = dentry->d_inode;
+       struct inode *dir, *inode;
+       struct umsdos_info info;
+       struct dentry *temp, *old_dentry = NULL;
        int ret;
 
+       ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
+                               &info);
+       if (ret)
+               goto out;
+       ret = umsdos_findentry (dentry->d_parent, &info, 0);
+       if (ret) {
+printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+               goto out;
+       }
+
+       if (info.entry.flags & UMSDOS_HLINK) {
+               /*
+                * In order to get the correct (real) inode, we just drop
+                * the original dentry.
+                */ 
+               d_drop(dentry);
+Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
+       
+               /* Do a real lookup to get the short name dentry */
+               temp = umsdos_covered(dentry->d_parent, info.fake.fname,
+                                               info.fake.len);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out;
+       
+               /* now resolve the link ... */
+               temp = umsdos_solve_hlink(temp);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out;
+               old_dentry = dentry;
+               dentry = temp;  /* so umsdos_notify_change_locked will operate on that */
+       }
+
+       dir = dentry->d_parent->d_inode;
+       inode = dentry->d_inode;
+
        ret = inode_change_ok (inode, attr);
        if (ret)
                goto out;
@@ -173,9 +213,12 @@ int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
        if (ret == 0)
                inode_setattr (inode, attr);
 out:
+       if (old_dentry)
+               dput (dentry);  /* if we had to use fake dentry for hardlinks, dput() it now */
        return ret;
 }
 
+
 /*
  * Must be called with the parent lock held.
  */
@@ -316,16 +359,16 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
        struct super_block *res;
        struct dentry *new_root;
 
-       MSDOS_SB(sb)->options.isvfat = 0;
        /*
         * Call msdos-fs to mount the disk.
         * Note: this returns res == sb or NULL
         */
        res = msdos_read_super (sb, data, silent);
+
        if (!res)
                goto out_fail;
 
-       printk (KERN_INFO "UMSDOS 0.86i "
+       printk (KERN_INFO "UMSDOS 0.86k "
                "(compatibility level %d.%d, fast msdos)\n", 
                UMSDOS_VERSION, UMSDOS_RELEASE);
 
@@ -334,6 +377,7 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
 
        /* install our dentry operations ... */
        sb->s_root->d_op = &umsdos_dentry_operations;
+
        umsdos_patch_dentry_inode(sb->s_root, 0);
 
        /* Check whether to change to the /linux root */
@@ -345,10 +389,9 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
                        printk("umsdos_read_super: pseudo-root wrong ops!\n");
 
                pseudo_root = new_root->d_inode;
-
                saved_root = sb->s_root;
-               sb->s_root = new_root;
                printk(KERN_INFO "UMSDOS: changed to alternate root\n");
+               dget (sb->s_root); sb->s_root = dget(new_root);
        }
        return sb;
 
@@ -381,10 +424,12 @@ static struct dentry *check_pseudo_root(struct super_block *sb)
        root = lookup_one_len(UMSDOS_PSDROOT_NAME, sb->s_root,UMSDOS_PSDROOT_LEN); 
        if (IS_ERR(root))
                goto out_noroot;
+               
        if (!root->d_inode || !S_ISDIR(root->d_inode->i_mode))
                goto out_dput;
 
-       printk(KERN_INFO "check_pseudo_root: found %s/%s\n", root->d_parent->d_name.name, root->d_name.name);
+printk(KERN_INFO "check_pseudo_root: found %s/%s\n",
+root->d_parent->d_name.name, root->d_name.name);
 
        /* look for /sbin/init */
        sbin = lookup_one_len("sbin", root, 4);
index e6f9c3f948077b6ac2d92ab261f5e66f847d2943..9049610da7ac0df3f4ae178b8d24e9955b3978f1 100644 (file)
@@ -405,8 +405,15 @@ static int umsdos_rename_f (struct inode *old_dir, struct dentry *old_dentry,
                goto out_unlock;
        /* make sure it's the same inode! */
        ret = -ENOENT;
-       if (old->d_inode != old_inode)
-               goto out_dput;
+       /*
+        * note: for hardlinks they will be different!
+        *  old_inode will contain inode of .LINKxxx file containing data, and
+        *  old->d_inode will contain inode of file containing path to .LINKxxx file
+        */
+       if (!(old_info.entry.flags & UMSDOS_HLINK)) {
+               if (old->d_inode != old_inode)
+                       goto out_dput;
+       }
 
        new = umsdos_covered(new_dentry->d_parent, new_info.fake.fname, 
                                        new_info.fake.len);
@@ -531,7 +538,7 @@ int UMSDOS_link (struct dentry *olddentry, struct inode *dir,
        struct umsdos_info hid_info;
 
 #ifdef UMSDOS_DEBUG_VERBOSE
-printk("umsdos_link: new %s%s -> %s/%s\n",
+printk("umsdos_link: new %s/%s -> %s/%s\n",
 dentry->d_parent->d_name.name, dentry->d_name.name, 
 olddentry->d_parent->d_name.name, olddentry->d_name.name);
 #endif
@@ -698,17 +705,36 @@ out_unlock:
        if (ret == 0) {
                struct iattr newattrs;
 
+               /* Do a real lookup to get the short name dentry */
+               temp = umsdos_covered(olddentry->d_parent,
+                                       old_info.fake.fname,
+                                       old_info.fake.len);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out_unlock2;
+
+               /* now resolve the link ... */
+               temp = umsdos_solve_hlink(temp);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out_unlock2;
+
+
 #ifdef UMSDOS_PARANOIA
 if (!oldinode->u.umsdos_i.i_is_hlink)
 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
 #endif
-               oldinode->i_nlink++;
+               temp->d_inode->i_nlink++;
 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name,
 oldinode->i_ino, oldinode->i_nlink));
                newattrs.ia_valid = 0;
-               ret = umsdos_notify_change_locked(olddentry, &newattrs);
+               ret = umsdos_notify_change_locked(temp, &newattrs);
+               if (ret == 0)
+                       mark_inode_dirty(temp->d_inode);
+               dput(temp);
+out_unlock2:   
                if (ret == 0)
                        mark_inode_dirty(olddentry->d_inode);
        }
index 192009aa56f565140e39714a37709fc56c439029..9fbca39419344662df24cd4d44b2817bcb230580 100644 (file)
@@ -111,6 +111,9 @@ struct dentry *umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int
                 */
 Printk ((KERN_DEBUG "umsdos_rlookup_x: patch_dentry_inode %s/%s\n",
 dentry->d_parent->d_name.name, dentry->d_name.name));
+/* only patch if needed (because we get called even for lookup
+   (not only rlookup) stuff sometimes, like in umsdos_covered() */
+               if (dentry->d_inode->u.umsdos_i.i_patched == 0) 
                umsdos_patch_dentry_inode(dentry, 0);
 
        }
index c99045972cf37ad636a1537924d03ba55a2a2d7b..cdedca57e80cfb6ca5070bdc840e4e2dba76855d 100644 (file)
@@ -130,7 +130,7 @@ asmlinkage void call_##x(void); \
 __asm__( \
 "\n"__ALIGN_STR"\n" \
 SYMBOL_NAME_STR(x) ":\n\t" \
-       "pushl $"#v"\n\t" \
+       "pushl $"#v"-256\n\t" \
        SAVE_ALL \
        SYMBOL_NAME_STR(call_##x)":\n\t" \
        "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
@@ -143,7 +143,7 @@ asmlinkage void call_##x(void); \
 __asm__( \
 "\n"__ALIGN_STR"\n" \
 SYMBOL_NAME_STR(x) ":\n\t" \
-       "pushl $"#v"\n\t" \
+       "pushl $"#v"-256\n\t" \
        SAVE_ALL \
        "movl %esp,%eax\n\t" \
        "pushl %eax\n\t" \
index 72bf155e92cab6f9b895d5489f2281094ff0d8a3..11bcb7f29e4216189bd0cd889ee797182ae51985 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef __ASM_MSR_H
+#define __ASM_MSR_H
+
 /*
  * Access to machine-specific registers (available on 586 and better only)
  * Note: the rd* operations modify the parameters directly (without using
@@ -5,9 +8,9 @@
  */
 
 #define rdmsr(msr,val1,val2) \
-       __asm__ __volatile__("rdmsr" \
-                           : "=a" (val1), "=d" (val2) \
-                           : "c" (msr))
+     __asm__ __volatile__("rdmsr" \
+                         : "=a" (val1), "=d" (val2) \
+                         : "c" (msr))
 
 #define wrmsr(msr,val1,val2) \
      __asm__ __volatile__("wrmsr" \
      __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
 
 #define rdtscl(low) \
-     __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
+     __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
 
 #define rdtscll(val) \
-     __asm__ __volatile__ ("rdtsc" : "=A" (val))
+     __asm__ __volatile__("rdtsc" : "=A" (val))
 
 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
 
                          : "c" (counter))
 
 /* symbolic names for some interesting MSRs */
-#define MSR_IA32_PLATFORM_ID   0x17
-#define MSR_IA32_UCODE_WRITE   0x79
-#define MSR_IA32_UCODE_REV     0x8B
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR            0
+#define MSR_IA32_P5_MC_TYPE            1
+#define MSR_IA32_PLATFORM_ID           0x17
+#define MSR_IA32_EBL_CR_POWERON                0x2a
+
+#define MSR_IA32_APICBASE              0x1b
+#define MSR_IA32_APICBASE_BSP          (1<<8)
+#define MSR_IA32_APICBASE_ENABLE       (1<<11)
+#define MSR_IA32_APICBASE_BASE         (0xfffff<<12)
+
+#define MSR_IA32_UCODE_WRITE           0x79
+#define MSR_IA32_UCODE_REV             0x8b
+
+#define MSR_IA32_PERFCTR0              0xc1
+#define MSR_IA32_PERFCTR1              0xc2
+
+#define MSR_IA32_BBL_CR_CTL            0x119
+
+#define MSR_IA32_MCG_CAP               0x179
+#define MSR_IA32_MCG_STATUS            0x17a
+#define MSR_IA32_MCG_CTL               0x17b
+
+#define MSR_IA32_EVNTSEL0              0x186
+#define MSR_IA32_EVNTSEL1              0x187
+
+#define MSR_IA32_DEBUGCTLMSR           0x1d9
+#define MSR_IA32_LASTBRANCHFROMIP      0x1db
+#define MSR_IA32_LASTBRANCHTOIP                0x1dc
+#define MSR_IA32_LASTINTFROMIP         0x1dd
+#define MSR_IA32_LASTINTTOIP           0x1de
+
+#define MSR_IA32_MC0_CTL               0x400
+#define MSR_IA32_MC0_STATUS            0x401
+#define MSR_IA32_MC0_ADDR              0x402
+#define MSR_IA32_MC0_MISC              0x403
+
+/* AMD Defined MSRs */
+#define MSR_K6_EFER                    0xC0000080
+#define MSR_K6_STAR                    0xC0000081
+#define MSR_K6_WHCR                    0xC0000082
+#define MSR_K6_UWCCR                   0xC0000085
+#define MSR_K6_PSOR                    0xC0000087
+#define MSR_K6_PFIR                    0xC0000088
+
+#define MSR_K7_EVNTSEL0                        0xC0010000
+#define MSR_K7_PERFCTR0                        0xC0010004
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1                   0x107
+#define MSR_IDT_FCR2                   0x108
+#define MSR_IDT_FCR3                   0x109
+#define MSR_IDT_FCR4                   0x10a
+
+#define MSR_IDT_MCR0                   0x110
+#define MSR_IDT_MCR1                   0x111
+#define MSR_IDT_MCR2                   0x112
+#define MSR_IDT_MCR3                   0x113
+#define MSR_IDT_MCR4                   0x114
+#define MSR_IDT_MCR5                   0x115
+#define MSR_IDT_MCR6                   0x116
+#define MSR_IDT_MCR7                   0x117
+#define MSR_IDT_MCR_CTRL               0x120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR                    0x1107
+
+#endif /* __ASM_MSR_H */
index 6f2f63a8e3d336294ce74d99dbabb83d904a77b5..932aa29c5f49822889f5c81c65348ea0eda5da33 100644 (file)
@@ -110,10 +110,23 @@ static inline unsigned long _get_base(char * addr)
 })
 #define write_cr0(x) \
        __asm__("movl %0,%%cr0": :"r" (x));
+
+#define read_cr4() ({ \
+       unsigned int __dummy; \
+       __asm__( \
+               "movl %%cr4,%0\n\t" \
+               :"=r" (__dummy)); \
+       __dummy; \
+})
+#define write_cr4(x) \
+       __asm__("movl %0,%%cr4": :"r" (x));
 #define stts() write_cr0(8 | read_cr0())
 
 #endif /* __KERNEL__ */
 
+#define wbinvd() \
+       __asm__ __volatile__ ("wbinvd": : :"memory");
+
 static inline unsigned long get_limit(unsigned long segment)
 {
        unsigned long __limit;
index 1cb3b96b471adee3e8aa7c1d423ec2cd615bda3b..97099dd0d4148355529588da12c63e01b3171db3 100644 (file)
@@ -45,4 +45,6 @@ static inline cycles_t get_cycles (void)
 #endif
 }
 
+extern unsigned long cpu_khz;
+
 #endif
index 4cc11f04d47e875a49d131b312c641f9dfc5d024..d8e414c84cb3c4061e40f550167029a98eeada59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.keyboard.h 1.11 08/29/01 10:07:29 paulus
  */
 /*
  *  linux/include/asm-ppc/keyboard.h
@@ -75,7 +75,6 @@ static inline void kbd_init_hw(void)
                ppc_md.kbd_init_hw();
 }
 
-#define kbd_rate       (ppc_md.kbd_rate_fn)
 #define kbd_sysrq_xlate        (ppc_md.ppc_kbd_sysrq_xlate)
 
 extern unsigned long SYSRQ_KEY;
index b5243504f2ca33c33c425921ca1ef0ca51091df7..af043961090867ca5bac0329d57cd998f674aec0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.kmap_types.h 1.6 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.kmap_types.h 1.9 08/29/01 14:03:05 paulus
  */
 #ifdef __KERNEL__
 #ifndef _ASM_KMAP_TYPES_H
@@ -10,6 +10,8 @@ enum km_type {
        KM_BOUNCE_WRITE,
        KM_SKB_DATA,
        KM_SKB_DATA_SOFTIRQ,
+       KM_USER0,
+       KM_USER1,
        KM_TYPE_NR
 };
 
index 2862d8c89c7bf81008808b4537de0695a1d24d7c..5f3cb66dd81cd8ef9665eab38cada196137df112 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.machdep.h 1.19 08/18/01 18:16:33 paulus
+ * BK Id: SCCS/s.machdep.h 1.21 08/29/01 10:07:29 paulus
  */
 #ifdef __KERNEL__
 #ifndef _PPC_MACHDEP_H
@@ -14,7 +14,6 @@
 struct pt_regs;
 struct pci_bus;        
 struct pci_dev;
-struct kbd_repeat;
 
 struct machdep_calls {
        void            (*setup_arch)(void);
@@ -61,7 +60,6 @@ struct machdep_calls {
                                char raw_mode);
        char            (*kbd_unexpected_up)(unsigned char keycode);
        void            (*kbd_leds)(unsigned char leds);
-       int             (*kbd_rate_fn)(struct kbd_repeat *rep);
        void            (*kbd_init_hw)(void);
 #ifdef CONFIG_MAGIC_SYSRQ
        unsigned char   *ppc_kbd_sysrq_xlate;
@@ -74,6 +72,10 @@ struct machdep_calls {
        /* Called after scanning the bus, before allocating resources */
        void (*pcibios_fixup)(void);
 
+       /* Called after PPC generic resource fixup to perform
+          machine specific fixups */
+       void (*pcibios_fixup_resources)(struct pci_dev *);
+
        /* Called for each PCI bus in the system when it's probed */
        void (*pcibios_fixup_bus)(struct pci_bus *);
 
@@ -82,6 +84,13 @@ struct machdep_calls {
         * Returns 0 to allow assignment/enabling of the device. */
        int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
 
+       /* For interrupt routing */
+       unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
+       int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
+
+       /* Called in indirect_* to avoid touching devices */
+       int (*pci_exclude_device)(unsigned char, unsigned char);
+
        /* Called at then very end of pcibios_init() */
        void (*pcibios_after_init)(void);
 
index 3388fa5bcd3a6a0ae2eae02d566198bb611f1ffc..82af4b9e8379db475e0e9cab3d3257902cff89e8 100644 (file)
@@ -6,6 +6,8 @@ enum km_type {
        KM_BOUNCE_WRITE,
        KM_SKB_DATA,
        KM_SKB_DATA_SOFTIRQ,
+       KM_USER0,
+       KM_USER1,
        KM_TYPE_NR
 };
 
index 8d70498784f5f4b6572acccfda0729de76243f0d..1a8efa4044ea54fbada6890445d62bf7679c5505 100644 (file)
@@ -182,7 +182,9 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
 /* This was here just to show that the number is taken -
    probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
 #endif
-
+/* A jump here: 108-111 have been used for various private purposes. */
+#define BLKBSZGET  _IOR(0x12,112,sizeof(int))
+#define BLKBSZSET  _IOW(0x12,113,sizeof(int))
 
 #define BMAP_IOCTL 1           /* obsolete - kept for compatibility */
 #define FIBMAP    _IO(0x00,1)  /* bmap access */
index cd1ac601af84ed21391a60fe720a89db9ba27a0e..1186ebc301a8de7ed8bf0e73ab931acd526e7ece 100644 (file)
@@ -7,6 +7,9 @@
  */
 
 #include <linux/config.h>
+
+#define PMU_DRIVER_VERSION     2
+
 /*
  * PMU commands
  */
@@ -23,6 +26,7 @@
 #define PMU_GET_VOLBUTTON      0x48    /* get volume up/down position */
 #define PMU_PCEJECT            0x4c    /* eject PC-card from slot */
 #define PMU_BATTERY_STATE      0x6b    /* report battery state etc. */
+#define PMU_SMART_BATTERY_STATE        0x6f    /* report battery state (new way) */
 #define PMU_SET_INTR_MASK      0x70    /* set PMU interrupt mask */
 #define PMU_INT_ACK            0x78    /* read interrupt bits */
 #define PMU_SHUTDOWN           0x7e    /* turn power off */
@@ -32,6 +36,7 @@
 #define PMU_GET_BRIGHTBUTTON   0xd9    /* report brightness up/down pos */
 #define PMU_GET_COVER          0xdc    /* report cover open/closed */
 #define PMU_SYSTEM_READY       0xdf    /* tell PMU we are awake */
+#define PMU_GET_VERSION                0xea    /* read the PMU version */
 
 /* Bits to use with the PMU_POWER_CTRL0 command */
 #define PMU_POW0_ON            0x80    /* OR this to power ON the device */
 #define PMU_POW_IRLED          0x04    /* IR led power (on wallstreet) */
 #define PMU_POW_MEDIABAY       0x08    /* media bay power (wallstreet/lombard ?) */
 
-
 /* Bits in PMU interrupt and interrupt mask bytes */
-#define PMU_INT_ADB_AUTO       0x04    /* ADB autopoll, when PMU_INT_ADB */
 #define PMU_INT_PCEJECT                0x04    /* PC-card eject buttons */
 #define PMU_INT_SNDBRT         0x08    /* sound/brightness up/down buttons */
 #define PMU_INT_ADB            0x10    /* ADB autopoll or reply data */
-#define PMU_INT_BATTERY                0x20
-#define PMU_INT_WAKEUP         0x40
+#define PMU_INT_BATTERY                0x20    /* Battery state change */
+#define PMU_INT_ENVIRONMENT    0x40    /* Environment interrupts */
 #define PMU_INT_TICK           0x80    /* 1-second tick interrupt */
 
+/* Other bits in PMU interrupt valid when PMU_INT_ADB is set */
+#define PMU_INT_ADB_AUTO       0x04    /* ADB autopoll, when PMU_INT_ADB */
+#define PMU_INT_WAITING_CHARGER        0x01    /* ??? */
+#define PMU_INT_AUTO_SRQ_POLL  0x02    /* ??? */
+
+/* Bits in the environement message (either obtained via PMU_GET_COVER,
+ * or via PMU_INT_ENVIRONMENT on core99 */
+#define PMU_ENV_LID_CLOSED     0x01    /* The lid is closed */
+
 /* Kind of PMU (model) */
 enum {
        PMU_UNKNOWN,
@@ -99,6 +111,8 @@ enum {
 #define PMU_IOC_GET_MODEL      _IOR('B', 3, sizeof(__u32*))
 /* out param: u32*     has_adb: 0 or 1 */
 #define PMU_IOC_HAS_ADB                _IOR('B', 4, sizeof(__u32*)) 
+/* out param: u32*     can_sleep: 0 or 1 */
+#define PMU_IOC_CAN_SLEEP      _IOR('B', 5, sizeof(__u32*)) 
 
 #ifdef __KERNEL__
 
@@ -160,7 +174,7 @@ struct pmu_sleep_notifier
 #define SLEEP_LEVEL_NET                60      /* bmac */
 #define SLEEP_LEVEL_ADB                50      /* ADB */
 #define SLEEP_LEVEL_MISC       30      /* Anything */
-#define SLEEP_LEVEL_LAST       0       /* Anything */
+#define SLEEP_LEVEL_LAST       0       /* Reserved for apm_emu */
 
 /* special register notifier functions */
 int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier);
index 09eee390b5bc33a3fead5e1830ebf95722f91ac1..b2fc5595c04bb467d8bdc5ed15d10c6a642c10cc 100644 (file)
@@ -1082,7 +1082,7 @@ skb_cow(struct sk_buff *skb, unsigned int headroom)
 /**
  *     skb_linearize - convert paged skb to linear one
  *     @skb: buffer to linarize
- *     @gfp_mask: allocation mode
+ *     @gfp: allocation mode
  *
  *     If there is no free memory -ENOMEM is returned, otherwise zero
  *     is returned and the old skb data released.  */
index 1dfb9d1b76a0cbd632ac3095d8414a5e25a875f2..e6fed11b1e0709856387d299b3f921b6a450b2de 100644 (file)
@@ -818,10 +818,12 @@ int inactive_shortage(void)
 #define GENERAL_SHORTAGE 4
 static int do_try_to_free_pages(unsigned int gfp_mask, int user)
 {
-       /* Always walk at least the active queue when called */
-       int shortage = INACTIVE_SHORTAGE;
+       int shortage = 0;
        int maxtry;
 
+       /* Always walk at least the active queue when called */
+       refill_inactive_scan(DEF_PRIORITY);
+
        maxtry = 1 << DEF_PRIORITY;
        do {
                /*
@@ -872,7 +874,8 @@ static int do_try_to_free_pages(unsigned int gfp_mask, int user)
                        break;
        } while (shortage);
 
-       return !shortage;
+       /* Return success if we're not "totally short" */
+       return shortage != (FREE_SHORTAGE | INACTIVE_SHORTAGE | GENERAL_SHORTAGE);
 }
 
 DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
index 8bc8096dede1708d5c0c54bdf740ae0c35564f46..a5a459f0b1d1f7b93bb930ac733eca54513060cc 100644 (file)
@@ -26,7 +26,7 @@ mount --version | awk -F\- '{print "mount                 ", $NF}'
 
 insmod -V  2>&1 | awk 'NR==1 {print "modutils              ",$NF}'
 
-tune2fs 2>&1 | grep tune2fs | sed 's/,//' |  awk \
+tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' |  awk \
 'NR==1 {print "e2fsprogs             ", $2}'
 
 reiserfsck 2>&1 | grep reiserfsprogs | awk \